mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Use vendored go-swagger (#8087)
* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
This commit is contained in:
		
				
					committed by
					
						 Lauris BH
						Lauris BH
					
				
			
			
				
	
			
			
			
						parent
						
							4cb1bdddc8
						
					
				
				
					commit
					9fe4437bda
				
			
							
								
								
									
										2
									
								
								vendor/github.com/pelletier/go-toml/.dockerignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/pelletier/go-toml/.dockerignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| cmd/tomll/tomll | ||||
| cmd/tomljson/tomljson | ||||
							
								
								
									
										5
									
								
								vendor/github.com/pelletier/go-toml/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/pelletier/go-toml/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| test_program/test_program_bin | ||||
| fuzz/ | ||||
| cmd/tomll/tomll | ||||
| cmd/tomljson/tomljson | ||||
| cmd/tomltestgen/tomltestgen | ||||
							
								
								
									
										22
									
								
								vendor/github.com/pelletier/go-toml/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/pelletier/go-toml/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| sudo: false | ||||
| language: go | ||||
| go: | ||||
|   - 1.11.x | ||||
|   - 1.12.x | ||||
|   - tip | ||||
| matrix: | ||||
|   allow_failures: | ||||
|     - go: tip | ||||
|   fast_finish: true | ||||
| env: | ||||
|   - GO111MODULE=on | ||||
| script: | ||||
|   - if [ -n "$(go fmt ./...)" ]; then exit 1; fi | ||||
|   - go test github.com/pelletier/go-toml -race -coverprofile=coverage.txt -covermode=atomic | ||||
|   - go test github.com/pelletier/go-toml/cmd/tomljson | ||||
|   - go test github.com/pelletier/go-toml/cmd/tomll | ||||
|   - go test github.com/pelletier/go-toml/query | ||||
|   - ./benchmark.sh $TRAVIS_BRANCH https://github.com/$TRAVIS_REPO_SLUG.git | ||||
|  | ||||
| after_success: | ||||
|   - bash <(curl -s https://codecov.io/bash) | ||||
							
								
								
									
										132
									
								
								vendor/github.com/pelletier/go-toml/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/pelletier/go-toml/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| ## Contributing | ||||
|  | ||||
| Thank you for your interest in go-toml! We appreciate you considering | ||||
| contributing to go-toml! | ||||
|  | ||||
| The main goal is the project is to provide an easy-to-use TOML | ||||
| implementation for Go that gets the job done and gets out of your way – | ||||
| dealing with TOML is probably not the central piece of your project. | ||||
|  | ||||
| As the single maintainer of go-toml, time is scarce. All help, big or | ||||
| small, is more than welcomed! | ||||
|  | ||||
| ### Ask questions | ||||
|  | ||||
| Any question you may have, somebody else might have it too. Always feel | ||||
| free to ask them on the [issues tracker][issues-tracker].  We will try to | ||||
| answer them as clearly and quickly as possible, time permitting. | ||||
|  | ||||
| Asking questions also helps us identify areas where the documentation needs | ||||
| improvement, or new features that weren't envisioned before. Sometimes, a | ||||
| seemingly innocent question leads to the fix of a bug. Don't hesitate and | ||||
| ask away! | ||||
|  | ||||
| ### Improve the documentation | ||||
|  | ||||
| The best way to share your knowledge and experience with go-toml is to | ||||
| improve the documentation. Fix a typo, clarify an interface, add an | ||||
| example, anything goes! | ||||
|  | ||||
| The documentation is present in the [README][readme] and thorough the | ||||
| source code. On release, it gets updated on [GoDoc][godoc]. To make a | ||||
| change to the documentation, create a pull request with your proposed | ||||
| changes. For simple changes like that, the easiest way to go is probably | ||||
| the "Fork this project and edit the file" button on Github, displayed at | ||||
| the top right of the file. Unless it's a trivial change (for example a | ||||
| typo), provide a little bit of context in your pull request description or | ||||
| commit message. | ||||
|  | ||||
| ### Report a bug | ||||
|  | ||||
| Found a bug! Sorry to hear that :(. Help us and other track them down and | ||||
| fix by reporting it. [File a new bug report][bug-report] on the [issues | ||||
| tracker][issues-tracker]. The template should provide enough guidance on | ||||
| what to include. When in doubt: add more details! By reducing ambiguity and | ||||
| providing more information, it decreases back and forth and saves everyone | ||||
| time. | ||||
|  | ||||
| ### Code changes | ||||
|  | ||||
| Want to contribute a patch? Very happy to hear that! | ||||
|  | ||||
| First, some high-level rules: | ||||
|  | ||||
| * A short proposal with some POC code is better than a lengthy piece of | ||||
|   text with no code. Code speaks louder than words. | ||||
| * No backward-incompatible patch will be accepted unless discussed. | ||||
|   Sometimes it's hard, and Go's lack of versioning by default does not | ||||
|   help, but we try not to break people's programs unless we absolutely have | ||||
|   to. | ||||
| * If you are writing a new feature or extending an existing one, make sure | ||||
|   to write some documentation. | ||||
| * Bug fixes need to be accompanied with regression tests. | ||||
| * New code needs to be tested. | ||||
| * Your commit messages need to explain why the change is needed, even if | ||||
|   already included in the PR description. | ||||
|  | ||||
| It does sound like a lot, but those best practices are here to save time | ||||
| overall and continuously improve the quality of the project, which is | ||||
| something everyone benefits from. | ||||
|  | ||||
| #### Get started | ||||
|  | ||||
| The fairly standard code contribution process looks like that: | ||||
|  | ||||
| 1. [Fork the project][fork]. | ||||
| 2. Make your changes, commit on any branch you like. | ||||
| 3. [Open up a pull request][pull-request] | ||||
| 4. Review, potential ask for changes. | ||||
| 5. Merge. You're in! | ||||
|  | ||||
| Feel free to ask for help! You can create draft pull requests to gather | ||||
| some early feedback! | ||||
|  | ||||
| #### Run the tests | ||||
|  | ||||
| You can run tests for go-toml using Go's test tool: `go test ./...`. | ||||
| When creating a pull requests, all tests will be ran on Linux on a few Go | ||||
| versions (Travis CI), and on Windows using the latest Go version | ||||
| (AppVeyor). | ||||
|  | ||||
| #### Style | ||||
|  | ||||
| Try to look around and follow the same format and structure as the rest of | ||||
| the code. We enforce using `go fmt` on the whole code base. | ||||
|  | ||||
| --- | ||||
|  | ||||
| ### Maintainers-only | ||||
|  | ||||
| #### Merge pull request | ||||
|  | ||||
| Checklist: | ||||
|  | ||||
| * Passing CI. | ||||
| * Does not introduce backward-incompatible changes (unless discussed). | ||||
| * Has relevant doc changes. | ||||
| * Has relevant unit tests. | ||||
|  | ||||
| 1. Merge using "squash and merge". | ||||
| 2. Make sure to edit the commit message to keep all the useful information | ||||
|    nice and clean. | ||||
| 3. Make sure the commit title is clear and contains the PR number (#123). | ||||
|  | ||||
| #### New release | ||||
|  | ||||
| 1. Go to [releases][releases]. Click on "X commits to master since this | ||||
|    release". | ||||
| 2. Make note of all the changes. Look for backward incompatible changes, | ||||
|    new features, and bug fixes. | ||||
| 3. Pick the new version using the above and semver. | ||||
| 4. Create a [new release][new-release]. | ||||
| 5. Follow the same format as [1.1.0][release-110]. | ||||
|  | ||||
| [issues-tracker]: https://github.com/pelletier/go-toml/issues | ||||
| [bug-report]: https://github.com/pelletier/go-toml/issues/new?template=bug_report.md | ||||
| [godoc]: https://godoc.org/github.com/pelletier/go-toml | ||||
| [readme]: ./README.md | ||||
| [fork]: https://help.github.com/articles/fork-a-repo | ||||
| [pull-request]: https://help.github.com/en/articles/creating-a-pull-request | ||||
| [releases]: https://github.com/pelletier/go-toml/releases | ||||
| [new-release]: https://github.com/pelletier/go-toml/releases/new | ||||
| [release-110]: https://github.com/pelletier/go-toml/releases/tag/v1.1.0 | ||||
							
								
								
									
										10
									
								
								vendor/github.com/pelletier/go-toml/Dockerfile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/pelletier/go-toml/Dockerfile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| FROM golang:1.12-alpine3.9 as builder | ||||
| WORKDIR /go/src/github.com/pelletier/go-toml | ||||
| COPY . . | ||||
| ENV CGO_ENABLED=0 | ||||
| ENV GOOS=linux | ||||
| RUN go install ./... | ||||
|  | ||||
| FROM scratch | ||||
| COPY --from=builder /go/bin/tomll /usr/bin/tomll | ||||
| COPY --from=builder /go/bin/tomljson /usr/bin/tomljson | ||||
							
								
								
									
										21
									
								
								vendor/github.com/pelletier/go-toml/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/pelletier/go-toml/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton | ||||
|  | ||||
| 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. | ||||
							
								
								
									
										5
									
								
								vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| **Issue:** add link to pelletier/go-toml issue here | ||||
|  | ||||
| Explanation of what this pull request does. | ||||
|  | ||||
| More detailed description of the decisions being made and the reasons why (if the patch is non-trivial). | ||||
							
								
								
									
										145
									
								
								vendor/github.com/pelletier/go-toml/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/pelletier/go-toml/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| # go-toml | ||||
|  | ||||
| Go library for the [TOML](https://github.com/mojombo/toml) format. | ||||
|  | ||||
| This library supports TOML version | ||||
| [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) | ||||
|  | ||||
| [](http://godoc.org/github.com/pelletier/go-toml) | ||||
| [](https://github.com/pelletier/go-toml/blob/master/LICENSE) | ||||
| [](https://travis-ci.org/pelletier/go-toml) | ||||
| [](https://ci.appveyor.com/project/pelletier/go-toml/branch/master) | ||||
| [](https://codecov.io/gh/pelletier/go-toml) | ||||
| [](https://goreportcard.com/report/github.com/pelletier/go-toml) | ||||
| [](https://app.fossa.io/projects/git%2Bgithub.com%2Fpelletier%2Fgo-toml?ref=badge_shield) | ||||
|  | ||||
| ## Features | ||||
|  | ||||
| Go-toml provides the following features for using data parsed from TOML documents: | ||||
|  | ||||
| * Load TOML documents from files and string data | ||||
| * Easily navigate TOML structure using Tree | ||||
| * Mashaling and unmarshaling to and from data structures | ||||
| * Line & column position data for all parsed elements | ||||
| * [Query support similar to JSON-Path](query/) | ||||
| * Syntax errors contain line and column numbers | ||||
|  | ||||
| ## Import | ||||
|  | ||||
| ```go | ||||
| import "github.com/pelletier/go-toml" | ||||
| ``` | ||||
|  | ||||
| ## Usage example | ||||
|  | ||||
| Read a TOML document: | ||||
|  | ||||
| ```go | ||||
| config, _ := toml.Load(` | ||||
| [postgres] | ||||
| user = "pelletier" | ||||
| password = "mypassword"`) | ||||
| // retrieve data directly | ||||
| user := config.Get("postgres.user").(string) | ||||
|  | ||||
| // or using an intermediate object | ||||
| postgresConfig := config.Get("postgres").(*toml.Tree) | ||||
| password := postgresConfig.Get("password").(string) | ||||
| ``` | ||||
|  | ||||
| Or use Unmarshal: | ||||
|  | ||||
| ```go | ||||
| type Postgres struct { | ||||
|     User     string | ||||
|     Password string | ||||
| } | ||||
| type Config struct { | ||||
|     Postgres Postgres | ||||
| } | ||||
|  | ||||
| doc := []byte(` | ||||
| [Postgres] | ||||
| User = "pelletier" | ||||
| Password = "mypassword"`) | ||||
|  | ||||
| config := Config{} | ||||
| toml.Unmarshal(doc, &config) | ||||
| fmt.Println("user=", config.Postgres.User) | ||||
| ``` | ||||
|  | ||||
| Or use a query: | ||||
|  | ||||
| ```go | ||||
| // use a query to gather elements without walking the tree | ||||
| q, _ := query.Compile("$..[user,password]") | ||||
| results := q.Execute(config) | ||||
| for ii, item := range results.Values() { | ||||
|     fmt.Println("Query result %d: %v", ii, item) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| ## Documentation | ||||
|  | ||||
| The documentation and additional examples are available at | ||||
| [godoc.org](http://godoc.org/github.com/pelletier/go-toml). | ||||
|  | ||||
| ## Tools | ||||
|  | ||||
| Go-toml provides two handy command line tools: | ||||
|  | ||||
| * `tomll`: Reads TOML files and lint them. | ||||
|  | ||||
|     ``` | ||||
|     go install github.com/pelletier/go-toml/cmd/tomll | ||||
|     tomll --help | ||||
|     ``` | ||||
| * `tomljson`: Reads a TOML file and outputs its JSON representation. | ||||
|  | ||||
|     ``` | ||||
|     go install github.com/pelletier/go-toml/cmd/tomljson | ||||
|     tomljson --help | ||||
|     ``` | ||||
|  | ||||
| ### Docker image | ||||
|  | ||||
| Those tools are also availble as a Docker image from | ||||
| [dockerhub](https://hub.docker.com/r/pelletier/go-toml). For example, to | ||||
| use `tomljson`: | ||||
|  | ||||
| ``` | ||||
| docker run -v $PWD:/workdir pelletier/go-toml tomljson /workdir/example.toml | ||||
| ``` | ||||
|  | ||||
| Only master (`latest`) and tagged versions are published to dockerhub. You | ||||
| can build your own image as usual: | ||||
|  | ||||
| ``` | ||||
| docker build -t go-toml . | ||||
| ``` | ||||
|  | ||||
| ## Contribute | ||||
|  | ||||
| Feel free to report bugs and patches using GitHub's pull requests system on | ||||
| [pelletier/go-toml](https://github.com/pelletier/go-toml). Any feedback would be | ||||
| much appreciated! | ||||
|  | ||||
| ### Run tests | ||||
|  | ||||
| `go test ./...` | ||||
|  | ||||
| ### Fuzzing | ||||
|  | ||||
| The script `./fuzz.sh` is available to | ||||
| run [go-fuzz](https://github.com/dvyukov/go-fuzz) on go-toml. | ||||
|  | ||||
| ## Versioning | ||||
|  | ||||
| Go-toml follows [Semantic Versioning](http://semver.org/). The supported version | ||||
| of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of | ||||
| this document. The last two major versions of Go are supported | ||||
| (see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)). | ||||
|  | ||||
| ## License | ||||
|  | ||||
| The MIT License (MIT). Read [LICENSE](LICENSE). | ||||
							
								
								
									
										34
									
								
								vendor/github.com/pelletier/go-toml/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/pelletier/go-toml/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| version: "{build}" | ||||
|  | ||||
| # Source Config | ||||
| clone_folder: c:\gopath\src\github.com\pelletier\go-toml | ||||
|  | ||||
| # Build host | ||||
| environment: | ||||
|   GOPATH: c:\gopath | ||||
|   DEPTESTBYPASS501: 1 | ||||
|   GOVERSION: 1.12 | ||||
|   GO111MODULE: on | ||||
|  | ||||
| init: | ||||
|   - git config --global core.autocrlf input | ||||
|  | ||||
| # Build | ||||
| install: | ||||
|   # Install the specific Go version. | ||||
|   - rmdir c:\go /s /q | ||||
|   - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.msi | ||||
|   - msiexec /i go%GOVERSION%.windows-amd64.msi /q | ||||
|   - choco install bzr | ||||
|   - set Path=c:\go\bin;c:\gopath\bin;C:\Program Files (x86)\Bazaar\;C:\Program Files\Mercurial\%Path% | ||||
|   - go version | ||||
|   - go env | ||||
|  | ||||
| build: false | ||||
| deploy: false | ||||
|  | ||||
| test_script: | ||||
|   - go test github.com/pelletier/go-toml | ||||
|   - go test github.com/pelletier/go-toml/cmd/tomljson | ||||
|   - go test github.com/pelletier/go-toml/cmd/tomll | ||||
|   - go test github.com/pelletier/go-toml/query | ||||
							
								
								
									
										164
									
								
								vendor/github.com/pelletier/go-toml/benchmark.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								vendor/github.com/pelletier/go-toml/benchmark.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| { | ||||
|     "array": { | ||||
|         "key1": [ | ||||
|             1, | ||||
|             2, | ||||
|             3 | ||||
|         ], | ||||
|         "key2": [ | ||||
|             "red", | ||||
|             "yellow", | ||||
|             "green" | ||||
|         ], | ||||
|         "key3": [ | ||||
|             [ | ||||
|                 1, | ||||
|                 2 | ||||
|             ], | ||||
|             [ | ||||
|                 3, | ||||
|                 4, | ||||
|                 5 | ||||
|             ] | ||||
|         ], | ||||
|         "key4": [ | ||||
|             [ | ||||
|                 1, | ||||
|                 2 | ||||
|             ], | ||||
|             [ | ||||
|                 "a", | ||||
|                 "b", | ||||
|                 "c" | ||||
|             ] | ||||
|         ], | ||||
|         "key5": [ | ||||
|             1, | ||||
|             2, | ||||
|             3 | ||||
|         ], | ||||
|         "key6": [ | ||||
|             1, | ||||
|             2 | ||||
|         ] | ||||
|     }, | ||||
|     "boolean": { | ||||
|         "False": false, | ||||
|         "True": true | ||||
|     }, | ||||
|     "datetime": { | ||||
|         "key1": "1979-05-27T07:32:00Z", | ||||
|         "key2": "1979-05-27T00:32:00-07:00", | ||||
|         "key3": "1979-05-27T00:32:00.999999-07:00" | ||||
|     }, | ||||
|     "float": { | ||||
|         "both": { | ||||
|             "key": 6.626e-34 | ||||
|         }, | ||||
|         "exponent": { | ||||
|             "key1": 5e+22, | ||||
|             "key2": 1000000, | ||||
|             "key3": -0.02 | ||||
|         }, | ||||
|         "fractional": { | ||||
|             "key1": 1, | ||||
|             "key2": 3.1415, | ||||
|             "key3": -0.01 | ||||
|         }, | ||||
|         "underscores": { | ||||
|             "key1": 9224617.445991227, | ||||
|             "key2": 1e+100 | ||||
|         } | ||||
|     }, | ||||
|     "fruit": [{ | ||||
|             "name": "apple", | ||||
|             "physical": { | ||||
|                 "color": "red", | ||||
|                 "shape": "round" | ||||
|             }, | ||||
|             "variety": [{ | ||||
|                     "name": "red delicious" | ||||
|                 }, | ||||
|                 { | ||||
|                     "name": "granny smith" | ||||
|                 } | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             "name": "banana", | ||||
|             "variety": [{ | ||||
|                 "name": "plantain" | ||||
|             }] | ||||
|         } | ||||
|     ], | ||||
|     "integer": { | ||||
|         "key1": 99, | ||||
|         "key2": 42, | ||||
|         "key3": 0, | ||||
|         "key4": -17, | ||||
|         "underscores": { | ||||
|             "key1": 1000, | ||||
|             "key2": 5349221, | ||||
|             "key3": 12345 | ||||
|         } | ||||
|     }, | ||||
|     "products": [{ | ||||
|             "name": "Hammer", | ||||
|             "sku": 738594937 | ||||
|         }, | ||||
|         {}, | ||||
|         { | ||||
|             "color": "gray", | ||||
|             "name": "Nail", | ||||
|             "sku": 284758393 | ||||
|         } | ||||
|     ], | ||||
|     "string": { | ||||
|         "basic": { | ||||
|             "basic": "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF." | ||||
|         }, | ||||
|         "literal": { | ||||
|             "multiline": { | ||||
|                 "lines": "The first newline is\ntrimmed in raw strings.\n   All other whitespace\n   is preserved.\n", | ||||
|                 "regex2": "I [dw]on't need \\d{2} apples" | ||||
|             }, | ||||
|             "quoted": "Tom \"Dubs\" Preston-Werner", | ||||
|             "regex": "\u003c\\i\\c*\\s*\u003e", | ||||
|             "winpath": "C:\\Users\\nodejs\\templates", | ||||
|             "winpath2": "\\\\ServerX\\admin$\\system32\\" | ||||
|         }, | ||||
|         "multiline": { | ||||
|             "continued": { | ||||
|                 "key1": "The quick brown fox jumps over the lazy dog.", | ||||
|                 "key2": "The quick brown fox jumps over the lazy dog.", | ||||
|                 "key3": "The quick brown fox jumps over the lazy dog." | ||||
|             }, | ||||
|             "key1": "One\nTwo", | ||||
|             "key2": "One\nTwo", | ||||
|             "key3": "One\nTwo" | ||||
|         } | ||||
|     }, | ||||
|     "table": { | ||||
|         "inline": { | ||||
|             "name": { | ||||
|                 "first": "Tom", | ||||
|                 "last": "Preston-Werner" | ||||
|             }, | ||||
|             "point": { | ||||
|                 "x": 1, | ||||
|                 "y": 2 | ||||
|             } | ||||
|         }, | ||||
|         "key": "value", | ||||
|         "subtable": { | ||||
|             "key": "another value" | ||||
|         } | ||||
|     }, | ||||
|     "x": { | ||||
|         "y": { | ||||
|             "z": { | ||||
|                 "w": {} | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								vendor/github.com/pelletier/go-toml/benchmark.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/pelletier/go-toml/benchmark.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -e | ||||
|  | ||||
| reference_ref=${1:-master} | ||||
| reference_git=${2:-.} | ||||
|  | ||||
| if ! `hash benchstat 2>/dev/null`; then | ||||
|     echo "Installing benchstat" | ||||
|     go get golang.org/x/perf/cmd/benchstat | ||||
|     go install golang.org/x/perf/cmd/benchstat | ||||
| fi | ||||
|  | ||||
| tempdir=`mktemp -d /tmp/go-toml-benchmark-XXXXXX` | ||||
| ref_tempdir="${tempdir}/ref" | ||||
| ref_benchmark="${ref_tempdir}/benchmark-`echo -n ${reference_ref}|tr -s '/' '-'`.txt" | ||||
| local_benchmark="`pwd`/benchmark-local.txt" | ||||
|  | ||||
| echo "=== ${reference_ref} (${ref_tempdir})" | ||||
| git clone ${reference_git} ${ref_tempdir} >/dev/null 2>/dev/null | ||||
| pushd ${ref_tempdir} >/dev/null | ||||
| git checkout ${reference_ref} >/dev/null 2>/dev/null | ||||
| go test -bench=. -benchmem | tee ${ref_benchmark} | ||||
| popd >/dev/null | ||||
|  | ||||
| echo "" | ||||
| echo "=== local" | ||||
| go test -bench=. -benchmem  | tee ${local_benchmark} | ||||
|  | ||||
| echo "" | ||||
| echo "=== diff" | ||||
| benchstat -delta-test=none ${ref_benchmark} ${local_benchmark} | ||||
							
								
								
									
										244
									
								
								vendor/github.com/pelletier/go-toml/benchmark.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								vendor/github.com/pelletier/go-toml/benchmark.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| ################################################################################ | ||||
| ## Comment | ||||
|  | ||||
| # Speak your mind with the hash symbol. They go from the symbol to the end of | ||||
| # the line. | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Table | ||||
|  | ||||
| # Tables (also known as hash tables or dictionaries) are collections of | ||||
| # key/value pairs. They appear in square brackets on a line by themselves. | ||||
|  | ||||
| [table] | ||||
|  | ||||
| key = "value" # Yeah, you can do this. | ||||
|  | ||||
| # Nested tables are denoted by table names with dots in them. Name your tables | ||||
| # whatever crap you please, just don't use #, ., [ or ]. | ||||
|  | ||||
| [table.subtable] | ||||
|  | ||||
| key = "another value" | ||||
|  | ||||
| # You don't need to specify all the super-tables if you don't want to. TOML | ||||
| # knows how to do it for you. | ||||
|  | ||||
| # [x] you | ||||
| # [x.y] don't | ||||
| # [x.y.z] need these | ||||
| [x.y.z.w] # for this to work | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Inline Table | ||||
|  | ||||
| # Inline tables provide a more compact syntax for expressing tables. They are | ||||
| # especially useful for grouped data that can otherwise quickly become verbose. | ||||
| # Inline tables are enclosed in curly braces `{` and `}`. No newlines are | ||||
| # allowed between the curly braces unless they are valid within a value. | ||||
|  | ||||
| [table.inline] | ||||
|  | ||||
| name = { first = "Tom", last = "Preston-Werner" } | ||||
| point = { x = 1, y = 2 } | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## String | ||||
|  | ||||
| # There are four ways to express strings: basic, multi-line basic, literal, and | ||||
| # multi-line literal. All strings must contain only valid UTF-8 characters. | ||||
|  | ||||
| [string.basic] | ||||
|  | ||||
| basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." | ||||
|  | ||||
| [string.multiline] | ||||
|  | ||||
| # The following strings are byte-for-byte equivalent: | ||||
| key1 = "One\nTwo" | ||||
| key2 = """One\nTwo""" | ||||
| key3 = """ | ||||
| One | ||||
| Two""" | ||||
|  | ||||
| [string.multiline.continued] | ||||
|  | ||||
| # The following strings are byte-for-byte equivalent: | ||||
| key1 = "The quick brown fox jumps over the lazy dog." | ||||
|  | ||||
| key2 = """ | ||||
| The quick brown \ | ||||
|  | ||||
|  | ||||
|   fox jumps over \ | ||||
|     the lazy dog.""" | ||||
|  | ||||
| key3 = """\ | ||||
|        The quick brown \ | ||||
|        fox jumps over \ | ||||
|        the lazy dog.\ | ||||
|        """ | ||||
|  | ||||
| [string.literal] | ||||
|  | ||||
| # What you see is what you get. | ||||
| winpath  = 'C:\Users\nodejs\templates' | ||||
| winpath2 = '\\ServerX\admin$\system32\' | ||||
| quoted   = 'Tom "Dubs" Preston-Werner' | ||||
| regex    = '<\i\c*\s*>' | ||||
|  | ||||
|  | ||||
| [string.literal.multiline] | ||||
|  | ||||
| regex2 = '''I [dw]on't need \d{2} apples''' | ||||
| lines  = ''' | ||||
| The first newline is | ||||
| trimmed in raw strings. | ||||
|    All other whitespace | ||||
|    is preserved. | ||||
| ''' | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Integer | ||||
|  | ||||
| # Integers are whole numbers. Positive numbers may be prefixed with a plus sign. | ||||
| # Negative numbers are prefixed with a minus sign. | ||||
|  | ||||
| [integer] | ||||
|  | ||||
| key1 = +99 | ||||
| key2 = 42 | ||||
| key3 = 0 | ||||
| key4 = -17 | ||||
|  | ||||
| [integer.underscores] | ||||
|  | ||||
| # For large numbers, you may use underscores to enhance readability. Each | ||||
| # underscore must be surrounded by at least one digit. | ||||
| key1 = 1_000 | ||||
| key2 = 5_349_221 | ||||
| key3 = 1_2_3_4_5     # valid but inadvisable | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Float | ||||
|  | ||||
| # A float consists of an integer part (which may be prefixed with a plus or | ||||
| # minus sign) followed by a fractional part and/or an exponent part. | ||||
|  | ||||
| [float.fractional] | ||||
|  | ||||
| key1 = +1.0 | ||||
| key2 = 3.1415 | ||||
| key3 = -0.01 | ||||
|  | ||||
| [float.exponent] | ||||
|  | ||||
| key1 = 5e+22 | ||||
| key2 = 1e6 | ||||
| key3 = -2E-2 | ||||
|  | ||||
| [float.both] | ||||
|  | ||||
| key = 6.626e-34 | ||||
|  | ||||
| [float.underscores] | ||||
|  | ||||
| key1 = 9_224_617.445_991_228_313 | ||||
| key2 = 1e1_00 | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Boolean | ||||
|  | ||||
| # Booleans are just the tokens you're used to. Always lowercase. | ||||
|  | ||||
| [boolean] | ||||
|  | ||||
| True = true | ||||
| False = false | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Datetime | ||||
|  | ||||
| # Datetimes are RFC 3339 dates. | ||||
|  | ||||
| [datetime] | ||||
|  | ||||
| key1 = 1979-05-27T07:32:00Z | ||||
| key2 = 1979-05-27T00:32:00-07:00 | ||||
| key3 = 1979-05-27T00:32:00.999999-07:00 | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Array | ||||
|  | ||||
| # Arrays are square brackets with other primitives inside. Whitespace is | ||||
| # ignored. Elements are separated by commas. Data types may not be mixed. | ||||
|  | ||||
| [array] | ||||
|  | ||||
| key1 = [ 1, 2, 3 ] | ||||
| key2 = [ "red", "yellow", "green" ] | ||||
| key3 = [ [ 1, 2 ], [3, 4, 5] ] | ||||
| #key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok | ||||
|  | ||||
| # Arrays can also be multiline. So in addition to ignoring whitespace, arrays | ||||
| # also ignore newlines between the brackets.  Terminating commas are ok before | ||||
| # the closing bracket. | ||||
|  | ||||
| key5 = [ | ||||
|   1, 2, 3 | ||||
| ] | ||||
| key6 = [ | ||||
|   1, | ||||
|   2, # this is ok | ||||
| ] | ||||
|  | ||||
|  | ||||
| ################################################################################ | ||||
| ## Array of Tables | ||||
|  | ||||
| # These can be expressed by using a table name in double brackets. Each table | ||||
| # with the same double bracketed name will be an element in the array. The | ||||
| # tables are inserted in the order encountered. | ||||
|  | ||||
| [[products]] | ||||
|  | ||||
| name = "Hammer" | ||||
| sku = 738594937 | ||||
|  | ||||
| [[products]] | ||||
|  | ||||
| [[products]] | ||||
|  | ||||
| name = "Nail" | ||||
| sku = 284758393 | ||||
| color = "gray" | ||||
|  | ||||
|  | ||||
| # You can create nested arrays of tables as well. | ||||
|  | ||||
| [[fruit]] | ||||
|   name = "apple" | ||||
|  | ||||
|   [fruit.physical] | ||||
|     color = "red" | ||||
|     shape = "round" | ||||
|  | ||||
|   [[fruit.variety]] | ||||
|     name = "red delicious" | ||||
|  | ||||
|   [[fruit.variety]] | ||||
|     name = "granny smith" | ||||
|  | ||||
| [[fruit]] | ||||
|   name = "banana" | ||||
|  | ||||
|   [[fruit.variety]] | ||||
|     name = "plantain" | ||||
							
								
								
									
										121
									
								
								vendor/github.com/pelletier/go-toml/benchmark.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								vendor/github.com/pelletier/go-toml/benchmark.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| --- | ||||
| array: | ||||
|   key1: | ||||
|   - 1 | ||||
|   - 2 | ||||
|   - 3 | ||||
|   key2: | ||||
|   - red | ||||
|   - yellow | ||||
|   - green | ||||
|   key3: | ||||
|   - - 1 | ||||
|     - 2 | ||||
|   - - 3 | ||||
|     - 4 | ||||
|     - 5 | ||||
|   key4: | ||||
|   - - 1 | ||||
|     - 2 | ||||
|   - - a | ||||
|     - b | ||||
|     - c | ||||
|   key5: | ||||
|   - 1 | ||||
|   - 2 | ||||
|   - 3 | ||||
|   key6: | ||||
|   - 1 | ||||
|   - 2 | ||||
| boolean: | ||||
|   'False': false | ||||
|   'True': true | ||||
| datetime: | ||||
|   key1: '1979-05-27T07:32:00Z' | ||||
|   key2: '1979-05-27T00:32:00-07:00' | ||||
|   key3: '1979-05-27T00:32:00.999999-07:00' | ||||
| float: | ||||
|   both: | ||||
|     key: 6.626e-34 | ||||
|   exponent: | ||||
|     key1: 5.0e+22 | ||||
|     key2: 1000000 | ||||
|     key3: -0.02 | ||||
|   fractional: | ||||
|     key1: 1 | ||||
|     key2: 3.1415 | ||||
|     key3: -0.01 | ||||
|   underscores: | ||||
|     key1: 9224617.445991227 | ||||
|     key2: 1.0e+100 | ||||
| fruit: | ||||
| - name: apple | ||||
|   physical: | ||||
|     color: red | ||||
|     shape: round | ||||
|   variety: | ||||
|   - name: red delicious | ||||
|   - name: granny smith | ||||
| - name: banana | ||||
|   variety: | ||||
|   - name: plantain | ||||
| integer: | ||||
|   key1: 99 | ||||
|   key2: 42 | ||||
|   key3: 0 | ||||
|   key4: -17 | ||||
|   underscores: | ||||
|     key1: 1000 | ||||
|     key2: 5349221 | ||||
|     key3: 12345 | ||||
| products: | ||||
| - name: Hammer | ||||
|   sku: 738594937 | ||||
| - {} | ||||
| - color: gray | ||||
|   name: Nail | ||||
|   sku: 284758393 | ||||
| string: | ||||
|   basic: | ||||
|     basic: "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF." | ||||
|   literal: | ||||
|     multiline: | ||||
|       lines: | | ||||
|         The first newline is | ||||
|         trimmed in raw strings. | ||||
|            All other whitespace | ||||
|            is preserved. | ||||
|       regex2: I [dw]on't need \d{2} apples | ||||
|     quoted: Tom "Dubs" Preston-Werner | ||||
|     regex: "<\\i\\c*\\s*>" | ||||
|     winpath: C:\Users\nodejs\templates | ||||
|     winpath2: "\\\\ServerX\\admin$\\system32\\" | ||||
|   multiline: | ||||
|     continued: | ||||
|       key1: The quick brown fox jumps over the lazy dog. | ||||
|       key2: The quick brown fox jumps over the lazy dog. | ||||
|       key3: The quick brown fox jumps over the lazy dog. | ||||
|     key1: |- | ||||
|       One | ||||
|       Two | ||||
|     key2: |- | ||||
|       One | ||||
|       Two | ||||
|     key3: |- | ||||
|       One | ||||
|       Two | ||||
| table: | ||||
|   inline: | ||||
|     name: | ||||
|       first: Tom | ||||
|       last: Preston-Werner | ||||
|     point: | ||||
|       x: 1 | ||||
|       y: 2 | ||||
|   key: value | ||||
|   subtable: | ||||
|     key: another value | ||||
| x: | ||||
|   y: | ||||
|     z: | ||||
|       w: {} | ||||
							
								
								
									
										23
									
								
								vendor/github.com/pelletier/go-toml/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/pelletier/go-toml/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| // Package toml is a TOML parser and manipulation library. | ||||
| // | ||||
| // This version supports the specification as described in | ||||
| // https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md | ||||
| // | ||||
| // Marshaling | ||||
| // | ||||
| // Go-toml can marshal and unmarshal TOML documents from and to data | ||||
| // structures. | ||||
| // | ||||
| // TOML document as a tree | ||||
| // | ||||
| // Go-toml can operate on a TOML document as a tree. Use one of the Load* | ||||
| // functions to parse TOML data and obtain a Tree instance, then one of its | ||||
| // methods to manipulate the tree. | ||||
| // | ||||
| // JSONPath-like queries | ||||
| // | ||||
| // The package github.com/pelletier/go-toml/query implements a system | ||||
| // similar to JSONPath to quickly retrieve elements of a TOML document using a | ||||
| // single expression. See the package documentation for more information. | ||||
| // | ||||
| package toml | ||||
							
								
								
									
										29
									
								
								vendor/github.com/pelletier/go-toml/example-crlf.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/pelletier/go-toml/example-crlf.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # This is a TOML document. Boom. | ||||
|  | ||||
| title = "TOML Example" | ||||
|  | ||||
| [owner] | ||||
| name = "Tom Preston-Werner" | ||||
| organization = "GitHub" | ||||
| bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." | ||||
| dob = 1979-05-27T07:32:00Z # First class dates? Why not? | ||||
|  | ||||
| [database] | ||||
| server = "192.168.1.1" | ||||
| ports = [ 8001, 8001, 8002 ] | ||||
| connection_max = 5000 | ||||
| enabled = true | ||||
|  | ||||
| [servers] | ||||
|  | ||||
|   # You can indent as you please. Tabs or spaces. TOML don't care. | ||||
|   [servers.alpha] | ||||
|   ip = "10.0.0.1" | ||||
|   dc = "eqdc10" | ||||
|  | ||||
|   [servers.beta] | ||||
|   ip = "10.0.0.2" | ||||
|   dc = "eqdc10" | ||||
|  | ||||
| [clients] | ||||
| data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it | ||||
							
								
								
									
										29
									
								
								vendor/github.com/pelletier/go-toml/example.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/pelletier/go-toml/example.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| # This is a TOML document. Boom. | ||||
|  | ||||
| title = "TOML Example" | ||||
|  | ||||
| [owner] | ||||
| name = "Tom Preston-Werner" | ||||
| organization = "GitHub" | ||||
| bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." | ||||
| dob = 1979-05-27T07:32:00Z # First class dates? Why not? | ||||
|  | ||||
| [database] | ||||
| server = "192.168.1.1" | ||||
| ports = [ 8001, 8001, 8002 ] | ||||
| connection_max = 5000 | ||||
| enabled = true | ||||
|  | ||||
| [servers] | ||||
|  | ||||
|   # You can indent as you please. Tabs or spaces. TOML don't care. | ||||
|   [servers.alpha] | ||||
|   ip = "10.0.0.1" | ||||
|   dc = "eqdc10" | ||||
|  | ||||
|   [servers.beta] | ||||
|   ip = "10.0.0.2" | ||||
|   dc = "eqdc10" | ||||
|  | ||||
| [clients] | ||||
| data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it | ||||
							
								
								
									
										31
									
								
								vendor/github.com/pelletier/go-toml/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/pelletier/go-toml/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // +build gofuzz | ||||
|  | ||||
| package toml | ||||
|  | ||||
| func Fuzz(data []byte) int { | ||||
| 	tree, err := LoadBytes(data) | ||||
| 	if err != nil { | ||||
| 		if tree != nil { | ||||
| 			panic("tree must be nil if there is an error") | ||||
| 		} | ||||
| 		return 0 | ||||
| 	} | ||||
|  | ||||
| 	str, err := tree.ToTomlString() | ||||
| 	if err != nil { | ||||
| 		if str != "" { | ||||
| 			panic(`str must be "" if there is an error`) | ||||
| 		} | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	tree, err = Load(str) | ||||
| 	if err != nil { | ||||
| 		if tree != nil { | ||||
| 			panic("tree must be nil if there is an error") | ||||
| 		} | ||||
| 		return 0 | ||||
| 	} | ||||
|  | ||||
| 	return 1 | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/github.com/pelletier/go-toml/fuzz.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/pelletier/go-toml/fuzz.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #! /bin/sh | ||||
| set -eu | ||||
|  | ||||
| go get github.com/dvyukov/go-fuzz/go-fuzz | ||||
| go get github.com/dvyukov/go-fuzz/go-fuzz-build | ||||
|  | ||||
| if [ ! -e toml-fuzz.zip ]; then | ||||
|     go-fuzz-build github.com/pelletier/go-toml | ||||
| fi | ||||
|  | ||||
| rm -fr fuzz | ||||
| mkdir -p fuzz/corpus | ||||
| cp *.toml fuzz/corpus | ||||
|  | ||||
| go-fuzz -bin=toml-fuzz.zip -workdir=fuzz | ||||
							
								
								
									
										9
									
								
								vendor/github.com/pelletier/go-toml/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/pelletier/go-toml/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| module github.com/pelletier/go-toml | ||||
|  | ||||
| go 1.12 | ||||
|  | ||||
| require ( | ||||
| 	github.com/BurntSushi/toml v0.3.1 | ||||
| 	github.com/davecgh/go-spew v1.1.1 | ||||
| 	gopkg.in/yaml.v2 v2.2.2 | ||||
| ) | ||||
							
								
								
									
										7
									
								
								vendor/github.com/pelletier/go-toml/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/pelletier/go-toml/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
							
								
								
									
										113
									
								
								vendor/github.com/pelletier/go-toml/keysparsing.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								vendor/github.com/pelletier/go-toml/keysparsing.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| // Parsing keys handling both bare and quoted keys. | ||||
|  | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"unicode" | ||||
| ) | ||||
|  | ||||
| // Convert the bare key group string to an array. | ||||
| // The input supports double quotation and single quotation, | ||||
| // but escape sequences are not supported. Lexers must unescape them beforehand. | ||||
| func parseKey(key string) ([]string, error) { | ||||
| 	runes := []rune(key) | ||||
| 	var groups []string | ||||
|  | ||||
| 	if len(key) == 0 { | ||||
| 		return nil, errors.New("empty key") | ||||
| 	} | ||||
|  | ||||
| 	idx := 0 | ||||
| 	for idx < len(runes) { | ||||
| 		for ; idx < len(runes) && isSpace(runes[idx]); idx++ { | ||||
| 			// skip leading whitespace | ||||
| 		} | ||||
| 		if idx >= len(runes) { | ||||
| 			break | ||||
| 		} | ||||
| 		r := runes[idx] | ||||
| 		if isValidBareChar(r) { | ||||
| 			// parse bare key | ||||
| 			startIdx := idx | ||||
| 			endIdx := -1 | ||||
| 			idx++ | ||||
| 			for idx < len(runes) { | ||||
| 				r = runes[idx] | ||||
| 				if isValidBareChar(r) { | ||||
| 					idx++ | ||||
| 				} else if r == '.' { | ||||
| 					endIdx = idx | ||||
| 					break | ||||
| 				} else if isSpace(r) { | ||||
| 					endIdx = idx | ||||
| 					for ; idx < len(runes) && isSpace(runes[idx]); idx++ { | ||||
| 						// skip trailing whitespace | ||||
| 					} | ||||
| 					if idx < len(runes) && runes[idx] != '.' { | ||||
| 						return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx]) | ||||
| 					} | ||||
| 					break | ||||
| 				} else { | ||||
| 					return nil, fmt.Errorf("invalid bare key character: %c", r) | ||||
| 				} | ||||
| 			} | ||||
| 			if endIdx == -1 { | ||||
| 				endIdx = idx | ||||
| 			} | ||||
| 			groups = append(groups, string(runes[startIdx:endIdx])) | ||||
| 		} else if r == '\'' { | ||||
| 			// parse single quoted key | ||||
| 			idx++ | ||||
| 			startIdx := idx | ||||
| 			for { | ||||
| 				if idx >= len(runes) { | ||||
| 					return nil, fmt.Errorf("unclosed single-quoted key") | ||||
| 				} | ||||
| 				r = runes[idx] | ||||
| 				if r == '\'' { | ||||
| 					groups = append(groups, string(runes[startIdx:idx])) | ||||
| 					idx++ | ||||
| 					break | ||||
| 				} | ||||
| 				idx++ | ||||
| 			} | ||||
| 		} else if r == '"' { | ||||
| 			// parse double quoted key | ||||
| 			idx++ | ||||
| 			startIdx := idx | ||||
| 			for { | ||||
| 				if idx >= len(runes) { | ||||
| 					return nil, fmt.Errorf("unclosed double-quoted key") | ||||
| 				} | ||||
| 				r = runes[idx] | ||||
| 				if r == '"' { | ||||
| 					groups = append(groups, string(runes[startIdx:idx])) | ||||
| 					idx++ | ||||
| 					break | ||||
| 				} | ||||
| 				idx++ | ||||
| 			} | ||||
| 		} else if r == '.' { | ||||
| 			idx++ | ||||
| 			if idx >= len(runes) { | ||||
| 				return nil, fmt.Errorf("unexpected end of key") | ||||
| 			} | ||||
| 			r = runes[idx] | ||||
| 			if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' { | ||||
| 				return nil, fmt.Errorf("expecting key part after dot") | ||||
| 			} | ||||
| 		} else { | ||||
| 			return nil, fmt.Errorf("invalid key character: %c", r) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(groups) == 0 { | ||||
| 		return nil, fmt.Errorf("empty key") | ||||
| 	} | ||||
| 	return groups, nil | ||||
| } | ||||
|  | ||||
| func isValidBareChar(r rune) bool { | ||||
| 	return isAlphanumeric(r) || r == '-' || unicode.IsNumber(r) | ||||
| } | ||||
							
								
								
									
										752
									
								
								vendor/github.com/pelletier/go-toml/lexer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										752
									
								
								vendor/github.com/pelletier/go-toml/lexer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,752 @@ | ||||
| // TOML lexer. | ||||
| // | ||||
| // Written using the principles developed by Rob Pike in | ||||
| // http://www.youtube.com/watch?v=HxaD_trXwRE | ||||
|  | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var dateRegexp *regexp.Regexp | ||||
|  | ||||
| // Define state functions | ||||
| type tomlLexStateFn func() tomlLexStateFn | ||||
|  | ||||
| // Define lexer | ||||
| type tomlLexer struct { | ||||
| 	inputIdx          int | ||||
| 	input             []rune // Textual source | ||||
| 	currentTokenStart int | ||||
| 	currentTokenStop  int | ||||
| 	tokens            []token | ||||
| 	depth             int | ||||
| 	line              int | ||||
| 	col               int | ||||
| 	endbufferLine     int | ||||
| 	endbufferCol      int | ||||
| } | ||||
|  | ||||
| // Basic read operations on input | ||||
|  | ||||
| func (l *tomlLexer) read() rune { | ||||
| 	r := l.peek() | ||||
| 	if r == '\n' { | ||||
| 		l.endbufferLine++ | ||||
| 		l.endbufferCol = 1 | ||||
| 	} else { | ||||
| 		l.endbufferCol++ | ||||
| 	} | ||||
| 	l.inputIdx++ | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) next() rune { | ||||
| 	r := l.read() | ||||
|  | ||||
| 	if r != eof { | ||||
| 		l.currentTokenStop++ | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) ignore() { | ||||
| 	l.currentTokenStart = l.currentTokenStop | ||||
| 	l.line = l.endbufferLine | ||||
| 	l.col = l.endbufferCol | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) skip() { | ||||
| 	l.next() | ||||
| 	l.ignore() | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) fastForward(n int) { | ||||
| 	for i := 0; i < n; i++ { | ||||
| 		l.next() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) emitWithValue(t tokenType, value string) { | ||||
| 	l.tokens = append(l.tokens, token{ | ||||
| 		Position: Position{l.line, l.col}, | ||||
| 		typ:      t, | ||||
| 		val:      value, | ||||
| 	}) | ||||
| 	l.ignore() | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) emit(t tokenType) { | ||||
| 	l.emitWithValue(t, string(l.input[l.currentTokenStart:l.currentTokenStop])) | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) peek() rune { | ||||
| 	if l.inputIdx >= len(l.input) { | ||||
| 		return eof | ||||
| 	} | ||||
| 	return l.input[l.inputIdx] | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) peekString(size int) string { | ||||
| 	maxIdx := len(l.input) | ||||
| 	upperIdx := l.inputIdx + size // FIXME: potential overflow | ||||
| 	if upperIdx > maxIdx { | ||||
| 		upperIdx = maxIdx | ||||
| 	} | ||||
| 	return string(l.input[l.inputIdx:upperIdx]) | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) follow(next string) bool { | ||||
| 	return next == l.peekString(len(next)) | ||||
| } | ||||
|  | ||||
| // Error management | ||||
|  | ||||
| func (l *tomlLexer) errorf(format string, args ...interface{}) tomlLexStateFn { | ||||
| 	l.tokens = append(l.tokens, token{ | ||||
| 		Position: Position{l.line, l.col}, | ||||
| 		typ:      tokenError, | ||||
| 		val:      fmt.Sprintf(format, args...), | ||||
| 	}) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // State functions | ||||
|  | ||||
| func (l *tomlLexer) lexVoid() tomlLexStateFn { | ||||
| 	for { | ||||
| 		next := l.peek() | ||||
| 		switch next { | ||||
| 		case '[': | ||||
| 			return l.lexTableKey | ||||
| 		case '#': | ||||
| 			return l.lexComment(l.lexVoid) | ||||
| 		case '=': | ||||
| 			return l.lexEqual | ||||
| 		case '\r': | ||||
| 			fallthrough | ||||
| 		case '\n': | ||||
| 			l.skip() | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if isSpace(next) { | ||||
| 			l.skip() | ||||
| 		} | ||||
|  | ||||
| 		if l.depth > 0 { | ||||
| 			return l.lexRvalue | ||||
| 		} | ||||
|  | ||||
| 		if isKeyStartChar(next) { | ||||
| 			return l.lexKey | ||||
| 		} | ||||
|  | ||||
| 		if next == eof { | ||||
| 			l.next() | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	l.emit(tokenEOF) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexRvalue() tomlLexStateFn { | ||||
| 	for { | ||||
| 		next := l.peek() | ||||
| 		switch next { | ||||
| 		case '.': | ||||
| 			return l.errorf("cannot start float with a dot") | ||||
| 		case '=': | ||||
| 			return l.lexEqual | ||||
| 		case '[': | ||||
| 			l.depth++ | ||||
| 			return l.lexLeftBracket | ||||
| 		case ']': | ||||
| 			l.depth-- | ||||
| 			return l.lexRightBracket | ||||
| 		case '{': | ||||
| 			return l.lexLeftCurlyBrace | ||||
| 		case '}': | ||||
| 			return l.lexRightCurlyBrace | ||||
| 		case '#': | ||||
| 			return l.lexComment(l.lexRvalue) | ||||
| 		case '"': | ||||
| 			return l.lexString | ||||
| 		case '\'': | ||||
| 			return l.lexLiteralString | ||||
| 		case ',': | ||||
| 			return l.lexComma | ||||
| 		case '\r': | ||||
| 			fallthrough | ||||
| 		case '\n': | ||||
| 			l.skip() | ||||
| 			if l.depth == 0 { | ||||
| 				return l.lexVoid | ||||
| 			} | ||||
| 			return l.lexRvalue | ||||
| 		case '_': | ||||
| 			return l.errorf("cannot start number with underscore") | ||||
| 		} | ||||
|  | ||||
| 		if l.follow("true") { | ||||
| 			return l.lexTrue | ||||
| 		} | ||||
|  | ||||
| 		if l.follow("false") { | ||||
| 			return l.lexFalse | ||||
| 		} | ||||
|  | ||||
| 		if l.follow("inf") { | ||||
| 			return l.lexInf | ||||
| 		} | ||||
|  | ||||
| 		if l.follow("nan") { | ||||
| 			return l.lexNan | ||||
| 		} | ||||
|  | ||||
| 		if isSpace(next) { | ||||
| 			l.skip() | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if next == eof { | ||||
| 			l.next() | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		possibleDate := l.peekString(35) | ||||
| 		dateMatch := dateRegexp.FindString(possibleDate) | ||||
| 		if dateMatch != "" { | ||||
| 			l.fastForward(len(dateMatch)) | ||||
| 			return l.lexDate | ||||
| 		} | ||||
|  | ||||
| 		if next == '+' || next == '-' || isDigit(next) { | ||||
| 			return l.lexNumber | ||||
| 		} | ||||
|  | ||||
| 		if isAlphanumeric(next) { | ||||
| 			return l.lexKey | ||||
| 		} | ||||
|  | ||||
| 		return l.errorf("no value can start with %c", next) | ||||
| 	} | ||||
|  | ||||
| 	l.emit(tokenEOF) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexLeftCurlyBrace() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenLeftCurlyBrace) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexRightCurlyBrace() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenRightCurlyBrace) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexDate() tomlLexStateFn { | ||||
| 	l.emit(tokenDate) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexTrue() tomlLexStateFn { | ||||
| 	l.fastForward(4) | ||||
| 	l.emit(tokenTrue) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexFalse() tomlLexStateFn { | ||||
| 	l.fastForward(5) | ||||
| 	l.emit(tokenFalse) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexInf() tomlLexStateFn { | ||||
| 	l.fastForward(3) | ||||
| 	l.emit(tokenInf) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexNan() tomlLexStateFn { | ||||
| 	l.fastForward(3) | ||||
| 	l.emit(tokenNan) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexEqual() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenEqual) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexComma() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenComma) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| // Parse the key and emits its value without escape sequences. | ||||
| // bare keys, basic string keys and literal string keys are supported. | ||||
| func (l *tomlLexer) lexKey() tomlLexStateFn { | ||||
| 	growingString := "" | ||||
|  | ||||
| 	for r := l.peek(); isKeyChar(r) || r == '\n' || r == '\r'; r = l.peek() { | ||||
| 		if r == '"' { | ||||
| 			l.next() | ||||
| 			str, err := l.lexStringAsString(`"`, false, true) | ||||
| 			if err != nil { | ||||
| 				return l.errorf(err.Error()) | ||||
| 			} | ||||
| 			growingString += "\"" + str + "\"" | ||||
| 			l.next() | ||||
| 			continue | ||||
| 		} else if r == '\'' { | ||||
| 			l.next() | ||||
| 			str, err := l.lexLiteralStringAsString(`'`, false) | ||||
| 			if err != nil { | ||||
| 				return l.errorf(err.Error()) | ||||
| 			} | ||||
| 			growingString += "'" + str + "'" | ||||
| 			l.next() | ||||
| 			continue | ||||
| 		} else if r == '\n' { | ||||
| 			return l.errorf("keys cannot contain new lines") | ||||
| 		} else if isSpace(r) { | ||||
| 			break | ||||
| 		} else if r == '.' { | ||||
| 			// skip | ||||
| 		} else if !isValidBareChar(r) { | ||||
| 			return l.errorf("keys cannot contain %c character", r) | ||||
| 		} | ||||
| 		growingString += string(r) | ||||
| 		l.next() | ||||
| 	} | ||||
| 	l.emitWithValue(tokenKey, growingString) | ||||
| 	return l.lexVoid | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexComment(previousState tomlLexStateFn) tomlLexStateFn { | ||||
| 	return func() tomlLexStateFn { | ||||
| 		for next := l.peek(); next != '\n' && next != eof; next = l.peek() { | ||||
| 			if next == '\r' && l.follow("\r\n") { | ||||
| 				break | ||||
| 			} | ||||
| 			l.next() | ||||
| 		} | ||||
| 		l.ignore() | ||||
| 		return previousState | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexLeftBracket() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenLeftBracket) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexLiteralStringAsString(terminator string, discardLeadingNewLine bool) (string, error) { | ||||
| 	growingString := "" | ||||
|  | ||||
| 	if discardLeadingNewLine { | ||||
| 		if l.follow("\r\n") { | ||||
| 			l.skip() | ||||
| 			l.skip() | ||||
| 		} else if l.peek() == '\n' { | ||||
| 			l.skip() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// find end of string | ||||
| 	for { | ||||
| 		if l.follow(terminator) { | ||||
| 			return growingString, nil | ||||
| 		} | ||||
|  | ||||
| 		next := l.peek() | ||||
| 		if next == eof { | ||||
| 			break | ||||
| 		} | ||||
| 		growingString += string(l.next()) | ||||
| 	} | ||||
|  | ||||
| 	return "", errors.New("unclosed string") | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexLiteralString() tomlLexStateFn { | ||||
| 	l.skip() | ||||
|  | ||||
| 	// handle special case for triple-quote | ||||
| 	terminator := "'" | ||||
| 	discardLeadingNewLine := false | ||||
| 	if l.follow("''") { | ||||
| 		l.skip() | ||||
| 		l.skip() | ||||
| 		terminator = "'''" | ||||
| 		discardLeadingNewLine = true | ||||
| 	} | ||||
|  | ||||
| 	str, err := l.lexLiteralStringAsString(terminator, discardLeadingNewLine) | ||||
| 	if err != nil { | ||||
| 		return l.errorf(err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	l.emitWithValue(tokenString, str) | ||||
| 	l.fastForward(len(terminator)) | ||||
| 	l.ignore() | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| // Lex a string and return the results as a string. | ||||
| // Terminator is the substring indicating the end of the token. | ||||
| // The resulting string does not include the terminator. | ||||
| func (l *tomlLexer) lexStringAsString(terminator string, discardLeadingNewLine, acceptNewLines bool) (string, error) { | ||||
| 	growingString := "" | ||||
|  | ||||
| 	if discardLeadingNewLine { | ||||
| 		if l.follow("\r\n") { | ||||
| 			l.skip() | ||||
| 			l.skip() | ||||
| 		} else if l.peek() == '\n' { | ||||
| 			l.skip() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for { | ||||
| 		if l.follow(terminator) { | ||||
| 			return growingString, nil | ||||
| 		} | ||||
|  | ||||
| 		if l.follow("\\") { | ||||
| 			l.next() | ||||
| 			switch l.peek() { | ||||
| 			case '\r': | ||||
| 				fallthrough | ||||
| 			case '\n': | ||||
| 				fallthrough | ||||
| 			case '\t': | ||||
| 				fallthrough | ||||
| 			case ' ': | ||||
| 				// skip all whitespace chars following backslash | ||||
| 				for strings.ContainsRune("\r\n\t ", l.peek()) { | ||||
| 					l.next() | ||||
| 				} | ||||
| 			case '"': | ||||
| 				growingString += "\"" | ||||
| 				l.next() | ||||
| 			case 'n': | ||||
| 				growingString += "\n" | ||||
| 				l.next() | ||||
| 			case 'b': | ||||
| 				growingString += "\b" | ||||
| 				l.next() | ||||
| 			case 'f': | ||||
| 				growingString += "\f" | ||||
| 				l.next() | ||||
| 			case '/': | ||||
| 				growingString += "/" | ||||
| 				l.next() | ||||
| 			case 't': | ||||
| 				growingString += "\t" | ||||
| 				l.next() | ||||
| 			case 'r': | ||||
| 				growingString += "\r" | ||||
| 				l.next() | ||||
| 			case '\\': | ||||
| 				growingString += "\\" | ||||
| 				l.next() | ||||
| 			case 'u': | ||||
| 				l.next() | ||||
| 				code := "" | ||||
| 				for i := 0; i < 4; i++ { | ||||
| 					c := l.peek() | ||||
| 					if !isHexDigit(c) { | ||||
| 						return "", errors.New("unfinished unicode escape") | ||||
| 					} | ||||
| 					l.next() | ||||
| 					code = code + string(c) | ||||
| 				} | ||||
| 				intcode, err := strconv.ParseInt(code, 16, 32) | ||||
| 				if err != nil { | ||||
| 					return "", errors.New("invalid unicode escape: \\u" + code) | ||||
| 				} | ||||
| 				growingString += string(rune(intcode)) | ||||
| 			case 'U': | ||||
| 				l.next() | ||||
| 				code := "" | ||||
| 				for i := 0; i < 8; i++ { | ||||
| 					c := l.peek() | ||||
| 					if !isHexDigit(c) { | ||||
| 						return "", errors.New("unfinished unicode escape") | ||||
| 					} | ||||
| 					l.next() | ||||
| 					code = code + string(c) | ||||
| 				} | ||||
| 				intcode, err := strconv.ParseInt(code, 16, 64) | ||||
| 				if err != nil { | ||||
| 					return "", errors.New("invalid unicode escape: \\U" + code) | ||||
| 				} | ||||
| 				growingString += string(rune(intcode)) | ||||
| 			default: | ||||
| 				return "", errors.New("invalid escape sequence: \\" + string(l.peek())) | ||||
| 			} | ||||
| 		} else { | ||||
| 			r := l.peek() | ||||
|  | ||||
| 			if 0x00 <= r && r <= 0x1F && !(acceptNewLines && (r == '\n' || r == '\r')) { | ||||
| 				return "", fmt.Errorf("unescaped control character %U", r) | ||||
| 			} | ||||
| 			l.next() | ||||
| 			growingString += string(r) | ||||
| 		} | ||||
|  | ||||
| 		if l.peek() == eof { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return "", errors.New("unclosed string") | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexString() tomlLexStateFn { | ||||
| 	l.skip() | ||||
|  | ||||
| 	// handle special case for triple-quote | ||||
| 	terminator := `"` | ||||
| 	discardLeadingNewLine := false | ||||
| 	acceptNewLines := false | ||||
| 	if l.follow(`""`) { | ||||
| 		l.skip() | ||||
| 		l.skip() | ||||
| 		terminator = `"""` | ||||
| 		discardLeadingNewLine = true | ||||
| 		acceptNewLines = true | ||||
| 	} | ||||
|  | ||||
| 	str, err := l.lexStringAsString(terminator, discardLeadingNewLine, acceptNewLines) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return l.errorf(err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	l.emitWithValue(tokenString, str) | ||||
| 	l.fastForward(len(terminator)) | ||||
| 	l.ignore() | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexTableKey() tomlLexStateFn { | ||||
| 	l.next() | ||||
|  | ||||
| 	if l.peek() == '[' { | ||||
| 		// token '[[' signifies an array of tables | ||||
| 		l.next() | ||||
| 		l.emit(tokenDoubleLeftBracket) | ||||
| 		return l.lexInsideTableArrayKey | ||||
| 	} | ||||
| 	// vanilla table key | ||||
| 	l.emit(tokenLeftBracket) | ||||
| 	return l.lexInsideTableKey | ||||
| } | ||||
|  | ||||
| // Parse the key till "]]", but only bare keys are supported | ||||
| func (l *tomlLexer) lexInsideTableArrayKey() tomlLexStateFn { | ||||
| 	for r := l.peek(); r != eof; r = l.peek() { | ||||
| 		switch r { | ||||
| 		case ']': | ||||
| 			if l.currentTokenStop > l.currentTokenStart { | ||||
| 				l.emit(tokenKeyGroupArray) | ||||
| 			} | ||||
| 			l.next() | ||||
| 			if l.peek() != ']' { | ||||
| 				break | ||||
| 			} | ||||
| 			l.next() | ||||
| 			l.emit(tokenDoubleRightBracket) | ||||
| 			return l.lexVoid | ||||
| 		case '[': | ||||
| 			return l.errorf("table array key cannot contain ']'") | ||||
| 		default: | ||||
| 			l.next() | ||||
| 		} | ||||
| 	} | ||||
| 	return l.errorf("unclosed table array key") | ||||
| } | ||||
|  | ||||
| // Parse the key till "]" but only bare keys are supported | ||||
| func (l *tomlLexer) lexInsideTableKey() tomlLexStateFn { | ||||
| 	for r := l.peek(); r != eof; r = l.peek() { | ||||
| 		switch r { | ||||
| 		case ']': | ||||
| 			if l.currentTokenStop > l.currentTokenStart { | ||||
| 				l.emit(tokenKeyGroup) | ||||
| 			} | ||||
| 			l.next() | ||||
| 			l.emit(tokenRightBracket) | ||||
| 			return l.lexVoid | ||||
| 		case '[': | ||||
| 			return l.errorf("table key cannot contain ']'") | ||||
| 		default: | ||||
| 			l.next() | ||||
| 		} | ||||
| 	} | ||||
| 	return l.errorf("unclosed table key") | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexRightBracket() tomlLexStateFn { | ||||
| 	l.next() | ||||
| 	l.emit(tokenRightBracket) | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| type validRuneFn func(r rune) bool | ||||
|  | ||||
| func isValidHexRune(r rune) bool { | ||||
| 	return r >= 'a' && r <= 'f' || | ||||
| 		r >= 'A' && r <= 'F' || | ||||
| 		r >= '0' && r <= '9' || | ||||
| 		r == '_' | ||||
| } | ||||
|  | ||||
| func isValidOctalRune(r rune) bool { | ||||
| 	return r >= '0' && r <= '7' || r == '_' | ||||
| } | ||||
|  | ||||
| func isValidBinaryRune(r rune) bool { | ||||
| 	return r == '0' || r == '1' || r == '_' | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) lexNumber() tomlLexStateFn { | ||||
| 	r := l.peek() | ||||
|  | ||||
| 	if r == '0' { | ||||
| 		follow := l.peekString(2) | ||||
| 		if len(follow) == 2 { | ||||
| 			var isValidRune validRuneFn | ||||
| 			switch follow[1] { | ||||
| 			case 'x': | ||||
| 				isValidRune = isValidHexRune | ||||
| 			case 'o': | ||||
| 				isValidRune = isValidOctalRune | ||||
| 			case 'b': | ||||
| 				isValidRune = isValidBinaryRune | ||||
| 			default: | ||||
| 				if follow[1] >= 'a' && follow[1] <= 'z' || follow[1] >= 'A' && follow[1] <= 'Z' { | ||||
| 					return l.errorf("unknown number base: %s. possible options are x (hex) o (octal) b (binary)", string(follow[1])) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if isValidRune != nil { | ||||
| 				l.next() | ||||
| 				l.next() | ||||
| 				digitSeen := false | ||||
| 				for { | ||||
| 					next := l.peek() | ||||
| 					if !isValidRune(next) { | ||||
| 						break | ||||
| 					} | ||||
| 					digitSeen = true | ||||
| 					l.next() | ||||
| 				} | ||||
|  | ||||
| 				if !digitSeen { | ||||
| 					return l.errorf("number needs at least one digit") | ||||
| 				} | ||||
|  | ||||
| 				l.emit(tokenInteger) | ||||
|  | ||||
| 				return l.lexRvalue | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if r == '+' || r == '-' { | ||||
| 		l.next() | ||||
| 		if l.follow("inf") { | ||||
| 			return l.lexInf | ||||
| 		} | ||||
| 		if l.follow("nan") { | ||||
| 			return l.lexNan | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	pointSeen := false | ||||
| 	expSeen := false | ||||
| 	digitSeen := false | ||||
| 	for { | ||||
| 		next := l.peek() | ||||
| 		if next == '.' { | ||||
| 			if pointSeen { | ||||
| 				return l.errorf("cannot have two dots in one float") | ||||
| 			} | ||||
| 			l.next() | ||||
| 			if !isDigit(l.peek()) { | ||||
| 				return l.errorf("float cannot end with a dot") | ||||
| 			} | ||||
| 			pointSeen = true | ||||
| 		} else if next == 'e' || next == 'E' { | ||||
| 			expSeen = true | ||||
| 			l.next() | ||||
| 			r := l.peek() | ||||
| 			if r == '+' || r == '-' { | ||||
| 				l.next() | ||||
| 			} | ||||
| 		} else if isDigit(next) { | ||||
| 			digitSeen = true | ||||
| 			l.next() | ||||
| 		} else if next == '_' { | ||||
| 			l.next() | ||||
| 		} else { | ||||
| 			break | ||||
| 		} | ||||
| 		if pointSeen && !digitSeen { | ||||
| 			return l.errorf("cannot start float with a dot") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !digitSeen { | ||||
| 		return l.errorf("no digit in that number") | ||||
| 	} | ||||
| 	if pointSeen || expSeen { | ||||
| 		l.emit(tokenFloat) | ||||
| 	} else { | ||||
| 		l.emit(tokenInteger) | ||||
| 	} | ||||
| 	return l.lexRvalue | ||||
| } | ||||
|  | ||||
| func (l *tomlLexer) run() { | ||||
| 	for state := l.lexVoid; state != nil; { | ||||
| 		state = state() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	dateRegexp = regexp.MustCompile(`^\d{1,4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,9})?(Z|[+-]\d{2}:\d{2})`) | ||||
| } | ||||
|  | ||||
| // Entry point | ||||
| func lexToml(inputBytes []byte) []token { | ||||
| 	runes := bytes.Runes(inputBytes) | ||||
| 	l := &tomlLexer{ | ||||
| 		input:         runes, | ||||
| 		tokens:        make([]token, 0, 256), | ||||
| 		line:          1, | ||||
| 		col:           1, | ||||
| 		endbufferLine: 1, | ||||
| 		endbufferCol:  1, | ||||
| 	} | ||||
| 	l.run() | ||||
| 	return l.tokens | ||||
| } | ||||
							
								
								
									
										803
									
								
								vendor/github.com/pelletier/go-toml/marshal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										803
									
								
								vendor/github.com/pelletier/go-toml/marshal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,803 @@ | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	tagFieldName    = "toml" | ||||
| 	tagFieldComment = "comment" | ||||
| 	tagCommented    = "commented" | ||||
| 	tagMultiline    = "multiline" | ||||
| 	tagDefault      = "default" | ||||
| ) | ||||
|  | ||||
| type tomlOpts struct { | ||||
| 	name         string | ||||
| 	comment      string | ||||
| 	commented    bool | ||||
| 	multiline    bool | ||||
| 	include      bool | ||||
| 	omitempty    bool | ||||
| 	defaultValue string | ||||
| } | ||||
|  | ||||
| type encOpts struct { | ||||
| 	quoteMapKeys            bool | ||||
| 	arraysOneElementPerLine bool | ||||
| } | ||||
|  | ||||
| var encOptsDefaults = encOpts{ | ||||
| 	quoteMapKeys: false, | ||||
| } | ||||
|  | ||||
| type annotation struct { | ||||
| 	tag          string | ||||
| 	comment      string | ||||
| 	commented    string | ||||
| 	multiline    string | ||||
| 	defaultValue string | ||||
| } | ||||
|  | ||||
| var annotationDefault = annotation{ | ||||
| 	tag:          tagFieldName, | ||||
| 	comment:      tagFieldComment, | ||||
| 	commented:    tagCommented, | ||||
| 	multiline:    tagMultiline, | ||||
| 	defaultValue: tagDefault, | ||||
| } | ||||
|  | ||||
| type marshalOrder int | ||||
|  | ||||
| // Orders the Encoder can write the fields to the output stream. | ||||
| const ( | ||||
| 	// Sort fields alphabetically. | ||||
| 	OrderAlphabetical marshalOrder = iota + 1 | ||||
| 	// Preserve the order the fields are encountered. For example, the order of fields in | ||||
| 	// a struct. | ||||
| 	OrderPreserve | ||||
| ) | ||||
|  | ||||
| var timeType = reflect.TypeOf(time.Time{}) | ||||
| var marshalerType = reflect.TypeOf(new(Marshaler)).Elem() | ||||
|  | ||||
| // Check if the given marshal type maps to a Tree primitive | ||||
| func isPrimitive(mtype reflect.Type) bool { | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Ptr: | ||||
| 		return isPrimitive(mtype.Elem()) | ||||
| 	case reflect.Bool: | ||||
| 		return true | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		return true | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		return true | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		return true | ||||
| 	case reflect.String: | ||||
| 		return true | ||||
| 	case reflect.Struct: | ||||
| 		return mtype == timeType || isCustomMarshaler(mtype) | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Check if the given marshal type maps to a Tree slice | ||||
| func isTreeSlice(mtype reflect.Type) bool { | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Slice: | ||||
| 		return !isOtherSlice(mtype) | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Check if the given marshal type maps to a non-Tree slice | ||||
| func isOtherSlice(mtype reflect.Type) bool { | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Ptr: | ||||
| 		return isOtherSlice(mtype.Elem()) | ||||
| 	case reflect.Slice: | ||||
| 		return isPrimitive(mtype.Elem()) || isOtherSlice(mtype.Elem()) | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Check if the given marshal type maps to a Tree | ||||
| func isTree(mtype reflect.Type) bool { | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Map: | ||||
| 		return true | ||||
| 	case reflect.Struct: | ||||
| 		return !isPrimitive(mtype) | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func isCustomMarshaler(mtype reflect.Type) bool { | ||||
| 	return mtype.Implements(marshalerType) | ||||
| } | ||||
|  | ||||
| func callCustomMarshaler(mval reflect.Value) ([]byte, error) { | ||||
| 	return mval.Interface().(Marshaler).MarshalTOML() | ||||
| } | ||||
|  | ||||
| // Marshaler is the interface implemented by types that | ||||
| // can marshal themselves into valid TOML. | ||||
| type Marshaler interface { | ||||
| 	MarshalTOML() ([]byte, error) | ||||
| } | ||||
|  | ||||
| /* | ||||
| Marshal returns the TOML encoding of v.  Behavior is similar to the Go json | ||||
| encoder, except that there is no concept of a Marshaler interface or MarshalTOML | ||||
| function for sub-structs, and currently only definite types can be marshaled | ||||
| (i.e. no `interface{}`). | ||||
|  | ||||
| The following struct annotations are supported: | ||||
|  | ||||
|   toml:"Field"      Overrides the field's name to output. | ||||
|   omitempty         When set, empty values and groups are not emitted. | ||||
|   comment:"comment" Emits a # comment on the same line. This supports new lines. | ||||
|   commented:"true"  Emits the value as commented. | ||||
|  | ||||
| Note that pointers are automatically assigned the "omitempty" option, as TOML | ||||
| explicitly does not handle null values (saying instead the label should be | ||||
| dropped). | ||||
|  | ||||
| Tree structural types and corresponding marshal types: | ||||
|  | ||||
|   *Tree                            (*)struct, (*)map[string]interface{} | ||||
|   []*Tree                          (*)[](*)struct, (*)[](*)map[string]interface{} | ||||
|   []interface{} (as interface{})   (*)[]primitive, (*)[]([]interface{}) | ||||
|   interface{}                      (*)primitive | ||||
|  | ||||
| Tree primitive types and corresponding marshal types: | ||||
|  | ||||
|   uint64     uint, uint8-uint64, pointers to same | ||||
|   int64      int, int8-uint64, pointers to same | ||||
|   float64    float32, float64, pointers to same | ||||
|   string     string, pointers to same | ||||
|   bool       bool, pointers to same | ||||
|   time.Time  time.Time{}, pointers to same | ||||
|  | ||||
| For additional flexibility, use the Encoder API. | ||||
| */ | ||||
| func Marshal(v interface{}) ([]byte, error) { | ||||
| 	return NewEncoder(nil).marshal(v) | ||||
| } | ||||
|  | ||||
| // Encoder writes TOML values to an output stream. | ||||
| type Encoder struct { | ||||
| 	w io.Writer | ||||
| 	encOpts | ||||
| 	annotation | ||||
| 	line  int | ||||
| 	col   int | ||||
| 	order marshalOrder | ||||
| } | ||||
|  | ||||
| // NewEncoder returns a new encoder that writes to w. | ||||
| func NewEncoder(w io.Writer) *Encoder { | ||||
| 	return &Encoder{ | ||||
| 		w:          w, | ||||
| 		encOpts:    encOptsDefaults, | ||||
| 		annotation: annotationDefault, | ||||
| 		line:       0, | ||||
| 		col:        1, | ||||
| 		order:      OrderAlphabetical, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Encode writes the TOML encoding of v to the stream. | ||||
| // | ||||
| // See the documentation for Marshal for details. | ||||
| func (e *Encoder) Encode(v interface{}) error { | ||||
| 	b, err := e.marshal(v) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if _, err := e.w.Write(b); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // QuoteMapKeys sets up the encoder to encode | ||||
| // maps with string type keys with quoted TOML keys. | ||||
| // | ||||
| // This relieves the character limitations on map keys. | ||||
| func (e *Encoder) QuoteMapKeys(v bool) *Encoder { | ||||
| 	e.quoteMapKeys = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // ArraysWithOneElementPerLine sets up the encoder to encode arrays | ||||
| // with more than one element on multiple lines instead of one. | ||||
| // | ||||
| // For example: | ||||
| // | ||||
| //   A = [1,2,3] | ||||
| // | ||||
| // Becomes | ||||
| // | ||||
| //   A = [ | ||||
| //     1, | ||||
| //     2, | ||||
| //     3, | ||||
| //   ] | ||||
| func (e *Encoder) ArraysWithOneElementPerLine(v bool) *Encoder { | ||||
| 	e.arraysOneElementPerLine = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // Order allows to change in which order fields will be written to the output stream. | ||||
| func (e *Encoder) Order(ord marshalOrder) *Encoder { | ||||
| 	e.order = ord | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // SetTagName allows changing default tag "toml" | ||||
| func (e *Encoder) SetTagName(v string) *Encoder { | ||||
| 	e.tag = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // SetTagComment allows changing default tag "comment" | ||||
| func (e *Encoder) SetTagComment(v string) *Encoder { | ||||
| 	e.comment = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // SetTagCommented allows changing default tag "commented" | ||||
| func (e *Encoder) SetTagCommented(v string) *Encoder { | ||||
| 	e.commented = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // SetTagMultiline allows changing default tag "multiline" | ||||
| func (e *Encoder) SetTagMultiline(v string) *Encoder { | ||||
| 	e.multiline = v | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| func (e *Encoder) marshal(v interface{}) ([]byte, error) { | ||||
| 	mtype := reflect.TypeOf(v) | ||||
|  | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Struct, reflect.Map: | ||||
| 	case reflect.Ptr: | ||||
| 		if mtype.Elem().Kind() != reflect.Struct { | ||||
| 			return []byte{}, errors.New("Only pointer to struct can be marshaled to TOML") | ||||
| 		} | ||||
| 	default: | ||||
| 		return []byte{}, errors.New("Only a struct or map can be marshaled to TOML") | ||||
| 	} | ||||
|  | ||||
| 	sval := reflect.ValueOf(v) | ||||
| 	if isCustomMarshaler(mtype) { | ||||
| 		return callCustomMarshaler(sval) | ||||
| 	} | ||||
| 	t, err := e.valueToTree(mtype, sval) | ||||
| 	if err != nil { | ||||
| 		return []byte{}, err | ||||
| 	} | ||||
|  | ||||
| 	var buf bytes.Buffer | ||||
| 	_, err = t.writeToOrdered(&buf, "", "", 0, e.arraysOneElementPerLine, e.order) | ||||
|  | ||||
| 	return buf.Bytes(), err | ||||
| } | ||||
|  | ||||
| // Create next tree with a position based on Encoder.line | ||||
| func (e *Encoder) nextTree() *Tree { | ||||
| 	return newTreeWithPosition(Position{Line: e.line, Col: 1}) | ||||
| } | ||||
|  | ||||
| // Convert given marshal struct or map value to toml tree | ||||
| func (e *Encoder) valueToTree(mtype reflect.Type, mval reflect.Value) (*Tree, error) { | ||||
| 	if mtype.Kind() == reflect.Ptr { | ||||
| 		return e.valueToTree(mtype.Elem(), mval.Elem()) | ||||
| 	} | ||||
| 	tval := e.nextTree() | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Struct: | ||||
| 		for i := 0; i < mtype.NumField(); i++ { | ||||
| 			mtypef, mvalf := mtype.Field(i), mval.Field(i) | ||||
| 			opts := tomlOptions(mtypef, e.annotation) | ||||
| 			if opts.include && (!opts.omitempty || !isZero(mvalf)) { | ||||
| 				val, err := e.valueToToml(mtypef.Type, mvalf) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
|  | ||||
| 				tval.SetWithOptions(opts.name, SetOptions{ | ||||
| 					Comment:   opts.comment, | ||||
| 					Commented: opts.commented, | ||||
| 					Multiline: opts.multiline, | ||||
| 				}, val) | ||||
| 			} | ||||
| 		} | ||||
| 	case reflect.Map: | ||||
| 		keys := mval.MapKeys() | ||||
| 		if e.order == OrderPreserve && len(keys) > 0 { | ||||
| 			// Sorting []reflect.Value is not straight forward. | ||||
| 			// | ||||
| 			// OrderPreserve will support deterministic results when string is used | ||||
| 			// as the key to maps. | ||||
| 			typ := keys[0].Type() | ||||
| 			kind := keys[0].Kind() | ||||
| 			if kind == reflect.String { | ||||
| 				ikeys := make([]string, len(keys)) | ||||
| 				for i := range keys { | ||||
| 					ikeys[i] = keys[i].Interface().(string) | ||||
| 				} | ||||
| 				sort.Strings(ikeys) | ||||
| 				for i := range ikeys { | ||||
| 					keys[i] = reflect.ValueOf(ikeys[i]).Convert(typ) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		for _, key := range keys { | ||||
| 			mvalf := mval.MapIndex(key) | ||||
| 			val, err := e.valueToToml(mtype.Elem(), mvalf) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			if e.quoteMapKeys { | ||||
| 				keyStr, err := tomlValueStringRepresentation(key.String(), "", e.arraysOneElementPerLine) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				tval.SetPath([]string{keyStr}, val) | ||||
| 			} else { | ||||
| 				tval.Set(key.String(), val) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return tval, nil | ||||
| } | ||||
|  | ||||
| // Convert given marshal slice to slice of Toml trees | ||||
| func (e *Encoder) valueToTreeSlice(mtype reflect.Type, mval reflect.Value) ([]*Tree, error) { | ||||
| 	tval := make([]*Tree, mval.Len(), mval.Len()) | ||||
| 	for i := 0; i < mval.Len(); i++ { | ||||
| 		val, err := e.valueToTree(mtype.Elem(), mval.Index(i)) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		tval[i] = val | ||||
| 	} | ||||
| 	return tval, nil | ||||
| } | ||||
|  | ||||
| // Convert given marshal slice to slice of toml values | ||||
| func (e *Encoder) valueToOtherSlice(mtype reflect.Type, mval reflect.Value) (interface{}, error) { | ||||
| 	tval := make([]interface{}, mval.Len(), mval.Len()) | ||||
| 	for i := 0; i < mval.Len(); i++ { | ||||
| 		val, err := e.valueToToml(mtype.Elem(), mval.Index(i)) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		tval[i] = val | ||||
| 	} | ||||
| 	return tval, nil | ||||
| } | ||||
|  | ||||
| // Convert given marshal value to toml value | ||||
| func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface{}, error) { | ||||
| 	e.line++ | ||||
| 	if mtype.Kind() == reflect.Ptr { | ||||
| 		return e.valueToToml(mtype.Elem(), mval.Elem()) | ||||
| 	} | ||||
| 	switch { | ||||
| 	case isCustomMarshaler(mtype): | ||||
| 		return callCustomMarshaler(mval) | ||||
| 	case isTree(mtype): | ||||
| 		return e.valueToTree(mtype, mval) | ||||
| 	case isTreeSlice(mtype): | ||||
| 		return e.valueToTreeSlice(mtype, mval) | ||||
| 	case isOtherSlice(mtype): | ||||
| 		return e.valueToOtherSlice(mtype, mval) | ||||
| 	default: | ||||
| 		switch mtype.Kind() { | ||||
| 		case reflect.Bool: | ||||
| 			return mval.Bool(), nil | ||||
| 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) { | ||||
| 				return fmt.Sprint(mval), nil | ||||
| 			} | ||||
| 			return mval.Int(), nil | ||||
| 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 			return mval.Uint(), nil | ||||
| 		case reflect.Float32, reflect.Float64: | ||||
| 			return mval.Float(), nil | ||||
| 		case reflect.String: | ||||
| 			return mval.String(), nil | ||||
| 		case reflect.Struct: | ||||
| 			return mval.Interface().(time.Time), nil | ||||
| 		default: | ||||
| 			return nil, fmt.Errorf("Marshal can't handle %v(%v)", mtype, mtype.Kind()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Unmarshal attempts to unmarshal the Tree into a Go struct pointed by v. | ||||
| // Neither Unmarshaler interfaces nor UnmarshalTOML functions are supported for | ||||
| // sub-structs, and only definite types can be unmarshaled. | ||||
| func (t *Tree) Unmarshal(v interface{}) error { | ||||
| 	d := Decoder{tval: t, tagName: tagFieldName} | ||||
| 	return d.unmarshal(v) | ||||
| } | ||||
|  | ||||
| // Marshal returns the TOML encoding of Tree. | ||||
| // See Marshal() documentation for types mapping table. | ||||
| func (t *Tree) Marshal() ([]byte, error) { | ||||
| 	var buf bytes.Buffer | ||||
| 	err := NewEncoder(&buf).Encode(t) | ||||
| 	return buf.Bytes(), err | ||||
| } | ||||
|  | ||||
| // Unmarshal parses the TOML-encoded data and stores the result in the value | ||||
| // pointed to by v. Behavior is similar to the Go json encoder, except that there | ||||
| // is no concept of an Unmarshaler interface or UnmarshalTOML function for | ||||
| // sub-structs, and currently only definite types can be unmarshaled to (i.e. no | ||||
| // `interface{}`). | ||||
| // | ||||
| // The following struct annotations are supported: | ||||
| // | ||||
| //   toml:"Field" Overrides the field's name to map to. | ||||
| //   default:"foo" Provides a default value. | ||||
| // | ||||
| // For default values, only fields of the following types are supported: | ||||
| //   * string | ||||
| //   * bool | ||||
| //   * int | ||||
| //   * int64 | ||||
| //   * float64 | ||||
| // | ||||
| // See Marshal() documentation for types mapping table. | ||||
| func Unmarshal(data []byte, v interface{}) error { | ||||
| 	t, err := LoadReader(bytes.NewReader(data)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return t.Unmarshal(v) | ||||
| } | ||||
|  | ||||
| // Decoder reads and decodes TOML values from an input stream. | ||||
| type Decoder struct { | ||||
| 	r    io.Reader | ||||
| 	tval *Tree | ||||
| 	encOpts | ||||
| 	tagName string | ||||
| } | ||||
|  | ||||
| // NewDecoder returns a new decoder that reads from r. | ||||
| func NewDecoder(r io.Reader) *Decoder { | ||||
| 	return &Decoder{ | ||||
| 		r:       r, | ||||
| 		encOpts: encOptsDefaults, | ||||
| 		tagName: tagFieldName, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Decode reads a TOML-encoded value from it's input | ||||
| // and unmarshals it in the value pointed at by v. | ||||
| // | ||||
| // See the documentation for Marshal for details. | ||||
| func (d *Decoder) Decode(v interface{}) error { | ||||
| 	var err error | ||||
| 	d.tval, err = LoadReader(d.r) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return d.unmarshal(v) | ||||
| } | ||||
|  | ||||
| // SetTagName allows changing default tag "toml" | ||||
| func (d *Decoder) SetTagName(v string) *Decoder { | ||||
| 	d.tagName = v | ||||
| 	return d | ||||
| } | ||||
|  | ||||
| func (d *Decoder) unmarshal(v interface{}) error { | ||||
| 	mtype := reflect.TypeOf(v) | ||||
| 	if mtype.Kind() != reflect.Ptr { | ||||
| 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML") | ||||
| 	} | ||||
|  | ||||
| 	elem := mtype.Elem() | ||||
|  | ||||
| 	switch elem.Kind() { | ||||
| 	case reflect.Struct, reflect.Map: | ||||
| 	default: | ||||
| 		return errors.New("only a pointer to struct or map can be unmarshaled from TOML") | ||||
| 	} | ||||
|  | ||||
| 	sval, err := d.valueFromTree(elem, d.tval) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	reflect.ValueOf(v).Elem().Set(sval) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Convert toml tree to marshal struct or map, using marshal type | ||||
| func (d *Decoder) valueFromTree(mtype reflect.Type, tval *Tree) (reflect.Value, error) { | ||||
| 	if mtype.Kind() == reflect.Ptr { | ||||
| 		return d.unwrapPointer(mtype, tval) | ||||
| 	} | ||||
| 	var mval reflect.Value | ||||
| 	switch mtype.Kind() { | ||||
| 	case reflect.Struct: | ||||
| 		mval = reflect.New(mtype).Elem() | ||||
| 		for i := 0; i < mtype.NumField(); i++ { | ||||
| 			mtypef := mtype.Field(i) | ||||
| 			an := annotation{tag: d.tagName} | ||||
| 			opts := tomlOptions(mtypef, an) | ||||
| 			if opts.include { | ||||
| 				baseKey := opts.name | ||||
| 				keysToTry := []string{ | ||||
| 					baseKey, | ||||
| 					strings.ToLower(baseKey), | ||||
| 					strings.ToTitle(baseKey), | ||||
| 					strings.ToLower(string(baseKey[0])) + baseKey[1:], | ||||
| 				} | ||||
|  | ||||
| 				found := false | ||||
| 				for _, key := range keysToTry { | ||||
| 					exists := tval.Has(key) | ||||
| 					if !exists { | ||||
| 						continue | ||||
| 					} | ||||
| 					val := tval.Get(key) | ||||
| 					mvalf, err := d.valueFromToml(mtypef.Type, val) | ||||
| 					if err != nil { | ||||
| 						return mval, formatError(err, tval.GetPosition(key)) | ||||
| 					} | ||||
| 					mval.Field(i).Set(mvalf) | ||||
| 					found = true | ||||
| 					break | ||||
| 				} | ||||
|  | ||||
| 				if !found && opts.defaultValue != "" { | ||||
| 					mvalf := mval.Field(i) | ||||
| 					var val interface{} | ||||
| 					var err error | ||||
| 					switch mvalf.Kind() { | ||||
| 					case reflect.Bool: | ||||
| 						val, err = strconv.ParseBool(opts.defaultValue) | ||||
| 						if err != nil { | ||||
| 							return mval.Field(i), err | ||||
| 						} | ||||
| 					case reflect.Int: | ||||
| 						val, err = strconv.Atoi(opts.defaultValue) | ||||
| 						if err != nil { | ||||
| 							return mval.Field(i), err | ||||
| 						} | ||||
| 					case reflect.String: | ||||
| 						val = opts.defaultValue | ||||
| 					case reflect.Int64: | ||||
| 						val, err = strconv.ParseInt(opts.defaultValue, 10, 64) | ||||
| 						if err != nil { | ||||
| 							return mval.Field(i), err | ||||
| 						} | ||||
| 					case reflect.Float64: | ||||
| 						val, err = strconv.ParseFloat(opts.defaultValue, 64) | ||||
| 						if err != nil { | ||||
| 							return mval.Field(i), err | ||||
| 						} | ||||
| 					default: | ||||
| 						return mval.Field(i), fmt.Errorf("unsuported field type for default option") | ||||
| 					} | ||||
| 					mval.Field(i).Set(reflect.ValueOf(val)) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	case reflect.Map: | ||||
| 		mval = reflect.MakeMap(mtype) | ||||
| 		for _, key := range tval.Keys() { | ||||
| 			// TODO: path splits key | ||||
| 			val := tval.GetPath([]string{key}) | ||||
| 			mvalf, err := d.valueFromToml(mtype.Elem(), val) | ||||
| 			if err != nil { | ||||
| 				return mval, formatError(err, tval.GetPosition(key)) | ||||
| 			} | ||||
| 			mval.SetMapIndex(reflect.ValueOf(key).Convert(mtype.Key()), mvalf) | ||||
| 		} | ||||
| 	} | ||||
| 	return mval, nil | ||||
| } | ||||
|  | ||||
| // Convert toml value to marshal struct/map slice, using marshal type | ||||
| func (d *Decoder) valueFromTreeSlice(mtype reflect.Type, tval []*Tree) (reflect.Value, error) { | ||||
| 	mval := reflect.MakeSlice(mtype, len(tval), len(tval)) | ||||
| 	for i := 0; i < len(tval); i++ { | ||||
| 		val, err := d.valueFromTree(mtype.Elem(), tval[i]) | ||||
| 		if err != nil { | ||||
| 			return mval, err | ||||
| 		} | ||||
| 		mval.Index(i).Set(val) | ||||
| 	} | ||||
| 	return mval, nil | ||||
| } | ||||
|  | ||||
| // Convert toml value to marshal primitive slice, using marshal type | ||||
| func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (reflect.Value, error) { | ||||
| 	mval := reflect.MakeSlice(mtype, len(tval), len(tval)) | ||||
| 	for i := 0; i < len(tval); i++ { | ||||
| 		val, err := d.valueFromToml(mtype.Elem(), tval[i]) | ||||
| 		if err != nil { | ||||
| 			return mval, err | ||||
| 		} | ||||
| 		mval.Index(i).Set(val) | ||||
| 	} | ||||
| 	return mval, nil | ||||
| } | ||||
|  | ||||
| // Convert toml value to marshal value, using marshal type | ||||
| func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.Value, error) { | ||||
| 	if mtype.Kind() == reflect.Ptr { | ||||
| 		return d.unwrapPointer(mtype, tval) | ||||
| 	} | ||||
|  | ||||
| 	switch t := tval.(type) { | ||||
| 	case *Tree: | ||||
| 		if isTree(mtype) { | ||||
| 			return d.valueFromTree(mtype, t) | ||||
| 		} | ||||
| 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval) | ||||
| 	case []*Tree: | ||||
| 		if isTreeSlice(mtype) { | ||||
| 			return d.valueFromTreeSlice(mtype, t) | ||||
| 		} | ||||
| 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval) | ||||
| 	case []interface{}: | ||||
| 		if isOtherSlice(mtype) { | ||||
| 			return d.valueFromOtherSlice(mtype, t) | ||||
| 		} | ||||
| 		return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval) | ||||
| 	default: | ||||
| 		switch mtype.Kind() { | ||||
| 		case reflect.Bool, reflect.Struct: | ||||
| 			val := reflect.ValueOf(tval) | ||||
| 			// if this passes for when mtype is reflect.Struct, tval is a time.Time | ||||
| 			if !val.Type().ConvertibleTo(mtype) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			return val.Convert(mtype), nil | ||||
| 		case reflect.String: | ||||
| 			val := reflect.ValueOf(tval) | ||||
| 			// stupidly, int64 is convertible to string. So special case this. | ||||
| 			if !val.Type().ConvertibleTo(mtype) || val.Kind() == reflect.Int64 { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			return val.Convert(mtype), nil | ||||
| 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 			val := reflect.ValueOf(tval) | ||||
| 			if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) && val.Kind() == reflect.String { | ||||
| 				d, err := time.ParseDuration(val.String()) | ||||
| 				if err != nil { | ||||
| 					return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err) | ||||
| 				} | ||||
| 				return reflect.ValueOf(d), nil | ||||
| 			} | ||||
| 			if !val.Type().ConvertibleTo(mtype) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
| 			if reflect.Indirect(reflect.New(mtype)).OverflowInt(val.Convert(mtype).Int()) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			return val.Convert(mtype), nil | ||||
| 		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: | ||||
| 			val := reflect.ValueOf(tval) | ||||
| 			if !val.Type().ConvertibleTo(mtype) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			if val.Convert(reflect.TypeOf(int(1))).Int() < 0 { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) is negative so does not fit in %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
| 			if reflect.Indirect(reflect.New(mtype)).OverflowUint(uint64(val.Convert(mtype).Uint())) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			return val.Convert(mtype), nil | ||||
| 		case reflect.Float32, reflect.Float64: | ||||
| 			val := reflect.ValueOf(tval) | ||||
| 			if !val.Type().ConvertibleTo(mtype) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
| 			if reflect.Indirect(reflect.New(mtype)).OverflowFloat(val.Convert(mtype).Float()) { | ||||
| 				return reflect.ValueOf(nil), fmt.Errorf("%v(%T) would overflow %v", tval, tval, mtype.String()) | ||||
| 			} | ||||
|  | ||||
| 			return val.Convert(mtype), nil | ||||
| 		default: | ||||
| 			return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (d *Decoder) unwrapPointer(mtype reflect.Type, tval interface{}) (reflect.Value, error) { | ||||
| 	val, err := d.valueFromToml(mtype.Elem(), tval) | ||||
| 	if err != nil { | ||||
| 		return reflect.ValueOf(nil), err | ||||
| 	} | ||||
| 	mval := reflect.New(mtype.Elem()) | ||||
| 	mval.Elem().Set(val) | ||||
| 	return mval, nil | ||||
| } | ||||
|  | ||||
| func tomlOptions(vf reflect.StructField, an annotation) tomlOpts { | ||||
| 	tag := vf.Tag.Get(an.tag) | ||||
| 	parse := strings.Split(tag, ",") | ||||
| 	var comment string | ||||
| 	if c := vf.Tag.Get(an.comment); c != "" { | ||||
| 		comment = c | ||||
| 	} | ||||
| 	commented, _ := strconv.ParseBool(vf.Tag.Get(an.commented)) | ||||
| 	multiline, _ := strconv.ParseBool(vf.Tag.Get(an.multiline)) | ||||
| 	defaultValue := vf.Tag.Get(tagDefault) | ||||
| 	result := tomlOpts{ | ||||
| 		name:         vf.Name, | ||||
| 		comment:      comment, | ||||
| 		commented:    commented, | ||||
| 		multiline:    multiline, | ||||
| 		include:      true, | ||||
| 		omitempty:    false, | ||||
| 		defaultValue: defaultValue, | ||||
| 	} | ||||
| 	if parse[0] != "" { | ||||
| 		if parse[0] == "-" && len(parse) == 1 { | ||||
| 			result.include = false | ||||
| 		} else { | ||||
| 			result.name = strings.Trim(parse[0], " ") | ||||
| 		} | ||||
| 	} | ||||
| 	if vf.PkgPath != "" { | ||||
| 		result.include = false | ||||
| 	} | ||||
| 	if len(parse) > 1 && strings.Trim(parse[1], " ") == "omitempty" { | ||||
| 		result.omitempty = true | ||||
| 	} | ||||
| 	if vf.Type.Kind() == reflect.Ptr { | ||||
| 		result.omitempty = true | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func isZero(val reflect.Value) bool { | ||||
| 	switch val.Type().Kind() { | ||||
| 	case reflect.Map: | ||||
| 		fallthrough | ||||
| 	case reflect.Array: | ||||
| 		fallthrough | ||||
| 	case reflect.Slice: | ||||
| 		return val.Len() == 0 | ||||
| 	default: | ||||
| 		return reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func formatError(err error, pos Position) error { | ||||
| 	if err.Error()[0] == '(' { // Error already contains position information | ||||
| 		return err | ||||
| 	} | ||||
| 	return fmt.Errorf("%s: %s", pos, err) | ||||
| } | ||||
							
								
								
									
										17
									
								
								vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_Map_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_Map_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| title = "TOML Marshal Testing" | ||||
|  | ||||
| [basic_map] | ||||
|   one = "one" | ||||
|   two = "two" | ||||
|  | ||||
| [long_map] | ||||
|   a7 = "1" | ||||
|   b3 = "2" | ||||
|   c8 = "3" | ||||
|   d4 = "4" | ||||
|   e6 = "5" | ||||
|   f5 = "6" | ||||
|   g10 = "7" | ||||
|   h1 = "8" | ||||
|   i2 = "9" | ||||
|   j9 = "10" | ||||
							
								
								
									
										38
									
								
								vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| title = "TOML Marshal Testing" | ||||
|  | ||||
| [basic_lists] | ||||
|   floats = [12.3,45.6,78.9] | ||||
|   bools = [true,false,true] | ||||
|   dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z] | ||||
|   ints = [8001,8001,8002] | ||||
|   uints = [5002,5003] | ||||
|   strings = ["One","Two","Three"] | ||||
|  | ||||
| [[subdocptrs]] | ||||
|   name = "Second" | ||||
|  | ||||
| [basic_map] | ||||
|   one = "one" | ||||
|   two = "two" | ||||
|  | ||||
| [subdoc] | ||||
|  | ||||
|   [subdoc.second] | ||||
|     name = "Second" | ||||
|  | ||||
|   [subdoc.first] | ||||
|     name = "First" | ||||
|  | ||||
| [basic] | ||||
|   uint = 5001 | ||||
|   bool = true | ||||
|   float = 123.4 | ||||
|   int = 5000 | ||||
|   string = "Bite me" | ||||
|   date = 1979-05-27T07:32:00Z | ||||
|  | ||||
| [[subdoclist]] | ||||
|   name = "List.First" | ||||
|  | ||||
| [[subdoclist]] | ||||
|   name = "List.Second" | ||||
							
								
								
									
										38
									
								
								vendor/github.com/pelletier/go-toml/marshal_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/pelletier/go-toml/marshal_test.toml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| title = "TOML Marshal Testing" | ||||
|  | ||||
| [basic] | ||||
|   bool = true | ||||
|   date = 1979-05-27T07:32:00Z | ||||
|   float = 123.4 | ||||
|   int = 5000 | ||||
|   string = "Bite me" | ||||
|   uint = 5001 | ||||
|  | ||||
| [basic_lists] | ||||
|   bools = [true,false,true] | ||||
|   dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z] | ||||
|   floats = [12.3,45.6,78.9] | ||||
|   ints = [8001,8001,8002] | ||||
|   strings = ["One","Two","Three"] | ||||
|   uints = [5002,5003] | ||||
|  | ||||
| [basic_map] | ||||
|   one = "one" | ||||
|   two = "two" | ||||
|  | ||||
| [subdoc] | ||||
|  | ||||
|   [subdoc.first] | ||||
|     name = "First" | ||||
|  | ||||
|   [subdoc.second] | ||||
|     name = "Second" | ||||
|  | ||||
| [[subdoclist]] | ||||
|   name = "List.First" | ||||
|  | ||||
| [[subdoclist]] | ||||
|   name = "List.Second" | ||||
|  | ||||
| [[subdocptrs]] | ||||
|   name = "Second" | ||||
							
								
								
									
										442
									
								
								vendor/github.com/pelletier/go-toml/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								vendor/github.com/pelletier/go-toml/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,442 @@ | ||||
| // TOML Parser. | ||||
|  | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"reflect" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type tomlParser struct { | ||||
| 	flowIdx       int | ||||
| 	flow          []token | ||||
| 	tree          *Tree | ||||
| 	currentTable  []string | ||||
| 	seenTableKeys []string | ||||
| } | ||||
|  | ||||
| type tomlParserStateFn func() tomlParserStateFn | ||||
|  | ||||
| // Formats and panics an error message based on a token | ||||
| func (p *tomlParser) raiseError(tok *token, msg string, args ...interface{}) { | ||||
| 	panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...)) | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) run() { | ||||
| 	for state := p.parseStart; state != nil; { | ||||
| 		state = state() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) peek() *token { | ||||
| 	if p.flowIdx >= len(p.flow) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return &p.flow[p.flowIdx] | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) assume(typ tokenType) { | ||||
| 	tok := p.getToken() | ||||
| 	if tok == nil { | ||||
| 		p.raiseError(tok, "was expecting token %s, but token stream is empty", tok) | ||||
| 	} | ||||
| 	if tok.typ != typ { | ||||
| 		p.raiseError(tok, "was expecting token %s, but got %s instead", typ, tok) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) getToken() *token { | ||||
| 	tok := p.peek() | ||||
| 	if tok == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	p.flowIdx++ | ||||
| 	return tok | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseStart() tomlParserStateFn { | ||||
| 	tok := p.peek() | ||||
|  | ||||
| 	// end of stream, parsing is finished | ||||
| 	if tok == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	switch tok.typ { | ||||
| 	case tokenDoubleLeftBracket: | ||||
| 		return p.parseGroupArray | ||||
| 	case tokenLeftBracket: | ||||
| 		return p.parseGroup | ||||
| 	case tokenKey: | ||||
| 		return p.parseAssign | ||||
| 	case tokenEOF: | ||||
| 		return nil | ||||
| 	case tokenError: | ||||
| 		p.raiseError(tok, "parsing error: %s", tok.String()) | ||||
| 	default: | ||||
| 		p.raiseError(tok, "unexpected token %s", tok.typ) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseGroupArray() tomlParserStateFn { | ||||
| 	startToken := p.getToken() // discard the [[ | ||||
| 	key := p.getToken() | ||||
| 	if key.typ != tokenKeyGroupArray { | ||||
| 		p.raiseError(key, "unexpected token %s, was expecting a table array key", key) | ||||
| 	} | ||||
|  | ||||
| 	// get or create table array element at the indicated part in the path | ||||
| 	keys, err := parseKey(key.val) | ||||
| 	if err != nil { | ||||
| 		p.raiseError(key, "invalid table array key: %s", err) | ||||
| 	} | ||||
| 	p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries | ||||
| 	destTree := p.tree.GetPath(keys) | ||||
| 	var array []*Tree | ||||
| 	if destTree == nil { | ||||
| 		array = make([]*Tree, 0) | ||||
| 	} else if target, ok := destTree.([]*Tree); ok && target != nil { | ||||
| 		array = destTree.([]*Tree) | ||||
| 	} else { | ||||
| 		p.raiseError(key, "key %s is already assigned and not of type table array", key) | ||||
| 	} | ||||
| 	p.currentTable = keys | ||||
|  | ||||
| 	// add a new tree to the end of the table array | ||||
| 	newTree := newTree() | ||||
| 	newTree.position = startToken.Position | ||||
| 	array = append(array, newTree) | ||||
| 	p.tree.SetPath(p.currentTable, array) | ||||
|  | ||||
| 	// remove all keys that were children of this table array | ||||
| 	prefix := key.val + "." | ||||
| 	found := false | ||||
| 	for ii := 0; ii < len(p.seenTableKeys); { | ||||
| 		tableKey := p.seenTableKeys[ii] | ||||
| 		if strings.HasPrefix(tableKey, prefix) { | ||||
| 			p.seenTableKeys = append(p.seenTableKeys[:ii], p.seenTableKeys[ii+1:]...) | ||||
| 		} else { | ||||
| 			found = (tableKey == key.val) | ||||
| 			ii++ | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// keep this key name from use by other kinds of assignments | ||||
| 	if !found { | ||||
| 		p.seenTableKeys = append(p.seenTableKeys, key.val) | ||||
| 	} | ||||
|  | ||||
| 	// move to next parser state | ||||
| 	p.assume(tokenDoubleRightBracket) | ||||
| 	return p.parseStart | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseGroup() tomlParserStateFn { | ||||
| 	startToken := p.getToken() // discard the [ | ||||
| 	key := p.getToken() | ||||
| 	if key.typ != tokenKeyGroup { | ||||
| 		p.raiseError(key, "unexpected token %s, was expecting a table key", key) | ||||
| 	} | ||||
| 	for _, item := range p.seenTableKeys { | ||||
| 		if item == key.val { | ||||
| 			p.raiseError(key, "duplicated tables") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	p.seenTableKeys = append(p.seenTableKeys, key.val) | ||||
| 	keys, err := parseKey(key.val) | ||||
| 	if err != nil { | ||||
| 		p.raiseError(key, "invalid table array key: %s", err) | ||||
| 	} | ||||
| 	if err := p.tree.createSubTree(keys, startToken.Position); err != nil { | ||||
| 		p.raiseError(key, "%s", err) | ||||
| 	} | ||||
| 	p.assume(tokenRightBracket) | ||||
| 	p.currentTable = keys | ||||
| 	return p.parseStart | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseAssign() tomlParserStateFn { | ||||
| 	key := p.getToken() | ||||
| 	p.assume(tokenEqual) | ||||
|  | ||||
| 	parsedKey, err := parseKey(key.val) | ||||
| 	if err != nil { | ||||
| 		p.raiseError(key, "invalid key: %s", err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	value := p.parseRvalue() | ||||
| 	var tableKey []string | ||||
| 	if len(p.currentTable) > 0 { | ||||
| 		tableKey = p.currentTable | ||||
| 	} else { | ||||
| 		tableKey = []string{} | ||||
| 	} | ||||
|  | ||||
| 	prefixKey := parsedKey[0 : len(parsedKey)-1] | ||||
| 	tableKey = append(tableKey, prefixKey...) | ||||
|  | ||||
| 	// find the table to assign, looking out for arrays of tables | ||||
| 	var targetNode *Tree | ||||
| 	switch node := p.tree.GetPath(tableKey).(type) { | ||||
| 	case []*Tree: | ||||
| 		targetNode = node[len(node)-1] | ||||
| 	case *Tree: | ||||
| 		targetNode = node | ||||
| 	case nil: | ||||
| 		// create intermediate | ||||
| 		if err := p.tree.createSubTree(tableKey, key.Position); err != nil { | ||||
| 			p.raiseError(key, "could not create intermediate group: %s", err) | ||||
| 		} | ||||
| 		targetNode = p.tree.GetPath(tableKey).(*Tree) | ||||
| 	default: | ||||
| 		p.raiseError(key, "Unknown table type for path: %s", | ||||
| 			strings.Join(tableKey, ".")) | ||||
| 	} | ||||
|  | ||||
| 	// assign value to the found table | ||||
| 	keyVal := parsedKey[len(parsedKey)-1] | ||||
| 	localKey := []string{keyVal} | ||||
| 	finalKey := append(tableKey, keyVal) | ||||
| 	if targetNode.GetPath(localKey) != nil { | ||||
| 		p.raiseError(key, "The following key was defined twice: %s", | ||||
| 			strings.Join(finalKey, ".")) | ||||
| 	} | ||||
| 	var toInsert interface{} | ||||
|  | ||||
| 	switch value.(type) { | ||||
| 	case *Tree, []*Tree: | ||||
| 		toInsert = value | ||||
| 	default: | ||||
| 		toInsert = &tomlValue{value: value, position: key.Position} | ||||
| 	} | ||||
| 	targetNode.values[keyVal] = toInsert | ||||
| 	return p.parseStart | ||||
| } | ||||
|  | ||||
| var numberUnderscoreInvalidRegexp *regexp.Regexp | ||||
| var hexNumberUnderscoreInvalidRegexp *regexp.Regexp | ||||
|  | ||||
| func numberContainsInvalidUnderscore(value string) error { | ||||
| 	if numberUnderscoreInvalidRegexp.MatchString(value) { | ||||
| 		return errors.New("invalid use of _ in number") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func hexNumberContainsInvalidUnderscore(value string) error { | ||||
| 	if hexNumberUnderscoreInvalidRegexp.MatchString(value) { | ||||
| 		return errors.New("invalid use of _ in hex number") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func cleanupNumberToken(value string) string { | ||||
| 	cleanedVal := strings.Replace(value, "_", "", -1) | ||||
| 	return cleanedVal | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseRvalue() interface{} { | ||||
| 	tok := p.getToken() | ||||
| 	if tok == nil || tok.typ == tokenEOF { | ||||
| 		p.raiseError(tok, "expecting a value") | ||||
| 	} | ||||
|  | ||||
| 	switch tok.typ { | ||||
| 	case tokenString: | ||||
| 		return tok.val | ||||
| 	case tokenTrue: | ||||
| 		return true | ||||
| 	case tokenFalse: | ||||
| 		return false | ||||
| 	case tokenInf: | ||||
| 		if tok.val[0] == '-' { | ||||
| 			return math.Inf(-1) | ||||
| 		} | ||||
| 		return math.Inf(1) | ||||
| 	case tokenNan: | ||||
| 		return math.NaN() | ||||
| 	case tokenInteger: | ||||
| 		cleanedVal := cleanupNumberToken(tok.val) | ||||
| 		var err error | ||||
| 		var val int64 | ||||
| 		if len(cleanedVal) >= 3 && cleanedVal[0] == '0' { | ||||
| 			switch cleanedVal[1] { | ||||
| 			case 'x': | ||||
| 				err = hexNumberContainsInvalidUnderscore(tok.val) | ||||
| 				if err != nil { | ||||
| 					p.raiseError(tok, "%s", err) | ||||
| 				} | ||||
| 				val, err = strconv.ParseInt(cleanedVal[2:], 16, 64) | ||||
| 			case 'o': | ||||
| 				err = numberContainsInvalidUnderscore(tok.val) | ||||
| 				if err != nil { | ||||
| 					p.raiseError(tok, "%s", err) | ||||
| 				} | ||||
| 				val, err = strconv.ParseInt(cleanedVal[2:], 8, 64) | ||||
| 			case 'b': | ||||
| 				err = numberContainsInvalidUnderscore(tok.val) | ||||
| 				if err != nil { | ||||
| 					p.raiseError(tok, "%s", err) | ||||
| 				} | ||||
| 				val, err = strconv.ParseInt(cleanedVal[2:], 2, 64) | ||||
| 			default: | ||||
| 				panic("invalid base") // the lexer should catch this first | ||||
| 			} | ||||
| 		} else { | ||||
| 			err = numberContainsInvalidUnderscore(tok.val) | ||||
| 			if err != nil { | ||||
| 				p.raiseError(tok, "%s", err) | ||||
| 			} | ||||
| 			val, err = strconv.ParseInt(cleanedVal, 10, 64) | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			p.raiseError(tok, "%s", err) | ||||
| 		} | ||||
| 		return val | ||||
| 	case tokenFloat: | ||||
| 		err := numberContainsInvalidUnderscore(tok.val) | ||||
| 		if err != nil { | ||||
| 			p.raiseError(tok, "%s", err) | ||||
| 		} | ||||
| 		cleanedVal := cleanupNumberToken(tok.val) | ||||
| 		val, err := strconv.ParseFloat(cleanedVal, 64) | ||||
| 		if err != nil { | ||||
| 			p.raiseError(tok, "%s", err) | ||||
| 		} | ||||
| 		return val | ||||
| 	case tokenDate: | ||||
| 		val, err := time.ParseInLocation(time.RFC3339Nano, tok.val, time.UTC) | ||||
| 		if err != nil { | ||||
| 			p.raiseError(tok, "%s", err) | ||||
| 		} | ||||
| 		return val | ||||
| 	case tokenLeftBracket: | ||||
| 		return p.parseArray() | ||||
| 	case tokenLeftCurlyBrace: | ||||
| 		return p.parseInlineTable() | ||||
| 	case tokenEqual: | ||||
| 		p.raiseError(tok, "cannot have multiple equals for the same key") | ||||
| 	case tokenError: | ||||
| 		p.raiseError(tok, "%s", tok) | ||||
| 	} | ||||
|  | ||||
| 	p.raiseError(tok, "never reached") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func tokenIsComma(t *token) bool { | ||||
| 	return t != nil && t.typ == tokenComma | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseInlineTable() *Tree { | ||||
| 	tree := newTree() | ||||
| 	var previous *token | ||||
| Loop: | ||||
| 	for { | ||||
| 		follow := p.peek() | ||||
| 		if follow == nil || follow.typ == tokenEOF { | ||||
| 			p.raiseError(follow, "unterminated inline table") | ||||
| 		} | ||||
| 		switch follow.typ { | ||||
| 		case tokenRightCurlyBrace: | ||||
| 			p.getToken() | ||||
| 			break Loop | ||||
| 		case tokenKey, tokenInteger, tokenString: | ||||
| 			if !tokenIsComma(previous) && previous != nil { | ||||
| 				p.raiseError(follow, "comma expected between fields in inline table") | ||||
| 			} | ||||
| 			key := p.getToken() | ||||
| 			p.assume(tokenEqual) | ||||
| 			value := p.parseRvalue() | ||||
| 			tree.Set(key.val, value) | ||||
| 		case tokenComma: | ||||
| 			if previous == nil { | ||||
| 				p.raiseError(follow, "inline table cannot start with a comma") | ||||
| 			} | ||||
| 			if tokenIsComma(previous) { | ||||
| 				p.raiseError(follow, "need field between two commas in inline table") | ||||
| 			} | ||||
| 			p.getToken() | ||||
| 		default: | ||||
| 			p.raiseError(follow, "unexpected token type in inline table: %s", follow.String()) | ||||
| 		} | ||||
| 		previous = follow | ||||
| 	} | ||||
| 	if tokenIsComma(previous) { | ||||
| 		p.raiseError(previous, "trailing comma at the end of inline table") | ||||
| 	} | ||||
| 	return tree | ||||
| } | ||||
|  | ||||
| func (p *tomlParser) parseArray() interface{} { | ||||
| 	var array []interface{} | ||||
| 	arrayType := reflect.TypeOf(nil) | ||||
| 	for { | ||||
| 		follow := p.peek() | ||||
| 		if follow == nil || follow.typ == tokenEOF { | ||||
| 			p.raiseError(follow, "unterminated array") | ||||
| 		} | ||||
| 		if follow.typ == tokenRightBracket { | ||||
| 			p.getToken() | ||||
| 			break | ||||
| 		} | ||||
| 		val := p.parseRvalue() | ||||
| 		if arrayType == nil { | ||||
| 			arrayType = reflect.TypeOf(val) | ||||
| 		} | ||||
| 		if reflect.TypeOf(val) != arrayType { | ||||
| 			p.raiseError(follow, "mixed types in array") | ||||
| 		} | ||||
| 		array = append(array, val) | ||||
| 		follow = p.peek() | ||||
| 		if follow == nil || follow.typ == tokenEOF { | ||||
| 			p.raiseError(follow, "unterminated array") | ||||
| 		} | ||||
| 		if follow.typ != tokenRightBracket && follow.typ != tokenComma { | ||||
| 			p.raiseError(follow, "missing comma") | ||||
| 		} | ||||
| 		if follow.typ == tokenComma { | ||||
| 			p.getToken() | ||||
| 		} | ||||
| 	} | ||||
| 	// An array of Trees is actually an array of inline | ||||
| 	// tables, which is a shorthand for a table array. If the | ||||
| 	// array was not converted from []interface{} to []*Tree, | ||||
| 	// the two notations would not be equivalent. | ||||
| 	if arrayType == reflect.TypeOf(newTree()) { | ||||
| 		tomlArray := make([]*Tree, len(array)) | ||||
| 		for i, v := range array { | ||||
| 			tomlArray[i] = v.(*Tree) | ||||
| 		} | ||||
| 		return tomlArray | ||||
| 	} | ||||
| 	return array | ||||
| } | ||||
|  | ||||
| func parseToml(flow []token) *Tree { | ||||
| 	result := newTree() | ||||
| 	result.position = Position{1, 1} | ||||
| 	parser := &tomlParser{ | ||||
| 		flowIdx:       0, | ||||
| 		flow:          flow, | ||||
| 		tree:          result, | ||||
| 		currentTable:  make([]string, 0), | ||||
| 		seenTableKeys: make([]string, 0), | ||||
| 	} | ||||
| 	parser.run() | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	numberUnderscoreInvalidRegexp = regexp.MustCompile(`([^\d]_|_[^\d])|_$|^_`) | ||||
| 	hexNumberUnderscoreInvalidRegexp = regexp.MustCompile(`(^0x_)|([^\da-f]_|_[^\da-f])|_$|^_`) | ||||
| } | ||||
							
								
								
									
										29
									
								
								vendor/github.com/pelletier/go-toml/position.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/pelletier/go-toml/position.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| // Position support for go-toml | ||||
|  | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| ) | ||||
|  | ||||
| // Position of a document element within a TOML document. | ||||
| // | ||||
| // Line and Col are both 1-indexed positions for the element's line number and | ||||
| // column number, respectively.  Values of zero or less will cause Invalid(), | ||||
| // to return true. | ||||
| type Position struct { | ||||
| 	Line int // line within the document | ||||
| 	Col  int // column within the line | ||||
| } | ||||
|  | ||||
| // String representation of the position. | ||||
| // Displays 1-indexed line and column numbers. | ||||
| func (p Position) String() string { | ||||
| 	return fmt.Sprintf("(%d, %d)", p.Line, p.Col) | ||||
| } | ||||
|  | ||||
| // Invalid returns whether or not the position is valid (i.e. with negative or | ||||
| // null values) | ||||
| func (p Position) Invalid() bool { | ||||
| 	return p.Line <= 0 || p.Col <= 0 | ||||
| } | ||||
							
								
								
									
										144
									
								
								vendor/github.com/pelletier/go-toml/token.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								vendor/github.com/pelletier/go-toml/token.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"unicode" | ||||
| ) | ||||
|  | ||||
| // Define tokens | ||||
| type tokenType int | ||||
|  | ||||
| const ( | ||||
| 	eof = -(iota + 1) | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	tokenError tokenType = iota | ||||
| 	tokenEOF | ||||
| 	tokenComment | ||||
| 	tokenKey | ||||
| 	tokenString | ||||
| 	tokenInteger | ||||
| 	tokenTrue | ||||
| 	tokenFalse | ||||
| 	tokenFloat | ||||
| 	tokenInf | ||||
| 	tokenNan | ||||
| 	tokenEqual | ||||
| 	tokenLeftBracket | ||||
| 	tokenRightBracket | ||||
| 	tokenLeftCurlyBrace | ||||
| 	tokenRightCurlyBrace | ||||
| 	tokenLeftParen | ||||
| 	tokenRightParen | ||||
| 	tokenDoubleLeftBracket | ||||
| 	tokenDoubleRightBracket | ||||
| 	tokenDate | ||||
| 	tokenKeyGroup | ||||
| 	tokenKeyGroupArray | ||||
| 	tokenComma | ||||
| 	tokenColon | ||||
| 	tokenDollar | ||||
| 	tokenStar | ||||
| 	tokenQuestion | ||||
| 	tokenDot | ||||
| 	tokenDotDot | ||||
| 	tokenEOL | ||||
| ) | ||||
|  | ||||
| var tokenTypeNames = []string{ | ||||
| 	"Error", | ||||
| 	"EOF", | ||||
| 	"Comment", | ||||
| 	"Key", | ||||
| 	"String", | ||||
| 	"Integer", | ||||
| 	"True", | ||||
| 	"False", | ||||
| 	"Float", | ||||
| 	"Inf", | ||||
| 	"NaN", | ||||
| 	"=", | ||||
| 	"[", | ||||
| 	"]", | ||||
| 	"{", | ||||
| 	"}", | ||||
| 	"(", | ||||
| 	")", | ||||
| 	"]]", | ||||
| 	"[[", | ||||
| 	"Date", | ||||
| 	"KeyGroup", | ||||
| 	"KeyGroupArray", | ||||
| 	",", | ||||
| 	":", | ||||
| 	"$", | ||||
| 	"*", | ||||
| 	"?", | ||||
| 	".", | ||||
| 	"..", | ||||
| 	"EOL", | ||||
| } | ||||
|  | ||||
| type token struct { | ||||
| 	Position | ||||
| 	typ tokenType | ||||
| 	val string | ||||
| } | ||||
|  | ||||
| func (tt tokenType) String() string { | ||||
| 	idx := int(tt) | ||||
| 	if idx < len(tokenTypeNames) { | ||||
| 		return tokenTypeNames[idx] | ||||
| 	} | ||||
| 	return "Unknown" | ||||
| } | ||||
|  | ||||
| func (t token) Int() int { | ||||
| 	if result, err := strconv.Atoi(t.val); err != nil { | ||||
| 		panic(err) | ||||
| 	} else { | ||||
| 		return result | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (t token) String() string { | ||||
| 	switch t.typ { | ||||
| 	case tokenEOF: | ||||
| 		return "EOF" | ||||
| 	case tokenError: | ||||
| 		return t.val | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Sprintf("%q", t.val) | ||||
| } | ||||
|  | ||||
| func isSpace(r rune) bool { | ||||
| 	return r == ' ' || r == '\t' | ||||
| } | ||||
|  | ||||
| func isAlphanumeric(r rune) bool { | ||||
| 	return unicode.IsLetter(r) || r == '_' | ||||
| } | ||||
|  | ||||
| func isKeyChar(r rune) bool { | ||||
| 	// Keys start with the first character that isn't whitespace or [ and end | ||||
| 	// with the last non-whitespace character before the equals sign. Keys | ||||
| 	// cannot contain a # character." | ||||
| 	return !(r == '\r' || r == '\n' || r == eof || r == '=') | ||||
| } | ||||
|  | ||||
| func isKeyStartChar(r rune) bool { | ||||
| 	return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '[') | ||||
| } | ||||
|  | ||||
| func isDigit(r rune) bool { | ||||
| 	return unicode.IsNumber(r) | ||||
| } | ||||
|  | ||||
| func isHexDigit(r rune) bool { | ||||
| 	return isDigit(r) || | ||||
| 		(r >= 'a' && r <= 'f') || | ||||
| 		(r >= 'A' && r <= 'F') | ||||
| } | ||||
							
								
								
									
										393
									
								
								vendor/github.com/pelletier/go-toml/toml.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								vendor/github.com/pelletier/go-toml/toml.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,393 @@ | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type tomlValue struct { | ||||
| 	value     interface{} // string, int64, uint64, float64, bool, time.Time, [] of any of this list | ||||
| 	comment   string | ||||
| 	commented bool | ||||
| 	multiline bool | ||||
| 	position  Position | ||||
| } | ||||
|  | ||||
| // Tree is the result of the parsing of a TOML file. | ||||
| type Tree struct { | ||||
| 	values    map[string]interface{} // string -> *tomlValue, *Tree, []*Tree | ||||
| 	comment   string | ||||
| 	commented bool | ||||
| 	position  Position | ||||
| } | ||||
|  | ||||
| func newTree() *Tree { | ||||
| 	return newTreeWithPosition(Position{}) | ||||
| } | ||||
|  | ||||
| func newTreeWithPosition(pos Position) *Tree { | ||||
| 	return &Tree{ | ||||
| 		values:   make(map[string]interface{}), | ||||
| 		position: pos, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TreeFromMap initializes a new Tree object using the given map. | ||||
| func TreeFromMap(m map[string]interface{}) (*Tree, error) { | ||||
| 	result, err := toTree(m) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return result.(*Tree), nil | ||||
| } | ||||
|  | ||||
| // Position returns the position of the tree. | ||||
| func (t *Tree) Position() Position { | ||||
| 	return t.position | ||||
| } | ||||
|  | ||||
| // Has returns a boolean indicating if the given key exists. | ||||
| func (t *Tree) Has(key string) bool { | ||||
| 	if key == "" { | ||||
| 		return false | ||||
| 	} | ||||
| 	return t.HasPath(strings.Split(key, ".")) | ||||
| } | ||||
|  | ||||
| // HasPath returns true if the given path of keys exists, false otherwise. | ||||
| func (t *Tree) HasPath(keys []string) bool { | ||||
| 	return t.GetPath(keys) != nil | ||||
| } | ||||
|  | ||||
| // Keys returns the keys of the toplevel tree (does not recurse). | ||||
| func (t *Tree) Keys() []string { | ||||
| 	keys := make([]string, len(t.values)) | ||||
| 	i := 0 | ||||
| 	for k := range t.values { | ||||
| 		keys[i] = k | ||||
| 		i++ | ||||
| 	} | ||||
| 	return keys | ||||
| } | ||||
|  | ||||
| // Get the value at key in the Tree. | ||||
| // Key is a dot-separated path (e.g. a.b.c) without single/double quoted strings. | ||||
| // If you need to retrieve non-bare keys, use GetPath. | ||||
| // Returns nil if the path does not exist in the tree. | ||||
| // If keys is of length zero, the current tree is returned. | ||||
| func (t *Tree) Get(key string) interface{} { | ||||
| 	if key == "" { | ||||
| 		return t | ||||
| 	} | ||||
| 	return t.GetPath(strings.Split(key, ".")) | ||||
| } | ||||
|  | ||||
| // GetPath returns the element in the tree indicated by 'keys'. | ||||
| // If keys is of length zero, the current tree is returned. | ||||
| func (t *Tree) GetPath(keys []string) interface{} { | ||||
| 	if len(keys) == 0 { | ||||
| 		return t | ||||
| 	} | ||||
| 	subtree := t | ||||
| 	for _, intermediateKey := range keys[:len(keys)-1] { | ||||
| 		value, exists := subtree.values[intermediateKey] | ||||
| 		if !exists { | ||||
| 			return nil | ||||
| 		} | ||||
| 		switch node := value.(type) { | ||||
| 		case *Tree: | ||||
| 			subtree = node | ||||
| 		case []*Tree: | ||||
| 			// go to most recent element | ||||
| 			if len(node) == 0 { | ||||
| 				return nil | ||||
| 			} | ||||
| 			subtree = node[len(node)-1] | ||||
| 		default: | ||||
| 			return nil // cannot navigate through other node types | ||||
| 		} | ||||
| 	} | ||||
| 	// branch based on final node type | ||||
| 	switch node := subtree.values[keys[len(keys)-1]].(type) { | ||||
| 	case *tomlValue: | ||||
| 		return node.value | ||||
| 	default: | ||||
| 		return node | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetPosition returns the position of the given key. | ||||
| func (t *Tree) GetPosition(key string) Position { | ||||
| 	if key == "" { | ||||
| 		return t.position | ||||
| 	} | ||||
| 	return t.GetPositionPath(strings.Split(key, ".")) | ||||
| } | ||||
|  | ||||
| // GetPositionPath returns the element in the tree indicated by 'keys'. | ||||
| // If keys is of length zero, the current tree is returned. | ||||
| func (t *Tree) GetPositionPath(keys []string) Position { | ||||
| 	if len(keys) == 0 { | ||||
| 		return t.position | ||||
| 	} | ||||
| 	subtree := t | ||||
| 	for _, intermediateKey := range keys[:len(keys)-1] { | ||||
| 		value, exists := subtree.values[intermediateKey] | ||||
| 		if !exists { | ||||
| 			return Position{0, 0} | ||||
| 		} | ||||
| 		switch node := value.(type) { | ||||
| 		case *Tree: | ||||
| 			subtree = node | ||||
| 		case []*Tree: | ||||
| 			// go to most recent element | ||||
| 			if len(node) == 0 { | ||||
| 				return Position{0, 0} | ||||
| 			} | ||||
| 			subtree = node[len(node)-1] | ||||
| 		default: | ||||
| 			return Position{0, 0} | ||||
| 		} | ||||
| 	} | ||||
| 	// branch based on final node type | ||||
| 	switch node := subtree.values[keys[len(keys)-1]].(type) { | ||||
| 	case *tomlValue: | ||||
| 		return node.position | ||||
| 	case *Tree: | ||||
| 		return node.position | ||||
| 	case []*Tree: | ||||
| 		// go to most recent element | ||||
| 		if len(node) == 0 { | ||||
| 			return Position{0, 0} | ||||
| 		} | ||||
| 		return node[len(node)-1].position | ||||
| 	default: | ||||
| 		return Position{0, 0} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // GetDefault works like Get but with a default value | ||||
| func (t *Tree) GetDefault(key string, def interface{}) interface{} { | ||||
| 	val := t.Get(key) | ||||
| 	if val == nil { | ||||
| 		return def | ||||
| 	} | ||||
| 	return val | ||||
| } | ||||
|  | ||||
| // SetOptions arguments are supplied to the SetWithOptions and SetPathWithOptions functions to modify marshalling behaviour. | ||||
| // The default values within the struct are valid default options. | ||||
| type SetOptions struct { | ||||
| 	Comment   string | ||||
| 	Commented bool | ||||
| 	Multiline bool | ||||
| } | ||||
|  | ||||
| // SetWithOptions is the same as Set, but allows you to provide formatting | ||||
| // instructions to the key, that will be used by Marshal(). | ||||
| func (t *Tree) SetWithOptions(key string, opts SetOptions, value interface{}) { | ||||
| 	t.SetPathWithOptions(strings.Split(key, "."), opts, value) | ||||
| } | ||||
|  | ||||
| // SetPathWithOptions is the same as SetPath, but allows you to provide | ||||
| // formatting instructions to the key, that will be reused by Marshal(). | ||||
| func (t *Tree) SetPathWithOptions(keys []string, opts SetOptions, value interface{}) { | ||||
| 	subtree := t | ||||
| 	for i, intermediateKey := range keys[:len(keys)-1] { | ||||
| 		nextTree, exists := subtree.values[intermediateKey] | ||||
| 		if !exists { | ||||
| 			nextTree = newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}) | ||||
| 			subtree.values[intermediateKey] = nextTree // add new element here | ||||
| 		} | ||||
| 		switch node := nextTree.(type) { | ||||
| 		case *Tree: | ||||
| 			subtree = node | ||||
| 		case []*Tree: | ||||
| 			// go to most recent element | ||||
| 			if len(node) == 0 { | ||||
| 				// create element if it does not exist | ||||
| 				subtree.values[intermediateKey] = append(node, newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col})) | ||||
| 			} | ||||
| 			subtree = node[len(node)-1] | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var toInsert interface{} | ||||
|  | ||||
| 	switch v := value.(type) { | ||||
| 	case *Tree: | ||||
| 		v.comment = opts.Comment | ||||
| 		toInsert = value | ||||
| 	case []*Tree: | ||||
| 		toInsert = value | ||||
| 	case *tomlValue: | ||||
| 		v.comment = opts.Comment | ||||
| 		toInsert = v | ||||
| 	default: | ||||
| 		toInsert = &tomlValue{value: value, | ||||
| 			comment:   opts.Comment, | ||||
| 			commented: opts.Commented, | ||||
| 			multiline: opts.Multiline, | ||||
| 			position:  Position{Line: subtree.position.Line + len(subtree.values) + 1, Col: subtree.position.Col}} | ||||
| 	} | ||||
|  | ||||
| 	subtree.values[keys[len(keys)-1]] = toInsert | ||||
| } | ||||
|  | ||||
| // Set an element in the tree. | ||||
| // Key is a dot-separated path (e.g. a.b.c). | ||||
| // Creates all necessary intermediate trees, if needed. | ||||
| func (t *Tree) Set(key string, value interface{}) { | ||||
| 	t.SetWithComment(key, "", false, value) | ||||
| } | ||||
|  | ||||
| // SetWithComment is the same as Set, but allows you to provide comment | ||||
| // information to the key, that will be reused by Marshal(). | ||||
| func (t *Tree) SetWithComment(key string, comment string, commented bool, value interface{}) { | ||||
| 	t.SetPathWithComment(strings.Split(key, "."), comment, commented, value) | ||||
| } | ||||
|  | ||||
| // SetPath sets an element in the tree. | ||||
| // Keys is an array of path elements (e.g. {"a","b","c"}). | ||||
| // Creates all necessary intermediate trees, if needed. | ||||
| func (t *Tree) SetPath(keys []string, value interface{}) { | ||||
| 	t.SetPathWithComment(keys, "", false, value) | ||||
| } | ||||
|  | ||||
| // SetPathWithComment is the same as SetPath, but allows you to provide comment | ||||
| // information to the key, that will be reused by Marshal(). | ||||
| func (t *Tree) SetPathWithComment(keys []string, comment string, commented bool, value interface{}) { | ||||
| 	t.SetPathWithOptions(keys, SetOptions{Comment: comment, Commented: commented}, value) | ||||
| } | ||||
|  | ||||
| // Delete removes a key from the tree. | ||||
| // Key is a dot-separated path (e.g. a.b.c). | ||||
| func (t *Tree) Delete(key string) error { | ||||
| 	keys, err := parseKey(key) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return t.DeletePath(keys) | ||||
| } | ||||
|  | ||||
| // DeletePath removes a key from the tree. | ||||
| // Keys is an array of path elements (e.g. {"a","b","c"}). | ||||
| func (t *Tree) DeletePath(keys []string) error { | ||||
| 	keyLen := len(keys) | ||||
| 	if keyLen == 1 { | ||||
| 		delete(t.values, keys[0]) | ||||
| 		return nil | ||||
| 	} | ||||
| 	tree := t.GetPath(keys[:keyLen-1]) | ||||
| 	item := keys[keyLen-1] | ||||
| 	switch node := tree.(type) { | ||||
| 	case *Tree: | ||||
| 		delete(node.values, item) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return errors.New("no such key to delete") | ||||
| } | ||||
|  | ||||
| // createSubTree takes a tree and a key and create the necessary intermediate | ||||
| // subtrees to create a subtree at that point. In-place. | ||||
| // | ||||
| // e.g. passing a.b.c will create (assuming tree is empty) tree[a], tree[a][b] | ||||
| // and tree[a][b][c] | ||||
| // | ||||
| // Returns nil on success, error object on failure | ||||
| func (t *Tree) createSubTree(keys []string, pos Position) error { | ||||
| 	subtree := t | ||||
| 	for i, intermediateKey := range keys { | ||||
| 		nextTree, exists := subtree.values[intermediateKey] | ||||
| 		if !exists { | ||||
| 			tree := newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}) | ||||
| 			tree.position = pos | ||||
| 			subtree.values[intermediateKey] = tree | ||||
| 			nextTree = tree | ||||
| 		} | ||||
|  | ||||
| 		switch node := nextTree.(type) { | ||||
| 		case []*Tree: | ||||
| 			subtree = node[len(node)-1] | ||||
| 		case *Tree: | ||||
| 			subtree = node | ||||
| 		default: | ||||
| 			return fmt.Errorf("unknown type for path %s (%s): %T (%#v)", | ||||
| 				strings.Join(keys, "."), intermediateKey, nextTree, nextTree) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // LoadBytes creates a Tree from a []byte. | ||||
| func LoadBytes(b []byte) (tree *Tree, err error) { | ||||
| 	defer func() { | ||||
| 		if r := recover(); r != nil { | ||||
| 			if _, ok := r.(runtime.Error); ok { | ||||
| 				panic(r) | ||||
| 			} | ||||
| 			err = errors.New(r.(string)) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	if len(b) >= 4 && (hasUTF32BigEndianBOM4(b) || hasUTF32LittleEndianBOM4(b)) { | ||||
| 		b = b[4:] | ||||
| 	} else if len(b) >= 3 && hasUTF8BOM3(b) { | ||||
| 		b = b[3:] | ||||
| 	} else if len(b) >= 2 && (hasUTF16BigEndianBOM2(b) || hasUTF16LittleEndianBOM2(b)) { | ||||
| 		b = b[2:] | ||||
| 	} | ||||
|  | ||||
| 	tree = parseToml(lexToml(b)) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func hasUTF16BigEndianBOM2(b []byte) bool { | ||||
| 	return b[0] == 0xFE && b[1] == 0xFF | ||||
| } | ||||
|  | ||||
| func hasUTF16LittleEndianBOM2(b []byte) bool { | ||||
| 	return b[0] == 0xFF && b[1] == 0xFE | ||||
| } | ||||
|  | ||||
| func hasUTF8BOM3(b []byte) bool { | ||||
| 	return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF | ||||
| } | ||||
|  | ||||
| func hasUTF32BigEndianBOM4(b []byte) bool { | ||||
| 	return b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF | ||||
| } | ||||
|  | ||||
| func hasUTF32LittleEndianBOM4(b []byte) bool { | ||||
| 	return b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00 | ||||
| } | ||||
|  | ||||
| // LoadReader creates a Tree from any io.Reader. | ||||
| func LoadReader(reader io.Reader) (tree *Tree, err error) { | ||||
| 	inputBytes, err := ioutil.ReadAll(reader) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	tree, err = LoadBytes(inputBytes) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Load creates a Tree from a string. | ||||
| func Load(content string) (tree *Tree, err error) { | ||||
| 	return LoadBytes([]byte(content)) | ||||
| } | ||||
|  | ||||
| // LoadFile creates a Tree from a file. | ||||
| func LoadFile(path string) (tree *Tree, err error) { | ||||
| 	file, err := os.Open(path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
| 	return LoadReader(file) | ||||
| } | ||||
							
								
								
									
										142
									
								
								vendor/github.com/pelletier/go-toml/tomltree_create.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/pelletier/go-toml/tomltree_create.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var kindToType = [reflect.String + 1]reflect.Type{ | ||||
| 	reflect.Bool:    reflect.TypeOf(true), | ||||
| 	reflect.String:  reflect.TypeOf(""), | ||||
| 	reflect.Float32: reflect.TypeOf(float64(1)), | ||||
| 	reflect.Float64: reflect.TypeOf(float64(1)), | ||||
| 	reflect.Int:     reflect.TypeOf(int64(1)), | ||||
| 	reflect.Int8:    reflect.TypeOf(int64(1)), | ||||
| 	reflect.Int16:   reflect.TypeOf(int64(1)), | ||||
| 	reflect.Int32:   reflect.TypeOf(int64(1)), | ||||
| 	reflect.Int64:   reflect.TypeOf(int64(1)), | ||||
| 	reflect.Uint:    reflect.TypeOf(uint64(1)), | ||||
| 	reflect.Uint8:   reflect.TypeOf(uint64(1)), | ||||
| 	reflect.Uint16:  reflect.TypeOf(uint64(1)), | ||||
| 	reflect.Uint32:  reflect.TypeOf(uint64(1)), | ||||
| 	reflect.Uint64:  reflect.TypeOf(uint64(1)), | ||||
| } | ||||
|  | ||||
| // typeFor returns a reflect.Type for a reflect.Kind, or nil if none is found. | ||||
| // supported values: | ||||
| // string, bool, int64, uint64, float64, time.Time, int, int8, int16, int32, uint, uint8, uint16, uint32, float32 | ||||
| func typeFor(k reflect.Kind) reflect.Type { | ||||
| 	if k > 0 && int(k) < len(kindToType) { | ||||
| 		return kindToType[k] | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func simpleValueCoercion(object interface{}) (interface{}, error) { | ||||
| 	switch original := object.(type) { | ||||
| 	case string, bool, int64, uint64, float64, time.Time: | ||||
| 		return original, nil | ||||
| 	case int: | ||||
| 		return int64(original), nil | ||||
| 	case int8: | ||||
| 		return int64(original), nil | ||||
| 	case int16: | ||||
| 		return int64(original), nil | ||||
| 	case int32: | ||||
| 		return int64(original), nil | ||||
| 	case uint: | ||||
| 		return uint64(original), nil | ||||
| 	case uint8: | ||||
| 		return uint64(original), nil | ||||
| 	case uint16: | ||||
| 		return uint64(original), nil | ||||
| 	case uint32: | ||||
| 		return uint64(original), nil | ||||
| 	case float32: | ||||
| 		return float64(original), nil | ||||
| 	case fmt.Stringer: | ||||
| 		return original.String(), nil | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("cannot convert type %T to Tree", object) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func sliceToTree(object interface{}) (interface{}, error) { | ||||
| 	// arrays are a bit tricky, since they can represent either a | ||||
| 	// collection of simple values, which is represented by one | ||||
| 	// *tomlValue, or an array of tables, which is represented by an | ||||
| 	// array of *Tree. | ||||
|  | ||||
| 	// holding the assumption that this function is called from toTree only when value.Kind() is Array or Slice | ||||
| 	value := reflect.ValueOf(object) | ||||
| 	insideType := value.Type().Elem() | ||||
| 	length := value.Len() | ||||
| 	if length > 0 { | ||||
| 		insideType = reflect.ValueOf(value.Index(0).Interface()).Type() | ||||
| 	} | ||||
| 	if insideType.Kind() == reflect.Map { | ||||
| 		// this is considered as an array of tables | ||||
| 		tablesArray := make([]*Tree, 0, length) | ||||
| 		for i := 0; i < length; i++ { | ||||
| 			table := value.Index(i) | ||||
| 			tree, err := toTree(table.Interface()) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			tablesArray = append(tablesArray, tree.(*Tree)) | ||||
| 		} | ||||
| 		return tablesArray, nil | ||||
| 	} | ||||
|  | ||||
| 	sliceType := typeFor(insideType.Kind()) | ||||
| 	if sliceType == nil { | ||||
| 		sliceType = insideType | ||||
| 	} | ||||
|  | ||||
| 	arrayValue := reflect.MakeSlice(reflect.SliceOf(sliceType), 0, length) | ||||
|  | ||||
| 	for i := 0; i < length; i++ { | ||||
| 		val := value.Index(i).Interface() | ||||
| 		simpleValue, err := simpleValueCoercion(val) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		arrayValue = reflect.Append(arrayValue, reflect.ValueOf(simpleValue)) | ||||
| 	} | ||||
| 	return &tomlValue{value: arrayValue.Interface(), position: Position{}}, nil | ||||
| } | ||||
|  | ||||
| func toTree(object interface{}) (interface{}, error) { | ||||
| 	value := reflect.ValueOf(object) | ||||
|  | ||||
| 	if value.Kind() == reflect.Map { | ||||
| 		values := map[string]interface{}{} | ||||
| 		keys := value.MapKeys() | ||||
| 		for _, key := range keys { | ||||
| 			if key.Kind() != reflect.String { | ||||
| 				if _, ok := key.Interface().(string); !ok { | ||||
| 					return nil, fmt.Errorf("map key needs to be a string, not %T (%v)", key.Interface(), key.Kind()) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			v := value.MapIndex(key) | ||||
| 			newValue, err := toTree(v.Interface()) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			values[key.String()] = newValue | ||||
| 		} | ||||
| 		return &Tree{values: values, position: Position{}}, nil | ||||
| 	} | ||||
|  | ||||
| 	if value.Kind() == reflect.Array || value.Kind() == reflect.Slice { | ||||
| 		return sliceToTree(object) | ||||
| 	} | ||||
|  | ||||
| 	simpleValue, err := simpleValueCoercion(object) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &tomlValue{value: simpleValue, position: Position{}}, nil | ||||
| } | ||||
							
								
								
									
										434
									
								
								vendor/github.com/pelletier/go-toml/tomltree_write.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								vendor/github.com/pelletier/go-toml/tomltree_write.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,434 @@ | ||||
| package toml | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"math" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type valueComplexity int | ||||
|  | ||||
| const ( | ||||
| 	valueSimple valueComplexity = iota + 1 | ||||
| 	valueComplex | ||||
| ) | ||||
|  | ||||
| type sortNode struct { | ||||
| 	key        string | ||||
| 	complexity valueComplexity | ||||
| } | ||||
|  | ||||
| // Encodes a string to a TOML-compliant multi-line string value | ||||
| // This function is a clone of the existing encodeTomlString function, except that whitespace characters | ||||
| // are preserved. Quotation marks and backslashes are also not escaped. | ||||
| func encodeMultilineTomlString(value string) string { | ||||
| 	var b bytes.Buffer | ||||
|  | ||||
| 	for _, rr := range value { | ||||
| 		switch rr { | ||||
| 		case '\b': | ||||
| 			b.WriteString(`\b`) | ||||
| 		case '\t': | ||||
| 			b.WriteString("\t") | ||||
| 		case '\n': | ||||
| 			b.WriteString("\n") | ||||
| 		case '\f': | ||||
| 			b.WriteString(`\f`) | ||||
| 		case '\r': | ||||
| 			b.WriteString("\r") | ||||
| 		case '"': | ||||
| 			b.WriteString(`"`) | ||||
| 		case '\\': | ||||
| 			b.WriteString(`\`) | ||||
| 		default: | ||||
| 			intRr := uint16(rr) | ||||
| 			if intRr < 0x001F { | ||||
| 				b.WriteString(fmt.Sprintf("\\u%0.4X", intRr)) | ||||
| 			} else { | ||||
| 				b.WriteRune(rr) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| // Encodes a string to a TOML-compliant string value | ||||
| func encodeTomlString(value string) string { | ||||
| 	var b bytes.Buffer | ||||
|  | ||||
| 	for _, rr := range value { | ||||
| 		switch rr { | ||||
| 		case '\b': | ||||
| 			b.WriteString(`\b`) | ||||
| 		case '\t': | ||||
| 			b.WriteString(`\t`) | ||||
| 		case '\n': | ||||
| 			b.WriteString(`\n`) | ||||
| 		case '\f': | ||||
| 			b.WriteString(`\f`) | ||||
| 		case '\r': | ||||
| 			b.WriteString(`\r`) | ||||
| 		case '"': | ||||
| 			b.WriteString(`\"`) | ||||
| 		case '\\': | ||||
| 			b.WriteString(`\\`) | ||||
| 		default: | ||||
| 			intRr := uint16(rr) | ||||
| 			if intRr < 0x001F { | ||||
| 				b.WriteString(fmt.Sprintf("\\u%0.4X", intRr)) | ||||
| 			} else { | ||||
| 				b.WriteRune(rr) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return b.String() | ||||
| } | ||||
|  | ||||
| func tomlValueStringRepresentation(v interface{}, indent string, arraysOneElementPerLine bool) (string, error) { | ||||
| 	// this interface check is added to dereference the change made in the writeTo function. | ||||
| 	// That change was made to allow this function to see formatting options. | ||||
| 	tv, ok := v.(*tomlValue) | ||||
| 	if ok { | ||||
| 		v = tv.value | ||||
| 	} else { | ||||
| 		tv = &tomlValue{} | ||||
| 	} | ||||
|  | ||||
| 	switch value := v.(type) { | ||||
| 	case uint64: | ||||
| 		return strconv.FormatUint(value, 10), nil | ||||
| 	case int64: | ||||
| 		return strconv.FormatInt(value, 10), nil | ||||
| 	case float64: | ||||
| 		// Ensure a round float does contain a decimal point. Otherwise feeding | ||||
| 		// the output back to the parser would convert to an integer. | ||||
| 		if math.Trunc(value) == value { | ||||
| 			return strings.ToLower(strconv.FormatFloat(value, 'f', 1, 32)), nil | ||||
| 		} | ||||
| 		return strings.ToLower(strconv.FormatFloat(value, 'f', -1, 32)), nil | ||||
| 	case string: | ||||
| 		if tv.multiline { | ||||
| 			return "\"\"\"\n" + encodeMultilineTomlString(value) + "\"\"\"", nil | ||||
| 		} | ||||
| 		return "\"" + encodeTomlString(value) + "\"", nil | ||||
| 	case []byte: | ||||
| 		b, _ := v.([]byte) | ||||
| 		return tomlValueStringRepresentation(string(b), indent, arraysOneElementPerLine) | ||||
| 	case bool: | ||||
| 		if value { | ||||
| 			return "true", nil | ||||
| 		} | ||||
| 		return "false", nil | ||||
| 	case time.Time: | ||||
| 		return value.Format(time.RFC3339), nil | ||||
| 	case nil: | ||||
| 		return "", nil | ||||
| 	} | ||||
|  | ||||
| 	rv := reflect.ValueOf(v) | ||||
|  | ||||
| 	if rv.Kind() == reflect.Slice { | ||||
| 		var values []string | ||||
| 		for i := 0; i < rv.Len(); i++ { | ||||
| 			item := rv.Index(i).Interface() | ||||
| 			itemRepr, err := tomlValueStringRepresentation(item, indent, arraysOneElementPerLine) | ||||
| 			if err != nil { | ||||
| 				return "", err | ||||
| 			} | ||||
| 			values = append(values, itemRepr) | ||||
| 		} | ||||
| 		if arraysOneElementPerLine && len(values) > 1 { | ||||
| 			stringBuffer := bytes.Buffer{} | ||||
| 			valueIndent := indent + `  ` // TODO: move that to a shared encoder state | ||||
|  | ||||
| 			stringBuffer.WriteString("[\n") | ||||
|  | ||||
| 			for _, value := range values { | ||||
| 				stringBuffer.WriteString(valueIndent) | ||||
| 				stringBuffer.WriteString(value) | ||||
| 				stringBuffer.WriteString(`,`) | ||||
| 				stringBuffer.WriteString("\n") | ||||
| 			} | ||||
|  | ||||
| 			stringBuffer.WriteString(indent + "]") | ||||
|  | ||||
| 			return stringBuffer.String(), nil | ||||
| 		} | ||||
| 		return "[" + strings.Join(values, ",") + "]", nil | ||||
| 	} | ||||
| 	return "", fmt.Errorf("unsupported value type %T: %v", v, v) | ||||
| } | ||||
|  | ||||
| func getTreeArrayLine(trees []*Tree) (line int) { | ||||
| 	// get lowest line number that is not 0 | ||||
| 	for _, tv := range trees { | ||||
| 		if tv.position.Line < line || line == 0 { | ||||
| 			line = tv.position.Line | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func sortByLines(t *Tree) (vals []sortNode) { | ||||
| 	var ( | ||||
| 		line  int | ||||
| 		lines []int | ||||
| 		tv    *Tree | ||||
| 		tom   *tomlValue | ||||
| 		node  sortNode | ||||
| 	) | ||||
| 	vals = make([]sortNode, 0) | ||||
| 	m := make(map[int]sortNode) | ||||
|  | ||||
| 	for k := range t.values { | ||||
| 		v := t.values[k] | ||||
| 		switch v.(type) { | ||||
| 		case *Tree: | ||||
| 			tv = v.(*Tree) | ||||
| 			line = tv.position.Line | ||||
| 			node = sortNode{key: k, complexity: valueComplex} | ||||
| 		case []*Tree: | ||||
| 			line = getTreeArrayLine(v.([]*Tree)) | ||||
| 			node = sortNode{key: k, complexity: valueComplex} | ||||
| 		default: | ||||
| 			tom = v.(*tomlValue) | ||||
| 			line = tom.position.Line | ||||
| 			node = sortNode{key: k, complexity: valueSimple} | ||||
| 		} | ||||
| 		lines = append(lines, line) | ||||
| 		vals = append(vals, node) | ||||
| 		m[line] = node | ||||
| 	} | ||||
| 	sort.Ints(lines) | ||||
|  | ||||
| 	for i, line := range lines { | ||||
| 		vals[i] = m[line] | ||||
| 	} | ||||
|  | ||||
| 	return vals | ||||
| } | ||||
|  | ||||
| func sortAlphabetical(t *Tree) (vals []sortNode) { | ||||
| 	var ( | ||||
| 		node     sortNode | ||||
| 		simpVals []string | ||||
| 		compVals []string | ||||
| 	) | ||||
| 	vals = make([]sortNode, 0) | ||||
| 	m := make(map[string]sortNode) | ||||
|  | ||||
| 	for k := range t.values { | ||||
| 		v := t.values[k] | ||||
| 		switch v.(type) { | ||||
| 		case *Tree, []*Tree: | ||||
| 			node = sortNode{key: k, complexity: valueComplex} | ||||
| 			compVals = append(compVals, node.key) | ||||
| 		default: | ||||
| 			node = sortNode{key: k, complexity: valueSimple} | ||||
| 			simpVals = append(simpVals, node.key) | ||||
| 		} | ||||
| 		vals = append(vals, node) | ||||
| 		m[node.key] = node | ||||
| 	} | ||||
|  | ||||
| 	// Simples first to match previous implementation | ||||
| 	sort.Strings(simpVals) | ||||
| 	i := 0 | ||||
| 	for _, key := range simpVals { | ||||
| 		vals[i] = m[key] | ||||
| 		i++ | ||||
| 	} | ||||
|  | ||||
| 	sort.Strings(compVals) | ||||
| 	for _, key := range compVals { | ||||
| 		vals[i] = m[key] | ||||
| 		i++ | ||||
| 	} | ||||
|  | ||||
| 	return vals | ||||
| } | ||||
|  | ||||
| func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) { | ||||
| 	return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical) | ||||
| } | ||||
|  | ||||
| func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord marshalOrder) (int64, error) { | ||||
| 	var orderedVals []sortNode | ||||
|  | ||||
| 	switch ord { | ||||
| 	case OrderPreserve: | ||||
| 		orderedVals = sortByLines(t) | ||||
| 	default: | ||||
| 		orderedVals = sortAlphabetical(t) | ||||
| 	} | ||||
|  | ||||
| 	for _, node := range orderedVals { | ||||
| 		switch node.complexity { | ||||
| 		case valueComplex: | ||||
| 			k := node.key | ||||
| 			v := t.values[k] | ||||
|  | ||||
| 			combinedKey := k | ||||
| 			if keyspace != "" { | ||||
| 				combinedKey = keyspace + "." + combinedKey | ||||
| 			} | ||||
| 			var commented string | ||||
| 			if t.commented { | ||||
| 				commented = "# " | ||||
| 			} | ||||
|  | ||||
| 			switch node := v.(type) { | ||||
| 			// node has to be of those two types given how keys are sorted above | ||||
| 			case *Tree: | ||||
| 				tv, ok := t.values[k].(*Tree) | ||||
| 				if !ok { | ||||
| 					return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k]) | ||||
| 				} | ||||
| 				if tv.comment != "" { | ||||
| 					comment := strings.Replace(tv.comment, "\n", "\n"+indent+"#", -1) | ||||
| 					start := "# " | ||||
| 					if strings.HasPrefix(comment, "#") { | ||||
| 						start = "" | ||||
| 					} | ||||
| 					writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment) | ||||
| 					bytesCount += int64(writtenBytesCountComment) | ||||
| 					if errc != nil { | ||||
| 						return bytesCount, errc | ||||
| 					} | ||||
| 				} | ||||
| 				writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[", combinedKey, "]\n") | ||||
| 				bytesCount += int64(writtenBytesCount) | ||||
| 				if err != nil { | ||||
| 					return bytesCount, err | ||||
| 				} | ||||
| 				bytesCount, err = node.writeToOrdered(w, indent+"  ", combinedKey, bytesCount, arraysOneElementPerLine, ord) | ||||
| 				if err != nil { | ||||
| 					return bytesCount, err | ||||
| 				} | ||||
| 			case []*Tree: | ||||
| 				for _, subTree := range node { | ||||
| 					writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[[", combinedKey, "]]\n") | ||||
| 					bytesCount += int64(writtenBytesCount) | ||||
| 					if err != nil { | ||||
| 						return bytesCount, err | ||||
| 					} | ||||
|  | ||||
| 					bytesCount, err = subTree.writeToOrdered(w, indent+"  ", combinedKey, bytesCount, arraysOneElementPerLine, ord) | ||||
| 					if err != nil { | ||||
| 						return bytesCount, err | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		default: // Simple | ||||
| 			k := node.key | ||||
| 			v, ok := t.values[k].(*tomlValue) | ||||
| 			if !ok { | ||||
| 				return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k]) | ||||
| 			} | ||||
|  | ||||
| 			repr, err := tomlValueStringRepresentation(v, indent, arraysOneElementPerLine) | ||||
| 			if err != nil { | ||||
| 				return bytesCount, err | ||||
| 			} | ||||
|  | ||||
| 			if v.comment != "" { | ||||
| 				comment := strings.Replace(v.comment, "\n", "\n"+indent+"#", -1) | ||||
| 				start := "# " | ||||
| 				if strings.HasPrefix(comment, "#") { | ||||
| 					start = "" | ||||
| 				} | ||||
| 				writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment, "\n") | ||||
| 				bytesCount += int64(writtenBytesCountComment) | ||||
| 				if errc != nil { | ||||
| 					return bytesCount, errc | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			var commented string | ||||
| 			if v.commented { | ||||
| 				commented = "# " | ||||
| 			} | ||||
| 			writtenBytesCount, err := writeStrings(w, indent, commented, k, " = ", repr, "\n") | ||||
| 			bytesCount += int64(writtenBytesCount) | ||||
| 			if err != nil { | ||||
| 				return bytesCount, err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return bytesCount, nil | ||||
| } | ||||
|  | ||||
| func writeStrings(w io.Writer, s ...string) (int, error) { | ||||
| 	var n int | ||||
| 	for i := range s { | ||||
| 		b, err := io.WriteString(w, s[i]) | ||||
| 		n += b | ||||
| 		if err != nil { | ||||
| 			return n, err | ||||
| 		} | ||||
| 	} | ||||
| 	return n, nil | ||||
| } | ||||
|  | ||||
| // WriteTo encode the Tree as Toml and writes it to the writer w. | ||||
| // Returns the number of bytes written in case of success, or an error if anything happened. | ||||
| func (t *Tree) WriteTo(w io.Writer) (int64, error) { | ||||
| 	return t.writeTo(w, "", "", 0, false) | ||||
| } | ||||
|  | ||||
| // ToTomlString generates a human-readable representation of the current tree. | ||||
| // Output spans multiple lines, and is suitable for ingest by a TOML parser. | ||||
| // If the conversion cannot be performed, ToString returns a non-nil error. | ||||
| func (t *Tree) ToTomlString() (string, error) { | ||||
| 	var buf bytes.Buffer | ||||
| 	_, err := t.WriteTo(&buf) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return buf.String(), nil | ||||
| } | ||||
|  | ||||
| // String generates a human-readable representation of the current tree. | ||||
| // Alias of ToString. Present to implement the fmt.Stringer interface. | ||||
| func (t *Tree) String() string { | ||||
| 	result, _ := t.ToTomlString() | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // ToMap recursively generates a representation of the tree using Go built-in structures. | ||||
| // The following types are used: | ||||
| // | ||||
| //	* bool | ||||
| //	* float64 | ||||
| //	* int64 | ||||
| //	* string | ||||
| //	* uint64 | ||||
| //	* time.Time | ||||
| //	* map[string]interface{} (where interface{} is any of this list) | ||||
| //	* []interface{} (where interface{} is any of this list) | ||||
| func (t *Tree) ToMap() map[string]interface{} { | ||||
| 	result := map[string]interface{}{} | ||||
|  | ||||
| 	for k, v := range t.values { | ||||
| 		switch node := v.(type) { | ||||
| 		case []*Tree: | ||||
| 			var array []interface{} | ||||
| 			for _, item := range node { | ||||
| 				array = append(array, item.ToMap()) | ||||
| 			} | ||||
| 			result[k] = array | ||||
| 		case *Tree: | ||||
| 			result[k] = node.ToMap() | ||||
| 		case *tomlValue: | ||||
| 			result[k] = node.value | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
		Reference in New Issue
	
	Block a user