├── .gitignore
├── Procfile
├── assets
├── apple-touch-icon.png
├── apple-touch-icon-precomposed.png
└── master.css
├── vendor
├── github.com
│ └── ChimeraCoder
│ │ └── gojson
│ │ ├── .gitignore
│ │ ├── .appveyor.yml
│ │ ├── Gopkg.lock
│ │ ├── Gopkg.toml
│ │ ├── .travis.yml
│ │ ├── README.md
│ │ └── json-to-struct.go
├── modules.txt
└── gopkg.in
│ └── yaml.v2
│ ├── .travis.yml
│ ├── NOTICE
│ ├── writerc.go
│ ├── LICENSE.libyaml
│ ├── sorter.go
│ ├── README.md
│ ├── yamlprivateh.go
│ ├── resolve.go
│ ├── encode.go
│ ├── LICENSE
│ ├── readerc.go
│ ├── yaml.go
│ ├── decode.go
│ ├── apic.go
│ └── yamlh.go
├── go.mod
├── README.md
├── Dockerfile
├── example.json
├── docker-compose.yml
├── Makefile
├── go.sum
├── LICENSE
├── index.html
└── main.go
/.gitignore:
--------------------------------------------------------------------------------
1 | log.out
2 | gojson-http
3 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: gojson-http -port $PORT -listen 0.0.0.0 -template /app/index.html
2 |
--------------------------------------------------------------------------------
/assets/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmervine/gojson-http/HEAD/assets/apple-touch-icon.png
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.swo
3 | *.swn
4 | *.db
5 | *.log
6 | build/
7 | conf.go
8 | build/
9 |
--------------------------------------------------------------------------------
/assets/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jmervine/gojson-http/HEAD/assets/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/jmervine/gojson-http
2 |
3 | go 1.20
4 |
5 | require github.com/ChimeraCoder/gojson v1.1.0
6 |
7 | require gopkg.in/yaml.v2 v2.2.8 // indirect
8 |
--------------------------------------------------------------------------------
/vendor/modules.txt:
--------------------------------------------------------------------------------
1 | # github.com/ChimeraCoder/gojson v1.1.0
2 | ## explicit
3 | github.com/ChimeraCoder/gojson
4 | # gopkg.in/yaml.v2 v2.2.8
5 | ## explicit
6 | gopkg.in/yaml.v2
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | gojson-http
2 | ===========
3 |
4 | Simple web interface to convert json to a go struct, based on the work of [github.com/ChimeraCoder/gojson](https://github.com/ChimeraCoder/gojson).
5 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.20
2 | ENV PORT 3000
3 | EXPOSE ${PORT}
4 | WORKDIR /src
5 | COPY . .
6 | RUN make clean && make && \
7 | echo "PORT=${PORT}" >> /etc/profile
8 | CMD [ "make", "start" ]
9 |
--------------------------------------------------------------------------------
/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors": [
3 | {
4 | "red": "#f00",
5 | "green": "#0f0",
6 | "blue": "#00f",
7 | "cyan": "#0ff",
8 | "magenta": "#f0f",
9 | "yellow": "#ff0",
10 | "black": "#000"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/.appveyor.yml:
--------------------------------------------------------------------------------
1 | clone_folder: C:\gopath\src\github.com\ChimeraCoder\gojson
2 |
3 | shallow_clone: true
4 |
5 | pull_requests:
6 | do_not_increment_build_number: true
7 |
8 | environment:
9 | GOPATH: c:\gopath
10 |
11 | build_script:
12 | - go test -v
13 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - "1.4.x"
5 | - "1.5.x"
6 | - "1.6.x"
7 | - "1.7.x"
8 | - "1.8.x"
9 | - "1.9.x"
10 | - "1.10.x"
11 | - "1.11.x"
12 | - "1.12.x"
13 | - "1.13.x"
14 | - "tip"
15 |
16 | go_import_path: gopkg.in/yaml.v2
17 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | web:
2 | image: golang:1.20
3 | command: go run main.go -port 3000 -listen 0.0.0.0 -template /go/src/github.com/jmervine/gojson-http/index.html
4 | working_dir: /go/src/github.com/jmervine/gojson-http
5 | volumes:
6 | - .:/go/src/github.com/jmervine/gojson-http
7 | ports:
8 | - "3000:3000"
9 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PORT ?= 3333
2 | LISTEN ?= 0.0.0.0
3 | CWD=$(shell pwd)
4 |
5 | bin/gojson-http:
6 | go mod download
7 | go mod tidy
8 | go mod verify
9 | go build -o bin/gojson-http main.go
10 |
11 | .PHONY: clean
12 | clean:
13 | rm -rvf bin/gojson-http
14 |
15 | .PHONY: start
16 | start: bin/gojson-http
17 | $(CWD)/bin/gojson-http -port $(PORT) -listen $(LISTEN) -template $(CWD)/index.html
18 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/Gopkg.lock:
--------------------------------------------------------------------------------
1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
2 |
3 |
4 | [[projects]]
5 | branch = "v2"
6 | name = "gopkg.in/yaml.v2"
7 | packages = ["."]
8 | revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
9 |
10 | [solve-meta]
11 | analyzer-name = "dep"
12 | analyzer-version = 1
13 | inputs-digest = "c39e9119cc91080f9178c39214d6ca06156205351dec2523319554ee3669537e"
14 | solver-name = "gps-cdcl"
15 | solver-version = 1
16 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/ChimeraCoder/gojson v1.1.0 h1:/6S8djl/jColpJGTYniA3xrqJWuKeyEozzPtpr5L4Pw=
2 | github.com/ChimeraCoder/gojson v1.1.0/go.mod h1:nYbTQlu6hv8PETM15J927yM0zGj3njIldp72UT1MqSw=
3 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
6 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
7 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/NOTICE:
--------------------------------------------------------------------------------
1 | Copyright 2011-2016 Canonical Ltd.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/Gopkg.toml:
--------------------------------------------------------------------------------
1 |
2 | # Gopkg.toml example
3 | #
4 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
5 | # for detailed Gopkg.toml documentation.
6 | #
7 | # required = ["github.com/user/thing/cmd/thing"]
8 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
9 | #
10 | # [[constraint]]
11 | # name = "github.com/user/project"
12 | # version = "1.0.0"
13 | #
14 | # [[constraint]]
15 | # name = "github.com/user/project2"
16 | # branch = "dev"
17 | # source = "github.com/myfork/project2"
18 | #
19 | # [[override]]
20 | # name = "github.com/x/y"
21 | # version = "2.4.0"
22 |
23 |
24 | [[constraint]]
25 | branch = "v2"
26 | name = "gopkg.in/yaml.v2"
27 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/writerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | // Set the writer error and return false.
4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
5 | emitter.error = yaml_WRITER_ERROR
6 | emitter.problem = problem
7 | return false
8 | }
9 |
10 | // Flush the output buffer.
11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
12 | if emitter.write_handler == nil {
13 | panic("write handler not set")
14 | }
15 |
16 | // Check if the buffer is empty.
17 | if emitter.buffer_pos == 0 {
18 | return true
19 | }
20 |
21 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
22 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
23 | }
24 | emitter.buffer_pos = 0
25 | return true
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | os:
4 | - linux
5 | - osx
6 |
7 | go:
8 | - 1.7
9 | - 1.8
10 | - 1.9
11 | - tip
12 |
13 |
14 | matrix:
15 | include:
16 | - os: linux
17 | go: 1.5
18 | - os: linux
19 | go: 1.6
20 |
21 | before_script:
22 | - gofmt -w .
23 |
24 | # If `go generate` or `gofmt` yielded any changes,
25 | # this will fail with an error message like "too many arguments"
26 | # or "M: binary operator expected"
27 | - git add .
28 | - git diff-index --cached --exit-code HEAD
29 |
30 | script:
31 | - if [ "$TRAVIS_GO_VERSION" == "1.5" ] || [ "$TRAVIS_GO_VERSION" == "1.6" ] || [ "$TRAVIS_GO_VERSION" == "1.7" ] || [ "$TRAVIS_GO_VERSION" == "1.8" ]; then go list ./... | grep -v vendor | xargs go test -race -v -timeout 120s; else go test -race -v -timeout 120s ./...; fi
32 |
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Joshua P. Mervine
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/LICENSE.libyaml:
--------------------------------------------------------------------------------
1 | The following files were ported to Go from C files of libyaml, and thus
2 | are still covered by their original copyright and license:
3 |
4 | apic.go
5 | emitterc.go
6 | parserc.go
7 | readerc.go
8 | scannerc.go
9 | writerc.go
10 | yamlh.go
11 | yamlprivateh.go
12 |
13 | Copyright (c) 2006 Kirill Simonov
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy of
16 | this software and associated documentation files (the "Software"), to deal in
17 | the Software without restriction, including without limitation the rights to
18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
19 | of the Software, and to permit persons to whom the Software is furnished to do
20 | so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/sorter.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "reflect"
5 | "unicode"
6 | )
7 |
8 | type keyList []reflect.Value
9 |
10 | func (l keyList) Len() int { return len(l) }
11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
12 | func (l keyList) Less(i, j int) bool {
13 | a := l[i]
14 | b := l[j]
15 | ak := a.Kind()
16 | bk := b.Kind()
17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
18 | a = a.Elem()
19 | ak = a.Kind()
20 | }
21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
22 | b = b.Elem()
23 | bk = b.Kind()
24 | }
25 | af, aok := keyFloat(a)
26 | bf, bok := keyFloat(b)
27 | if aok && bok {
28 | if af != bf {
29 | return af < bf
30 | }
31 | if ak != bk {
32 | return ak < bk
33 | }
34 | return numLess(a, b)
35 | }
36 | if ak != reflect.String || bk != reflect.String {
37 | return ak < bk
38 | }
39 | ar, br := []rune(a.String()), []rune(b.String())
40 | for i := 0; i < len(ar) && i < len(br); i++ {
41 | if ar[i] == br[i] {
42 | continue
43 | }
44 | al := unicode.IsLetter(ar[i])
45 | bl := unicode.IsLetter(br[i])
46 | if al && bl {
47 | return ar[i] < br[i]
48 | }
49 | if al || bl {
50 | return bl
51 | }
52 | var ai, bi int
53 | var an, bn int64
54 | if ar[i] == '0' || br[i] == '0' {
55 | for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
56 | if ar[j] != '0' {
57 | an = 1
58 | bn = 1
59 | break
60 | }
61 | }
62 | }
63 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
64 | an = an*10 + int64(ar[ai]-'0')
65 | }
66 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
67 | bn = bn*10 + int64(br[bi]-'0')
68 | }
69 | if an != bn {
70 | return an < bn
71 | }
72 | if ai != bi {
73 | return ai < bi
74 | }
75 | return ar[i] < br[i]
76 | }
77 | return len(ar) < len(br)
78 | }
79 |
80 | // keyFloat returns a float value for v if it is a number/bool
81 | // and whether it is a number/bool or not.
82 | func keyFloat(v reflect.Value) (f float64, ok bool) {
83 | switch v.Kind() {
84 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
85 | return float64(v.Int()), true
86 | case reflect.Float32, reflect.Float64:
87 | return v.Float(), true
88 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
89 | return float64(v.Uint()), true
90 | case reflect.Bool:
91 | if v.Bool() {
92 | return 1, true
93 | }
94 | return 0, true
95 | }
96 | return 0, false
97 | }
98 |
99 | // numLess returns whether a < b.
100 | // a and b must necessarily have the same kind.
101 | func numLess(a, b reflect.Value) bool {
102 | switch a.Kind() {
103 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
104 | return a.Int() < b.Int()
105 | case reflect.Float32, reflect.Float64:
106 | return a.Float() < b.Float()
107 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
108 | return a.Uint() < b.Uint()
109 | case reflect.Bool:
110 | return !a.Bool() && b.Bool()
111 | }
112 | panic("not a number")
113 | }
114 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/README.md:
--------------------------------------------------------------------------------
1 | # YAML support for the Go language
2 |
3 | Introduction
4 | ------------
5 |
6 | The yaml package enables Go programs to comfortably encode and decode YAML
7 | values. It was developed within [Canonical](https://www.canonical.com) as
8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a
9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
10 | C library to parse and generate YAML data quickly and reliably.
11 |
12 | Compatibility
13 | -------------
14 |
15 | The yaml package supports most of YAML 1.1 and 1.2, including support for
16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
17 | implemented, and base-60 floats from YAML 1.1 are purposefully not
18 | supported since they're a poor design and are gone in YAML 1.2.
19 |
20 | Installation and usage
21 | ----------------------
22 |
23 | The import path for the package is *gopkg.in/yaml.v2*.
24 |
25 | To install it, run:
26 |
27 | go get gopkg.in/yaml.v2
28 |
29 | API documentation
30 | -----------------
31 |
32 | If opened in a browser, the import path itself leads to the API documentation:
33 |
34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
35 |
36 | API stability
37 | -------------
38 |
39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
40 |
41 |
42 | License
43 | -------
44 |
45 | The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
46 |
47 |
48 | Example
49 | -------
50 |
51 | ```Go
52 | package main
53 |
54 | import (
55 | "fmt"
56 | "log"
57 |
58 | "gopkg.in/yaml.v2"
59 | )
60 |
61 | var data = `
62 | a: Easy!
63 | b:
64 | c: 2
65 | d: [3, 4]
66 | `
67 |
68 | // Note: struct fields must be public in order for unmarshal to
69 | // correctly populate the data.
70 | type T struct {
71 | A string
72 | B struct {
73 | RenamedC int `yaml:"c"`
74 | D []int `yaml:",flow"`
75 | }
76 | }
77 |
78 | func main() {
79 | t := T{}
80 |
81 | err := yaml.Unmarshal([]byte(data), &t)
82 | if err != nil {
83 | log.Fatalf("error: %v", err)
84 | }
85 | fmt.Printf("--- t:\n%v\n\n", t)
86 |
87 | d, err := yaml.Marshal(&t)
88 | if err != nil {
89 | log.Fatalf("error: %v", err)
90 | }
91 | fmt.Printf("--- t dump:\n%s\n\n", string(d))
92 |
93 | m := make(map[interface{}]interface{})
94 |
95 | err = yaml.Unmarshal([]byte(data), &m)
96 | if err != nil {
97 | log.Fatalf("error: %v", err)
98 | }
99 | fmt.Printf("--- m:\n%v\n\n", m)
100 |
101 | d, err = yaml.Marshal(&m)
102 | if err != nil {
103 | log.Fatalf("error: %v", err)
104 | }
105 | fmt.Printf("--- m dump:\n%s\n\n", string(d))
106 | }
107 | ```
108 |
109 | This example will generate the following output:
110 |
111 | ```
112 | --- t:
113 | {Easy! {2 [3 4]}}
114 |
115 | --- t dump:
116 | a: Easy!
117 | b:
118 | c: 2
119 | d: [3, 4]
120 |
121 |
122 | --- m:
123 | map[a:Easy! b:map[c:2 d:[3 4]]]
124 |
125 | --- m dump:
126 | a: Easy!
127 | b:
128 | c: 2
129 | d:
130 | - 3
131 | - 4
132 | ```
133 |
134 |
--------------------------------------------------------------------------------
/assets/master.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 50px;
3 | }
4 |
5 | code {
6 | background-color: #141414;
7 | color: #F8F8F8;
8 | }
9 |
10 | @media (max-width: 767px) {
11 | .page_content.container {
12 | margin-left: 0px !important;
13 | margin-right: 0px !important;
14 | padding-left: 0px !important;
15 | padding-right: 0px !important;
16 | }
17 | .page_content.well {
18 | width: 650px !important;
19 | margin-left: 0px !important;
20 | margin-right: 0px !important;
21 | }
22 | }
23 |
24 | pre.twilight {
25 | overflow-x: auto !important;
26 | word-wrap: normal !important;
27 | white-space: pre !important;
28 | }
29 |
30 | hr.article_seperator {
31 | border-top: 1px solid lightgrey;
32 | border-bottom: 0px;
33 | border-left: 1px;
34 | border-right: 1px;
35 | }
36 |
37 | pre.twilight .DiffInserted {
38 | background-color: #253B22;
39 | color: #F8F8F8; }
40 |
41 | pre.twilight .DiffHeader {
42 | background-color: #0E2231;
43 | color: #F8F8F8;
44 | font-style: italic; }
45 |
46 | pre.twilight .CssPropertyValue {
47 | color: #F9EE98; }
48 |
49 | pre.twilight .CCCPreprocessorDirective {
50 | color: #AFC4DB; }
51 |
52 | pre.twilight .Constant {
53 | color: #CF6A4C; }
54 |
55 | pre.twilight .DiffChanged {
56 | background-color: #4A410D;
57 | color: #F8F8F8; }
58 |
59 | pre.twilight .EmbeddedSource {
60 | background-color: #A3A6AD; }
61 |
62 | pre.twilight .Support {
63 | color: #9B859D; }
64 |
65 | pre.twilight .MarkupList {
66 | color: #F9EE98; }
67 |
68 | pre.twilight .CssConstructorArgument {
69 | color: #8F9D6A; }
70 |
71 | pre.twilight .Storage {
72 | color: #F9EE98; }
73 |
74 | pre.twilight .line-numbers {
75 | background-color: #DDF0FF;
76 | color: #000000; }
77 |
78 | pre.twilight .CssClass {
79 | color: #9B703F; }
80 |
81 | pre.twilight .StringConstant {
82 | color: #DDF2A4; }
83 |
84 | pre.twilight .CssAtRule {
85 | color: #8693A5; }
86 |
87 | pre.twilight .MetaTagInline {
88 | color: #E0C589; }
89 |
90 | pre.twilight .MarkupHeading {
91 | color: #CF6A4C; }
92 |
93 | pre.twilight .CssTagName {
94 | color: #CDA869; }
95 |
96 | pre.twilight .SupportConstant {
97 | color: #CF6A4C; }
98 |
99 | pre.twilight .DiffDeleted {
100 | background-color: #420E09;
101 | color: #F8F8F8; }
102 |
103 | pre.twilight .CCCPreprocessorLine {
104 | color: #8996A8; }
105 |
106 | pre.twilight .StringRegexpSpecial {
107 | color: #CF7D34; }
108 |
109 | pre.twilight .EmbeddedSourceBright {
110 | background-color: #9C9EA4; }
111 |
112 | pre.twilight .InvalidIllegal {
113 | background-color: #241A24;
114 | color: #F8F8F8; }
115 |
116 | pre.twilight .SupportFunction {
117 | color: #DAD085; }
118 |
119 | pre.twilight .CssAdditionalConstants {
120 | color: #CA7840; }
121 |
122 | pre.twilight .MetaTagAll {
123 | color: #AC885B; }
124 |
125 | pre.twilight .StringRegexp {
126 | color: #E9C062; }
127 |
128 | pre.twilight .StringEmbeddedSource {
129 | color: #DAEFA3; }
130 |
131 | pre.twilight .EntityInheritedClass {
132 | color: #9B5C2E;
133 | font-style: italic; }
134 |
135 | pre.twilight .CssId {
136 | color: #8B98AB; }
137 |
138 | pre.twilight .CssPseudoClass {
139 | color: #8F9D6A; }
140 |
141 | pre.twilight .StringVariable {
142 | color: #8A9A95; }
143 |
144 | pre.twilight .String {
145 | color: #8F9D6A; }
146 |
147 | pre.twilight .Keyword {
148 | color: #CDA869; }
149 |
150 | pre.twilight {
151 | background-color: #141414;
152 | color: #F8F8F8; }
153 |
154 | pre.twilight .CssPropertyName {
155 | color: #C5AF75; }
156 |
157 | pre.twilight .DoctypeXmlProcessing {
158 | color: #494949; }
159 |
160 | pre.twilight .InvalidDeprecated {
161 | color: #D2A8A1;
162 | font-style: italic; }
163 |
164 | pre.twilight .Variable {
165 | color: #7587A6; }
166 |
167 | pre.twilight .Entity {
168 | color: #9B703F; }
169 |
170 | pre.twilight .Comment {
171 | color: #5F5A60;
172 | font-style: italic; }
173 |
174 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
38 |
58 |
59 |
60 |
Golang: Convert JSON in to a useful struct.
61 | Raw JSON Input
62 |
67 | Go Struct Output
68 |
71 |
72 |
73 |
83 |
84 |
85 | Fork me @ github.com/jmervine/gojson-http
86 |
87 |
88 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "html/template"
7 | "io/ioutil"
8 | "net/http"
9 | "os"
10 | "os/signal"
11 | "strings"
12 | "sync"
13 | "syscall"
14 | "time"
15 | "log"
16 |
17 | "github.com/ChimeraCoder/gojson"
18 | )
19 |
20 | var (
21 | Listen string
22 | Port int
23 | Template string
24 | Tmpl *template.Template
25 | defaultJson = `{ "example": { "from": { "json": true } } }`
26 | mutty = sync.Mutex{}
27 | )
28 |
29 | type Result struct {
30 | Json, Struct string
31 | }
32 |
33 | type Handler struct{}
34 |
35 | func init() {
36 | log.SetFlags(0)
37 | log.SetPrefix("app=gojson-http")
38 | }
39 |
40 | func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
41 | begin := time.Now()
42 |
43 | defer r.Body.Close()
44 |
45 | Tmpl, err := template.ParseFiles(Template)
46 | if err != nil {
47 | log.Fatalf("at=ServeHTTP error=%v", err)
48 | }
49 |
50 | log.Printf("at=ServeHTTP method=%s path=%s user-agent=%s took=%v",
51 | r.Method, r.URL.Path, r.Header["User-Agent"], time.Since(begin))
52 |
53 | res := Result{
54 | Json: defaultJson,
55 | }
56 |
57 | if strings.HasSuffix(r.URL.Path, "json") {
58 | fmt.Fprintln(w, fmt.Sprintf(`{ "example": { "from": { "path": "%s" } } }`, r.URL.String()))
59 | return
60 | }
61 |
62 | var src string
63 | if r.Method == "POST" {
64 | val := r.PostFormValue("json")
65 | res.Json = val
66 | } else {
67 | src = r.URL.Query().Get("src")
68 | if src != "" {
69 | res.Json = src
70 | }
71 | }
72 |
73 | if strings.HasPrefix(res.Json, "http") {
74 |
75 | // redirect wth to src param, if res.Json is path, but src path doesn't exist
76 | if src == "" {
77 | http.Redirect(w, r, r.URL.Path+"?src="+strings.TrimSpace(res.Json), 301)
78 | return
79 | }
80 |
81 | // fetch res.Json
82 | resp, err := http.DefaultClient.Get(strings.TrimSpace(res.Json))
83 | if err != nil {
84 | log.Printf("at=ServeHTTP method=%s path=%s user-agent=%s took=%v",
85 | r.Method, r.URL.Path, r.Header["User-Agent"], time.Since(begin))
86 | log.Printf("at=ServeHTTP error=%v", err)
87 | res.Struct = fmt.Sprintf("JSON Parse Error: %v\n", err)
88 | Tmpl.Execute(w, nil)
89 | return
90 | }
91 |
92 | read, err := ioutil.ReadAll(resp.Body)
93 | resp.Body.Close()
94 | if err != nil {
95 | log.Printf("at=ServeHTTP method=%s path=%s user-agent=%s took=%v",
96 | r.Method, r.URL.Path, r.Header["User-Agent"], time.Since(begin))
97 | log.Printf("at=ServeHTTP error=%v", err)
98 | res.Struct = fmt.Sprintf("JSON Fetch Error: %v\n", err)
99 | }
100 | res.Json = string(read)
101 | }
102 |
103 | if out, e := gojson.Generate(strings.NewReader(res.Json), gojson.ParseJson, "MyJsonName", "main", []string{"json"}, false, true); e == nil {
104 | res.Struct = string(out)
105 | } else {
106 | log.Printf("at=ServeHTTP method=%s path=%s user-agent=%s took=%v",
107 | r.Method, r.URL.Path, r.Header["User-Agent"], time.Since(begin))
108 | log.Printf("at=ServeHTTP error=%v", e)
109 | res.Struct = fmt.Sprintf("JSON Parse Error: %v\n", e)
110 | }
111 | Tmpl.Execute(w, res)
112 | }
113 |
114 | func main() {
115 | // reload tempalate on SIGHUP
116 | sigc := make(chan os.Signal, 1)
117 | signal.Notify(sigc, syscall.SIGHUP)
118 | go reloadTemplate(sigc)
119 |
120 | flag.IntVar(&Port, "port", 8080, "startup port")
121 | flag.StringVar(&Listen, "listen", "localhost", "listen address")
122 | flag.StringVar(&Template, "template", "index.html", "display template")
123 | flag.Parse()
124 |
125 | handler := Handler{}
126 |
127 | server := &http.Server{
128 | Addr: fmt.Sprintf("%s:%d", Listen, Port),
129 | Handler: handler,
130 | ReadTimeout: 10 * time.Second,
131 | WriteTimeout: 10 * time.Second,
132 | MaxHeaderBytes: 1 << 20,
133 | }
134 |
135 | log.Printf("at=main address=%s", server.Addr)
136 | log.Fatalf("at=main error=%s", server.ListenAndServe())
137 | }
138 |
139 | func reloadTemplate(sigc chan os.Signal) {
140 | for _ = range sigc {
141 | log.Print("at=reloadTemplate message=\"reloading template\"")
142 | t, e := template.ParseFiles(Template)
143 | if e != nil {
144 | log.Printf("at=reloadTemplate error=%v", e)
145 | }
146 | mutty.Lock()
147 | Tmpl = t
148 | mutty.Unlock()
149 | log.Println("at=reloadTemplate message=\"reloading template\"")
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/yamlprivateh.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | const (
4 | // The size of the input raw buffer.
5 | input_raw_buffer_size = 512
6 |
7 | // The size of the input buffer.
8 | // It should be possible to decode the whole raw buffer.
9 | input_buffer_size = input_raw_buffer_size * 3
10 |
11 | // The size of the output buffer.
12 | output_buffer_size = 128
13 |
14 | // The size of the output raw buffer.
15 | // It should be possible to encode the whole output buffer.
16 | output_raw_buffer_size = (output_buffer_size*2 + 2)
17 |
18 | // The size of other stacks and queues.
19 | initial_stack_size = 16
20 | initial_queue_size = 16
21 | initial_string_size = 16
22 | )
23 |
24 | // Check if the character at the specified position is an alphabetical
25 | // character, a digit, '_', or '-'.
26 | func is_alpha(b []byte, i int) bool {
27 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
28 | }
29 |
30 | // Check if the character at the specified position is a digit.
31 | func is_digit(b []byte, i int) bool {
32 | return b[i] >= '0' && b[i] <= '9'
33 | }
34 |
35 | // Get the value of a digit.
36 | func as_digit(b []byte, i int) int {
37 | return int(b[i]) - '0'
38 | }
39 |
40 | // Check if the character at the specified position is a hex-digit.
41 | func is_hex(b []byte, i int) bool {
42 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
43 | }
44 |
45 | // Get the value of a hex-digit.
46 | func as_hex(b []byte, i int) int {
47 | bi := b[i]
48 | if bi >= 'A' && bi <= 'F' {
49 | return int(bi) - 'A' + 10
50 | }
51 | if bi >= 'a' && bi <= 'f' {
52 | return int(bi) - 'a' + 10
53 | }
54 | return int(bi) - '0'
55 | }
56 |
57 | // Check if the character is ASCII.
58 | func is_ascii(b []byte, i int) bool {
59 | return b[i] <= 0x7F
60 | }
61 |
62 | // Check if the character at the start of the buffer can be printed unescaped.
63 | func is_printable(b []byte, i int) bool {
64 | return ((b[i] == 0x0A) || // . == #x0A
65 | (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
66 | (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
67 | (b[i] > 0xC2 && b[i] < 0xED) ||
68 | (b[i] == 0xED && b[i+1] < 0xA0) ||
69 | (b[i] == 0xEE) ||
70 | (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
71 | !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
72 | !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
73 | }
74 |
75 | // Check if the character at the specified position is NUL.
76 | func is_z(b []byte, i int) bool {
77 | return b[i] == 0x00
78 | }
79 |
80 | // Check if the beginning of the buffer is a BOM.
81 | func is_bom(b []byte, i int) bool {
82 | return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
83 | }
84 |
85 | // Check if the character at the specified position is space.
86 | func is_space(b []byte, i int) bool {
87 | return b[i] == ' '
88 | }
89 |
90 | // Check if the character at the specified position is tab.
91 | func is_tab(b []byte, i int) bool {
92 | return b[i] == '\t'
93 | }
94 |
95 | // Check if the character at the specified position is blank (space or tab).
96 | func is_blank(b []byte, i int) bool {
97 | //return is_space(b, i) || is_tab(b, i)
98 | return b[i] == ' ' || b[i] == '\t'
99 | }
100 |
101 | // Check if the character at the specified position is a line break.
102 | func is_break(b []byte, i int) bool {
103 | return (b[i] == '\r' || // CR (#xD)
104 | b[i] == '\n' || // LF (#xA)
105 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
106 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
107 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
108 | }
109 |
110 | func is_crlf(b []byte, i int) bool {
111 | return b[i] == '\r' && b[i+1] == '\n'
112 | }
113 |
114 | // Check if the character is a line break or NUL.
115 | func is_breakz(b []byte, i int) bool {
116 | //return is_break(b, i) || is_z(b, i)
117 | return ( // is_break:
118 | b[i] == '\r' || // CR (#xD)
119 | b[i] == '\n' || // LF (#xA)
120 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
121 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
122 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
123 | // is_z:
124 | b[i] == 0)
125 | }
126 |
127 | // Check if the character is a line break, space, or NUL.
128 | func is_spacez(b []byte, i int) bool {
129 | //return is_space(b, i) || is_breakz(b, i)
130 | return ( // is_space:
131 | b[i] == ' ' ||
132 | // is_breakz:
133 | b[i] == '\r' || // CR (#xD)
134 | b[i] == '\n' || // LF (#xA)
135 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
136 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
137 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
138 | b[i] == 0)
139 | }
140 |
141 | // Check if the character is a line break, space, tab, or NUL.
142 | func is_blankz(b []byte, i int) bool {
143 | //return is_blank(b, i) || is_breakz(b, i)
144 | return ( // is_blank:
145 | b[i] == ' ' || b[i] == '\t' ||
146 | // is_breakz:
147 | b[i] == '\r' || // CR (#xD)
148 | b[i] == '\n' || // LF (#xA)
149 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
150 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
151 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
152 | b[i] == 0)
153 | }
154 |
155 | // Determine the width of the character.
156 | func width(b byte) int {
157 | // Don't replace these by a switch without first
158 | // confirming that it is being inlined.
159 | if b&0x80 == 0x00 {
160 | return 1
161 | }
162 | if b&0xE0 == 0xC0 {
163 | return 2
164 | }
165 | if b&0xF0 == 0xE0 {
166 | return 3
167 | }
168 | if b&0xF8 == 0xF0 {
169 | return 4
170 | }
171 | return 0
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/ChimeraCoder/gojson)
2 | gojson
3 | ======
4 |
5 | gojson generates go struct definitions from json or yaml documents.
6 |
7 | Example
8 | ----------
9 |
10 | ```sh
11 | $ curl -s https://api.github.com/repos/chimeracoder/gojson | gojson -name=Repository
12 |
13 | package main
14 |
15 | type Repository struct {
16 | ArchiveURL string `json:"archive_url"`
17 | AssigneesURL string `json:"assignees_url"`
18 | BlobsURL string `json:"blobs_url"`
19 | BranchesURL string `json:"branches_url"`
20 | CloneURL string `json:"clone_url"`
21 | CollaboratorsURL string `json:"collaborators_url"`
22 | CommentsURL string `json:"comments_url"`
23 | CommitsURL string `json:"commits_url"`
24 | CompareURL string `json:"compare_url"`
25 | ContentsURL string `json:"contents_url"`
26 | ContributorsURL string `json:"contributors_url"`
27 | CreatedAt string `json:"created_at"`
28 | DefaultBranch string `json:"default_branch"`
29 | Description string `json:"description"`
30 | DownloadsURL string `json:"downloads_url"`
31 | EventsURL string `json:"events_url"`
32 | Fork bool `json:"fork"`
33 | Forks float64 `json:"forks"`
34 | ForksCount float64 `json:"forks_count"`
35 | ForksURL string `json:"forks_url"`
36 | FullName string `json:"full_name"`
37 | GitCommitsURL string `json:"git_commits_url"`
38 | GitRefsURL string `json:"git_refs_url"`
39 | GitTagsURL string `json:"git_tags_url"`
40 | GitURL string `json:"git_url"`
41 | HasDownloads bool `json:"has_downloads"`
42 | HasIssues bool `json:"has_issues"`
43 | HasWiki bool `json:"has_wiki"`
44 | Homepage interface{} `json:"homepage"`
45 | HooksURL string `json:"hooks_url"`
46 | HtmlURL string `json:"html_url"`
47 | ID float64 `json:"id"`
48 | IssueCommentURL string `json:"issue_comment_url"`
49 | IssueEventsURL string `json:"issue_events_url"`
50 | IssuesURL string `json:"issues_url"`
51 | KeysURL string `json:"keys_url"`
52 | LabelsURL string `json:"labels_url"`
53 | Language string `json:"language"`
54 | LanguagesURL string `json:"languages_url"`
55 | MasterBranch string `json:"master_branch"`
56 | MergesURL string `json:"merges_url"`
57 | MilestonesURL string `json:"milestones_url"`
58 | MirrorURL interface{} `json:"mirror_url"`
59 | Name string `json:"name"`
60 | NetworkCount float64 `json:"network_count"`
61 | NotificationsURL string `json:"notifications_url"`
62 | OpenIssues float64 `json:"open_issues"`
63 | OpenIssuesCount float64 `json:"open_issues_count"`
64 | Owner struct {
65 | AvatarURL string `json:"avatar_url"`
66 | EventsURL string `json:"events_url"`
67 | FollowersURL string `json:"followers_url"`
68 | FollowingURL string `json:"following_url"`
69 | GistsURL string `json:"gists_url"`
70 | GravatarID string `json:"gravatar_id"`
71 | HtmlURL string `json:"html_url"`
72 | ID float64 `json:"id"`
73 | Login string `json:"login"`
74 | OrganizationsURL string `json:"organizations_url"`
75 | ReceivedEventsURL string `json:"received_events_url"`
76 | ReposURL string `json:"repos_url"`
77 | SiteAdmin bool `json:"site_admin"`
78 | StarredURL string `json:"starred_url"`
79 | SubscriptionsURL string `json:"subscriptions_url"`
80 | Type string `json:"type"`
81 | URL string `json:"url"`
82 | } `json:"owner"`
83 | Private bool `json:"private"`
84 | PullsURL string `json:"pulls_url"`
85 | PushedAt string `json:"pushed_at"`
86 | Size float64 `json:"size"`
87 | SshURL string `json:"ssh_url"`
88 | StargazersURL string `json:"stargazers_url"`
89 | StatusesURL string `json:"statuses_url"`
90 | SubscribersURL string `json:"subscribers_url"`
91 | SubscriptionURL string `json:"subscription_url"`
92 | SvnURL string `json:"svn_url"`
93 | TagsURL string `json:"tags_url"`
94 | TeamsURL string `json:"teams_url"`
95 | TreesURL string `json:"trees_url"`
96 | UpdatedAt string `json:"updated_at"`
97 | URL string `json:"url"`
98 | Watchers float64 `json:"watchers"`
99 | WatchersCount float64 `json:"watchers_count"`
100 | }
101 | ```
102 |
103 | CLI Installation
104 | ----------------
105 |
106 | ```sh
107 | $ go get github.com/ChimeraCoder/gojson/gojson
108 | ```
109 |
110 | Assuming `$GOPATH/bin` is in your `PATH`, you can now invoke `gojson` directly.
111 |
112 |
113 | API Installation
114 | ----------------
115 |
116 | ```sh
117 | $ go get github.com/ChimeraCoder/gojson/gojson
118 | ```
119 |
120 | Development
121 | -----------
122 |
123 | ```
124 | $ git clone https://github.com/ChimeraCoder/gojson.git
125 | $ cd gojson
126 | $ go test
127 | ```
128 |
129 | **Building CLI**
130 |
131 | ```
132 | $ go build -o _build/gojson ./gojson
133 | ```
134 |
135 | **Installing CLI**
136 |
137 | ```
138 | $ go install ./gojson
139 | ```
140 |
141 | **Formatting**
142 |
143 | ```
144 | $ gofmt -w -e -s -l .
145 | ```
146 |
147 | Related Work
148 | ------------
149 |
150 | github.com/str1ngs/jflect
151 |
152 | License
153 | ----------
154 |
155 | gojson is free software distributed under Version 3 of the GNU Public License.
156 |
157 | As of the time of writing, this is the same license used for gcc (and therefore gccgo), so it is unlikely to restrict use in any way. Note that the GPL does not extend to any output generated by gojson; the GPL only applies to software which includes copies of gojson itself.
158 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/resolve.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding/base64"
5 | "math"
6 | "regexp"
7 | "strconv"
8 | "strings"
9 | "time"
10 | )
11 |
12 | type resolveMapItem struct {
13 | value interface{}
14 | tag string
15 | }
16 |
17 | var resolveTable = make([]byte, 256)
18 | var resolveMap = make(map[string]resolveMapItem)
19 |
20 | func init() {
21 | t := resolveTable
22 | t[int('+')] = 'S' // Sign
23 | t[int('-')] = 'S'
24 | for _, c := range "0123456789" {
25 | t[int(c)] = 'D' // Digit
26 | }
27 | for _, c := range "yYnNtTfFoO~" {
28 | t[int(c)] = 'M' // In map
29 | }
30 | t[int('.')] = '.' // Float (potentially in map)
31 |
32 | var resolveMapList = []struct {
33 | v interface{}
34 | tag string
35 | l []string
36 | }{
37 | {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
38 | {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
39 | {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
40 | {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
41 | {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
42 | {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
43 | {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
44 | {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
45 | {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
46 | {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
47 | {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
48 | {"<<", yaml_MERGE_TAG, []string{"<<"}},
49 | }
50 |
51 | m := resolveMap
52 | for _, item := range resolveMapList {
53 | for _, s := range item.l {
54 | m[s] = resolveMapItem{item.v, item.tag}
55 | }
56 | }
57 | }
58 |
59 | const longTagPrefix = "tag:yaml.org,2002:"
60 |
61 | func shortTag(tag string) string {
62 | // TODO This can easily be made faster and produce less garbage.
63 | if strings.HasPrefix(tag, longTagPrefix) {
64 | return "!!" + tag[len(longTagPrefix):]
65 | }
66 | return tag
67 | }
68 |
69 | func longTag(tag string) string {
70 | if strings.HasPrefix(tag, "!!") {
71 | return longTagPrefix + tag[2:]
72 | }
73 | return tag
74 | }
75 |
76 | func resolvableTag(tag string) bool {
77 | switch tag {
78 | case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
79 | return true
80 | }
81 | return false
82 | }
83 |
84 | var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`)
85 |
86 | func resolve(tag string, in string) (rtag string, out interface{}) {
87 | if !resolvableTag(tag) {
88 | return tag, in
89 | }
90 |
91 | defer func() {
92 | switch tag {
93 | case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
94 | return
95 | case yaml_FLOAT_TAG:
96 | if rtag == yaml_INT_TAG {
97 | switch v := out.(type) {
98 | case int64:
99 | rtag = yaml_FLOAT_TAG
100 | out = float64(v)
101 | return
102 | case int:
103 | rtag = yaml_FLOAT_TAG
104 | out = float64(v)
105 | return
106 | }
107 | }
108 | }
109 | failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
110 | }()
111 |
112 | // Any data is accepted as a !!str or !!binary.
113 | // Otherwise, the prefix is enough of a hint about what it might be.
114 | hint := byte('N')
115 | if in != "" {
116 | hint = resolveTable[in[0]]
117 | }
118 | if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
119 | // Handle things we can lookup in a map.
120 | if item, ok := resolveMap[in]; ok {
121 | return item.tag, item.value
122 | }
123 |
124 | // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
125 | // are purposefully unsupported here. They're still quoted on
126 | // the way out for compatibility with other parser, though.
127 |
128 | switch hint {
129 | case 'M':
130 | // We've already checked the map above.
131 |
132 | case '.':
133 | // Not in the map, so maybe a normal float.
134 | floatv, err := strconv.ParseFloat(in, 64)
135 | if err == nil {
136 | return yaml_FLOAT_TAG, floatv
137 | }
138 |
139 | case 'D', 'S':
140 | // Int, float, or timestamp.
141 | // Only try values as a timestamp if the value is unquoted or there's an explicit
142 | // !!timestamp tag.
143 | if tag == "" || tag == yaml_TIMESTAMP_TAG {
144 | t, ok := parseTimestamp(in)
145 | if ok {
146 | return yaml_TIMESTAMP_TAG, t
147 | }
148 | }
149 |
150 | plain := strings.Replace(in, "_", "", -1)
151 | intv, err := strconv.ParseInt(plain, 0, 64)
152 | if err == nil {
153 | if intv == int64(int(intv)) {
154 | return yaml_INT_TAG, int(intv)
155 | } else {
156 | return yaml_INT_TAG, intv
157 | }
158 | }
159 | uintv, err := strconv.ParseUint(plain, 0, 64)
160 | if err == nil {
161 | return yaml_INT_TAG, uintv
162 | }
163 | if yamlStyleFloat.MatchString(plain) {
164 | floatv, err := strconv.ParseFloat(plain, 64)
165 | if err == nil {
166 | return yaml_FLOAT_TAG, floatv
167 | }
168 | }
169 | if strings.HasPrefix(plain, "0b") {
170 | intv, err := strconv.ParseInt(plain[2:], 2, 64)
171 | if err == nil {
172 | if intv == int64(int(intv)) {
173 | return yaml_INT_TAG, int(intv)
174 | } else {
175 | return yaml_INT_TAG, intv
176 | }
177 | }
178 | uintv, err := strconv.ParseUint(plain[2:], 2, 64)
179 | if err == nil {
180 | return yaml_INT_TAG, uintv
181 | }
182 | } else if strings.HasPrefix(plain, "-0b") {
183 | intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
184 | if err == nil {
185 | if true || intv == int64(int(intv)) {
186 | return yaml_INT_TAG, int(intv)
187 | } else {
188 | return yaml_INT_TAG, intv
189 | }
190 | }
191 | }
192 | default:
193 | panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
194 | }
195 | }
196 | return yaml_STR_TAG, in
197 | }
198 |
199 | // encodeBase64 encodes s as base64 that is broken up into multiple lines
200 | // as appropriate for the resulting length.
201 | func encodeBase64(s string) string {
202 | const lineLen = 70
203 | encLen := base64.StdEncoding.EncodedLen(len(s))
204 | lines := encLen/lineLen + 1
205 | buf := make([]byte, encLen*2+lines)
206 | in := buf[0:encLen]
207 | out := buf[encLen:]
208 | base64.StdEncoding.Encode(in, []byte(s))
209 | k := 0
210 | for i := 0; i < len(in); i += lineLen {
211 | j := i + lineLen
212 | if j > len(in) {
213 | j = len(in)
214 | }
215 | k += copy(out[k:], in[i:j])
216 | if lines > 1 {
217 | out[k] = '\n'
218 | k++
219 | }
220 | }
221 | return string(out[:k])
222 | }
223 |
224 | // This is a subset of the formats allowed by the regular expression
225 | // defined at http://yaml.org/type/timestamp.html.
226 | var allowedTimestampFormats = []string{
227 | "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
228 | "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
229 | "2006-1-2 15:4:5.999999999", // space separated with no time zone
230 | "2006-1-2", // date only
231 | // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
232 | // from the set of examples.
233 | }
234 |
235 | // parseTimestamp parses s as a timestamp string and
236 | // returns the timestamp and reports whether it succeeded.
237 | // Timestamp formats are defined at http://yaml.org/type/timestamp.html
238 | func parseTimestamp(s string) (time.Time, bool) {
239 | // TODO write code to check all the formats supported by
240 | // http://yaml.org/type/timestamp.html instead of using time.Parse.
241 |
242 | // Quick check: all date formats start with YYYY-.
243 | i := 0
244 | for ; i < len(s); i++ {
245 | if c := s[i]; c < '0' || c > '9' {
246 | break
247 | }
248 | }
249 | if i != 4 || i == len(s) || s[i] != '-' {
250 | return time.Time{}, false
251 | }
252 | for _, format := range allowedTimestampFormats {
253 | if t, err := time.Parse(format, s); err == nil {
254 | return t, true
255 | }
256 | }
257 | return time.Time{}, false
258 | }
259 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/encode.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding"
5 | "fmt"
6 | "io"
7 | "reflect"
8 | "regexp"
9 | "sort"
10 | "strconv"
11 | "strings"
12 | "time"
13 | "unicode/utf8"
14 | )
15 |
16 | // jsonNumber is the interface of the encoding/json.Number datatype.
17 | // Repeating the interface here avoids a dependency on encoding/json, and also
18 | // supports other libraries like jsoniter, which use a similar datatype with
19 | // the same interface. Detecting this interface is useful when dealing with
20 | // structures containing json.Number, which is a string under the hood. The
21 | // encoder should prefer the use of Int64(), Float64() and string(), in that
22 | // order, when encoding this type.
23 | type jsonNumber interface {
24 | Float64() (float64, error)
25 | Int64() (int64, error)
26 | String() string
27 | }
28 |
29 | type encoder struct {
30 | emitter yaml_emitter_t
31 | event yaml_event_t
32 | out []byte
33 | flow bool
34 | // doneInit holds whether the initial stream_start_event has been
35 | // emitted.
36 | doneInit bool
37 | }
38 |
39 | func newEncoder() *encoder {
40 | e := &encoder{}
41 | yaml_emitter_initialize(&e.emitter)
42 | yaml_emitter_set_output_string(&e.emitter, &e.out)
43 | yaml_emitter_set_unicode(&e.emitter, true)
44 | return e
45 | }
46 |
47 | func newEncoderWithWriter(w io.Writer) *encoder {
48 | e := &encoder{}
49 | yaml_emitter_initialize(&e.emitter)
50 | yaml_emitter_set_output_writer(&e.emitter, w)
51 | yaml_emitter_set_unicode(&e.emitter, true)
52 | return e
53 | }
54 |
55 | func (e *encoder) init() {
56 | if e.doneInit {
57 | return
58 | }
59 | yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
60 | e.emit()
61 | e.doneInit = true
62 | }
63 |
64 | func (e *encoder) finish() {
65 | e.emitter.open_ended = false
66 | yaml_stream_end_event_initialize(&e.event)
67 | e.emit()
68 | }
69 |
70 | func (e *encoder) destroy() {
71 | yaml_emitter_delete(&e.emitter)
72 | }
73 |
74 | func (e *encoder) emit() {
75 | // This will internally delete the e.event value.
76 | e.must(yaml_emitter_emit(&e.emitter, &e.event))
77 | }
78 |
79 | func (e *encoder) must(ok bool) {
80 | if !ok {
81 | msg := e.emitter.problem
82 | if msg == "" {
83 | msg = "unknown problem generating YAML content"
84 | }
85 | failf("%s", msg)
86 | }
87 | }
88 |
89 | func (e *encoder) marshalDoc(tag string, in reflect.Value) {
90 | e.init()
91 | yaml_document_start_event_initialize(&e.event, nil, nil, true)
92 | e.emit()
93 | e.marshal(tag, in)
94 | yaml_document_end_event_initialize(&e.event, true)
95 | e.emit()
96 | }
97 |
98 | func (e *encoder) marshal(tag string, in reflect.Value) {
99 | if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
100 | e.nilv()
101 | return
102 | }
103 | iface := in.Interface()
104 | switch m := iface.(type) {
105 | case jsonNumber:
106 | integer, err := m.Int64()
107 | if err == nil {
108 | // In this case the json.Number is a valid int64
109 | in = reflect.ValueOf(integer)
110 | break
111 | }
112 | float, err := m.Float64()
113 | if err == nil {
114 | // In this case the json.Number is a valid float64
115 | in = reflect.ValueOf(float)
116 | break
117 | }
118 | // fallback case - no number could be obtained
119 | in = reflect.ValueOf(m.String())
120 | case time.Time, *time.Time:
121 | // Although time.Time implements TextMarshaler,
122 | // we don't want to treat it as a string for YAML
123 | // purposes because YAML has special support for
124 | // timestamps.
125 | case Marshaler:
126 | v, err := m.MarshalYAML()
127 | if err != nil {
128 | fail(err)
129 | }
130 | if v == nil {
131 | e.nilv()
132 | return
133 | }
134 | in = reflect.ValueOf(v)
135 | case encoding.TextMarshaler:
136 | text, err := m.MarshalText()
137 | if err != nil {
138 | fail(err)
139 | }
140 | in = reflect.ValueOf(string(text))
141 | case nil:
142 | e.nilv()
143 | return
144 | }
145 | switch in.Kind() {
146 | case reflect.Interface:
147 | e.marshal(tag, in.Elem())
148 | case reflect.Map:
149 | e.mapv(tag, in)
150 | case reflect.Ptr:
151 | if in.Type() == ptrTimeType {
152 | e.timev(tag, in.Elem())
153 | } else {
154 | e.marshal(tag, in.Elem())
155 | }
156 | case reflect.Struct:
157 | if in.Type() == timeType {
158 | e.timev(tag, in)
159 | } else {
160 | e.structv(tag, in)
161 | }
162 | case reflect.Slice, reflect.Array:
163 | if in.Type().Elem() == mapItemType {
164 | e.itemsv(tag, in)
165 | } else {
166 | e.slicev(tag, in)
167 | }
168 | case reflect.String:
169 | e.stringv(tag, in)
170 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
171 | if in.Type() == durationType {
172 | e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
173 | } else {
174 | e.intv(tag, in)
175 | }
176 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
177 | e.uintv(tag, in)
178 | case reflect.Float32, reflect.Float64:
179 | e.floatv(tag, in)
180 | case reflect.Bool:
181 | e.boolv(tag, in)
182 | default:
183 | panic("cannot marshal type: " + in.Type().String())
184 | }
185 | }
186 |
187 | func (e *encoder) mapv(tag string, in reflect.Value) {
188 | e.mappingv(tag, func() {
189 | keys := keyList(in.MapKeys())
190 | sort.Sort(keys)
191 | for _, k := range keys {
192 | e.marshal("", k)
193 | e.marshal("", in.MapIndex(k))
194 | }
195 | })
196 | }
197 |
198 | func (e *encoder) itemsv(tag string, in reflect.Value) {
199 | e.mappingv(tag, func() {
200 | slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
201 | for _, item := range slice {
202 | e.marshal("", reflect.ValueOf(item.Key))
203 | e.marshal("", reflect.ValueOf(item.Value))
204 | }
205 | })
206 | }
207 |
208 | func (e *encoder) structv(tag string, in reflect.Value) {
209 | sinfo, err := getStructInfo(in.Type())
210 | if err != nil {
211 | panic(err)
212 | }
213 | e.mappingv(tag, func() {
214 | for _, info := range sinfo.FieldsList {
215 | var value reflect.Value
216 | if info.Inline == nil {
217 | value = in.Field(info.Num)
218 | } else {
219 | value = in.FieldByIndex(info.Inline)
220 | }
221 | if info.OmitEmpty && isZero(value) {
222 | continue
223 | }
224 | e.marshal("", reflect.ValueOf(info.Key))
225 | e.flow = info.Flow
226 | e.marshal("", value)
227 | }
228 | if sinfo.InlineMap >= 0 {
229 | m := in.Field(sinfo.InlineMap)
230 | if m.Len() > 0 {
231 | e.flow = false
232 | keys := keyList(m.MapKeys())
233 | sort.Sort(keys)
234 | for _, k := range keys {
235 | if _, found := sinfo.FieldsMap[k.String()]; found {
236 | panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
237 | }
238 | e.marshal("", k)
239 | e.flow = false
240 | e.marshal("", m.MapIndex(k))
241 | }
242 | }
243 | }
244 | })
245 | }
246 |
247 | func (e *encoder) mappingv(tag string, f func()) {
248 | implicit := tag == ""
249 | style := yaml_BLOCK_MAPPING_STYLE
250 | if e.flow {
251 | e.flow = false
252 | style = yaml_FLOW_MAPPING_STYLE
253 | }
254 | yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
255 | e.emit()
256 | f()
257 | yaml_mapping_end_event_initialize(&e.event)
258 | e.emit()
259 | }
260 |
261 | func (e *encoder) slicev(tag string, in reflect.Value) {
262 | implicit := tag == ""
263 | style := yaml_BLOCK_SEQUENCE_STYLE
264 | if e.flow {
265 | e.flow = false
266 | style = yaml_FLOW_SEQUENCE_STYLE
267 | }
268 | e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
269 | e.emit()
270 | n := in.Len()
271 | for i := 0; i < n; i++ {
272 | e.marshal("", in.Index(i))
273 | }
274 | e.must(yaml_sequence_end_event_initialize(&e.event))
275 | e.emit()
276 | }
277 |
278 | // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
279 | //
280 | // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
281 | // in YAML 1.2 and by this package, but these should be marshalled quoted for
282 | // the time being for compatibility with other parsers.
283 | func isBase60Float(s string) (result bool) {
284 | // Fast path.
285 | if s == "" {
286 | return false
287 | }
288 | c := s[0]
289 | if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
290 | return false
291 | }
292 | // Do the full match.
293 | return base60float.MatchString(s)
294 | }
295 |
296 | // From http://yaml.org/type/float.html, except the regular expression there
297 | // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
298 | var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
299 |
300 | func (e *encoder) stringv(tag string, in reflect.Value) {
301 | var style yaml_scalar_style_t
302 | s := in.String()
303 | canUsePlain := true
304 | switch {
305 | case !utf8.ValidString(s):
306 | if tag == yaml_BINARY_TAG {
307 | failf("explicitly tagged !!binary data must be base64-encoded")
308 | }
309 | if tag != "" {
310 | failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
311 | }
312 | // It can't be encoded directly as YAML so use a binary tag
313 | // and encode it as base64.
314 | tag = yaml_BINARY_TAG
315 | s = encodeBase64(s)
316 | case tag == "":
317 | // Check to see if it would resolve to a specific
318 | // tag when encoded unquoted. If it doesn't,
319 | // there's no need to quote it.
320 | rtag, _ := resolve("", s)
321 | canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
322 | }
323 | // Note: it's possible for user code to emit invalid YAML
324 | // if they explicitly specify a tag and a string containing
325 | // text that's incompatible with that tag.
326 | switch {
327 | case strings.Contains(s, "\n"):
328 | style = yaml_LITERAL_SCALAR_STYLE
329 | case canUsePlain:
330 | style = yaml_PLAIN_SCALAR_STYLE
331 | default:
332 | style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
333 | }
334 | e.emitScalar(s, "", tag, style)
335 | }
336 |
337 | func (e *encoder) boolv(tag string, in reflect.Value) {
338 | var s string
339 | if in.Bool() {
340 | s = "true"
341 | } else {
342 | s = "false"
343 | }
344 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
345 | }
346 |
347 | func (e *encoder) intv(tag string, in reflect.Value) {
348 | s := strconv.FormatInt(in.Int(), 10)
349 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
350 | }
351 |
352 | func (e *encoder) uintv(tag string, in reflect.Value) {
353 | s := strconv.FormatUint(in.Uint(), 10)
354 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
355 | }
356 |
357 | func (e *encoder) timev(tag string, in reflect.Value) {
358 | t := in.Interface().(time.Time)
359 | s := t.Format(time.RFC3339Nano)
360 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
361 | }
362 |
363 | func (e *encoder) floatv(tag string, in reflect.Value) {
364 | // Issue #352: When formatting, use the precision of the underlying value
365 | precision := 64
366 | if in.Kind() == reflect.Float32 {
367 | precision = 32
368 | }
369 |
370 | s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
371 | switch s {
372 | case "+Inf":
373 | s = ".inf"
374 | case "-Inf":
375 | s = "-.inf"
376 | case "NaN":
377 | s = ".nan"
378 | }
379 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
380 | }
381 |
382 | func (e *encoder) nilv() {
383 | e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
384 | }
385 |
386 | func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
387 | implicit := tag == ""
388 | e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
389 | e.emit()
390 | }
391 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/readerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "io"
5 | )
6 |
7 | // Set the reader error and return 0.
8 | func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
9 | parser.error = yaml_READER_ERROR
10 | parser.problem = problem
11 | parser.problem_offset = offset
12 | parser.problem_value = value
13 | return false
14 | }
15 |
16 | // Byte order marks.
17 | const (
18 | bom_UTF8 = "\xef\xbb\xbf"
19 | bom_UTF16LE = "\xff\xfe"
20 | bom_UTF16BE = "\xfe\xff"
21 | )
22 |
23 | // Determine the input stream encoding by checking the BOM symbol. If no BOM is
24 | // found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
25 | func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
26 | // Ensure that we had enough bytes in the raw buffer.
27 | for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
28 | if !yaml_parser_update_raw_buffer(parser) {
29 | return false
30 | }
31 | }
32 |
33 | // Determine the encoding.
34 | buf := parser.raw_buffer
35 | pos := parser.raw_buffer_pos
36 | avail := len(buf) - pos
37 | if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
38 | parser.encoding = yaml_UTF16LE_ENCODING
39 | parser.raw_buffer_pos += 2
40 | parser.offset += 2
41 | } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
42 | parser.encoding = yaml_UTF16BE_ENCODING
43 | parser.raw_buffer_pos += 2
44 | parser.offset += 2
45 | } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
46 | parser.encoding = yaml_UTF8_ENCODING
47 | parser.raw_buffer_pos += 3
48 | parser.offset += 3
49 | } else {
50 | parser.encoding = yaml_UTF8_ENCODING
51 | }
52 | return true
53 | }
54 |
55 | // Update the raw buffer.
56 | func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
57 | size_read := 0
58 |
59 | // Return if the raw buffer is full.
60 | if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
61 | return true
62 | }
63 |
64 | // Return on EOF.
65 | if parser.eof {
66 | return true
67 | }
68 |
69 | // Move the remaining bytes in the raw buffer to the beginning.
70 | if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
71 | copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
72 | }
73 | parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
74 | parser.raw_buffer_pos = 0
75 |
76 | // Call the read handler to fill the buffer.
77 | size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
78 | parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
79 | if err == io.EOF {
80 | parser.eof = true
81 | } else if err != nil {
82 | return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
83 | }
84 | return true
85 | }
86 |
87 | // Ensure that the buffer contains at least `length` characters.
88 | // Return true on success, false on failure.
89 | //
90 | // The length is supposed to be significantly less that the buffer size.
91 | func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
92 | if parser.read_handler == nil {
93 | panic("read handler must be set")
94 | }
95 |
96 | // [Go] This function was changed to guarantee the requested length size at EOF.
97 | // The fact we need to do this is pretty awful, but the description above implies
98 | // for that to be the case, and there are tests
99 |
100 | // If the EOF flag is set and the raw buffer is empty, do nothing.
101 | if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
102 | // [Go] ACTUALLY! Read the documentation of this function above.
103 | // This is just broken. To return true, we need to have the
104 | // given length in the buffer. Not doing that means every single
105 | // check that calls this function to make sure the buffer has a
106 | // given length is Go) panicking; or C) accessing invalid memory.
107 | //return true
108 | }
109 |
110 | // Return if the buffer contains enough characters.
111 | if parser.unread >= length {
112 | return true
113 | }
114 |
115 | // Determine the input encoding if it is not known yet.
116 | if parser.encoding == yaml_ANY_ENCODING {
117 | if !yaml_parser_determine_encoding(parser) {
118 | return false
119 | }
120 | }
121 |
122 | // Move the unread characters to the beginning of the buffer.
123 | buffer_len := len(parser.buffer)
124 | if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
125 | copy(parser.buffer, parser.buffer[parser.buffer_pos:])
126 | buffer_len -= parser.buffer_pos
127 | parser.buffer_pos = 0
128 | } else if parser.buffer_pos == buffer_len {
129 | buffer_len = 0
130 | parser.buffer_pos = 0
131 | }
132 |
133 | // Open the whole buffer for writing, and cut it before returning.
134 | parser.buffer = parser.buffer[:cap(parser.buffer)]
135 |
136 | // Fill the buffer until it has enough characters.
137 | first := true
138 | for parser.unread < length {
139 |
140 | // Fill the raw buffer if necessary.
141 | if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
142 | if !yaml_parser_update_raw_buffer(parser) {
143 | parser.buffer = parser.buffer[:buffer_len]
144 | return false
145 | }
146 | }
147 | first = false
148 |
149 | // Decode the raw buffer.
150 | inner:
151 | for parser.raw_buffer_pos != len(parser.raw_buffer) {
152 | var value rune
153 | var width int
154 |
155 | raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
156 |
157 | // Decode the next character.
158 | switch parser.encoding {
159 | case yaml_UTF8_ENCODING:
160 | // Decode a UTF-8 character. Check RFC 3629
161 | // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
162 | //
163 | // The following table (taken from the RFC) is used for
164 | // decoding.
165 | //
166 | // Char. number range | UTF-8 octet sequence
167 | // (hexadecimal) | (binary)
168 | // --------------------+------------------------------------
169 | // 0000 0000-0000 007F | 0xxxxxxx
170 | // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
171 | // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
172 | // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
173 | //
174 | // Additionally, the characters in the range 0xD800-0xDFFF
175 | // are prohibited as they are reserved for use with UTF-16
176 | // surrogate pairs.
177 |
178 | // Determine the length of the UTF-8 sequence.
179 | octet := parser.raw_buffer[parser.raw_buffer_pos]
180 | switch {
181 | case octet&0x80 == 0x00:
182 | width = 1
183 | case octet&0xE0 == 0xC0:
184 | width = 2
185 | case octet&0xF0 == 0xE0:
186 | width = 3
187 | case octet&0xF8 == 0xF0:
188 | width = 4
189 | default:
190 | // The leading octet is invalid.
191 | return yaml_parser_set_reader_error(parser,
192 | "invalid leading UTF-8 octet",
193 | parser.offset, int(octet))
194 | }
195 |
196 | // Check if the raw buffer contains an incomplete character.
197 | if width > raw_unread {
198 | if parser.eof {
199 | return yaml_parser_set_reader_error(parser,
200 | "incomplete UTF-8 octet sequence",
201 | parser.offset, -1)
202 | }
203 | break inner
204 | }
205 |
206 | // Decode the leading octet.
207 | switch {
208 | case octet&0x80 == 0x00:
209 | value = rune(octet & 0x7F)
210 | case octet&0xE0 == 0xC0:
211 | value = rune(octet & 0x1F)
212 | case octet&0xF0 == 0xE0:
213 | value = rune(octet & 0x0F)
214 | case octet&0xF8 == 0xF0:
215 | value = rune(octet & 0x07)
216 | default:
217 | value = 0
218 | }
219 |
220 | // Check and decode the trailing octets.
221 | for k := 1; k < width; k++ {
222 | octet = parser.raw_buffer[parser.raw_buffer_pos+k]
223 |
224 | // Check if the octet is valid.
225 | if (octet & 0xC0) != 0x80 {
226 | return yaml_parser_set_reader_error(parser,
227 | "invalid trailing UTF-8 octet",
228 | parser.offset+k, int(octet))
229 | }
230 |
231 | // Decode the octet.
232 | value = (value << 6) + rune(octet&0x3F)
233 | }
234 |
235 | // Check the length of the sequence against the value.
236 | switch {
237 | case width == 1:
238 | case width == 2 && value >= 0x80:
239 | case width == 3 && value >= 0x800:
240 | case width == 4 && value >= 0x10000:
241 | default:
242 | return yaml_parser_set_reader_error(parser,
243 | "invalid length of a UTF-8 sequence",
244 | parser.offset, -1)
245 | }
246 |
247 | // Check the range of the value.
248 | if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
249 | return yaml_parser_set_reader_error(parser,
250 | "invalid Unicode character",
251 | parser.offset, int(value))
252 | }
253 |
254 | case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
255 | var low, high int
256 | if parser.encoding == yaml_UTF16LE_ENCODING {
257 | low, high = 0, 1
258 | } else {
259 | low, high = 1, 0
260 | }
261 |
262 | // The UTF-16 encoding is not as simple as one might
263 | // naively think. Check RFC 2781
264 | // (http://www.ietf.org/rfc/rfc2781.txt).
265 | //
266 | // Normally, two subsequent bytes describe a Unicode
267 | // character. However a special technique (called a
268 | // surrogate pair) is used for specifying character
269 | // values larger than 0xFFFF.
270 | //
271 | // A surrogate pair consists of two pseudo-characters:
272 | // high surrogate area (0xD800-0xDBFF)
273 | // low surrogate area (0xDC00-0xDFFF)
274 | //
275 | // The following formulas are used for decoding
276 | // and encoding characters using surrogate pairs:
277 | //
278 | // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
279 | // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
280 | // W1 = 110110yyyyyyyyyy
281 | // W2 = 110111xxxxxxxxxx
282 | //
283 | // where U is the character value, W1 is the high surrogate
284 | // area, W2 is the low surrogate area.
285 |
286 | // Check for incomplete UTF-16 character.
287 | if raw_unread < 2 {
288 | if parser.eof {
289 | return yaml_parser_set_reader_error(parser,
290 | "incomplete UTF-16 character",
291 | parser.offset, -1)
292 | }
293 | break inner
294 | }
295 |
296 | // Get the character.
297 | value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
298 | (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
299 |
300 | // Check for unexpected low surrogate area.
301 | if value&0xFC00 == 0xDC00 {
302 | return yaml_parser_set_reader_error(parser,
303 | "unexpected low surrogate area",
304 | parser.offset, int(value))
305 | }
306 |
307 | // Check for a high surrogate area.
308 | if value&0xFC00 == 0xD800 {
309 | width = 4
310 |
311 | // Check for incomplete surrogate pair.
312 | if raw_unread < 4 {
313 | if parser.eof {
314 | return yaml_parser_set_reader_error(parser,
315 | "incomplete UTF-16 surrogate pair",
316 | parser.offset, -1)
317 | }
318 | break inner
319 | }
320 |
321 | // Get the next character.
322 | value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
323 | (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
324 |
325 | // Check for a low surrogate area.
326 | if value2&0xFC00 != 0xDC00 {
327 | return yaml_parser_set_reader_error(parser,
328 | "expected low surrogate area",
329 | parser.offset+2, int(value2))
330 | }
331 |
332 | // Generate the value of the surrogate pair.
333 | value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
334 | } else {
335 | width = 2
336 | }
337 |
338 | default:
339 | panic("impossible")
340 | }
341 |
342 | // Check if the character is in the allowed range:
343 | // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
344 | // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
345 | // | [#x10000-#x10FFFF] (32 bit)
346 | switch {
347 | case value == 0x09:
348 | case value == 0x0A:
349 | case value == 0x0D:
350 | case value >= 0x20 && value <= 0x7E:
351 | case value == 0x85:
352 | case value >= 0xA0 && value <= 0xD7FF:
353 | case value >= 0xE000 && value <= 0xFFFD:
354 | case value >= 0x10000 && value <= 0x10FFFF:
355 | default:
356 | return yaml_parser_set_reader_error(parser,
357 | "control characters are not allowed",
358 | parser.offset, int(value))
359 | }
360 |
361 | // Move the raw pointers.
362 | parser.raw_buffer_pos += width
363 | parser.offset += width
364 |
365 | // Finally put the character into the buffer.
366 | if value <= 0x7F {
367 | // 0000 0000-0000 007F . 0xxxxxxx
368 | parser.buffer[buffer_len+0] = byte(value)
369 | buffer_len += 1
370 | } else if value <= 0x7FF {
371 | // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
372 | parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
373 | parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
374 | buffer_len += 2
375 | } else if value <= 0xFFFF {
376 | // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
377 | parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
378 | parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
379 | parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
380 | buffer_len += 3
381 | } else {
382 | // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
383 | parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
384 | parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
385 | parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
386 | parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
387 | buffer_len += 4
388 | }
389 |
390 | parser.unread++
391 | }
392 |
393 | // On EOF, put NUL into the buffer and return.
394 | if parser.eof {
395 | parser.buffer[buffer_len] = 0
396 | buffer_len++
397 | parser.unread++
398 | break
399 | }
400 | }
401 | // [Go] Read the documentation of this function above. To return true,
402 | // we need to have the given length in the buffer. Not doing that means
403 | // every single check that calls this function to make sure the buffer
404 | // has a given length is Go) panicking; or C) accessing invalid memory.
405 | // This happens here due to the EOF above breaking early.
406 | for buffer_len < length {
407 | parser.buffer[buffer_len] = 0
408 | buffer_len++
409 | }
410 | parser.buffer = parser.buffer[:buffer_len]
411 | return true
412 | }
413 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/yaml.go:
--------------------------------------------------------------------------------
1 | // Package yaml implements YAML support for the Go language.
2 | //
3 | // Source code and other details for the project are available at GitHub:
4 | //
5 | // https://github.com/go-yaml/yaml
6 | //
7 | package yaml
8 |
9 | import (
10 | "errors"
11 | "fmt"
12 | "io"
13 | "reflect"
14 | "strings"
15 | "sync"
16 | )
17 |
18 | // MapSlice encodes and decodes as a YAML map.
19 | // The order of keys is preserved when encoding and decoding.
20 | type MapSlice []MapItem
21 |
22 | // MapItem is an item in a MapSlice.
23 | type MapItem struct {
24 | Key, Value interface{}
25 | }
26 |
27 | // The Unmarshaler interface may be implemented by types to customize their
28 | // behavior when being unmarshaled from a YAML document. The UnmarshalYAML
29 | // method receives a function that may be called to unmarshal the original
30 | // YAML value into a field or variable. It is safe to call the unmarshal
31 | // function parameter more than once if necessary.
32 | type Unmarshaler interface {
33 | UnmarshalYAML(unmarshal func(interface{}) error) error
34 | }
35 |
36 | // The Marshaler interface may be implemented by types to customize their
37 | // behavior when being marshaled into a YAML document. The returned value
38 | // is marshaled in place of the original value implementing Marshaler.
39 | //
40 | // If an error is returned by MarshalYAML, the marshaling procedure stops
41 | // and returns with the provided error.
42 | type Marshaler interface {
43 | MarshalYAML() (interface{}, error)
44 | }
45 |
46 | // Unmarshal decodes the first document found within the in byte slice
47 | // and assigns decoded values into the out value.
48 | //
49 | // Maps and pointers (to a struct, string, int, etc) are accepted as out
50 | // values. If an internal pointer within a struct is not initialized,
51 | // the yaml package will initialize it if necessary for unmarshalling
52 | // the provided data. The out parameter must not be nil.
53 | //
54 | // The type of the decoded values should be compatible with the respective
55 | // values in out. If one or more values cannot be decoded due to a type
56 | // mismatches, decoding continues partially until the end of the YAML
57 | // content, and a *yaml.TypeError is returned with details for all
58 | // missed values.
59 | //
60 | // Struct fields are only unmarshalled if they are exported (have an
61 | // upper case first letter), and are unmarshalled using the field name
62 | // lowercased as the default key. Custom keys may be defined via the
63 | // "yaml" name in the field tag: the content preceding the first comma
64 | // is used as the key, and the following comma-separated options are
65 | // used to tweak the marshalling process (see Marshal).
66 | // Conflicting names result in a runtime error.
67 | //
68 | // For example:
69 | //
70 | // type T struct {
71 | // F int `yaml:"a,omitempty"`
72 | // B int
73 | // }
74 | // var t T
75 | // yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
76 | //
77 | // See the documentation of Marshal for the format of tags and a list of
78 | // supported tag options.
79 | //
80 | func Unmarshal(in []byte, out interface{}) (err error) {
81 | return unmarshal(in, out, false)
82 | }
83 |
84 | // UnmarshalStrict is like Unmarshal except that any fields that are found
85 | // in the data that do not have corresponding struct members, or mapping
86 | // keys that are duplicates, will result in
87 | // an error.
88 | func UnmarshalStrict(in []byte, out interface{}) (err error) {
89 | return unmarshal(in, out, true)
90 | }
91 |
92 | // A Decoder reads and decodes YAML values from an input stream.
93 | type Decoder struct {
94 | strict bool
95 | parser *parser
96 | }
97 |
98 | // NewDecoder returns a new decoder that reads from r.
99 | //
100 | // The decoder introduces its own buffering and may read
101 | // data from r beyond the YAML values requested.
102 | func NewDecoder(r io.Reader) *Decoder {
103 | return &Decoder{
104 | parser: newParserFromReader(r),
105 | }
106 | }
107 |
108 | // SetStrict sets whether strict decoding behaviour is enabled when
109 | // decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
110 | func (dec *Decoder) SetStrict(strict bool) {
111 | dec.strict = strict
112 | }
113 |
114 | // Decode reads the next YAML-encoded value from its input
115 | // and stores it in the value pointed to by v.
116 | //
117 | // See the documentation for Unmarshal for details about the
118 | // conversion of YAML into a Go value.
119 | func (dec *Decoder) Decode(v interface{}) (err error) {
120 | d := newDecoder(dec.strict)
121 | defer handleErr(&err)
122 | node := dec.parser.parse()
123 | if node == nil {
124 | return io.EOF
125 | }
126 | out := reflect.ValueOf(v)
127 | if out.Kind() == reflect.Ptr && !out.IsNil() {
128 | out = out.Elem()
129 | }
130 | d.unmarshal(node, out)
131 | if len(d.terrors) > 0 {
132 | return &TypeError{d.terrors}
133 | }
134 | return nil
135 | }
136 |
137 | func unmarshal(in []byte, out interface{}, strict bool) (err error) {
138 | defer handleErr(&err)
139 | d := newDecoder(strict)
140 | p := newParser(in)
141 | defer p.destroy()
142 | node := p.parse()
143 | if node != nil {
144 | v := reflect.ValueOf(out)
145 | if v.Kind() == reflect.Ptr && !v.IsNil() {
146 | v = v.Elem()
147 | }
148 | d.unmarshal(node, v)
149 | }
150 | if len(d.terrors) > 0 {
151 | return &TypeError{d.terrors}
152 | }
153 | return nil
154 | }
155 |
156 | // Marshal serializes the value provided into a YAML document. The structure
157 | // of the generated document will reflect the structure of the value itself.
158 | // Maps and pointers (to struct, string, int, etc) are accepted as the in value.
159 | //
160 | // Struct fields are only marshalled if they are exported (have an upper case
161 | // first letter), and are marshalled using the field name lowercased as the
162 | // default key. Custom keys may be defined via the "yaml" name in the field
163 | // tag: the content preceding the first comma is used as the key, and the
164 | // following comma-separated options are used to tweak the marshalling process.
165 | // Conflicting names result in a runtime error.
166 | //
167 | // The field tag format accepted is:
168 | //
169 | // `(...) yaml:"[
][,[,]]" (...)`
170 | //
171 | // The following flags are currently supported:
172 | //
173 | // omitempty Only include the field if it's not set to the zero
174 | // value for the type or to empty slices or maps.
175 | // Zero valued structs will be omitted if all their public
176 | // fields are zero, unless they implement an IsZero
177 | // method (see the IsZeroer interface type), in which
178 | // case the field will be included if that method returns true.
179 | //
180 | // flow Marshal using a flow style (useful for structs,
181 | // sequences and maps).
182 | //
183 | // inline Inline the field, which must be a struct or a map,
184 | // causing all of its fields or keys to be processed as if
185 | // they were part of the outer struct. For maps, keys must
186 | // not conflict with the yaml keys of other struct fields.
187 | //
188 | // In addition, if the key is "-", the field is ignored.
189 | //
190 | // For example:
191 | //
192 | // type T struct {
193 | // F int `yaml:"a,omitempty"`
194 | // B int
195 | // }
196 | // yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
197 | // yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
198 | //
199 | func Marshal(in interface{}) (out []byte, err error) {
200 | defer handleErr(&err)
201 | e := newEncoder()
202 | defer e.destroy()
203 | e.marshalDoc("", reflect.ValueOf(in))
204 | e.finish()
205 | out = e.out
206 | return
207 | }
208 |
209 | // An Encoder writes YAML values to an output stream.
210 | type Encoder struct {
211 | encoder *encoder
212 | }
213 |
214 | // NewEncoder returns a new encoder that writes to w.
215 | // The Encoder should be closed after use to flush all data
216 | // to w.
217 | func NewEncoder(w io.Writer) *Encoder {
218 | return &Encoder{
219 | encoder: newEncoderWithWriter(w),
220 | }
221 | }
222 |
223 | // Encode writes the YAML encoding of v to the stream.
224 | // If multiple items are encoded to the stream, the
225 | // second and subsequent document will be preceded
226 | // with a "---" document separator, but the first will not.
227 | //
228 | // See the documentation for Marshal for details about the conversion of Go
229 | // values to YAML.
230 | func (e *Encoder) Encode(v interface{}) (err error) {
231 | defer handleErr(&err)
232 | e.encoder.marshalDoc("", reflect.ValueOf(v))
233 | return nil
234 | }
235 |
236 | // Close closes the encoder by writing any remaining data.
237 | // It does not write a stream terminating string "...".
238 | func (e *Encoder) Close() (err error) {
239 | defer handleErr(&err)
240 | e.encoder.finish()
241 | return nil
242 | }
243 |
244 | func handleErr(err *error) {
245 | if v := recover(); v != nil {
246 | if e, ok := v.(yamlError); ok {
247 | *err = e.err
248 | } else {
249 | panic(v)
250 | }
251 | }
252 | }
253 |
254 | type yamlError struct {
255 | err error
256 | }
257 |
258 | func fail(err error) {
259 | panic(yamlError{err})
260 | }
261 |
262 | func failf(format string, args ...interface{}) {
263 | panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
264 | }
265 |
266 | // A TypeError is returned by Unmarshal when one or more fields in
267 | // the YAML document cannot be properly decoded into the requested
268 | // types. When this error is returned, the value is still
269 | // unmarshaled partially.
270 | type TypeError struct {
271 | Errors []string
272 | }
273 |
274 | func (e *TypeError) Error() string {
275 | return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
276 | }
277 |
278 | // --------------------------------------------------------------------------
279 | // Maintain a mapping of keys to structure field indexes
280 |
281 | // The code in this section was copied from mgo/bson.
282 |
283 | // structInfo holds details for the serialization of fields of
284 | // a given struct.
285 | type structInfo struct {
286 | FieldsMap map[string]fieldInfo
287 | FieldsList []fieldInfo
288 |
289 | // InlineMap is the number of the field in the struct that
290 | // contains an ,inline map, or -1 if there's none.
291 | InlineMap int
292 | }
293 |
294 | type fieldInfo struct {
295 | Key string
296 | Num int
297 | OmitEmpty bool
298 | Flow bool
299 | // Id holds the unique field identifier, so we can cheaply
300 | // check for field duplicates without maintaining an extra map.
301 | Id int
302 |
303 | // Inline holds the field index if the field is part of an inlined struct.
304 | Inline []int
305 | }
306 |
307 | var structMap = make(map[reflect.Type]*structInfo)
308 | var fieldMapMutex sync.RWMutex
309 |
310 | func getStructInfo(st reflect.Type) (*structInfo, error) {
311 | fieldMapMutex.RLock()
312 | sinfo, found := structMap[st]
313 | fieldMapMutex.RUnlock()
314 | if found {
315 | return sinfo, nil
316 | }
317 |
318 | n := st.NumField()
319 | fieldsMap := make(map[string]fieldInfo)
320 | fieldsList := make([]fieldInfo, 0, n)
321 | inlineMap := -1
322 | for i := 0; i != n; i++ {
323 | field := st.Field(i)
324 | if field.PkgPath != "" && !field.Anonymous {
325 | continue // Private field
326 | }
327 |
328 | info := fieldInfo{Num: i}
329 |
330 | tag := field.Tag.Get("yaml")
331 | if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
332 | tag = string(field.Tag)
333 | }
334 | if tag == "-" {
335 | continue
336 | }
337 |
338 | inline := false
339 | fields := strings.Split(tag, ",")
340 | if len(fields) > 1 {
341 | for _, flag := range fields[1:] {
342 | switch flag {
343 | case "omitempty":
344 | info.OmitEmpty = true
345 | case "flow":
346 | info.Flow = true
347 | case "inline":
348 | inline = true
349 | default:
350 | return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
351 | }
352 | }
353 | tag = fields[0]
354 | }
355 |
356 | if inline {
357 | switch field.Type.Kind() {
358 | case reflect.Map:
359 | if inlineMap >= 0 {
360 | return nil, errors.New("Multiple ,inline maps in struct " + st.String())
361 | }
362 | if field.Type.Key() != reflect.TypeOf("") {
363 | return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
364 | }
365 | inlineMap = info.Num
366 | case reflect.Struct:
367 | sinfo, err := getStructInfo(field.Type)
368 | if err != nil {
369 | return nil, err
370 | }
371 | for _, finfo := range sinfo.FieldsList {
372 | if _, found := fieldsMap[finfo.Key]; found {
373 | msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
374 | return nil, errors.New(msg)
375 | }
376 | if finfo.Inline == nil {
377 | finfo.Inline = []int{i, finfo.Num}
378 | } else {
379 | finfo.Inline = append([]int{i}, finfo.Inline...)
380 | }
381 | finfo.Id = len(fieldsList)
382 | fieldsMap[finfo.Key] = finfo
383 | fieldsList = append(fieldsList, finfo)
384 | }
385 | default:
386 | //return nil, errors.New("Option ,inline needs a struct value or map field")
387 | return nil, errors.New("Option ,inline needs a struct value field")
388 | }
389 | continue
390 | }
391 |
392 | if tag != "" {
393 | info.Key = tag
394 | } else {
395 | info.Key = strings.ToLower(field.Name)
396 | }
397 |
398 | if _, found = fieldsMap[info.Key]; found {
399 | msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
400 | return nil, errors.New(msg)
401 | }
402 |
403 | info.Id = len(fieldsList)
404 | fieldsList = append(fieldsList, info)
405 | fieldsMap[info.Key] = info
406 | }
407 |
408 | sinfo = &structInfo{
409 | FieldsMap: fieldsMap,
410 | FieldsList: fieldsList,
411 | InlineMap: inlineMap,
412 | }
413 |
414 | fieldMapMutex.Lock()
415 | structMap[st] = sinfo
416 | fieldMapMutex.Unlock()
417 | return sinfo, nil
418 | }
419 |
420 | // IsZeroer is used to check whether an object is zero to
421 | // determine whether it should be omitted when marshaling
422 | // with the omitempty flag. One notable implementation
423 | // is time.Time.
424 | type IsZeroer interface {
425 | IsZero() bool
426 | }
427 |
428 | func isZero(v reflect.Value) bool {
429 | kind := v.Kind()
430 | if z, ok := v.Interface().(IsZeroer); ok {
431 | if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
432 | return true
433 | }
434 | return z.IsZero()
435 | }
436 | switch kind {
437 | case reflect.String:
438 | return len(v.String()) == 0
439 | case reflect.Interface, reflect.Ptr:
440 | return v.IsNil()
441 | case reflect.Slice:
442 | return v.Len() == 0
443 | case reflect.Map:
444 | return v.Len() == 0
445 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
446 | return v.Int() == 0
447 | case reflect.Float32, reflect.Float64:
448 | return v.Float() == 0
449 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
450 | return v.Uint() == 0
451 | case reflect.Bool:
452 | return !v.Bool()
453 | case reflect.Struct:
454 | vt := v.Type()
455 | for i := v.NumField() - 1; i >= 0; i-- {
456 | if vt.Field(i).PkgPath != "" {
457 | continue // Private field
458 | }
459 | if !isZero(v.Field(i)) {
460 | return false
461 | }
462 | }
463 | return true
464 | }
465 | return false
466 | }
467 |
--------------------------------------------------------------------------------
/vendor/github.com/ChimeraCoder/gojson/json-to-struct.go:
--------------------------------------------------------------------------------
1 | // gojson generates go struct defintions from JSON documents
2 | //
3 | // Reads from stdin and prints to stdout
4 | //
5 | // Example:
6 | // curl -s https://api.github.com/repos/chimeracoder/gojson | gojson -name=Repository
7 | //
8 | // Output:
9 | // package main
10 | //
11 | // type Repository struct {
12 | // ArchiveURL string `json:"archive_url"`
13 | // AssigneesURL string `json:"assignees_url"`
14 | // BlobsURL string `json:"blobs_url"`
15 | // BranchesURL string `json:"branches_url"`
16 | // CloneURL string `json:"clone_url"`
17 | // CollaboratorsURL string `json:"collaborators_url"`
18 | // CommentsURL string `json:"comments_url"`
19 | // CommitsURL string `json:"commits_url"`
20 | // CompareURL string `json:"compare_url"`
21 | // ContentsURL string `json:"contents_url"`
22 | // ContributorsURL string `json:"contributors_url"`
23 | // CreatedAt string `json:"created_at"`
24 | // DefaultBranch string `json:"default_branch"`
25 | // Description string `json:"description"`
26 | // DownloadsURL string `json:"downloads_url"`
27 | // EventsURL string `json:"events_url"`
28 | // Fork bool `json:"fork"`
29 | // Forks float64 `json:"forks"`
30 | // ForksCount float64 `json:"forks_count"`
31 | // ForksURL string `json:"forks_url"`
32 | // FullName string `json:"full_name"`
33 | // GitCommitsURL string `json:"git_commits_url"`
34 | // GitRefsURL string `json:"git_refs_url"`
35 | // GitTagsURL string `json:"git_tags_url"`
36 | // GitURL string `json:"git_url"`
37 | // HasDownloads bool `json:"has_downloads"`
38 | // HasIssues bool `json:"has_issues"`
39 | // HasWiki bool `json:"has_wiki"`
40 | // Homepage interface{} `json:"homepage"`
41 | // HooksURL string `json:"hooks_url"`
42 | // HtmlURL string `json:"html_url"`
43 | // ID float64 `json:"id"`
44 | // IssueCommentURL string `json:"issue_comment_url"`
45 | // IssueEventsURL string `json:"issue_events_url"`
46 | // IssuesURL string `json:"issues_url"`
47 | // KeysURL string `json:"keys_url"`
48 | // LabelsURL string `json:"labels_url"`
49 | // Language string `json:"language"`
50 | // LanguagesURL string `json:"languages_url"`
51 | // MasterBranch string `json:"master_branch"`
52 | // MergesURL string `json:"merges_url"`
53 | // MilestonesURL string `json:"milestones_url"`
54 | // MirrorURL interface{} `json:"mirror_url"`
55 | // Name string `json:"name"`
56 | // NetworkCount float64 `json:"network_count"`
57 | // NotificationsURL string `json:"notifications_url"`
58 | // OpenIssues float64 `json:"open_issues"`
59 | // OpenIssuesCount float64 `json:"open_issues_count"`
60 | // Owner struct {
61 | // AvatarURL string `json:"avatar_url"`
62 | // EventsURL string `json:"events_url"`
63 | // FollowersURL string `json:"followers_url"`
64 | // FollowingURL string `json:"following_url"`
65 | // GistsURL string `json:"gists_url"`
66 | // GravatarID string `json:"gravatar_id"`
67 | // HtmlURL string `json:"html_url"`
68 | // ID float64 `json:"id"`
69 | // Login string `json:"login"`
70 | // OrganizationsURL string `json:"organizations_url"`
71 | // ReceivedEventsURL string `json:"received_events_url"`
72 | // ReposURL string `json:"repos_url"`
73 | // SiteAdmin bool `json:"site_admin"`
74 | // StarredURL string `json:"starred_url"`
75 | // SubscriptionsURL string `json:"subscriptions_url"`
76 | // Type string `json:"type"`
77 | // URL string `json:"url"`
78 | // } ` json:"owner"`
79 | // Private bool `json:"private"`
80 | // PullsURL string `json:"pulls_url"`
81 | // PushedAt string `json:"pushed_at"`
82 | // Size float64 `json:"size"`
83 | // SshURL string `json:"ssh_url"`
84 | // StargazersURL string `json:"stargazers_url"`
85 | // StatusesURL string `json:"statuses_url"`
86 | // SubscribersURL string `json:"subscribers_url"`
87 | // SubscriptionURL string `json:"subscription_url"`
88 | // SvnURL string `json:"svn_url"`
89 | // TagsURL string `json:"tags_url"`
90 | // TeamsURL string `json:"teams_url"`
91 | // TreesURL string `json:"trees_url"`
92 | // UpdatedAt string `json:"updated_at"`
93 | // URL string `json:"url"`
94 | // Watchers float64 `json:"watchers"`
95 | // WatchersCount float64 `json:"watchers_count"`
96 | // }
97 | package gojson
98 |
99 | import (
100 | "bytes"
101 | "encoding/json"
102 | "fmt"
103 | "go/format"
104 | "io"
105 | "math"
106 | "reflect"
107 | "sort"
108 | "strconv"
109 | "strings"
110 | "unicode"
111 |
112 | "gopkg.in/yaml.v2"
113 | )
114 |
115 | var ForceFloats bool
116 |
117 | // commonInitialisms is a set of common initialisms.
118 | // Only add entries that are highly unlikely to be non-initialisms.
119 | // For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
120 | var commonInitialisms = map[string]bool{
121 | "API": true,
122 | "ASCII": true,
123 | "CPU": true,
124 | "CSS": true,
125 | "DNS": true,
126 | "EOF": true,
127 | "GUID": true,
128 | "HTML": true,
129 | "HTTP": true,
130 | "HTTPS": true,
131 | "ID": true,
132 | "IP": true,
133 | "JSON": true,
134 | "LHS": true,
135 | "QPS": true,
136 | "RAM": true,
137 | "RHS": true,
138 | "RPC": true,
139 | "SLA": true,
140 | "SMTP": true,
141 | "SSH": true,
142 | "TLS": true,
143 | "TTL": true,
144 | "UI": true,
145 | "UID": true,
146 | "UUID": true,
147 | "URI": true,
148 | "URL": true,
149 | "UTF8": true,
150 | "VM": true,
151 | "XML": true,
152 | "NTP": true,
153 | "DB": true,
154 | }
155 |
156 | var intToWordMap = []string{
157 | "zero",
158 | "one",
159 | "two",
160 | "three",
161 | "four",
162 | "five",
163 | "six",
164 | "seven",
165 | "eight",
166 | "nine",
167 | }
168 |
169 | type Parser func(io.Reader) (interface{}, error)
170 |
171 | func ParseJson(input io.Reader) (interface{}, error) {
172 | var result interface{}
173 | if err := json.NewDecoder(input).Decode(&result); err != nil {
174 | return nil, err
175 | }
176 | return result, nil
177 | }
178 |
179 | func ParseYaml(input io.Reader) (interface{}, error) {
180 | var result interface{}
181 | b, err := readFile(input)
182 | if err != nil {
183 | return nil, err
184 | }
185 | if err := yaml.Unmarshal(b, &result); err != nil {
186 | return nil, err
187 | }
188 | return result, nil
189 | }
190 |
191 | func readFile(input io.Reader) ([]byte, error) {
192 | buf := bytes.NewBuffer(nil)
193 | _, err := io.Copy(buf, input)
194 | if err != nil {
195 | return []byte{}, nil
196 | }
197 | return buf.Bytes(), nil
198 | }
199 |
200 | // Generate a struct definition given a JSON string representation of an object and a name structName.
201 | func Generate(input io.Reader, parser Parser, structName, pkgName string, tags []string, subStruct bool, convertFloats bool) ([]byte, error) {
202 | var subStructMap map[string]string = nil
203 | if subStruct {
204 | subStructMap = make(map[string]string)
205 | }
206 |
207 | var result map[string]interface{}
208 |
209 | iresult, err := parser(input)
210 | if err != nil {
211 | return nil, err
212 | }
213 |
214 | switch iresult := iresult.(type) {
215 | case map[interface{}]interface{}:
216 | result = convertKeysToStrings(iresult)
217 | case map[string]interface{}:
218 | result = iresult
219 | case []interface{}:
220 | src := fmt.Sprintf("package %s\n\ntype %s %s\n",
221 | pkgName,
222 | structName,
223 | typeForValue(iresult, structName, tags, subStructMap, convertFloats))
224 | formatted, err := format.Source([]byte(src))
225 | if err != nil {
226 | err = fmt.Errorf("error formatting: %s, was formatting\n%s", err, src)
227 | }
228 | return formatted, err
229 | default:
230 | return nil, fmt.Errorf("unexpected type: %T", iresult)
231 | }
232 |
233 | src := fmt.Sprintf("package %s\ntype %s %s}",
234 | pkgName,
235 | structName,
236 | generateTypes(result, structName, tags, 0, subStructMap, convertFloats))
237 |
238 | keys := make([]string, 0, len(subStructMap))
239 | for key := range subStructMap {
240 | keys = append(keys, key)
241 | }
242 |
243 | sort.Strings(keys)
244 |
245 | for _, k := range keys {
246 | src = fmt.Sprintf("%v\n\ntype %v %v", src, subStructMap[k], k)
247 | }
248 |
249 | formatted, err := format.Source([]byte(src))
250 | if err != nil {
251 | err = fmt.Errorf("error formatting: %s, was formatting\n%s", err, src)
252 | }
253 | return formatted, err
254 | }
255 |
256 | func convertKeysToStrings(obj map[interface{}]interface{}) map[string]interface{} {
257 | res := make(map[string]interface{})
258 |
259 | for k, v := range obj {
260 | res[fmt.Sprintf("%v", k)] = v
261 | }
262 |
263 | return res
264 | }
265 |
266 | // Generate go struct entries for a map[string]interface{} structure
267 | func generateTypes(obj map[string]interface{}, structName string, tags []string, depth int, subStructMap map[string]string, convertFloats bool) string {
268 | structure := "struct {"
269 |
270 | keys := make([]string, 0, len(obj))
271 | for key := range obj {
272 | keys = append(keys, key)
273 | }
274 | sort.Strings(keys)
275 |
276 | for _, key := range keys {
277 | value := obj[key]
278 | valueType := typeForValue(value, structName, tags, subStructMap, convertFloats)
279 |
280 | //value = mergeElements(value)
281 |
282 | //If a nested value, recurse
283 | switch value := value.(type) {
284 | case []interface{}:
285 | if len(value) > 0 {
286 | sub := ""
287 | if v, ok := value[0].(map[interface{}]interface{}); ok {
288 | sub = generateTypes(convertKeysToStrings(v), structName, tags, depth+1, subStructMap, convertFloats) + "}"
289 | } else if v, ok := value[0].(map[string]interface{}); ok {
290 | sub = generateTypes(v, structName, tags, depth+1, subStructMap, convertFloats) + "}"
291 | }
292 |
293 | if sub != "" {
294 | subName := sub
295 |
296 | if subStructMap != nil {
297 | if val, ok := subStructMap[sub]; ok {
298 | subName = val
299 | } else {
300 | subName = fmt.Sprintf("%v_sub%v", structName, len(subStructMap)+1)
301 |
302 | subStructMap[sub] = subName
303 | }
304 | }
305 |
306 | valueType = "[]" + subName
307 | }
308 | }
309 | case map[interface{}]interface{}:
310 | sub := generateTypes(convertKeysToStrings(value), structName, tags, depth+1, subStructMap, convertFloats) + "}"
311 | subName := sub
312 |
313 | if subStructMap != nil {
314 | if val, ok := subStructMap[sub]; ok {
315 | subName = val
316 | } else {
317 | subName = fmt.Sprintf("%v_sub%v", structName, len(subStructMap)+1)
318 |
319 | subStructMap[sub] = subName
320 | }
321 | }
322 | valueType = subName
323 | case map[string]interface{}:
324 | sub := generateTypes(value, structName, tags, depth+1, subStructMap, convertFloats) + "}"
325 | subName := sub
326 |
327 | if subStructMap != nil {
328 | if val, ok := subStructMap[sub]; ok {
329 | subName = val
330 | } else {
331 | subName = fmt.Sprintf("%v_sub%v", structName, len(subStructMap)+1)
332 |
333 | subStructMap[sub] = subName
334 | }
335 | }
336 |
337 | valueType = subName
338 | }
339 |
340 | fieldName := FmtFieldName(key)
341 |
342 | tagList := make([]string, 0)
343 | for _, t := range tags {
344 | tagList = append(tagList, fmt.Sprintf("%s:\"%s\"", t, key))
345 | }
346 |
347 | structure += fmt.Sprintf("\n%s %s `%s`",
348 | fieldName,
349 | valueType,
350 | strings.Join(tagList, " "))
351 | }
352 | return structure
353 | }
354 |
355 | // FmtFieldName formats a string as a struct key
356 | //
357 | // Example:
358 | // FmtFieldName("foo_id")
359 | // Output: FooID
360 | func FmtFieldName(s string) string {
361 | runes := []rune(s)
362 | for len(runes) > 0 && !unicode.IsLetter(runes[0]) && !unicode.IsDigit(runes[0]) {
363 | runes = runes[1:]
364 | }
365 | if len(runes) == 0 {
366 | return "_"
367 | }
368 |
369 | s = stringifyFirstChar(string(runes))
370 | name := lintFieldName(s)
371 | runes = []rune(name)
372 | for i, c := range runes {
373 | ok := unicode.IsLetter(c) || unicode.IsDigit(c)
374 | if i == 0 {
375 | ok = unicode.IsLetter(c)
376 | }
377 | if !ok {
378 | runes[i] = '_'
379 | }
380 | }
381 | s = string(runes)
382 | s = strings.Trim(s, "_")
383 | if len(s) == 0 {
384 | return "_"
385 | }
386 | return s
387 | }
388 |
389 | func lintFieldName(name string) string {
390 | // Fast path for simple cases: "_" and all lowercase.
391 | if name == "_" {
392 | return name
393 | }
394 |
395 | allLower := true
396 | for _, r := range name {
397 | if !unicode.IsLower(r) {
398 | allLower = false
399 | break
400 | }
401 | }
402 | if allLower {
403 | runes := []rune(name)
404 | if u := strings.ToUpper(name); commonInitialisms[u] {
405 | copy(runes[0:], []rune(u))
406 | } else {
407 | runes[0] = unicode.ToUpper(runes[0])
408 | }
409 | return string(runes)
410 | }
411 |
412 | allUpperWithUnderscore := true
413 | for _, r := range name {
414 | if !unicode.IsUpper(r) && r != '_' {
415 | allUpperWithUnderscore = false
416 | break
417 | }
418 | }
419 | if allUpperWithUnderscore {
420 | name = strings.ToLower(name)
421 | }
422 |
423 | // Split camelCase at any lower->upper transition, and split on underscores.
424 | // Check each word for common initialisms.
425 | runes := []rune(name)
426 | w, i := 0, 0 // index of start of word, scan
427 | for i+1 <= len(runes) {
428 | eow := false // whether we hit the end of a word
429 |
430 | if i+1 == len(runes) {
431 | eow = true
432 | } else if runes[i+1] == '_' {
433 | // underscore; shift the remainder forward over any run of underscores
434 | eow = true
435 | n := 1
436 | for i+n+1 < len(runes) && runes[i+n+1] == '_' {
437 | n++
438 | }
439 |
440 | // Leave at most one underscore if the underscore is between two digits
441 | if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
442 | n--
443 | }
444 |
445 | copy(runes[i+1:], runes[i+n+1:])
446 | runes = runes[:len(runes)-n]
447 | } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
448 | // lower->non-lower
449 | eow = true
450 | }
451 | i++
452 | if !eow {
453 | continue
454 | }
455 |
456 | // [w,i) is a word.
457 | word := string(runes[w:i])
458 | if u := strings.ToUpper(word); commonInitialisms[u] {
459 | // All the common initialisms are ASCII,
460 | // so we can replace the bytes exactly.
461 | copy(runes[w:], []rune(u))
462 |
463 | } else if strings.ToLower(word) == word {
464 | // already all lowercase, and not the first word, so uppercase the first character.
465 | runes[w] = unicode.ToUpper(runes[w])
466 | }
467 | w = i
468 | }
469 | return string(runes)
470 | }
471 |
472 | // generate an appropriate struct type entry
473 | func typeForValue(value interface{}, structName string, tags []string, subStructMap map[string]string, convertFloats bool) string {
474 | //Check if this is an array
475 | if objects, ok := value.([]interface{}); ok {
476 | types := make(map[reflect.Type]bool, 0)
477 | for _, o := range objects {
478 | types[reflect.TypeOf(o)] = true
479 | }
480 | if len(types) == 1 {
481 | return "[]" + typeForValue(mergeElements(objects).([]interface{})[0], structName, tags, subStructMap, convertFloats)
482 | }
483 | return "[]interface{}"
484 | } else if object, ok := value.(map[interface{}]interface{}); ok {
485 | return generateTypes(convertKeysToStrings(object), structName, tags, 0, subStructMap, convertFloats) + "}"
486 | } else if object, ok := value.(map[string]interface{}); ok {
487 | return generateTypes(object, structName, tags, 0, subStructMap, convertFloats) + "}"
488 | } else if reflect.TypeOf(value) == nil {
489 | return "interface{}"
490 | }
491 | v := reflect.TypeOf(value).Name()
492 | if v == "float64" && convertFloats {
493 | v = disambiguateFloatInt(value)
494 | }
495 | return v
496 | }
497 |
498 | // All numbers will initially be read as float64
499 | // If the number appears to be an integer value, use int instead
500 | func disambiguateFloatInt(value interface{}) string {
501 | const epsilon = .0001
502 | vfloat := value.(float64)
503 | if !ForceFloats && math.Abs(vfloat-math.Floor(vfloat+epsilon)) < epsilon {
504 | var tmp int64
505 | return reflect.TypeOf(tmp).Name()
506 | }
507 | return reflect.TypeOf(value).Name()
508 | }
509 |
510 | // convert first character ints to strings
511 | func stringifyFirstChar(str string) string {
512 | first := str[:1]
513 |
514 | i, err := strconv.ParseInt(first, 10, 8)
515 |
516 | if err != nil {
517 | return str
518 | }
519 |
520 | return intToWordMap[i] + "_" + str[1:]
521 | }
522 |
523 | func mergeElements(i interface{}) interface{} {
524 | switch i := i.(type) {
525 | default:
526 | return i
527 | case []interface{}:
528 | l := len(i)
529 | if l == 0 {
530 | return i
531 | }
532 | for j := 1; j < l; j++ {
533 | i[0] = mergeObjects(i[0], i[j])
534 | }
535 | return i[0:1]
536 | }
537 | }
538 |
539 | func mergeObjects(o1, o2 interface{}) interface{} {
540 | if o1 == nil {
541 | return o2
542 | }
543 |
544 | if o2 == nil {
545 | return o1
546 | }
547 |
548 | if reflect.TypeOf(o1) != reflect.TypeOf(o2) {
549 | return nil
550 | }
551 |
552 | switch i := o1.(type) {
553 | default:
554 | return o1
555 | case []interface{}:
556 | if i2, ok := o2.([]interface{}); ok {
557 | i3 := append(i, i2...)
558 | return mergeElements(i3)
559 | }
560 | return mergeElements(i)
561 | case map[string]interface{}:
562 | if i2, ok := o2.(map[string]interface{}); ok {
563 | for k, v := range i2 {
564 | if v2, ok := i[k]; ok {
565 | i[k] = mergeObjects(v2, v)
566 | } else {
567 | i[k] = v
568 | }
569 | }
570 | }
571 | return i
572 | case map[interface{}]interface{}:
573 | if i2, ok := o2.(map[interface{}]interface{}); ok {
574 | for k, v := range i2 {
575 | if v2, ok := i[k]; ok {
576 | i[k] = mergeObjects(v2, v)
577 | } else {
578 | i[k] = v
579 | }
580 | }
581 | }
582 | return i
583 | }
584 | }
585 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/decode.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding"
5 | "encoding/base64"
6 | "fmt"
7 | "io"
8 | "math"
9 | "reflect"
10 | "strconv"
11 | "time"
12 | )
13 |
14 | const (
15 | documentNode = 1 << iota
16 | mappingNode
17 | sequenceNode
18 | scalarNode
19 | aliasNode
20 | )
21 |
22 | type node struct {
23 | kind int
24 | line, column int
25 | tag string
26 | // For an alias node, alias holds the resolved alias.
27 | alias *node
28 | value string
29 | implicit bool
30 | children []*node
31 | anchors map[string]*node
32 | }
33 |
34 | // ----------------------------------------------------------------------------
35 | // Parser, produces a node tree out of a libyaml event stream.
36 |
37 | type parser struct {
38 | parser yaml_parser_t
39 | event yaml_event_t
40 | doc *node
41 | doneInit bool
42 | }
43 |
44 | func newParser(b []byte) *parser {
45 | p := parser{}
46 | if !yaml_parser_initialize(&p.parser) {
47 | panic("failed to initialize YAML emitter")
48 | }
49 | if len(b) == 0 {
50 | b = []byte{'\n'}
51 | }
52 | yaml_parser_set_input_string(&p.parser, b)
53 | return &p
54 | }
55 |
56 | func newParserFromReader(r io.Reader) *parser {
57 | p := parser{}
58 | if !yaml_parser_initialize(&p.parser) {
59 | panic("failed to initialize YAML emitter")
60 | }
61 | yaml_parser_set_input_reader(&p.parser, r)
62 | return &p
63 | }
64 |
65 | func (p *parser) init() {
66 | if p.doneInit {
67 | return
68 | }
69 | p.expect(yaml_STREAM_START_EVENT)
70 | p.doneInit = true
71 | }
72 |
73 | func (p *parser) destroy() {
74 | if p.event.typ != yaml_NO_EVENT {
75 | yaml_event_delete(&p.event)
76 | }
77 | yaml_parser_delete(&p.parser)
78 | }
79 |
80 | // expect consumes an event from the event stream and
81 | // checks that it's of the expected type.
82 | func (p *parser) expect(e yaml_event_type_t) {
83 | if p.event.typ == yaml_NO_EVENT {
84 | if !yaml_parser_parse(&p.parser, &p.event) {
85 | p.fail()
86 | }
87 | }
88 | if p.event.typ == yaml_STREAM_END_EVENT {
89 | failf("attempted to go past the end of stream; corrupted value?")
90 | }
91 | if p.event.typ != e {
92 | p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
93 | p.fail()
94 | }
95 | yaml_event_delete(&p.event)
96 | p.event.typ = yaml_NO_EVENT
97 | }
98 |
99 | // peek peeks at the next event in the event stream,
100 | // puts the results into p.event and returns the event type.
101 | func (p *parser) peek() yaml_event_type_t {
102 | if p.event.typ != yaml_NO_EVENT {
103 | return p.event.typ
104 | }
105 | if !yaml_parser_parse(&p.parser, &p.event) {
106 | p.fail()
107 | }
108 | return p.event.typ
109 | }
110 |
111 | func (p *parser) fail() {
112 | var where string
113 | var line int
114 | if p.parser.problem_mark.line != 0 {
115 | line = p.parser.problem_mark.line
116 | // Scanner errors don't iterate line before returning error
117 | if p.parser.error == yaml_SCANNER_ERROR {
118 | line++
119 | }
120 | } else if p.parser.context_mark.line != 0 {
121 | line = p.parser.context_mark.line
122 | }
123 | if line != 0 {
124 | where = "line " + strconv.Itoa(line) + ": "
125 | }
126 | var msg string
127 | if len(p.parser.problem) > 0 {
128 | msg = p.parser.problem
129 | } else {
130 | msg = "unknown problem parsing YAML content"
131 | }
132 | failf("%s%s", where, msg)
133 | }
134 |
135 | func (p *parser) anchor(n *node, anchor []byte) {
136 | if anchor != nil {
137 | p.doc.anchors[string(anchor)] = n
138 | }
139 | }
140 |
141 | func (p *parser) parse() *node {
142 | p.init()
143 | switch p.peek() {
144 | case yaml_SCALAR_EVENT:
145 | return p.scalar()
146 | case yaml_ALIAS_EVENT:
147 | return p.alias()
148 | case yaml_MAPPING_START_EVENT:
149 | return p.mapping()
150 | case yaml_SEQUENCE_START_EVENT:
151 | return p.sequence()
152 | case yaml_DOCUMENT_START_EVENT:
153 | return p.document()
154 | case yaml_STREAM_END_EVENT:
155 | // Happens when attempting to decode an empty buffer.
156 | return nil
157 | default:
158 | panic("attempted to parse unknown event: " + p.event.typ.String())
159 | }
160 | }
161 |
162 | func (p *parser) node(kind int) *node {
163 | return &node{
164 | kind: kind,
165 | line: p.event.start_mark.line,
166 | column: p.event.start_mark.column,
167 | }
168 | }
169 |
170 | func (p *parser) document() *node {
171 | n := p.node(documentNode)
172 | n.anchors = make(map[string]*node)
173 | p.doc = n
174 | p.expect(yaml_DOCUMENT_START_EVENT)
175 | n.children = append(n.children, p.parse())
176 | p.expect(yaml_DOCUMENT_END_EVENT)
177 | return n
178 | }
179 |
180 | func (p *parser) alias() *node {
181 | n := p.node(aliasNode)
182 | n.value = string(p.event.anchor)
183 | n.alias = p.doc.anchors[n.value]
184 | if n.alias == nil {
185 | failf("unknown anchor '%s' referenced", n.value)
186 | }
187 | p.expect(yaml_ALIAS_EVENT)
188 | return n
189 | }
190 |
191 | func (p *parser) scalar() *node {
192 | n := p.node(scalarNode)
193 | n.value = string(p.event.value)
194 | n.tag = string(p.event.tag)
195 | n.implicit = p.event.implicit
196 | p.anchor(n, p.event.anchor)
197 | p.expect(yaml_SCALAR_EVENT)
198 | return n
199 | }
200 |
201 | func (p *parser) sequence() *node {
202 | n := p.node(sequenceNode)
203 | p.anchor(n, p.event.anchor)
204 | p.expect(yaml_SEQUENCE_START_EVENT)
205 | for p.peek() != yaml_SEQUENCE_END_EVENT {
206 | n.children = append(n.children, p.parse())
207 | }
208 | p.expect(yaml_SEQUENCE_END_EVENT)
209 | return n
210 | }
211 |
212 | func (p *parser) mapping() *node {
213 | n := p.node(mappingNode)
214 | p.anchor(n, p.event.anchor)
215 | p.expect(yaml_MAPPING_START_EVENT)
216 | for p.peek() != yaml_MAPPING_END_EVENT {
217 | n.children = append(n.children, p.parse(), p.parse())
218 | }
219 | p.expect(yaml_MAPPING_END_EVENT)
220 | return n
221 | }
222 |
223 | // ----------------------------------------------------------------------------
224 | // Decoder, unmarshals a node into a provided value.
225 |
226 | type decoder struct {
227 | doc *node
228 | aliases map[*node]bool
229 | mapType reflect.Type
230 | terrors []string
231 | strict bool
232 |
233 | decodeCount int
234 | aliasCount int
235 | aliasDepth int
236 | }
237 |
238 | var (
239 | mapItemType = reflect.TypeOf(MapItem{})
240 | durationType = reflect.TypeOf(time.Duration(0))
241 | defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
242 | ifaceType = defaultMapType.Elem()
243 | timeType = reflect.TypeOf(time.Time{})
244 | ptrTimeType = reflect.TypeOf(&time.Time{})
245 | )
246 |
247 | func newDecoder(strict bool) *decoder {
248 | d := &decoder{mapType: defaultMapType, strict: strict}
249 | d.aliases = make(map[*node]bool)
250 | return d
251 | }
252 |
253 | func (d *decoder) terror(n *node, tag string, out reflect.Value) {
254 | if n.tag != "" {
255 | tag = n.tag
256 | }
257 | value := n.value
258 | if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG {
259 | if len(value) > 10 {
260 | value = " `" + value[:7] + "...`"
261 | } else {
262 | value = " `" + value + "`"
263 | }
264 | }
265 | d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type()))
266 | }
267 |
268 | func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) {
269 | terrlen := len(d.terrors)
270 | err := u.UnmarshalYAML(func(v interface{}) (err error) {
271 | defer handleErr(&err)
272 | d.unmarshal(n, reflect.ValueOf(v))
273 | if len(d.terrors) > terrlen {
274 | issues := d.terrors[terrlen:]
275 | d.terrors = d.terrors[:terrlen]
276 | return &TypeError{issues}
277 | }
278 | return nil
279 | })
280 | if e, ok := err.(*TypeError); ok {
281 | d.terrors = append(d.terrors, e.Errors...)
282 | return false
283 | }
284 | if err != nil {
285 | fail(err)
286 | }
287 | return true
288 | }
289 |
290 | // d.prepare initializes and dereferences pointers and calls UnmarshalYAML
291 | // if a value is found to implement it.
292 | // It returns the initialized and dereferenced out value, whether
293 | // unmarshalling was already done by UnmarshalYAML, and if so whether
294 | // its types unmarshalled appropriately.
295 | //
296 | // If n holds a null value, prepare returns before doing anything.
297 | func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
298 | if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
299 | return out, false, false
300 | }
301 | again := true
302 | for again {
303 | again = false
304 | if out.Kind() == reflect.Ptr {
305 | if out.IsNil() {
306 | out.Set(reflect.New(out.Type().Elem()))
307 | }
308 | out = out.Elem()
309 | again = true
310 | }
311 | if out.CanAddr() {
312 | if u, ok := out.Addr().Interface().(Unmarshaler); ok {
313 | good = d.callUnmarshaler(n, u)
314 | return out, true, good
315 | }
316 | }
317 | }
318 | return out, false, false
319 | }
320 |
321 | const (
322 | // 400,000 decode operations is ~500kb of dense object declarations, or
323 | // ~5kb of dense object declarations with 10000% alias expansion
324 | alias_ratio_range_low = 400000
325 |
326 | // 4,000,000 decode operations is ~5MB of dense object declarations, or
327 | // ~4.5MB of dense object declarations with 10% alias expansion
328 | alias_ratio_range_high = 4000000
329 |
330 | // alias_ratio_range is the range over which we scale allowed alias ratios
331 | alias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)
332 | )
333 |
334 | func allowedAliasRatio(decodeCount int) float64 {
335 | switch {
336 | case decodeCount <= alias_ratio_range_low:
337 | // allow 99% to come from alias expansion for small-to-medium documents
338 | return 0.99
339 | case decodeCount >= alias_ratio_range_high:
340 | // allow 10% to come from alias expansion for very large documents
341 | return 0.10
342 | default:
343 | // scale smoothly from 99% down to 10% over the range.
344 | // this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.
345 | // 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).
346 | return 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)
347 | }
348 | }
349 |
350 | func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) {
351 | d.decodeCount++
352 | if d.aliasDepth > 0 {
353 | d.aliasCount++
354 | }
355 | if d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {
356 | failf("document contains excessive aliasing")
357 | }
358 | switch n.kind {
359 | case documentNode:
360 | return d.document(n, out)
361 | case aliasNode:
362 | return d.alias(n, out)
363 | }
364 | out, unmarshaled, good := d.prepare(n, out)
365 | if unmarshaled {
366 | return good
367 | }
368 | switch n.kind {
369 | case scalarNode:
370 | good = d.scalar(n, out)
371 | case mappingNode:
372 | good = d.mapping(n, out)
373 | case sequenceNode:
374 | good = d.sequence(n, out)
375 | default:
376 | panic("internal error: unknown node kind: " + strconv.Itoa(n.kind))
377 | }
378 | return good
379 | }
380 |
381 | func (d *decoder) document(n *node, out reflect.Value) (good bool) {
382 | if len(n.children) == 1 {
383 | d.doc = n
384 | d.unmarshal(n.children[0], out)
385 | return true
386 | }
387 | return false
388 | }
389 |
390 | func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
391 | if d.aliases[n] {
392 | // TODO this could actually be allowed in some circumstances.
393 | failf("anchor '%s' value contains itself", n.value)
394 | }
395 | d.aliases[n] = true
396 | d.aliasDepth++
397 | good = d.unmarshal(n.alias, out)
398 | d.aliasDepth--
399 | delete(d.aliases, n)
400 | return good
401 | }
402 |
403 | var zeroValue reflect.Value
404 |
405 | func resetMap(out reflect.Value) {
406 | for _, k := range out.MapKeys() {
407 | out.SetMapIndex(k, zeroValue)
408 | }
409 | }
410 |
411 | func (d *decoder) scalar(n *node, out reflect.Value) bool {
412 | var tag string
413 | var resolved interface{}
414 | if n.tag == "" && !n.implicit {
415 | tag = yaml_STR_TAG
416 | resolved = n.value
417 | } else {
418 | tag, resolved = resolve(n.tag, n.value)
419 | if tag == yaml_BINARY_TAG {
420 | data, err := base64.StdEncoding.DecodeString(resolved.(string))
421 | if err != nil {
422 | failf("!!binary value contains invalid base64 data")
423 | }
424 | resolved = string(data)
425 | }
426 | }
427 | if resolved == nil {
428 | if out.Kind() == reflect.Map && !out.CanAddr() {
429 | resetMap(out)
430 | } else {
431 | out.Set(reflect.Zero(out.Type()))
432 | }
433 | return true
434 | }
435 | if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
436 | // We've resolved to exactly the type we want, so use that.
437 | out.Set(resolvedv)
438 | return true
439 | }
440 | // Perhaps we can use the value as a TextUnmarshaler to
441 | // set its value.
442 | if out.CanAddr() {
443 | u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
444 | if ok {
445 | var text []byte
446 | if tag == yaml_BINARY_TAG {
447 | text = []byte(resolved.(string))
448 | } else {
449 | // We let any value be unmarshaled into TextUnmarshaler.
450 | // That might be more lax than we'd like, but the
451 | // TextUnmarshaler itself should bowl out any dubious values.
452 | text = []byte(n.value)
453 | }
454 | err := u.UnmarshalText(text)
455 | if err != nil {
456 | fail(err)
457 | }
458 | return true
459 | }
460 | }
461 | switch out.Kind() {
462 | case reflect.String:
463 | if tag == yaml_BINARY_TAG {
464 | out.SetString(resolved.(string))
465 | return true
466 | }
467 | if resolved != nil {
468 | out.SetString(n.value)
469 | return true
470 | }
471 | case reflect.Interface:
472 | if resolved == nil {
473 | out.Set(reflect.Zero(out.Type()))
474 | } else if tag == yaml_TIMESTAMP_TAG {
475 | // It looks like a timestamp but for backward compatibility
476 | // reasons we set it as a string, so that code that unmarshals
477 | // timestamp-like values into interface{} will continue to
478 | // see a string and not a time.Time.
479 | // TODO(v3) Drop this.
480 | out.Set(reflect.ValueOf(n.value))
481 | } else {
482 | out.Set(reflect.ValueOf(resolved))
483 | }
484 | return true
485 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
486 | switch resolved := resolved.(type) {
487 | case int:
488 | if !out.OverflowInt(int64(resolved)) {
489 | out.SetInt(int64(resolved))
490 | return true
491 | }
492 | case int64:
493 | if !out.OverflowInt(resolved) {
494 | out.SetInt(resolved)
495 | return true
496 | }
497 | case uint64:
498 | if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
499 | out.SetInt(int64(resolved))
500 | return true
501 | }
502 | case float64:
503 | if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
504 | out.SetInt(int64(resolved))
505 | return true
506 | }
507 | case string:
508 | if out.Type() == durationType {
509 | d, err := time.ParseDuration(resolved)
510 | if err == nil {
511 | out.SetInt(int64(d))
512 | return true
513 | }
514 | }
515 | }
516 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
517 | switch resolved := resolved.(type) {
518 | case int:
519 | if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
520 | out.SetUint(uint64(resolved))
521 | return true
522 | }
523 | case int64:
524 | if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
525 | out.SetUint(uint64(resolved))
526 | return true
527 | }
528 | case uint64:
529 | if !out.OverflowUint(uint64(resolved)) {
530 | out.SetUint(uint64(resolved))
531 | return true
532 | }
533 | case float64:
534 | if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
535 | out.SetUint(uint64(resolved))
536 | return true
537 | }
538 | }
539 | case reflect.Bool:
540 | switch resolved := resolved.(type) {
541 | case bool:
542 | out.SetBool(resolved)
543 | return true
544 | }
545 | case reflect.Float32, reflect.Float64:
546 | switch resolved := resolved.(type) {
547 | case int:
548 | out.SetFloat(float64(resolved))
549 | return true
550 | case int64:
551 | out.SetFloat(float64(resolved))
552 | return true
553 | case uint64:
554 | out.SetFloat(float64(resolved))
555 | return true
556 | case float64:
557 | out.SetFloat(resolved)
558 | return true
559 | }
560 | case reflect.Struct:
561 | if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
562 | out.Set(resolvedv)
563 | return true
564 | }
565 | case reflect.Ptr:
566 | if out.Type().Elem() == reflect.TypeOf(resolved) {
567 | // TODO DOes this make sense? When is out a Ptr except when decoding a nil value?
568 | elem := reflect.New(out.Type().Elem())
569 | elem.Elem().Set(reflect.ValueOf(resolved))
570 | out.Set(elem)
571 | return true
572 | }
573 | }
574 | d.terror(n, tag, out)
575 | return false
576 | }
577 |
578 | func settableValueOf(i interface{}) reflect.Value {
579 | v := reflect.ValueOf(i)
580 | sv := reflect.New(v.Type()).Elem()
581 | sv.Set(v)
582 | return sv
583 | }
584 |
585 | func (d *decoder) sequence(n *node, out reflect.Value) (good bool) {
586 | l := len(n.children)
587 |
588 | var iface reflect.Value
589 | switch out.Kind() {
590 | case reflect.Slice:
591 | out.Set(reflect.MakeSlice(out.Type(), l, l))
592 | case reflect.Array:
593 | if l != out.Len() {
594 | failf("invalid array: want %d elements but got %d", out.Len(), l)
595 | }
596 | case reflect.Interface:
597 | // No type hints. Will have to use a generic sequence.
598 | iface = out
599 | out = settableValueOf(make([]interface{}, l))
600 | default:
601 | d.terror(n, yaml_SEQ_TAG, out)
602 | return false
603 | }
604 | et := out.Type().Elem()
605 |
606 | j := 0
607 | for i := 0; i < l; i++ {
608 | e := reflect.New(et).Elem()
609 | if ok := d.unmarshal(n.children[i], e); ok {
610 | out.Index(j).Set(e)
611 | j++
612 | }
613 | }
614 | if out.Kind() != reflect.Array {
615 | out.Set(out.Slice(0, j))
616 | }
617 | if iface.IsValid() {
618 | iface.Set(out)
619 | }
620 | return true
621 | }
622 |
623 | func (d *decoder) mapping(n *node, out reflect.Value) (good bool) {
624 | switch out.Kind() {
625 | case reflect.Struct:
626 | return d.mappingStruct(n, out)
627 | case reflect.Slice:
628 | return d.mappingSlice(n, out)
629 | case reflect.Map:
630 | // okay
631 | case reflect.Interface:
632 | if d.mapType.Kind() == reflect.Map {
633 | iface := out
634 | out = reflect.MakeMap(d.mapType)
635 | iface.Set(out)
636 | } else {
637 | slicev := reflect.New(d.mapType).Elem()
638 | if !d.mappingSlice(n, slicev) {
639 | return false
640 | }
641 | out.Set(slicev)
642 | return true
643 | }
644 | default:
645 | d.terror(n, yaml_MAP_TAG, out)
646 | return false
647 | }
648 | outt := out.Type()
649 | kt := outt.Key()
650 | et := outt.Elem()
651 |
652 | mapType := d.mapType
653 | if outt.Key() == ifaceType && outt.Elem() == ifaceType {
654 | d.mapType = outt
655 | }
656 |
657 | if out.IsNil() {
658 | out.Set(reflect.MakeMap(outt))
659 | }
660 | l := len(n.children)
661 | for i := 0; i < l; i += 2 {
662 | if isMerge(n.children[i]) {
663 | d.merge(n.children[i+1], out)
664 | continue
665 | }
666 | k := reflect.New(kt).Elem()
667 | if d.unmarshal(n.children[i], k) {
668 | kkind := k.Kind()
669 | if kkind == reflect.Interface {
670 | kkind = k.Elem().Kind()
671 | }
672 | if kkind == reflect.Map || kkind == reflect.Slice {
673 | failf("invalid map key: %#v", k.Interface())
674 | }
675 | e := reflect.New(et).Elem()
676 | if d.unmarshal(n.children[i+1], e) {
677 | d.setMapIndex(n.children[i+1], out, k, e)
678 | }
679 | }
680 | }
681 | d.mapType = mapType
682 | return true
683 | }
684 |
685 | func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
686 | if d.strict && out.MapIndex(k) != zeroValue {
687 | d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
688 | return
689 | }
690 | out.SetMapIndex(k, v)
691 | }
692 |
693 | func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
694 | outt := out.Type()
695 | if outt.Elem() != mapItemType {
696 | d.terror(n, yaml_MAP_TAG, out)
697 | return false
698 | }
699 |
700 | mapType := d.mapType
701 | d.mapType = outt
702 |
703 | var slice []MapItem
704 | var l = len(n.children)
705 | for i := 0; i < l; i += 2 {
706 | if isMerge(n.children[i]) {
707 | d.merge(n.children[i+1], out)
708 | continue
709 | }
710 | item := MapItem{}
711 | k := reflect.ValueOf(&item.Key).Elem()
712 | if d.unmarshal(n.children[i], k) {
713 | v := reflect.ValueOf(&item.Value).Elem()
714 | if d.unmarshal(n.children[i+1], v) {
715 | slice = append(slice, item)
716 | }
717 | }
718 | }
719 | out.Set(reflect.ValueOf(slice))
720 | d.mapType = mapType
721 | return true
722 | }
723 |
724 | func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) {
725 | sinfo, err := getStructInfo(out.Type())
726 | if err != nil {
727 | panic(err)
728 | }
729 | name := settableValueOf("")
730 | l := len(n.children)
731 |
732 | var inlineMap reflect.Value
733 | var elemType reflect.Type
734 | if sinfo.InlineMap != -1 {
735 | inlineMap = out.Field(sinfo.InlineMap)
736 | inlineMap.Set(reflect.New(inlineMap.Type()).Elem())
737 | elemType = inlineMap.Type().Elem()
738 | }
739 |
740 | var doneFields []bool
741 | if d.strict {
742 | doneFields = make([]bool, len(sinfo.FieldsList))
743 | }
744 | for i := 0; i < l; i += 2 {
745 | ni := n.children[i]
746 | if isMerge(ni) {
747 | d.merge(n.children[i+1], out)
748 | continue
749 | }
750 | if !d.unmarshal(ni, name) {
751 | continue
752 | }
753 | if info, ok := sinfo.FieldsMap[name.String()]; ok {
754 | if d.strict {
755 | if doneFields[info.Id] {
756 | d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
757 | continue
758 | }
759 | doneFields[info.Id] = true
760 | }
761 | var field reflect.Value
762 | if info.Inline == nil {
763 | field = out.Field(info.Num)
764 | } else {
765 | field = out.FieldByIndex(info.Inline)
766 | }
767 | d.unmarshal(n.children[i+1], field)
768 | } else if sinfo.InlineMap != -1 {
769 | if inlineMap.IsNil() {
770 | inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
771 | }
772 | value := reflect.New(elemType).Elem()
773 | d.unmarshal(n.children[i+1], value)
774 | d.setMapIndex(n.children[i+1], inlineMap, name, value)
775 | } else if d.strict {
776 | d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
777 | }
778 | }
779 | return true
780 | }
781 |
782 | func failWantMap() {
783 | failf("map merge requires map or sequence of maps as the value")
784 | }
785 |
786 | func (d *decoder) merge(n *node, out reflect.Value) {
787 | switch n.kind {
788 | case mappingNode:
789 | d.unmarshal(n, out)
790 | case aliasNode:
791 | if n.alias != nil && n.alias.kind != mappingNode {
792 | failWantMap()
793 | }
794 | d.unmarshal(n, out)
795 | case sequenceNode:
796 | // Step backwards as earlier nodes take precedence.
797 | for i := len(n.children) - 1; i >= 0; i-- {
798 | ni := n.children[i]
799 | if ni.kind == aliasNode {
800 | if ni.alias != nil && ni.alias.kind != mappingNode {
801 | failWantMap()
802 | }
803 | } else if ni.kind != mappingNode {
804 | failWantMap()
805 | }
806 | d.unmarshal(ni, out)
807 | }
808 | default:
809 | failWantMap()
810 | }
811 | }
812 |
813 | func isMerge(n *node) bool {
814 | return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG)
815 | }
816 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/apic.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "io"
5 | )
6 |
7 | func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
8 | //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))
9 |
10 | // Check if we can move the queue at the beginning of the buffer.
11 | if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {
12 | if parser.tokens_head != len(parser.tokens) {
13 | copy(parser.tokens, parser.tokens[parser.tokens_head:])
14 | }
15 | parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]
16 | parser.tokens_head = 0
17 | }
18 | parser.tokens = append(parser.tokens, *token)
19 | if pos < 0 {
20 | return
21 | }
22 | copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])
23 | parser.tokens[parser.tokens_head+pos] = *token
24 | }
25 |
26 | // Create a new parser object.
27 | func yaml_parser_initialize(parser *yaml_parser_t) bool {
28 | *parser = yaml_parser_t{
29 | raw_buffer: make([]byte, 0, input_raw_buffer_size),
30 | buffer: make([]byte, 0, input_buffer_size),
31 | }
32 | return true
33 | }
34 |
35 | // Destroy a parser object.
36 | func yaml_parser_delete(parser *yaml_parser_t) {
37 | *parser = yaml_parser_t{}
38 | }
39 |
40 | // String read handler.
41 | func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
42 | if parser.input_pos == len(parser.input) {
43 | return 0, io.EOF
44 | }
45 | n = copy(buffer, parser.input[parser.input_pos:])
46 | parser.input_pos += n
47 | return n, nil
48 | }
49 |
50 | // Reader read handler.
51 | func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
52 | return parser.input_reader.Read(buffer)
53 | }
54 |
55 | // Set a string input.
56 | func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {
57 | if parser.read_handler != nil {
58 | panic("must set the input source only once")
59 | }
60 | parser.read_handler = yaml_string_read_handler
61 | parser.input = input
62 | parser.input_pos = 0
63 | }
64 |
65 | // Set a file input.
66 | func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
67 | if parser.read_handler != nil {
68 | panic("must set the input source only once")
69 | }
70 | parser.read_handler = yaml_reader_read_handler
71 | parser.input_reader = r
72 | }
73 |
74 | // Set the source encoding.
75 | func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {
76 | if parser.encoding != yaml_ANY_ENCODING {
77 | panic("must set the encoding only once")
78 | }
79 | parser.encoding = encoding
80 | }
81 |
82 | // Create a new emitter object.
83 | func yaml_emitter_initialize(emitter *yaml_emitter_t) {
84 | *emitter = yaml_emitter_t{
85 | buffer: make([]byte, output_buffer_size),
86 | raw_buffer: make([]byte, 0, output_raw_buffer_size),
87 | states: make([]yaml_emitter_state_t, 0, initial_stack_size),
88 | events: make([]yaml_event_t, 0, initial_queue_size),
89 | }
90 | }
91 |
92 | // Destroy an emitter object.
93 | func yaml_emitter_delete(emitter *yaml_emitter_t) {
94 | *emitter = yaml_emitter_t{}
95 | }
96 |
97 | // String write handler.
98 | func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
99 | *emitter.output_buffer = append(*emitter.output_buffer, buffer...)
100 | return nil
101 | }
102 |
103 | // yaml_writer_write_handler uses emitter.output_writer to write the
104 | // emitted text.
105 | func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
106 | _, err := emitter.output_writer.Write(buffer)
107 | return err
108 | }
109 |
110 | // Set a string output.
111 | func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {
112 | if emitter.write_handler != nil {
113 | panic("must set the output target only once")
114 | }
115 | emitter.write_handler = yaml_string_write_handler
116 | emitter.output_buffer = output_buffer
117 | }
118 |
119 | // Set a file output.
120 | func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
121 | if emitter.write_handler != nil {
122 | panic("must set the output target only once")
123 | }
124 | emitter.write_handler = yaml_writer_write_handler
125 | emitter.output_writer = w
126 | }
127 |
128 | // Set the output encoding.
129 | func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {
130 | if emitter.encoding != yaml_ANY_ENCODING {
131 | panic("must set the output encoding only once")
132 | }
133 | emitter.encoding = encoding
134 | }
135 |
136 | // Set the canonical output style.
137 | func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {
138 | emitter.canonical = canonical
139 | }
140 |
141 | //// Set the indentation increment.
142 | func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {
143 | if indent < 2 || indent > 9 {
144 | indent = 2
145 | }
146 | emitter.best_indent = indent
147 | }
148 |
149 | // Set the preferred line width.
150 | func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {
151 | if width < 0 {
152 | width = -1
153 | }
154 | emitter.best_width = width
155 | }
156 |
157 | // Set if unescaped non-ASCII characters are allowed.
158 | func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {
159 | emitter.unicode = unicode
160 | }
161 |
162 | // Set the preferred line break character.
163 | func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {
164 | emitter.line_break = line_break
165 | }
166 |
167 | ///*
168 | // * Destroy a token object.
169 | // */
170 | //
171 | //YAML_DECLARE(void)
172 | //yaml_token_delete(yaml_token_t *token)
173 | //{
174 | // assert(token); // Non-NULL token object expected.
175 | //
176 | // switch (token.type)
177 | // {
178 | // case YAML_TAG_DIRECTIVE_TOKEN:
179 | // yaml_free(token.data.tag_directive.handle);
180 | // yaml_free(token.data.tag_directive.prefix);
181 | // break;
182 | //
183 | // case YAML_ALIAS_TOKEN:
184 | // yaml_free(token.data.alias.value);
185 | // break;
186 | //
187 | // case YAML_ANCHOR_TOKEN:
188 | // yaml_free(token.data.anchor.value);
189 | // break;
190 | //
191 | // case YAML_TAG_TOKEN:
192 | // yaml_free(token.data.tag.handle);
193 | // yaml_free(token.data.tag.suffix);
194 | // break;
195 | //
196 | // case YAML_SCALAR_TOKEN:
197 | // yaml_free(token.data.scalar.value);
198 | // break;
199 | //
200 | // default:
201 | // break;
202 | // }
203 | //
204 | // memset(token, 0, sizeof(yaml_token_t));
205 | //}
206 | //
207 | ///*
208 | // * Check if a string is a valid UTF-8 sequence.
209 | // *
210 | // * Check 'reader.c' for more details on UTF-8 encoding.
211 | // */
212 | //
213 | //static int
214 | //yaml_check_utf8(yaml_char_t *start, size_t length)
215 | //{
216 | // yaml_char_t *end = start+length;
217 | // yaml_char_t *pointer = start;
218 | //
219 | // while (pointer < end) {
220 | // unsigned char octet;
221 | // unsigned int width;
222 | // unsigned int value;
223 | // size_t k;
224 | //
225 | // octet = pointer[0];
226 | // width = (octet & 0x80) == 0x00 ? 1 :
227 | // (octet & 0xE0) == 0xC0 ? 2 :
228 | // (octet & 0xF0) == 0xE0 ? 3 :
229 | // (octet & 0xF8) == 0xF0 ? 4 : 0;
230 | // value = (octet & 0x80) == 0x00 ? octet & 0x7F :
231 | // (octet & 0xE0) == 0xC0 ? octet & 0x1F :
232 | // (octet & 0xF0) == 0xE0 ? octet & 0x0F :
233 | // (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
234 | // if (!width) return 0;
235 | // if (pointer+width > end) return 0;
236 | // for (k = 1; k < width; k ++) {
237 | // octet = pointer[k];
238 | // if ((octet & 0xC0) != 0x80) return 0;
239 | // value = (value << 6) + (octet & 0x3F);
240 | // }
241 | // if (!((width == 1) ||
242 | // (width == 2 && value >= 0x80) ||
243 | // (width == 3 && value >= 0x800) ||
244 | // (width == 4 && value >= 0x10000))) return 0;
245 | //
246 | // pointer += width;
247 | // }
248 | //
249 | // return 1;
250 | //}
251 | //
252 |
253 | // Create STREAM-START.
254 | func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
255 | *event = yaml_event_t{
256 | typ: yaml_STREAM_START_EVENT,
257 | encoding: encoding,
258 | }
259 | }
260 |
261 | // Create STREAM-END.
262 | func yaml_stream_end_event_initialize(event *yaml_event_t) {
263 | *event = yaml_event_t{
264 | typ: yaml_STREAM_END_EVENT,
265 | }
266 | }
267 |
268 | // Create DOCUMENT-START.
269 | func yaml_document_start_event_initialize(
270 | event *yaml_event_t,
271 | version_directive *yaml_version_directive_t,
272 | tag_directives []yaml_tag_directive_t,
273 | implicit bool,
274 | ) {
275 | *event = yaml_event_t{
276 | typ: yaml_DOCUMENT_START_EVENT,
277 | version_directive: version_directive,
278 | tag_directives: tag_directives,
279 | implicit: implicit,
280 | }
281 | }
282 |
283 | // Create DOCUMENT-END.
284 | func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
285 | *event = yaml_event_t{
286 | typ: yaml_DOCUMENT_END_EVENT,
287 | implicit: implicit,
288 | }
289 | }
290 |
291 | ///*
292 | // * Create ALIAS.
293 | // */
294 | //
295 | //YAML_DECLARE(int)
296 | //yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t)
297 | //{
298 | // mark yaml_mark_t = { 0, 0, 0 }
299 | // anchor_copy *yaml_char_t = NULL
300 | //
301 | // assert(event) // Non-NULL event object is expected.
302 | // assert(anchor) // Non-NULL anchor is expected.
303 | //
304 | // if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0
305 | //
306 | // anchor_copy = yaml_strdup(anchor)
307 | // if (!anchor_copy)
308 | // return 0
309 | //
310 | // ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark)
311 | //
312 | // return 1
313 | //}
314 |
315 | // Create SCALAR.
316 | func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {
317 | *event = yaml_event_t{
318 | typ: yaml_SCALAR_EVENT,
319 | anchor: anchor,
320 | tag: tag,
321 | value: value,
322 | implicit: plain_implicit,
323 | quoted_implicit: quoted_implicit,
324 | style: yaml_style_t(style),
325 | }
326 | return true
327 | }
328 |
329 | // Create SEQUENCE-START.
330 | func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {
331 | *event = yaml_event_t{
332 | typ: yaml_SEQUENCE_START_EVENT,
333 | anchor: anchor,
334 | tag: tag,
335 | implicit: implicit,
336 | style: yaml_style_t(style),
337 | }
338 | return true
339 | }
340 |
341 | // Create SEQUENCE-END.
342 | func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {
343 | *event = yaml_event_t{
344 | typ: yaml_SEQUENCE_END_EVENT,
345 | }
346 | return true
347 | }
348 |
349 | // Create MAPPING-START.
350 | func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
351 | *event = yaml_event_t{
352 | typ: yaml_MAPPING_START_EVENT,
353 | anchor: anchor,
354 | tag: tag,
355 | implicit: implicit,
356 | style: yaml_style_t(style),
357 | }
358 | }
359 |
360 | // Create MAPPING-END.
361 | func yaml_mapping_end_event_initialize(event *yaml_event_t) {
362 | *event = yaml_event_t{
363 | typ: yaml_MAPPING_END_EVENT,
364 | }
365 | }
366 |
367 | // Destroy an event object.
368 | func yaml_event_delete(event *yaml_event_t) {
369 | *event = yaml_event_t{}
370 | }
371 |
372 | ///*
373 | // * Create a document object.
374 | // */
375 | //
376 | //YAML_DECLARE(int)
377 | //yaml_document_initialize(document *yaml_document_t,
378 | // version_directive *yaml_version_directive_t,
379 | // tag_directives_start *yaml_tag_directive_t,
380 | // tag_directives_end *yaml_tag_directive_t,
381 | // start_implicit int, end_implicit int)
382 | //{
383 | // struct {
384 | // error yaml_error_type_t
385 | // } context
386 | // struct {
387 | // start *yaml_node_t
388 | // end *yaml_node_t
389 | // top *yaml_node_t
390 | // } nodes = { NULL, NULL, NULL }
391 | // version_directive_copy *yaml_version_directive_t = NULL
392 | // struct {
393 | // start *yaml_tag_directive_t
394 | // end *yaml_tag_directive_t
395 | // top *yaml_tag_directive_t
396 | // } tag_directives_copy = { NULL, NULL, NULL }
397 | // value yaml_tag_directive_t = { NULL, NULL }
398 | // mark yaml_mark_t = { 0, 0, 0 }
399 | //
400 | // assert(document) // Non-NULL document object is expected.
401 | // assert((tag_directives_start && tag_directives_end) ||
402 | // (tag_directives_start == tag_directives_end))
403 | // // Valid tag directives are expected.
404 | //
405 | // if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error
406 | //
407 | // if (version_directive) {
408 | // version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))
409 | // if (!version_directive_copy) goto error
410 | // version_directive_copy.major = version_directive.major
411 | // version_directive_copy.minor = version_directive.minor
412 | // }
413 | //
414 | // if (tag_directives_start != tag_directives_end) {
415 | // tag_directive *yaml_tag_directive_t
416 | // if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
417 | // goto error
418 | // for (tag_directive = tag_directives_start
419 | // tag_directive != tag_directives_end; tag_directive ++) {
420 | // assert(tag_directive.handle)
421 | // assert(tag_directive.prefix)
422 | // if (!yaml_check_utf8(tag_directive.handle,
423 | // strlen((char *)tag_directive.handle)))
424 | // goto error
425 | // if (!yaml_check_utf8(tag_directive.prefix,
426 | // strlen((char *)tag_directive.prefix)))
427 | // goto error
428 | // value.handle = yaml_strdup(tag_directive.handle)
429 | // value.prefix = yaml_strdup(tag_directive.prefix)
430 | // if (!value.handle || !value.prefix) goto error
431 | // if (!PUSH(&context, tag_directives_copy, value))
432 | // goto error
433 | // value.handle = NULL
434 | // value.prefix = NULL
435 | // }
436 | // }
437 | //
438 | // DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
439 | // tag_directives_copy.start, tag_directives_copy.top,
440 | // start_implicit, end_implicit, mark, mark)
441 | //
442 | // return 1
443 | //
444 | //error:
445 | // STACK_DEL(&context, nodes)
446 | // yaml_free(version_directive_copy)
447 | // while (!STACK_EMPTY(&context, tag_directives_copy)) {
448 | // value yaml_tag_directive_t = POP(&context, tag_directives_copy)
449 | // yaml_free(value.handle)
450 | // yaml_free(value.prefix)
451 | // }
452 | // STACK_DEL(&context, tag_directives_copy)
453 | // yaml_free(value.handle)
454 | // yaml_free(value.prefix)
455 | //
456 | // return 0
457 | //}
458 | //
459 | ///*
460 | // * Destroy a document object.
461 | // */
462 | //
463 | //YAML_DECLARE(void)
464 | //yaml_document_delete(document *yaml_document_t)
465 | //{
466 | // struct {
467 | // error yaml_error_type_t
468 | // } context
469 | // tag_directive *yaml_tag_directive_t
470 | //
471 | // context.error = YAML_NO_ERROR // Eliminate a compiler warning.
472 | //
473 | // assert(document) // Non-NULL document object is expected.
474 | //
475 | // while (!STACK_EMPTY(&context, document.nodes)) {
476 | // node yaml_node_t = POP(&context, document.nodes)
477 | // yaml_free(node.tag)
478 | // switch (node.type) {
479 | // case YAML_SCALAR_NODE:
480 | // yaml_free(node.data.scalar.value)
481 | // break
482 | // case YAML_SEQUENCE_NODE:
483 | // STACK_DEL(&context, node.data.sequence.items)
484 | // break
485 | // case YAML_MAPPING_NODE:
486 | // STACK_DEL(&context, node.data.mapping.pairs)
487 | // break
488 | // default:
489 | // assert(0) // Should not happen.
490 | // }
491 | // }
492 | // STACK_DEL(&context, document.nodes)
493 | //
494 | // yaml_free(document.version_directive)
495 | // for (tag_directive = document.tag_directives.start
496 | // tag_directive != document.tag_directives.end
497 | // tag_directive++) {
498 | // yaml_free(tag_directive.handle)
499 | // yaml_free(tag_directive.prefix)
500 | // }
501 | // yaml_free(document.tag_directives.start)
502 | //
503 | // memset(document, 0, sizeof(yaml_document_t))
504 | //}
505 | //
506 | ///**
507 | // * Get a document node.
508 | // */
509 | //
510 | //YAML_DECLARE(yaml_node_t *)
511 | //yaml_document_get_node(document *yaml_document_t, index int)
512 | //{
513 | // assert(document) // Non-NULL document object is expected.
514 | //
515 | // if (index > 0 && document.nodes.start + index <= document.nodes.top) {
516 | // return document.nodes.start + index - 1
517 | // }
518 | // return NULL
519 | //}
520 | //
521 | ///**
522 | // * Get the root object.
523 | // */
524 | //
525 | //YAML_DECLARE(yaml_node_t *)
526 | //yaml_document_get_root_node(document *yaml_document_t)
527 | //{
528 | // assert(document) // Non-NULL document object is expected.
529 | //
530 | // if (document.nodes.top != document.nodes.start) {
531 | // return document.nodes.start
532 | // }
533 | // return NULL
534 | //}
535 | //
536 | ///*
537 | // * Add a scalar node to a document.
538 | // */
539 | //
540 | //YAML_DECLARE(int)
541 | //yaml_document_add_scalar(document *yaml_document_t,
542 | // tag *yaml_char_t, value *yaml_char_t, length int,
543 | // style yaml_scalar_style_t)
544 | //{
545 | // struct {
546 | // error yaml_error_type_t
547 | // } context
548 | // mark yaml_mark_t = { 0, 0, 0 }
549 | // tag_copy *yaml_char_t = NULL
550 | // value_copy *yaml_char_t = NULL
551 | // node yaml_node_t
552 | //
553 | // assert(document) // Non-NULL document object is expected.
554 | // assert(value) // Non-NULL value is expected.
555 | //
556 | // if (!tag) {
557 | // tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG
558 | // }
559 | //
560 | // if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
561 | // tag_copy = yaml_strdup(tag)
562 | // if (!tag_copy) goto error
563 | //
564 | // if (length < 0) {
565 | // length = strlen((char *)value)
566 | // }
567 | //
568 | // if (!yaml_check_utf8(value, length)) goto error
569 | // value_copy = yaml_malloc(length+1)
570 | // if (!value_copy) goto error
571 | // memcpy(value_copy, value, length)
572 | // value_copy[length] = '\0'
573 | //
574 | // SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)
575 | // if (!PUSH(&context, document.nodes, node)) goto error
576 | //
577 | // return document.nodes.top - document.nodes.start
578 | //
579 | //error:
580 | // yaml_free(tag_copy)
581 | // yaml_free(value_copy)
582 | //
583 | // return 0
584 | //}
585 | //
586 | ///*
587 | // * Add a sequence node to a document.
588 | // */
589 | //
590 | //YAML_DECLARE(int)
591 | //yaml_document_add_sequence(document *yaml_document_t,
592 | // tag *yaml_char_t, style yaml_sequence_style_t)
593 | //{
594 | // struct {
595 | // error yaml_error_type_t
596 | // } context
597 | // mark yaml_mark_t = { 0, 0, 0 }
598 | // tag_copy *yaml_char_t = NULL
599 | // struct {
600 | // start *yaml_node_item_t
601 | // end *yaml_node_item_t
602 | // top *yaml_node_item_t
603 | // } items = { NULL, NULL, NULL }
604 | // node yaml_node_t
605 | //
606 | // assert(document) // Non-NULL document object is expected.
607 | //
608 | // if (!tag) {
609 | // tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG
610 | // }
611 | //
612 | // if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
613 | // tag_copy = yaml_strdup(tag)
614 | // if (!tag_copy) goto error
615 | //
616 | // if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error
617 | //
618 | // SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
619 | // style, mark, mark)
620 | // if (!PUSH(&context, document.nodes, node)) goto error
621 | //
622 | // return document.nodes.top - document.nodes.start
623 | //
624 | //error:
625 | // STACK_DEL(&context, items)
626 | // yaml_free(tag_copy)
627 | //
628 | // return 0
629 | //}
630 | //
631 | ///*
632 | // * Add a mapping node to a document.
633 | // */
634 | //
635 | //YAML_DECLARE(int)
636 | //yaml_document_add_mapping(document *yaml_document_t,
637 | // tag *yaml_char_t, style yaml_mapping_style_t)
638 | //{
639 | // struct {
640 | // error yaml_error_type_t
641 | // } context
642 | // mark yaml_mark_t = { 0, 0, 0 }
643 | // tag_copy *yaml_char_t = NULL
644 | // struct {
645 | // start *yaml_node_pair_t
646 | // end *yaml_node_pair_t
647 | // top *yaml_node_pair_t
648 | // } pairs = { NULL, NULL, NULL }
649 | // node yaml_node_t
650 | //
651 | // assert(document) // Non-NULL document object is expected.
652 | //
653 | // if (!tag) {
654 | // tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG
655 | // }
656 | //
657 | // if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error
658 | // tag_copy = yaml_strdup(tag)
659 | // if (!tag_copy) goto error
660 | //
661 | // if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error
662 | //
663 | // MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
664 | // style, mark, mark)
665 | // if (!PUSH(&context, document.nodes, node)) goto error
666 | //
667 | // return document.nodes.top - document.nodes.start
668 | //
669 | //error:
670 | // STACK_DEL(&context, pairs)
671 | // yaml_free(tag_copy)
672 | //
673 | // return 0
674 | //}
675 | //
676 | ///*
677 | // * Append an item to a sequence node.
678 | // */
679 | //
680 | //YAML_DECLARE(int)
681 | //yaml_document_append_sequence_item(document *yaml_document_t,
682 | // sequence int, item int)
683 | //{
684 | // struct {
685 | // error yaml_error_type_t
686 | // } context
687 | //
688 | // assert(document) // Non-NULL document is required.
689 | // assert(sequence > 0
690 | // && document.nodes.start + sequence <= document.nodes.top)
691 | // // Valid sequence id is required.
692 | // assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)
693 | // // A sequence node is required.
694 | // assert(item > 0 && document.nodes.start + item <= document.nodes.top)
695 | // // Valid item id is required.
696 | //
697 | // if (!PUSH(&context,
698 | // document.nodes.start[sequence-1].data.sequence.items, item))
699 | // return 0
700 | //
701 | // return 1
702 | //}
703 | //
704 | ///*
705 | // * Append a pair of a key and a value to a mapping node.
706 | // */
707 | //
708 | //YAML_DECLARE(int)
709 | //yaml_document_append_mapping_pair(document *yaml_document_t,
710 | // mapping int, key int, value int)
711 | //{
712 | // struct {
713 | // error yaml_error_type_t
714 | // } context
715 | //
716 | // pair yaml_node_pair_t
717 | //
718 | // assert(document) // Non-NULL document is required.
719 | // assert(mapping > 0
720 | // && document.nodes.start + mapping <= document.nodes.top)
721 | // // Valid mapping id is required.
722 | // assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)
723 | // // A mapping node is required.
724 | // assert(key > 0 && document.nodes.start + key <= document.nodes.top)
725 | // // Valid key id is required.
726 | // assert(value > 0 && document.nodes.start + value <= document.nodes.top)
727 | // // Valid value id is required.
728 | //
729 | // pair.key = key
730 | // pair.value = value
731 | //
732 | // if (!PUSH(&context,
733 | // document.nodes.start[mapping-1].data.mapping.pairs, pair))
734 | // return 0
735 | //
736 | // return 1
737 | //}
738 | //
739 | //
740 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/yamlh.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | )
7 |
8 | // The version directive data.
9 | type yaml_version_directive_t struct {
10 | major int8 // The major version number.
11 | minor int8 // The minor version number.
12 | }
13 |
14 | // The tag directive data.
15 | type yaml_tag_directive_t struct {
16 | handle []byte // The tag handle.
17 | prefix []byte // The tag prefix.
18 | }
19 |
20 | type yaml_encoding_t int
21 |
22 | // The stream encoding.
23 | const (
24 | // Let the parser choose the encoding.
25 | yaml_ANY_ENCODING yaml_encoding_t = iota
26 |
27 | yaml_UTF8_ENCODING // The default UTF-8 encoding.
28 | yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
29 | yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
30 | )
31 |
32 | type yaml_break_t int
33 |
34 | // Line break types.
35 | const (
36 | // Let the parser choose the break type.
37 | yaml_ANY_BREAK yaml_break_t = iota
38 |
39 | yaml_CR_BREAK // Use CR for line breaks (Mac style).
40 | yaml_LN_BREAK // Use LN for line breaks (Unix style).
41 | yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
42 | )
43 |
44 | type yaml_error_type_t int
45 |
46 | // Many bad things could happen with the parser and emitter.
47 | const (
48 | // No error is produced.
49 | yaml_NO_ERROR yaml_error_type_t = iota
50 |
51 | yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory.
52 | yaml_READER_ERROR // Cannot read or decode the input stream.
53 | yaml_SCANNER_ERROR // Cannot scan the input stream.
54 | yaml_PARSER_ERROR // Cannot parse the input stream.
55 | yaml_COMPOSER_ERROR // Cannot compose a YAML document.
56 | yaml_WRITER_ERROR // Cannot write to the output stream.
57 | yaml_EMITTER_ERROR // Cannot emit a YAML stream.
58 | )
59 |
60 | // The pointer position.
61 | type yaml_mark_t struct {
62 | index int // The position index.
63 | line int // The position line.
64 | column int // The position column.
65 | }
66 |
67 | // Node Styles
68 |
69 | type yaml_style_t int8
70 |
71 | type yaml_scalar_style_t yaml_style_t
72 |
73 | // Scalar styles.
74 | const (
75 | // Let the emitter choose the style.
76 | yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
77 |
78 | yaml_PLAIN_SCALAR_STYLE // The plain scalar style.
79 | yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
80 | yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
81 | yaml_LITERAL_SCALAR_STYLE // The literal scalar style.
82 | yaml_FOLDED_SCALAR_STYLE // The folded scalar style.
83 | )
84 |
85 | type yaml_sequence_style_t yaml_style_t
86 |
87 | // Sequence styles.
88 | const (
89 | // Let the emitter choose the style.
90 | yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
91 |
92 | yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
93 | yaml_FLOW_SEQUENCE_STYLE // The flow sequence style.
94 | )
95 |
96 | type yaml_mapping_style_t yaml_style_t
97 |
98 | // Mapping styles.
99 | const (
100 | // Let the emitter choose the style.
101 | yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
102 |
103 | yaml_BLOCK_MAPPING_STYLE // The block mapping style.
104 | yaml_FLOW_MAPPING_STYLE // The flow mapping style.
105 | )
106 |
107 | // Tokens
108 |
109 | type yaml_token_type_t int
110 |
111 | // Token types.
112 | const (
113 | // An empty token.
114 | yaml_NO_TOKEN yaml_token_type_t = iota
115 |
116 | yaml_STREAM_START_TOKEN // A STREAM-START token.
117 | yaml_STREAM_END_TOKEN // A STREAM-END token.
118 |
119 | yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
120 | yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token.
121 | yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token.
122 | yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token.
123 |
124 | yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
125 | yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token.
126 | yaml_BLOCK_END_TOKEN // A BLOCK-END token.
127 |
128 | yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
129 | yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token.
130 | yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token.
131 | yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token.
132 |
133 | yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
134 | yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token.
135 | yaml_KEY_TOKEN // A KEY token.
136 | yaml_VALUE_TOKEN // A VALUE token.
137 |
138 | yaml_ALIAS_TOKEN // An ALIAS token.
139 | yaml_ANCHOR_TOKEN // An ANCHOR token.
140 | yaml_TAG_TOKEN // A TAG token.
141 | yaml_SCALAR_TOKEN // A SCALAR token.
142 | )
143 |
144 | func (tt yaml_token_type_t) String() string {
145 | switch tt {
146 | case yaml_NO_TOKEN:
147 | return "yaml_NO_TOKEN"
148 | case yaml_STREAM_START_TOKEN:
149 | return "yaml_STREAM_START_TOKEN"
150 | case yaml_STREAM_END_TOKEN:
151 | return "yaml_STREAM_END_TOKEN"
152 | case yaml_VERSION_DIRECTIVE_TOKEN:
153 | return "yaml_VERSION_DIRECTIVE_TOKEN"
154 | case yaml_TAG_DIRECTIVE_TOKEN:
155 | return "yaml_TAG_DIRECTIVE_TOKEN"
156 | case yaml_DOCUMENT_START_TOKEN:
157 | return "yaml_DOCUMENT_START_TOKEN"
158 | case yaml_DOCUMENT_END_TOKEN:
159 | return "yaml_DOCUMENT_END_TOKEN"
160 | case yaml_BLOCK_SEQUENCE_START_TOKEN:
161 | return "yaml_BLOCK_SEQUENCE_START_TOKEN"
162 | case yaml_BLOCK_MAPPING_START_TOKEN:
163 | return "yaml_BLOCK_MAPPING_START_TOKEN"
164 | case yaml_BLOCK_END_TOKEN:
165 | return "yaml_BLOCK_END_TOKEN"
166 | case yaml_FLOW_SEQUENCE_START_TOKEN:
167 | return "yaml_FLOW_SEQUENCE_START_TOKEN"
168 | case yaml_FLOW_SEQUENCE_END_TOKEN:
169 | return "yaml_FLOW_SEQUENCE_END_TOKEN"
170 | case yaml_FLOW_MAPPING_START_TOKEN:
171 | return "yaml_FLOW_MAPPING_START_TOKEN"
172 | case yaml_FLOW_MAPPING_END_TOKEN:
173 | return "yaml_FLOW_MAPPING_END_TOKEN"
174 | case yaml_BLOCK_ENTRY_TOKEN:
175 | return "yaml_BLOCK_ENTRY_TOKEN"
176 | case yaml_FLOW_ENTRY_TOKEN:
177 | return "yaml_FLOW_ENTRY_TOKEN"
178 | case yaml_KEY_TOKEN:
179 | return "yaml_KEY_TOKEN"
180 | case yaml_VALUE_TOKEN:
181 | return "yaml_VALUE_TOKEN"
182 | case yaml_ALIAS_TOKEN:
183 | return "yaml_ALIAS_TOKEN"
184 | case yaml_ANCHOR_TOKEN:
185 | return "yaml_ANCHOR_TOKEN"
186 | case yaml_TAG_TOKEN:
187 | return "yaml_TAG_TOKEN"
188 | case yaml_SCALAR_TOKEN:
189 | return "yaml_SCALAR_TOKEN"
190 | }
191 | return ""
192 | }
193 |
194 | // The token structure.
195 | type yaml_token_t struct {
196 | // The token type.
197 | typ yaml_token_type_t
198 |
199 | // The start/end of the token.
200 | start_mark, end_mark yaml_mark_t
201 |
202 | // The stream encoding (for yaml_STREAM_START_TOKEN).
203 | encoding yaml_encoding_t
204 |
205 | // The alias/anchor/scalar value or tag/tag directive handle
206 | // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
207 | value []byte
208 |
209 | // The tag suffix (for yaml_TAG_TOKEN).
210 | suffix []byte
211 |
212 | // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
213 | prefix []byte
214 |
215 | // The scalar style (for yaml_SCALAR_TOKEN).
216 | style yaml_scalar_style_t
217 |
218 | // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
219 | major, minor int8
220 | }
221 |
222 | // Events
223 |
224 | type yaml_event_type_t int8
225 |
226 | // Event types.
227 | const (
228 | // An empty event.
229 | yaml_NO_EVENT yaml_event_type_t = iota
230 |
231 | yaml_STREAM_START_EVENT // A STREAM-START event.
232 | yaml_STREAM_END_EVENT // A STREAM-END event.
233 | yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
234 | yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event.
235 | yaml_ALIAS_EVENT // An ALIAS event.
236 | yaml_SCALAR_EVENT // A SCALAR event.
237 | yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
238 | yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event.
239 | yaml_MAPPING_START_EVENT // A MAPPING-START event.
240 | yaml_MAPPING_END_EVENT // A MAPPING-END event.
241 | )
242 |
243 | var eventStrings = []string{
244 | yaml_NO_EVENT: "none",
245 | yaml_STREAM_START_EVENT: "stream start",
246 | yaml_STREAM_END_EVENT: "stream end",
247 | yaml_DOCUMENT_START_EVENT: "document start",
248 | yaml_DOCUMENT_END_EVENT: "document end",
249 | yaml_ALIAS_EVENT: "alias",
250 | yaml_SCALAR_EVENT: "scalar",
251 | yaml_SEQUENCE_START_EVENT: "sequence start",
252 | yaml_SEQUENCE_END_EVENT: "sequence end",
253 | yaml_MAPPING_START_EVENT: "mapping start",
254 | yaml_MAPPING_END_EVENT: "mapping end",
255 | }
256 |
257 | func (e yaml_event_type_t) String() string {
258 | if e < 0 || int(e) >= len(eventStrings) {
259 | return fmt.Sprintf("unknown event %d", e)
260 | }
261 | return eventStrings[e]
262 | }
263 |
264 | // The event structure.
265 | type yaml_event_t struct {
266 |
267 | // The event type.
268 | typ yaml_event_type_t
269 |
270 | // The start and end of the event.
271 | start_mark, end_mark yaml_mark_t
272 |
273 | // The document encoding (for yaml_STREAM_START_EVENT).
274 | encoding yaml_encoding_t
275 |
276 | // The version directive (for yaml_DOCUMENT_START_EVENT).
277 | version_directive *yaml_version_directive_t
278 |
279 | // The list of tag directives (for yaml_DOCUMENT_START_EVENT).
280 | tag_directives []yaml_tag_directive_t
281 |
282 | // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
283 | anchor []byte
284 |
285 | // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
286 | tag []byte
287 |
288 | // The scalar value (for yaml_SCALAR_EVENT).
289 | value []byte
290 |
291 | // Is the document start/end indicator implicit, or the tag optional?
292 | // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
293 | implicit bool
294 |
295 | // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
296 | quoted_implicit bool
297 |
298 | // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
299 | style yaml_style_t
300 | }
301 |
302 | func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) }
303 | func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
304 | func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) }
305 |
306 | // Nodes
307 |
308 | const (
309 | yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null.
310 | yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false.
311 | yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values.
312 | yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values.
313 | yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values.
314 | yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
315 |
316 | yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
317 | yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
318 |
319 | // Not in original libyaml.
320 | yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
321 | yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
322 |
323 | yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
324 | yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
325 | yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
326 | )
327 |
328 | type yaml_node_type_t int
329 |
330 | // Node types.
331 | const (
332 | // An empty node.
333 | yaml_NO_NODE yaml_node_type_t = iota
334 |
335 | yaml_SCALAR_NODE // A scalar node.
336 | yaml_SEQUENCE_NODE // A sequence node.
337 | yaml_MAPPING_NODE // A mapping node.
338 | )
339 |
340 | // An element of a sequence node.
341 | type yaml_node_item_t int
342 |
343 | // An element of a mapping node.
344 | type yaml_node_pair_t struct {
345 | key int // The key of the element.
346 | value int // The value of the element.
347 | }
348 |
349 | // The node structure.
350 | type yaml_node_t struct {
351 | typ yaml_node_type_t // The node type.
352 | tag []byte // The node tag.
353 |
354 | // The node data.
355 |
356 | // The scalar parameters (for yaml_SCALAR_NODE).
357 | scalar struct {
358 | value []byte // The scalar value.
359 | length int // The length of the scalar value.
360 | style yaml_scalar_style_t // The scalar style.
361 | }
362 |
363 | // The sequence parameters (for YAML_SEQUENCE_NODE).
364 | sequence struct {
365 | items_data []yaml_node_item_t // The stack of sequence items.
366 | style yaml_sequence_style_t // The sequence style.
367 | }
368 |
369 | // The mapping parameters (for yaml_MAPPING_NODE).
370 | mapping struct {
371 | pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value).
372 | pairs_start *yaml_node_pair_t // The beginning of the stack.
373 | pairs_end *yaml_node_pair_t // The end of the stack.
374 | pairs_top *yaml_node_pair_t // The top of the stack.
375 | style yaml_mapping_style_t // The mapping style.
376 | }
377 |
378 | start_mark yaml_mark_t // The beginning of the node.
379 | end_mark yaml_mark_t // The end of the node.
380 |
381 | }
382 |
383 | // The document structure.
384 | type yaml_document_t struct {
385 |
386 | // The document nodes.
387 | nodes []yaml_node_t
388 |
389 | // The version directive.
390 | version_directive *yaml_version_directive_t
391 |
392 | // The list of tag directives.
393 | tag_directives_data []yaml_tag_directive_t
394 | tag_directives_start int // The beginning of the tag directives list.
395 | tag_directives_end int // The end of the tag directives list.
396 |
397 | start_implicit int // Is the document start indicator implicit?
398 | end_implicit int // Is the document end indicator implicit?
399 |
400 | // The start/end of the document.
401 | start_mark, end_mark yaml_mark_t
402 | }
403 |
404 | // The prototype of a read handler.
405 | //
406 | // The read handler is called when the parser needs to read more bytes from the
407 | // source. The handler should write not more than size bytes to the buffer.
408 | // The number of written bytes should be set to the size_read variable.
409 | //
410 | // [in,out] data A pointer to an application data specified by
411 | // yaml_parser_set_input().
412 | // [out] buffer The buffer to write the data from the source.
413 | // [in] size The size of the buffer.
414 | // [out] size_read The actual number of bytes read from the source.
415 | //
416 | // On success, the handler should return 1. If the handler failed,
417 | // the returned value should be 0. On EOF, the handler should set the
418 | // size_read to 0 and return 1.
419 | type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
420 |
421 | // This structure holds information about a potential simple key.
422 | type yaml_simple_key_t struct {
423 | possible bool // Is a simple key possible?
424 | required bool // Is a simple key required?
425 | token_number int // The number of the token.
426 | mark yaml_mark_t // The position mark.
427 | }
428 |
429 | // The states of the parser.
430 | type yaml_parser_state_t int
431 |
432 | const (
433 | yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
434 |
435 | yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document.
436 | yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START.
437 | yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document.
438 | yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END.
439 | yaml_PARSE_BLOCK_NODE_STATE // Expect a block node.
440 | yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
441 | yaml_PARSE_FLOW_NODE_STATE // Expect a flow node.
442 | yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence.
443 | yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence.
444 | yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence.
445 | yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
446 | yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key.
447 | yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value.
448 | yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence.
449 | yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence.
450 | yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping.
451 | yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
452 | yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry.
453 | yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
454 | yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
455 | yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
456 | yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping.
457 | yaml_PARSE_END_STATE // Expect nothing.
458 | )
459 |
460 | func (ps yaml_parser_state_t) String() string {
461 | switch ps {
462 | case yaml_PARSE_STREAM_START_STATE:
463 | return "yaml_PARSE_STREAM_START_STATE"
464 | case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
465 | return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
466 | case yaml_PARSE_DOCUMENT_START_STATE:
467 | return "yaml_PARSE_DOCUMENT_START_STATE"
468 | case yaml_PARSE_DOCUMENT_CONTENT_STATE:
469 | return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
470 | case yaml_PARSE_DOCUMENT_END_STATE:
471 | return "yaml_PARSE_DOCUMENT_END_STATE"
472 | case yaml_PARSE_BLOCK_NODE_STATE:
473 | return "yaml_PARSE_BLOCK_NODE_STATE"
474 | case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
475 | return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
476 | case yaml_PARSE_FLOW_NODE_STATE:
477 | return "yaml_PARSE_FLOW_NODE_STATE"
478 | case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
479 | return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
480 | case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
481 | return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
482 | case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
483 | return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
484 | case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
485 | return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
486 | case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
487 | return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
488 | case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
489 | return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
490 | case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
491 | return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
492 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
493 | return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
494 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
495 | return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
496 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
497 | return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
498 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
499 | return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
500 | case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
501 | return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
502 | case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
503 | return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
504 | case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
505 | return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
506 | case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
507 | return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
508 | case yaml_PARSE_END_STATE:
509 | return "yaml_PARSE_END_STATE"
510 | }
511 | return ""
512 | }
513 |
514 | // This structure holds aliases data.
515 | type yaml_alias_data_t struct {
516 | anchor []byte // The anchor.
517 | index int // The node id.
518 | mark yaml_mark_t // The anchor mark.
519 | }
520 |
521 | // The parser structure.
522 | //
523 | // All members are internal. Manage the structure using the
524 | // yaml_parser_ family of functions.
525 | type yaml_parser_t struct {
526 |
527 | // Error handling
528 |
529 | error yaml_error_type_t // Error type.
530 |
531 | problem string // Error description.
532 |
533 | // The byte about which the problem occurred.
534 | problem_offset int
535 | problem_value int
536 | problem_mark yaml_mark_t
537 |
538 | // The error context.
539 | context string
540 | context_mark yaml_mark_t
541 |
542 | // Reader stuff
543 |
544 | read_handler yaml_read_handler_t // Read handler.
545 |
546 | input_reader io.Reader // File input data.
547 | input []byte // String input data.
548 | input_pos int
549 |
550 | eof bool // EOF flag
551 |
552 | buffer []byte // The working buffer.
553 | buffer_pos int // The current position of the buffer.
554 |
555 | unread int // The number of unread characters in the buffer.
556 |
557 | raw_buffer []byte // The raw buffer.
558 | raw_buffer_pos int // The current position of the buffer.
559 |
560 | encoding yaml_encoding_t // The input encoding.
561 |
562 | offset int // The offset of the current position (in bytes).
563 | mark yaml_mark_t // The mark of the current position.
564 |
565 | // Scanner stuff
566 |
567 | stream_start_produced bool // Have we started to scan the input stream?
568 | stream_end_produced bool // Have we reached the end of the input stream?
569 |
570 | flow_level int // The number of unclosed '[' and '{' indicators.
571 |
572 | tokens []yaml_token_t // The tokens queue.
573 | tokens_head int // The head of the tokens queue.
574 | tokens_parsed int // The number of tokens fetched from the queue.
575 | token_available bool // Does the tokens queue contain a token ready for dequeueing.
576 |
577 | indent int // The current indentation level.
578 | indents []int // The indentation levels stack.
579 |
580 | simple_key_allowed bool // May a simple key occur at the current position?
581 | simple_keys []yaml_simple_key_t // The stack of simple keys.
582 | simple_keys_by_tok map[int]int // possible simple_key indexes indexed by token_number
583 |
584 | // Parser stuff
585 |
586 | state yaml_parser_state_t // The current parser state.
587 | states []yaml_parser_state_t // The parser states stack.
588 | marks []yaml_mark_t // The stack of marks.
589 | tag_directives []yaml_tag_directive_t // The list of TAG directives.
590 |
591 | // Dumper stuff
592 |
593 | aliases []yaml_alias_data_t // The alias data.
594 |
595 | document *yaml_document_t // The currently parsed document.
596 | }
597 |
598 | // Emitter Definitions
599 |
600 | // The prototype of a write handler.
601 | //
602 | // The write handler is called when the emitter needs to flush the accumulated
603 | // characters to the output. The handler should write @a size bytes of the
604 | // @a buffer to the output.
605 | //
606 | // @param[in,out] data A pointer to an application data specified by
607 | // yaml_emitter_set_output().
608 | // @param[in] buffer The buffer with bytes to be written.
609 | // @param[in] size The size of the buffer.
610 | //
611 | // @returns On success, the handler should return @c 1. If the handler failed,
612 | // the returned value should be @c 0.
613 | //
614 | type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
615 |
616 | type yaml_emitter_state_t int
617 |
618 | // The emitter states.
619 | const (
620 | // Expect STREAM-START.
621 | yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
622 |
623 | yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
624 | yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
625 | yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
626 | yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
627 | yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
628 | yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
629 | yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
630 | yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
631 | yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
632 | yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
633 | yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
634 | yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
635 | yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
636 | yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
637 | yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
638 | yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
639 | yaml_EMIT_END_STATE // Expect nothing.
640 | )
641 |
642 | // The emitter structure.
643 | //
644 | // All members are internal. Manage the structure using the @c yaml_emitter_
645 | // family of functions.
646 | type yaml_emitter_t struct {
647 |
648 | // Error handling
649 |
650 | error yaml_error_type_t // Error type.
651 | problem string // Error description.
652 |
653 | // Writer stuff
654 |
655 | write_handler yaml_write_handler_t // Write handler.
656 |
657 | output_buffer *[]byte // String output data.
658 | output_writer io.Writer // File output data.
659 |
660 | buffer []byte // The working buffer.
661 | buffer_pos int // The current position of the buffer.
662 |
663 | raw_buffer []byte // The raw buffer.
664 | raw_buffer_pos int // The current position of the buffer.
665 |
666 | encoding yaml_encoding_t // The stream encoding.
667 |
668 | // Emitter stuff
669 |
670 | canonical bool // If the output is in the canonical style?
671 | best_indent int // The number of indentation spaces.
672 | best_width int // The preferred width of the output lines.
673 | unicode bool // Allow unescaped non-ASCII characters?
674 | line_break yaml_break_t // The preferred line break.
675 |
676 | state yaml_emitter_state_t // The current emitter state.
677 | states []yaml_emitter_state_t // The stack of states.
678 |
679 | events []yaml_event_t // The event queue.
680 | events_head int // The head of the event queue.
681 |
682 | indents []int // The stack of indentation levels.
683 |
684 | tag_directives []yaml_tag_directive_t // The list of tag directives.
685 |
686 | indent int // The current indentation level.
687 |
688 | flow_level int // The current flow level.
689 |
690 | root_context bool // Is it the document root context?
691 | sequence_context bool // Is it a sequence context?
692 | mapping_context bool // Is it a mapping context?
693 | simple_key_context bool // Is it a simple mapping key context?
694 |
695 | line int // The current line.
696 | column int // The current column.
697 | whitespace bool // If the last character was a whitespace?
698 | indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
699 | open_ended bool // If an explicit document end is required?
700 |
701 | // Anchor analysis.
702 | anchor_data struct {
703 | anchor []byte // The anchor value.
704 | alias bool // Is it an alias?
705 | }
706 |
707 | // Tag analysis.
708 | tag_data struct {
709 | handle []byte // The tag handle.
710 | suffix []byte // The tag suffix.
711 | }
712 |
713 | // Scalar analysis.
714 | scalar_data struct {
715 | value []byte // The scalar value.
716 | multiline bool // Does the scalar contain line breaks?
717 | flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
718 | block_plain_allowed bool // Can the scalar be expressed in the block plain style?
719 | single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
720 | block_allowed bool // Can the scalar be expressed in the literal or folded styles?
721 | style yaml_scalar_style_t // The output style.
722 | }
723 |
724 | // Dumper stuff
725 |
726 | opened bool // If the stream was already opened?
727 | closed bool // If the stream was already closed?
728 |
729 | // The information associated with the document nodes.
730 | anchors *struct {
731 | references int // The number of references.
732 | anchor int // The anchor id.
733 | serialized bool // If the node has been emitted?
734 | }
735 |
736 | last_anchor_id int // The last assigned anchor id.
737 |
738 | document *yaml_document_t // The currently emitted document.
739 | }
740 |
--------------------------------------------------------------------------------