···11+ Apache License
22+ Version 2.0, January 2004
33+ http://www.apache.org/licenses/
44+55+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
66+77+ 1. Definitions.
88+99+ "License" shall mean the terms and conditions for use, reproduction,
1010+ and distribution as defined by Sections 1 through 9 of this document.
1111+1212+ "Licensor" shall mean the copyright owner or entity authorized by
1313+ the copyright owner that is granting the License.
1414+1515+ "Legal Entity" shall mean the union of the acting entity and all
1616+ other entities that control, are controlled by, or are under common
1717+ control with that entity. For the purposes of this definition,
1818+ "control" means (i) the power, direct or indirect, to cause the
1919+ direction or management of such entity, whether by contract or
2020+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
2121+ outstanding shares, or (iii) beneficial ownership of such entity.
2222+2323+ "You" (or "Your") shall mean an individual or Legal Entity
2424+ exercising permissions granted by this License.
2525+2626+ "Source" form shall mean the preferred form for making modifications,
2727+ including but not limited to software source code, documentation
2828+ source, and configuration files.
2929+3030+ "Object" form shall mean any form resulting from mechanical
3131+ transformation or translation of a Source form, including but
3232+ not limited to compiled object code, generated documentation,
3333+ and conversions to other media types.
3434+3535+ "Work" shall mean the work of authorship, whether in Source or
3636+ Object form, made available under the License, as indicated by a
3737+ copyright notice that is included in or attached to the work
3838+ (an example is provided in the Appendix below).
3939+4040+ "Derivative Works" shall mean any work, whether in Source or Object
4141+ form, that is based on (or derived from) the Work and for which the
4242+ editorial revisions, annotations, elaborations, or other modifications
4343+ represent, as a whole, an original work of authorship. For the purposes
4444+ of this License, Derivative Works shall not include works that remain
4545+ separable from, or merely link (or bind by name) to the interfaces of,
4646+ the Work and Derivative Works thereof.
4747+4848+ "Contribution" shall mean any work of authorship, including
4949+ the original version of the Work and any modifications or additions
5050+ to that Work or Derivative Works thereof, that is intentionally
5151+ submitted to Licensor for inclusion in the Work by the copyright owner
5252+ or by an individual or Legal Entity authorized to submit on behalf of
5353+ the copyright owner. For the purposes of this definition, "submitted"
5454+ means any form of electronic, verbal, or written communication sent
5555+ to the Licensor or its representatives, including but not limited to
5656+ communication on electronic mailing lists, source code control systems,
5757+ and issue tracking systems that are managed by, or on behalf of, the
5858+ Licensor for the purpose of discussing and improving the Work, but
5959+ excluding communication that is conspicuously marked or otherwise
6060+ designated in writing by the copyright owner as "Not a Contribution."
6161+6262+ "Contributor" shall mean Licensor and any individual or Legal Entity
6363+ on behalf of whom a Contribution has been received by Licensor and
6464+ subsequently incorporated within the Work.
6565+6666+ 2. Grant of Copyright License. Subject to the terms and conditions of
6767+ this License, each Contributor hereby grants to You a perpetual,
6868+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
6969+ copyright license to reproduce, prepare Derivative Works of,
7070+ publicly display, publicly perform, sublicense, and distribute the
7171+ Work and such Derivative Works in Source or Object form.
7272+7373+ 3. Grant of Patent License. Subject to the terms and conditions of
7474+ this License, each Contributor hereby grants to You a perpetual,
7575+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
7676+ (except as stated in this section) patent license to make, have made,
7777+ use, offer to sell, sell, import, and otherwise transfer the Work,
7878+ where such license applies only to those patent claims licensable
7979+ by such Contributor that are necessarily infringed by their
8080+ Contribution(s) alone or by combination of their Contribution(s)
8181+ with the Work to which such Contribution(s) was submitted. If You
8282+ institute patent litigation against any entity (including a
8383+ cross-claim or counterclaim in a lawsuit) alleging that the Work
8484+ or a Contribution incorporated within the Work constitutes direct
8585+ or contributory patent infringement, then any patent licenses
8686+ granted to You under this License for that Work shall terminate
8787+ as of the date such litigation is filed.
8888+8989+ 4. Redistribution. You may reproduce and distribute copies of the
9090+ Work or Derivative Works thereof in any medium, with or without
9191+ modifications, and in Source or Object form, provided that You
9292+ meet the following conditions:
9393+9494+ (a) You must give any other recipients of the Work or
9595+ Derivative Works a copy of this License; and
9696+9797+ (b) You must cause any modified files to carry prominent notices
9898+ stating that You changed the files; and
9999+100100+ (c) You must retain, in the Source form of any Derivative Works
101101+ that You distribute, all copyright, patent, trademark, and
102102+ attribution notices from the Source form of the Work,
103103+ excluding those notices that do not pertain to any part of
104104+ the Derivative Works; and
105105+106106+ (d) If the Work includes a "NOTICE" text file as part of its
107107+ distribution, then any Derivative Works that You distribute must
108108+ include a readable copy of the attribution notices contained
109109+ within such NOTICE file, excluding those notices that do not
110110+ pertain to any part of the Derivative Works, in at least one
111111+ of the following places: within a NOTICE text file distributed
112112+ as part of the Derivative Works; within the Source form or
113113+ documentation, if provided along with the Derivative Works; or,
114114+ within a display generated by the Derivative Works, if and
115115+ wherever such third-party notices normally appear. The contents
116116+ of the NOTICE file are for informational purposes only and
117117+ do not modify the License. You may add Your own attribution
118118+ notices within Derivative Works that You distribute, alongside
119119+ or as an addendum to the NOTICE text from the Work, provided
120120+ that such additional attribution notices cannot be construed
121121+ as modifying the License.
122122+123123+ You may add Your own copyright statement to Your modifications and
124124+ may provide additional or different license terms and conditions
125125+ for use, reproduction, or distribution of Your modifications, or
126126+ for any such Derivative Works as a whole, provided Your use,
127127+ reproduction, and distribution of the Work otherwise complies with
128128+ the conditions stated in this License.
129129+130130+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131131+ any Contribution intentionally submitted for inclusion in the Work
132132+ by You to the Licensor shall be under the terms and conditions of
133133+ this License, without any additional terms or conditions.
134134+ Notwithstanding the above, nothing herein shall supersede or modify
135135+ the terms of any separate license agreement you may have executed
136136+ with Licensor regarding such Contributions.
137137+138138+ 6. Trademarks. This License does not grant permission to use the trade
139139+ names, trademarks, service marks, or product names of the Licensor,
140140+ except as required for reasonable and customary use in describing the
141141+ origin of the Work and reproducing the content of the NOTICE file.
142142+143143+ 7. Disclaimer of Warranty. Unless required by applicable law or
144144+ agreed to in writing, Licensor provides the Work (and each
145145+ Contributor provides its Contributions) on an "AS IS" BASIS,
146146+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147147+ implied, including, without limitation, any warranties or conditions
148148+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149149+ PARTICULAR PURPOSE. You are solely responsible for determining the
150150+ appropriateness of using or redistributing the Work and assume any
151151+ risks associated with Your exercise of permissions under this License.
152152+153153+ 8. Limitation of Liability. In no event and under no legal theory,
154154+ whether in tort (including negligence), contract, or otherwise,
155155+ unless required by applicable law (such as deliberate and grossly
156156+ negligent acts) or agreed to in writing, shall any Contributor be
157157+ liable to You for damages, including any direct, indirect, special,
158158+ incidental, or consequential damages of any character arising as a
159159+ result of this License or out of the use or inability to use the
160160+ Work (including but not limited to damages for loss of goodwill,
161161+ work stoppage, computer failure or malfunction, or any and all
162162+ other commercial damages or losses), even if such Contributor
163163+ has been advised of the possibility of such damages.
164164+165165+ 9. Accepting Warranty or Additional Liability. While redistributing
166166+ the Work or Derivative Works thereof, You may choose to offer,
167167+ and charge a fee for, acceptance of support, warranty, indemnity,
168168+ or other liability obligations and/or rights consistent with this
169169+ License. However, in accepting such obligations, You may act only
170170+ on Your own behalf and on Your sole responsibility, not on behalf
171171+ of any other Contributor, and only if You agree to indemnify,
172172+ defend, and hold each Contributor harmless for any liability
173173+ incurred by, or claims asserted against, such Contributor by reason
174174+ of your accepting any such warranty or additional liability.
175175+176176+ END OF TERMS AND CONDITIONS
177177+178178+ APPENDIX: How to apply the Apache License to your work.
179179+180180+ To apply the Apache License to your work, attach the following
181181+ boilerplate notice, with the fields enclosed by brackets "{}"
182182+ replaced with your own identifying information. (Don't include
183183+ the brackets!) The text should be enclosed in the appropriate
184184+ comment syntax for the file format. We also recommend that a
185185+ file or class name and description of purpose be included on the
186186+ same "printed page" as the copyright notice for easier
187187+ identification within third-party archives.
188188+189189+ Copyright {yyyy} {name of copyright owner}
190190+191191+ Licensed under the Apache License, Version 2.0 (the "License");
192192+ you may not use this file except in compliance with the License.
193193+ You may obtain a copy of the License at
194194+195195+ http://www.apache.org/licenses/LICENSE-2.0
196196+197197+ Unless required by applicable law or agreed to in writing, software
198198+ distributed under the License is distributed on an "AS IS" BASIS,
199199+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200200+ See the License for the specific language governing permissions and
201201+ limitations under the License.
+31
internal/third_party/yaml/LICENSE.libyaml
···11+The following files were ported to Go from C files of libyaml, and thus
22+are still covered by their original copyright and license:
33+44+ apic.go
55+ emitterc.go
66+ parserc.go
77+ readerc.go
88+ scannerc.go
99+ writerc.go
1010+ yamlh.go
1111+ yamlprivateh.go
1212+1313+Copyright (c) 2006 Kirill Simonov
1414+1515+Permission is hereby granted, free of charge, to any person obtaining a copy of
1616+this software and associated documentation files (the "Software"), to deal in
1717+the Software without restriction, including without limitation the rights to
1818+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1919+of the Software, and to permit persons to whom the Software is furnished to do
2020+so, subject to the following conditions:
2121+2222+The above copyright notice and this permission notice shall be included in all
2323+copies or substantial portions of the Software.
2424+2525+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2626+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2727+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2828+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2929+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3030+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3131+SOFTWARE.
+15
internal/third_party/yaml/METADATA
···11+name: "go-yaml"
22+description:
33+ "Heavily modified version of go-yaml files. Most of the original "
44+ "functionality is gone and replaced with CUE-specific code."
55+66+third_party {
77+ url {
88+ type: GIT
99+ value: "https://github.com/go-yaml/yaml"
1010+ }
1111+ version: "v2.2.1"
1212+ last_upgrade_date { year: 2018 month: 10 day: 24 }
1313+ license_type: NOTICE
1414+ local_modifications: "Replace Go-struct with CUE mapping."
1515+}
+13
internal/third_party/yaml/NOTICE
···11+Copyright 2011-2016 Canonical Ltd.
22+33+Licensed under the Apache License, Version 2.0 (the "License");
44+you may not use this file except in compliance with the License.
55+You may obtain a copy of the License at
66+77+ http://www.apache.org/licenses/LICENSE-2.0
88+99+Unless required by applicable law or agreed to in writing, software
1010+distributed under the License is distributed on an "AS IS" BASIS,
1111+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212+See the License for the specific language governing permissions and
1313+limitations under the License.
+133
internal/third_party/yaml/README.md
···11+# YAML support for the Go language
22+33+Introduction
44+------------
55+66+The yaml package enables Go programs to comfortably encode and decode YAML
77+values. It was developed within [Canonical](https://www.canonical.com) as
88+part of the [juju](https://juju.ubuntu.com) project, and is based on a
99+pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
1010+C library to parse and generate YAML data quickly and reliably.
1111+1212+Compatibility
1313+-------------
1414+1515+The yaml package supports most of YAML 1.1 and 1.2, including support for
1616+anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
1717+implemented, and base-60 floats from YAML 1.1 are purposefully not
1818+supported since they're a poor design and are gone in YAML 1.2.
1919+2020+Installation and usage
2121+----------------------
2222+2323+The import path for the package is *gopkg.in/yaml.v2*.
2424+2525+To install it, run:
2626+2727+ go get gopkg.in/yaml.v2
2828+2929+API documentation
3030+-----------------
3131+3232+If opened in a browser, the import path itself leads to the API documentation:
3333+3434+ * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
3535+3636+API stability
3737+-------------
3838+3939+The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
4040+4141+4242+License
4343+-------
4444+4545+The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
4646+4747+4848+Example
4949+-------
5050+5151+```Go
5252+package main
5353+5454+import (
5555+ "fmt"
5656+ "log"
5757+5858+ "gopkg.in/yaml.v2"
5959+)
6060+6161+var data = `
6262+a: Easy!
6363+b:
6464+ c: 2
6565+ d: [3, 4]
6666+`
6767+6868+// Note: struct fields must be public in order for unmarshal to
6969+// correctly populate the data.
7070+type T struct {
7171+ A string
7272+ B struct {
7373+ RenamedC int `yaml:"c"`
7474+ D []int `yaml:",flow"`
7575+ }
7676+}
7777+7878+func main() {
7979+ t := T{}
8080+8181+ err := yaml.Unmarshal([]byte(data), &t)
8282+ if err != nil {
8383+ log.Fatalf("error: %v", err)
8484+ }
8585+ fmt.Printf("--- t:\n%v\n\n", t)
8686+8787+ d, err := yaml.Marshal(&t)
8888+ if err != nil {
8989+ log.Fatalf("error: %v", err)
9090+ }
9191+ fmt.Printf("--- t dump:\n%s\n\n", string(d))
9292+9393+ m := make(map[interface{}]interface{})
9494+9595+ err = yaml.Unmarshal([]byte(data), &m)
9696+ if err != nil {
9797+ log.Fatalf("error: %v", err)
9898+ }
9999+ fmt.Printf("--- m:\n%v\n\n", m)
100100+101101+ d, err = yaml.Marshal(&m)
102102+ if err != nil {
103103+ log.Fatalf("error: %v", err)
104104+ }
105105+ fmt.Printf("--- m dump:\n%s\n\n", string(d))
106106+}
107107+```
108108+109109+This example will generate the following output:
110110+111111+```
112112+--- t:
113113+{Easy! {2 [3 4]}}
114114+115115+--- t dump:
116116+a: Easy!
117117+b:
118118+ c: 2
119119+ d: [3, 4]
120120+121121+122122+--- m:
123123+map[a:Easy! b:map[c:2 d:[3 4]]]
124124+125125+--- m dump:
126126+a: Easy!
127127+b:
128128+ c: 2
129129+ d:
130130+ - 3
131131+ - 4
132132+```
133133+
···11+package yaml_test
22+33+import (
44+ "fmt"
55+ "log"
66+77+ "gopkg.in/yaml.v2"
88+)
99+1010+// An example showing how to unmarshal embedded
1111+// structs from YAML.
1212+1313+type StructA struct {
1414+ A string `yaml:"a"`
1515+}
1616+1717+type StructB struct {
1818+ // Embedded structs are not treated as embedded in YAML by default. To do that,
1919+ // add the ",inline" annotation below
2020+ StructA `yaml:",inline"`
2121+ B string `yaml:"b"`
2222+}
2323+2424+var data = `
2525+a: a string from struct A
2626+b: a string from struct B
2727+`
2828+2929+func ExampleUnmarshal_embedded() {
3030+ var b StructB
3131+3232+ err := yaml.Unmarshal([]byte(data), &b)
3333+ if err != nil {
3434+ log.Fatalf("cannot unmarshal data: %v", err)
3535+ }
3636+ fmt.Println(b.A)
3737+ fmt.Println(b.B)
3838+ // Output:
3939+ // a string from struct A
4040+ // a string from struct B
4141+}
···11+package yaml
22+33+import (
44+ "io"
55+)
66+77+// Set the reader error and return 0.
88+func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {
99+ parser.error = yaml_READER_ERROR
1010+ parser.problem = problem
1111+ parser.problem_offset = offset
1212+ parser.problem_value = value
1313+ return false
1414+}
1515+1616+// Byte order marks.
1717+const (
1818+ bom_UTF8 = "\xef\xbb\xbf"
1919+ bom_UTF16LE = "\xff\xfe"
2020+ bom_UTF16BE = "\xfe\xff"
2121+)
2222+2323+// Determine the input stream encoding by checking the BOM symbol. If no BOM is
2424+// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
2525+func yaml_parser_determine_encoding(parser *yaml_parser_t) bool {
2626+ // Ensure that we had enough bytes in the raw buffer.
2727+ for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {
2828+ if !yaml_parser_update_raw_buffer(parser) {
2929+ return false
3030+ }
3131+ }
3232+3333+ // Determine the encoding.
3434+ buf := parser.raw_buffer
3535+ pos := parser.raw_buffer_pos
3636+ avail := len(buf) - pos
3737+ if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {
3838+ parser.encoding = yaml_UTF16LE_ENCODING
3939+ parser.raw_buffer_pos += 2
4040+ parser.offset += 2
4141+ } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {
4242+ parser.encoding = yaml_UTF16BE_ENCODING
4343+ parser.raw_buffer_pos += 2
4444+ parser.offset += 2
4545+ } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {
4646+ parser.encoding = yaml_UTF8_ENCODING
4747+ parser.raw_buffer_pos += 3
4848+ parser.offset += 3
4949+ } else {
5050+ parser.encoding = yaml_UTF8_ENCODING
5151+ }
5252+ return true
5353+}
5454+5555+// Update the raw buffer.
5656+func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {
5757+ size_read := 0
5858+5959+ // Return if the raw buffer is full.
6060+ if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {
6161+ return true
6262+ }
6363+6464+ // Return on EOF.
6565+ if parser.eof {
6666+ return true
6767+ }
6868+6969+ // Move the remaining bytes in the raw buffer to the beginning.
7070+ if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {
7171+ copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])
7272+ }
7373+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]
7474+ parser.raw_buffer_pos = 0
7575+7676+ // Call the read handler to fill the buffer.
7777+ size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])
7878+ parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]
7979+ if err == io.EOF {
8080+ parser.eof = true
8181+ } else if err != nil {
8282+ return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1)
8383+ }
8484+ return true
8585+}
8686+8787+// Ensure that the buffer contains at least `length` characters.
8888+// Return true on success, false on failure.
8989+//
9090+// The length is supposed to be significantly less that the buffer size.
9191+func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {
9292+ if parser.read_handler == nil {
9393+ panic("read handler must be set")
9494+ }
9595+9696+ // [Go] This function was changed to guarantee the requested length size at EOF.
9797+ // The fact we need to do this is pretty awful, but the description above implies
9898+ // for that to be the case, and there are tests
9999+100100+ // If the EOF flag is set and the raw buffer is empty, do nothing.
101101+ if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
102102+ // [Go] ACTUALLY! Read the documentation of this function above.
103103+ // This is just broken. To return true, we need to have the
104104+ // given length in the buffer. Not doing that means every single
105105+ // check that calls this function to make sure the buffer has a
106106+ // given length is Go) panicking; or C) accessing invalid memory.
107107+ //return true
108108+ }
109109+110110+ // Return if the buffer contains enough characters.
111111+ if parser.unread >= length {
112112+ return true
113113+ }
114114+115115+ // Determine the input encoding if it is not known yet.
116116+ if parser.encoding == yaml_ANY_ENCODING {
117117+ if !yaml_parser_determine_encoding(parser) {
118118+ return false
119119+ }
120120+ }
121121+122122+ // Move the unread characters to the beginning of the buffer.
123123+ buffer_len := len(parser.buffer)
124124+ if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {
125125+ copy(parser.buffer, parser.buffer[parser.buffer_pos:])
126126+ buffer_len -= parser.buffer_pos
127127+ parser.buffer_pos = 0
128128+ } else if parser.buffer_pos == buffer_len {
129129+ buffer_len = 0
130130+ parser.buffer_pos = 0
131131+ }
132132+133133+ // Open the whole buffer for writing, and cut it before returning.
134134+ parser.buffer = parser.buffer[:cap(parser.buffer)]
135135+136136+ // Fill the buffer until it has enough characters.
137137+ first := true
138138+ for parser.unread < length {
139139+140140+ // Fill the raw buffer if necessary.
141141+ if !first || parser.raw_buffer_pos == len(parser.raw_buffer) {
142142+ if !yaml_parser_update_raw_buffer(parser) {
143143+ parser.buffer = parser.buffer[:buffer_len]
144144+ return false
145145+ }
146146+ }
147147+ first = false
148148+149149+ // Decode the raw buffer.
150150+ inner:
151151+ for parser.raw_buffer_pos != len(parser.raw_buffer) {
152152+ var value rune
153153+ var width int
154154+155155+ raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos
156156+157157+ // Decode the next character.
158158+ switch parser.encoding {
159159+ case yaml_UTF8_ENCODING:
160160+ // Decode a UTF-8 character. Check RFC 3629
161161+ // (http://www.ietf.org/rfc/rfc3629.txt) for more details.
162162+ //
163163+ // The following table (taken from the RFC) is used for
164164+ // decoding.
165165+ //
166166+ // Char. number range | UTF-8 octet sequence
167167+ // (hexadecimal) | (binary)
168168+ // --------------------+------------------------------------
169169+ // 0000 0000-0000 007F | 0xxxxxxx
170170+ // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
171171+ // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
172172+ // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
173173+ //
174174+ // Additionally, the characters in the range 0xD800-0xDFFF
175175+ // are prohibited as they are reserved for use with UTF-16
176176+ // surrogate pairs.
177177+178178+ // Determine the length of the UTF-8 sequence.
179179+ octet := parser.raw_buffer[parser.raw_buffer_pos]
180180+ switch {
181181+ case octet&0x80 == 0x00:
182182+ width = 1
183183+ case octet&0xE0 == 0xC0:
184184+ width = 2
185185+ case octet&0xF0 == 0xE0:
186186+ width = 3
187187+ case octet&0xF8 == 0xF0:
188188+ width = 4
189189+ default:
190190+ // The leading octet is invalid.
191191+ return yaml_parser_set_reader_error(parser,
192192+ "invalid leading UTF-8 octet",
193193+ parser.offset, int(octet))
194194+ }
195195+196196+ // Check if the raw buffer contains an incomplete character.
197197+ if width > raw_unread {
198198+ if parser.eof {
199199+ return yaml_parser_set_reader_error(parser,
200200+ "incomplete UTF-8 octet sequence",
201201+ parser.offset, -1)
202202+ }
203203+ break inner
204204+ }
205205+206206+ // Decode the leading octet.
207207+ switch {
208208+ case octet&0x80 == 0x00:
209209+ value = rune(octet & 0x7F)
210210+ case octet&0xE0 == 0xC0:
211211+ value = rune(octet & 0x1F)
212212+ case octet&0xF0 == 0xE0:
213213+ value = rune(octet & 0x0F)
214214+ case octet&0xF8 == 0xF0:
215215+ value = rune(octet & 0x07)
216216+ default:
217217+ value = 0
218218+ }
219219+220220+ // Check and decode the trailing octets.
221221+ for k := 1; k < width; k++ {
222222+ octet = parser.raw_buffer[parser.raw_buffer_pos+k]
223223+224224+ // Check if the octet is valid.
225225+ if (octet & 0xC0) != 0x80 {
226226+ return yaml_parser_set_reader_error(parser,
227227+ "invalid trailing UTF-8 octet",
228228+ parser.offset+k, int(octet))
229229+ }
230230+231231+ // Decode the octet.
232232+ value = (value << 6) + rune(octet&0x3F)
233233+ }
234234+235235+ // Check the length of the sequence against the value.
236236+ switch {
237237+ case width == 1:
238238+ case width == 2 && value >= 0x80:
239239+ case width == 3 && value >= 0x800:
240240+ case width == 4 && value >= 0x10000:
241241+ default:
242242+ return yaml_parser_set_reader_error(parser,
243243+ "invalid length of a UTF-8 sequence",
244244+ parser.offset, -1)
245245+ }
246246+247247+ // Check the range of the value.
248248+ if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
249249+ return yaml_parser_set_reader_error(parser,
250250+ "invalid Unicode character",
251251+ parser.offset, int(value))
252252+ }
253253+254254+ case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:
255255+ var low, high int
256256+ if parser.encoding == yaml_UTF16LE_ENCODING {
257257+ low, high = 0, 1
258258+ } else {
259259+ low, high = 1, 0
260260+ }
261261+262262+ // The UTF-16 encoding is not as simple as one might
263263+ // naively think. Check RFC 2781
264264+ // (http://www.ietf.org/rfc/rfc2781.txt).
265265+ //
266266+ // Normally, two subsequent bytes describe a Unicode
267267+ // character. However a special technique (called a
268268+ // surrogate pair) is used for specifying character
269269+ // values larger than 0xFFFF.
270270+ //
271271+ // A surrogate pair consists of two pseudo-characters:
272272+ // high surrogate area (0xD800-0xDBFF)
273273+ // low surrogate area (0xDC00-0xDFFF)
274274+ //
275275+ // The following formulas are used for decoding
276276+ // and encoding characters using surrogate pairs:
277277+ //
278278+ // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
279279+ // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
280280+ // W1 = 110110yyyyyyyyyy
281281+ // W2 = 110111xxxxxxxxxx
282282+ //
283283+ // where U is the character value, W1 is the high surrogate
284284+ // area, W2 is the low surrogate area.
285285+286286+ // Check for incomplete UTF-16 character.
287287+ if raw_unread < 2 {
288288+ if parser.eof {
289289+ return yaml_parser_set_reader_error(parser,
290290+ "incomplete UTF-16 character",
291291+ parser.offset, -1)
292292+ }
293293+ break inner
294294+ }
295295+296296+ // Get the character.
297297+ value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +
298298+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)
299299+300300+ // Check for unexpected low surrogate area.
301301+ if value&0xFC00 == 0xDC00 {
302302+ return yaml_parser_set_reader_error(parser,
303303+ "unexpected low surrogate area",
304304+ parser.offset, int(value))
305305+ }
306306+307307+ // Check for a high surrogate area.
308308+ if value&0xFC00 == 0xD800 {
309309+ width = 4
310310+311311+ // Check for incomplete surrogate pair.
312312+ if raw_unread < 4 {
313313+ if parser.eof {
314314+ return yaml_parser_set_reader_error(parser,
315315+ "incomplete UTF-16 surrogate pair",
316316+ parser.offset, -1)
317317+ }
318318+ break inner
319319+ }
320320+321321+ // Get the next character.
322322+ value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +
323323+ (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)
324324+325325+ // Check for a low surrogate area.
326326+ if value2&0xFC00 != 0xDC00 {
327327+ return yaml_parser_set_reader_error(parser,
328328+ "expected low surrogate area",
329329+ parser.offset+2, int(value2))
330330+ }
331331+332332+ // Generate the value of the surrogate pair.
333333+ value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)
334334+ } else {
335335+ width = 2
336336+ }
337337+338338+ default:
339339+ panic("impossible")
340340+ }
341341+342342+ // Check if the character is in the allowed range:
343343+ // #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
344344+ // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
345345+ // | [#x10000-#x10FFFF] (32 bit)
346346+ switch {
347347+ case value == 0x09:
348348+ case value == 0x0A:
349349+ case value == 0x0D:
350350+ case value >= 0x20 && value <= 0x7E:
351351+ case value == 0x85:
352352+ case value >= 0xA0 && value <= 0xD7FF:
353353+ case value >= 0xE000 && value <= 0xFFFD:
354354+ case value >= 0x10000 && value <= 0x10FFFF:
355355+ default:
356356+ return yaml_parser_set_reader_error(parser,
357357+ "control characters are not allowed",
358358+ parser.offset, int(value))
359359+ }
360360+361361+ // Move the raw pointers.
362362+ parser.raw_buffer_pos += width
363363+ parser.offset += width
364364+365365+ // Finally put the character into the buffer.
366366+ if value <= 0x7F {
367367+ // 0000 0000-0000 007F . 0xxxxxxx
368368+ parser.buffer[buffer_len+0] = byte(value)
369369+ buffer_len += 1
370370+ } else if value <= 0x7FF {
371371+ // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx
372372+ parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))
373373+ parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))
374374+ buffer_len += 2
375375+ } else if value <= 0xFFFF {
376376+ // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx
377377+ parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))
378378+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))
379379+ parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))
380380+ buffer_len += 3
381381+ } else {
382382+ // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
383383+ parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))
384384+ parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))
385385+ parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))
386386+ parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))
387387+ buffer_len += 4
388388+ }
389389+390390+ parser.unread++
391391+ }
392392+393393+ // On EOF, put NUL into the buffer and return.
394394+ if parser.eof {
395395+ parser.buffer[buffer_len] = 0
396396+ buffer_len++
397397+ parser.unread++
398398+ break
399399+ }
400400+ }
401401+ // [Go] Read the documentation of this function above. To return true,
402402+ // we need to have the given length in the buffer. Not doing that means
403403+ // every single check that calls this function to make sure the buffer
404404+ // has a given length is Go) panicking; or C) accessing invalid memory.
405405+ // This happens here due to the EOF above breaking early.
406406+ for buffer_len < length {
407407+ parser.buffer[buffer_len] = 0
408408+ buffer_len++
409409+ }
410410+ parser.buffer = parser.buffer[:buffer_len]
411411+ return true
412412+}
+258
internal/third_party/yaml/resolve.go
···11+package yaml
22+33+import (
44+ "encoding/base64"
55+ "math"
66+ "regexp"
77+ "strconv"
88+ "strings"
99+ "time"
1010+)
1111+1212+type resolveMapItem struct {
1313+ value interface{}
1414+ tag string
1515+}
1616+1717+var resolveTable = make([]byte, 256)
1818+var resolveMap = make(map[string]resolveMapItem)
1919+2020+func init() {
2121+ t := resolveTable
2222+ t[int('+')] = 'S' // Sign
2323+ t[int('-')] = 'S'
2424+ for _, c := range "0123456789" {
2525+ t[int(c)] = 'D' // Digit
2626+ }
2727+ for _, c := range "yYnNtTfFoO~" {
2828+ t[int(c)] = 'M' // In map
2929+ }
3030+ t[int('.')] = '.' // Float (potentially in map)
3131+3232+ var resolveMapList = []struct {
3333+ v interface{}
3434+ tag string
3535+ l []string
3636+ }{
3737+ {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
3838+ {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
3939+ {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
4040+ {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
4141+ {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
4242+ {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
4343+ {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
4444+ {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
4545+ {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
4646+ {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
4747+ {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
4848+ {"<<", yaml_MERGE_TAG, []string{"<<"}},
4949+ }
5050+5151+ m := resolveMap
5252+ for _, item := range resolveMapList {
5353+ for _, s := range item.l {
5454+ m[s] = resolveMapItem{item.v, item.tag}
5555+ }
5656+ }
5757+}
5858+5959+const longTagPrefix = "tag:yaml.org,2002:"
6060+6161+func shortTag(tag string) string {
6262+ // TODO This can easily be made faster and produce less garbage.
6363+ if strings.HasPrefix(tag, longTagPrefix) {
6464+ return "!!" + tag[len(longTagPrefix):]
6565+ }
6666+ return tag
6767+}
6868+6969+func longTag(tag string) string {
7070+ if strings.HasPrefix(tag, "!!") {
7171+ return longTagPrefix + tag[2:]
7272+ }
7373+ return tag
7474+}
7575+7676+func resolvableTag(tag string) bool {
7777+ switch tag {
7878+ case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
7979+ return true
8080+ }
8181+ return false
8282+}
8383+8484+var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`)
8585+8686+func resolve(tag string, in string) (rtag string, out interface{}) {
8787+ if !resolvableTag(tag) {
8888+ return tag, in
8989+ }
9090+9191+ defer func() {
9292+ switch tag {
9393+ case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
9494+ return
9595+ case yaml_FLOAT_TAG:
9696+ if rtag == yaml_INT_TAG {
9797+ switch v := out.(type) {
9898+ case int64:
9999+ rtag = yaml_FLOAT_TAG
100100+ out = float64(v)
101101+ return
102102+ case int:
103103+ rtag = yaml_FLOAT_TAG
104104+ out = float64(v)
105105+ return
106106+ }
107107+ }
108108+ }
109109+ failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
110110+ }()
111111+112112+ // Any data is accepted as a !!str or !!binary.
113113+ // Otherwise, the prefix is enough of a hint about what it might be.
114114+ hint := byte('N')
115115+ if in != "" {
116116+ hint = resolveTable[in[0]]
117117+ }
118118+ if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
119119+ // Handle things we can lookup in a map.
120120+ if item, ok := resolveMap[in]; ok {
121121+ return item.tag, item.value
122122+ }
123123+124124+ // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
125125+ // are purposefully unsupported here. They're still quoted on
126126+ // the way out for compatibility with other parser, though.
127127+128128+ switch hint {
129129+ case 'M':
130130+ // We've already checked the map above.
131131+132132+ case '.':
133133+ // Not in the map, so maybe a normal float.
134134+ floatv, err := strconv.ParseFloat(in, 64)
135135+ if err == nil {
136136+ return yaml_FLOAT_TAG, floatv
137137+ }
138138+139139+ case 'D', 'S':
140140+ // Int, float, or timestamp.
141141+ // Only try values as a timestamp if the value is unquoted or there's an explicit
142142+ // !!timestamp tag.
143143+ if tag == "" || tag == yaml_TIMESTAMP_TAG {
144144+ t, ok := parseTimestamp(in)
145145+ if ok {
146146+ return yaml_TIMESTAMP_TAG, t
147147+ }
148148+ }
149149+150150+ plain := strings.Replace(in, "_", "", -1)
151151+ intv, err := strconv.ParseInt(plain, 0, 64)
152152+ if err == nil {
153153+ if intv == int64(int(intv)) {
154154+ return yaml_INT_TAG, int(intv)
155155+ } else {
156156+ return yaml_INT_TAG, intv
157157+ }
158158+ }
159159+ uintv, err := strconv.ParseUint(plain, 0, 64)
160160+ if err == nil {
161161+ return yaml_INT_TAG, uintv
162162+ }
163163+ if yamlStyleFloat.MatchString(plain) {
164164+ floatv, err := strconv.ParseFloat(plain, 64)
165165+ if err == nil {
166166+ return yaml_FLOAT_TAG, floatv
167167+ }
168168+ }
169169+ if strings.HasPrefix(plain, "0b") {
170170+ intv, err := strconv.ParseInt(plain[2:], 2, 64)
171171+ if err == nil {
172172+ if intv == int64(int(intv)) {
173173+ return yaml_INT_TAG, int(intv)
174174+ } else {
175175+ return yaml_INT_TAG, intv
176176+ }
177177+ }
178178+ uintv, err := strconv.ParseUint(plain[2:], 2, 64)
179179+ if err == nil {
180180+ return yaml_INT_TAG, uintv
181181+ }
182182+ } else if strings.HasPrefix(plain, "-0b") {
183183+ intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
184184+ if err == nil {
185185+ if true || intv == int64(int(intv)) {
186186+ return yaml_INT_TAG, int(intv)
187187+ } else {
188188+ return yaml_INT_TAG, intv
189189+ }
190190+ }
191191+ }
192192+ default:
193193+ panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
194194+ }
195195+ }
196196+ return yaml_STR_TAG, in
197197+}
198198+199199+// encodeBase64 encodes s as base64 that is broken up into multiple lines
200200+// as appropriate for the resulting length.
201201+func encodeBase64(s string) string {
202202+ const lineLen = 70
203203+ encLen := base64.StdEncoding.EncodedLen(len(s))
204204+ lines := encLen/lineLen + 1
205205+ buf := make([]byte, encLen*2+lines)
206206+ in := buf[0:encLen]
207207+ out := buf[encLen:]
208208+ base64.StdEncoding.Encode(in, []byte(s))
209209+ k := 0
210210+ for i := 0; i < len(in); i += lineLen {
211211+ j := i + lineLen
212212+ if j > len(in) {
213213+ j = len(in)
214214+ }
215215+ k += copy(out[k:], in[i:j])
216216+ if lines > 1 {
217217+ out[k] = '\n'
218218+ k++
219219+ }
220220+ }
221221+ return string(out[:k])
222222+}
223223+224224+// This is a subset of the formats allowed by the regular expression
225225+// defined at http://yaml.org/type/timestamp.html.
226226+var allowedTimestampFormats = []string{
227227+ "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
228228+ "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
229229+ "2006-1-2 15:4:5.999999999", // space separated with no time zone
230230+ "2006-1-2", // date only
231231+ // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
232232+ // from the set of examples.
233233+}
234234+235235+// parseTimestamp parses s as a timestamp string and
236236+// returns the timestamp and reports whether it succeeded.
237237+// Timestamp formats are defined at http://yaml.org/type/timestamp.html
238238+func parseTimestamp(s string) (time.Time, bool) {
239239+ // TODO write code to check all the formats supported by
240240+ // http://yaml.org/type/timestamp.html instead of using time.Parse.
241241+242242+ // Quick check: all date formats start with YYYY-.
243243+ i := 0
244244+ for ; i < len(s); i++ {
245245+ if c := s[i]; c < '0' || c > '9' {
246246+ break
247247+ }
248248+ }
249249+ if i != 4 || i == len(s) || s[i] != '-' {
250250+ return time.Time{}, false
251251+ }
252252+ for _, format := range allowedTimestampFormats {
253253+ if t, err := time.Parse(format, s); err == nil {
254254+ return t, true
255255+ }
256256+ }
257257+ return time.Time{}, false
258258+}
+2696
internal/third_party/yaml/scannerc.go
···11+package yaml
22+33+import (
44+ "bytes"
55+ "fmt"
66+)
77+88+// Introduction
99+// ************
1010+//
1111+// The following notes assume that you are familiar with the YAML specification
1212+// (http://yaml.org/spec/1.2/spec.html). We mostly follow it, although in
1313+// some cases we are less restrictive that it requires.
1414+//
1515+// The process of transforming a YAML stream into a sequence of events is
1616+// divided on two steps: Scanning and Parsing.
1717+//
1818+// The Scanner transforms the input stream into a sequence of tokens, while the
1919+// parser transform the sequence of tokens produced by the Scanner into a
2020+// sequence of parsing events.
2121+//
2222+// The Scanner is rather clever and complicated. The Parser, on the contrary,
2323+// is a straightforward implementation of a recursive-descendant parser (or,
2424+// LL(1) parser, as it is usually called).
2525+//
2626+// Actually there are two issues of Scanning that might be called "clever", the
2727+// rest is quite straightforward. The issues are "block collection start" and
2828+// "simple keys". Both issues are explained below in details.
2929+//
3030+// Here the Scanning step is explained and implemented. We start with the list
3131+// of all the tokens produced by the Scanner together with short descriptions.
3232+//
3333+// Now, tokens:
3434+//
3535+// STREAM-START(encoding) # The stream start.
3636+// STREAM-END # The stream end.
3737+// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
3838+// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
3939+// DOCUMENT-START # '---'
4040+// DOCUMENT-END # '...'
4141+// BLOCK-SEQUENCE-START # Indentation increase denoting a block
4242+// BLOCK-MAPPING-START # sequence or a block mapping.
4343+// BLOCK-END # Indentation decrease.
4444+// FLOW-SEQUENCE-START # '['
4545+// FLOW-SEQUENCE-END # ']'
4646+// BLOCK-SEQUENCE-START # '{'
4747+// BLOCK-SEQUENCE-END # '}'
4848+// BLOCK-ENTRY # '-'
4949+// FLOW-ENTRY # ','
5050+// KEY # '?' or nothing (simple keys).
5151+// VALUE # ':'
5252+// ALIAS(anchor) # '*anchor'
5353+// ANCHOR(anchor) # '&anchor'
5454+// TAG(handle,suffix) # '!handle!suffix'
5555+// SCALAR(value,style) # A scalar.
5656+//
5757+// The following two tokens are "virtual" tokens denoting the beginning and the
5858+// end of the stream:
5959+//
6060+// STREAM-START(encoding)
6161+// STREAM-END
6262+//
6363+// We pass the information about the input stream encoding with the
6464+// STREAM-START token.
6565+//
6666+// The next two tokens are responsible for tags:
6767+//
6868+// VERSION-DIRECTIVE(major,minor)
6969+// TAG-DIRECTIVE(handle,prefix)
7070+//
7171+// Example:
7272+//
7373+// %YAML 1.1
7474+// %TAG ! !foo
7575+// %TAG !yaml! tag:yaml.org,2002:
7676+// ---
7777+//
7878+// The correspoding sequence of tokens:
7979+//
8080+// STREAM-START(utf-8)
8181+// VERSION-DIRECTIVE(1,1)
8282+// TAG-DIRECTIVE("!","!foo")
8383+// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
8484+// DOCUMENT-START
8585+// STREAM-END
8686+//
8787+// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
8888+// line.
8989+//
9090+// The document start and end indicators are represented by:
9191+//
9292+// DOCUMENT-START
9393+// DOCUMENT-END
9494+//
9595+// Note that if a YAML stream contains an implicit document (without '---'
9696+// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
9797+// produced.
9898+//
9999+// In the following examples, we present whole documents together with the
100100+// produced tokens.
101101+//
102102+// 1. An implicit document:
103103+//
104104+// 'a scalar'
105105+//
106106+// Tokens:
107107+//
108108+// STREAM-START(utf-8)
109109+// SCALAR("a scalar",single-quoted)
110110+// STREAM-END
111111+//
112112+// 2. An explicit document:
113113+//
114114+// ---
115115+// 'a scalar'
116116+// ...
117117+//
118118+// Tokens:
119119+//
120120+// STREAM-START(utf-8)
121121+// DOCUMENT-START
122122+// SCALAR("a scalar",single-quoted)
123123+// DOCUMENT-END
124124+// STREAM-END
125125+//
126126+// 3. Several documents in a stream:
127127+//
128128+// 'a scalar'
129129+// ---
130130+// 'another scalar'
131131+// ---
132132+// 'yet another scalar'
133133+//
134134+// Tokens:
135135+//
136136+// STREAM-START(utf-8)
137137+// SCALAR("a scalar",single-quoted)
138138+// DOCUMENT-START
139139+// SCALAR("another scalar",single-quoted)
140140+// DOCUMENT-START
141141+// SCALAR("yet another scalar",single-quoted)
142142+// STREAM-END
143143+//
144144+// We have already introduced the SCALAR token above. The following tokens are
145145+// used to describe aliases, anchors, tag, and scalars:
146146+//
147147+// ALIAS(anchor)
148148+// ANCHOR(anchor)
149149+// TAG(handle,suffix)
150150+// SCALAR(value,style)
151151+//
152152+// The following series of examples illustrate the usage of these tokens:
153153+//
154154+// 1. A recursive sequence:
155155+//
156156+// &A [ *A ]
157157+//
158158+// Tokens:
159159+//
160160+// STREAM-START(utf-8)
161161+// ANCHOR("A")
162162+// FLOW-SEQUENCE-START
163163+// ALIAS("A")
164164+// FLOW-SEQUENCE-END
165165+// STREAM-END
166166+//
167167+// 2. A tagged scalar:
168168+//
169169+// !!float "3.14" # A good approximation.
170170+//
171171+// Tokens:
172172+//
173173+// STREAM-START(utf-8)
174174+// TAG("!!","float")
175175+// SCALAR("3.14",double-quoted)
176176+// STREAM-END
177177+//
178178+// 3. Various scalar styles:
179179+//
180180+// --- # Implicit empty plain scalars do not produce tokens.
181181+// --- a plain scalar
182182+// --- 'a single-quoted scalar'
183183+// --- "a double-quoted scalar"
184184+// --- |-
185185+// a literal scalar
186186+// --- >-
187187+// a folded
188188+// scalar
189189+//
190190+// Tokens:
191191+//
192192+// STREAM-START(utf-8)
193193+// DOCUMENT-START
194194+// DOCUMENT-START
195195+// SCALAR("a plain scalar",plain)
196196+// DOCUMENT-START
197197+// SCALAR("a single-quoted scalar",single-quoted)
198198+// DOCUMENT-START
199199+// SCALAR("a double-quoted scalar",double-quoted)
200200+// DOCUMENT-START
201201+// SCALAR("a literal scalar",literal)
202202+// DOCUMENT-START
203203+// SCALAR("a folded scalar",folded)
204204+// STREAM-END
205205+//
206206+// Now it's time to review collection-related tokens. We will start with
207207+// flow collections:
208208+//
209209+// FLOW-SEQUENCE-START
210210+// FLOW-SEQUENCE-END
211211+// FLOW-MAPPING-START
212212+// FLOW-MAPPING-END
213213+// FLOW-ENTRY
214214+// KEY
215215+// VALUE
216216+//
217217+// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
218218+// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
219219+// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
220220+// indicators '?' and ':', which are used for denoting mapping keys and values,
221221+// are represented by the KEY and VALUE tokens.
222222+//
223223+// The following examples show flow collections:
224224+//
225225+// 1. A flow sequence:
226226+//
227227+// [item 1, item 2, item 3]
228228+//
229229+// Tokens:
230230+//
231231+// STREAM-START(utf-8)
232232+// FLOW-SEQUENCE-START
233233+// SCALAR("item 1",plain)
234234+// FLOW-ENTRY
235235+// SCALAR("item 2",plain)
236236+// FLOW-ENTRY
237237+// SCALAR("item 3",plain)
238238+// FLOW-SEQUENCE-END
239239+// STREAM-END
240240+//
241241+// 2. A flow mapping:
242242+//
243243+// {
244244+// a simple key: a value, # Note that the KEY token is produced.
245245+// ? a complex key: another value,
246246+// }
247247+//
248248+// Tokens:
249249+//
250250+// STREAM-START(utf-8)
251251+// FLOW-MAPPING-START
252252+// KEY
253253+// SCALAR("a simple key",plain)
254254+// VALUE
255255+// SCALAR("a value",plain)
256256+// FLOW-ENTRY
257257+// KEY
258258+// SCALAR("a complex key",plain)
259259+// VALUE
260260+// SCALAR("another value",plain)
261261+// FLOW-ENTRY
262262+// FLOW-MAPPING-END
263263+// STREAM-END
264264+//
265265+// A simple key is a key which is not denoted by the '?' indicator. Note that
266266+// the Scanner still produce the KEY token whenever it encounters a simple key.
267267+//
268268+// For scanning block collections, the following tokens are used (note that we
269269+// repeat KEY and VALUE here):
270270+//
271271+// BLOCK-SEQUENCE-START
272272+// BLOCK-MAPPING-START
273273+// BLOCK-END
274274+// BLOCK-ENTRY
275275+// KEY
276276+// VALUE
277277+//
278278+// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
279279+// increase that precedes a block collection (cf. the INDENT token in Python).
280280+// The token BLOCK-END denote indentation decrease that ends a block collection
281281+// (cf. the DEDENT token in Python). However YAML has some syntax pecularities
282282+// that makes detections of these tokens more complex.
283283+//
284284+// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
285285+// '-', '?', and ':' correspondingly.
286286+//
287287+// The following examples show how the tokens BLOCK-SEQUENCE-START,
288288+// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
289289+//
290290+// 1. Block sequences:
291291+//
292292+// - item 1
293293+// - item 2
294294+// -
295295+// - item 3.1
296296+// - item 3.2
297297+// -
298298+// key 1: value 1
299299+// key 2: value 2
300300+//
301301+// Tokens:
302302+//
303303+// STREAM-START(utf-8)
304304+// BLOCK-SEQUENCE-START
305305+// BLOCK-ENTRY
306306+// SCALAR("item 1",plain)
307307+// BLOCK-ENTRY
308308+// SCALAR("item 2",plain)
309309+// BLOCK-ENTRY
310310+// BLOCK-SEQUENCE-START
311311+// BLOCK-ENTRY
312312+// SCALAR("item 3.1",plain)
313313+// BLOCK-ENTRY
314314+// SCALAR("item 3.2",plain)
315315+// BLOCK-END
316316+// BLOCK-ENTRY
317317+// BLOCK-MAPPING-START
318318+// KEY
319319+// SCALAR("key 1",plain)
320320+// VALUE
321321+// SCALAR("value 1",plain)
322322+// KEY
323323+// SCALAR("key 2",plain)
324324+// VALUE
325325+// SCALAR("value 2",plain)
326326+// BLOCK-END
327327+// BLOCK-END
328328+// STREAM-END
329329+//
330330+// 2. Block mappings:
331331+//
332332+// a simple key: a value # The KEY token is produced here.
333333+// ? a complex key
334334+// : another value
335335+// a mapping:
336336+// key 1: value 1
337337+// key 2: value 2
338338+// a sequence:
339339+// - item 1
340340+// - item 2
341341+//
342342+// Tokens:
343343+//
344344+// STREAM-START(utf-8)
345345+// BLOCK-MAPPING-START
346346+// KEY
347347+// SCALAR("a simple key",plain)
348348+// VALUE
349349+// SCALAR("a value",plain)
350350+// KEY
351351+// SCALAR("a complex key",plain)
352352+// VALUE
353353+// SCALAR("another value",plain)
354354+// KEY
355355+// SCALAR("a mapping",plain)
356356+// BLOCK-MAPPING-START
357357+// KEY
358358+// SCALAR("key 1",plain)
359359+// VALUE
360360+// SCALAR("value 1",plain)
361361+// KEY
362362+// SCALAR("key 2",plain)
363363+// VALUE
364364+// SCALAR("value 2",plain)
365365+// BLOCK-END
366366+// KEY
367367+// SCALAR("a sequence",plain)
368368+// VALUE
369369+// BLOCK-SEQUENCE-START
370370+// BLOCK-ENTRY
371371+// SCALAR("item 1",plain)
372372+// BLOCK-ENTRY
373373+// SCALAR("item 2",plain)
374374+// BLOCK-END
375375+// BLOCK-END
376376+// STREAM-END
377377+//
378378+// YAML does not always require to start a new block collection from a new
379379+// line. If the current line contains only '-', '?', and ':' indicators, a new
380380+// block collection may start at the current line. The following examples
381381+// illustrate this case:
382382+//
383383+// 1. Collections in a sequence:
384384+//
385385+// - - item 1
386386+// - item 2
387387+// - key 1: value 1
388388+// key 2: value 2
389389+// - ? complex key
390390+// : complex value
391391+//
392392+// Tokens:
393393+//
394394+// STREAM-START(utf-8)
395395+// BLOCK-SEQUENCE-START
396396+// BLOCK-ENTRY
397397+// BLOCK-SEQUENCE-START
398398+// BLOCK-ENTRY
399399+// SCALAR("item 1",plain)
400400+// BLOCK-ENTRY
401401+// SCALAR("item 2",plain)
402402+// BLOCK-END
403403+// BLOCK-ENTRY
404404+// BLOCK-MAPPING-START
405405+// KEY
406406+// SCALAR("key 1",plain)
407407+// VALUE
408408+// SCALAR("value 1",plain)
409409+// KEY
410410+// SCALAR("key 2",plain)
411411+// VALUE
412412+// SCALAR("value 2",plain)
413413+// BLOCK-END
414414+// BLOCK-ENTRY
415415+// BLOCK-MAPPING-START
416416+// KEY
417417+// SCALAR("complex key")
418418+// VALUE
419419+// SCALAR("complex value")
420420+// BLOCK-END
421421+// BLOCK-END
422422+// STREAM-END
423423+//
424424+// 2. Collections in a mapping:
425425+//
426426+// ? a sequence
427427+// : - item 1
428428+// - item 2
429429+// ? a mapping
430430+// : key 1: value 1
431431+// key 2: value 2
432432+//
433433+// Tokens:
434434+//
435435+// STREAM-START(utf-8)
436436+// BLOCK-MAPPING-START
437437+// KEY
438438+// SCALAR("a sequence",plain)
439439+// VALUE
440440+// BLOCK-SEQUENCE-START
441441+// BLOCK-ENTRY
442442+// SCALAR("item 1",plain)
443443+// BLOCK-ENTRY
444444+// SCALAR("item 2",plain)
445445+// BLOCK-END
446446+// KEY
447447+// SCALAR("a mapping",plain)
448448+// VALUE
449449+// BLOCK-MAPPING-START
450450+// KEY
451451+// SCALAR("key 1",plain)
452452+// VALUE
453453+// SCALAR("value 1",plain)
454454+// KEY
455455+// SCALAR("key 2",plain)
456456+// VALUE
457457+// SCALAR("value 2",plain)
458458+// BLOCK-END
459459+// BLOCK-END
460460+// STREAM-END
461461+//
462462+// YAML also permits non-indented sequences if they are included into a block
463463+// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
464464+//
465465+// key:
466466+// - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
467467+// - item 2
468468+//
469469+// Tokens:
470470+//
471471+// STREAM-START(utf-8)
472472+// BLOCK-MAPPING-START
473473+// KEY
474474+// SCALAR("key",plain)
475475+// VALUE
476476+// BLOCK-ENTRY
477477+// SCALAR("item 1",plain)
478478+// BLOCK-ENTRY
479479+// SCALAR("item 2",plain)
480480+// BLOCK-END
481481+//
482482+483483+// Ensure that the buffer contains the required number of characters.
484484+// Return true on success, false on failure (reader error or memory error).
485485+func cache(parser *yaml_parser_t, length int) bool {
486486+ // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)
487487+ return parser.unread >= length || yaml_parser_update_buffer(parser, length)
488488+}
489489+490490+// Advance the buffer pointer.
491491+func skip(parser *yaml_parser_t) {
492492+ parser.mark.index++
493493+ parser.mark.column++
494494+ parser.unread--
495495+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
496496+}
497497+498498+func skip_line(parser *yaml_parser_t) {
499499+ if is_crlf(parser.buffer, parser.buffer_pos) {
500500+ parser.mark.index += 2
501501+ parser.mark.column = 0
502502+ parser.mark.line++
503503+ parser.unread -= 2
504504+ parser.buffer_pos += 2
505505+ } else if is_break(parser.buffer, parser.buffer_pos) {
506506+ parser.mark.index++
507507+ parser.mark.column = 0
508508+ parser.mark.line++
509509+ parser.unread--
510510+ parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
511511+ }
512512+}
513513+514514+// Copy a character to a string buffer and advance pointers.
515515+func read(parser *yaml_parser_t, s []byte) []byte {
516516+ w := width(parser.buffer[parser.buffer_pos])
517517+ if w == 0 {
518518+ panic("invalid character sequence")
519519+ }
520520+ if len(s) == 0 {
521521+ s = make([]byte, 0, 32)
522522+ }
523523+ if w == 1 && len(s)+w <= cap(s) {
524524+ s = s[:len(s)+1]
525525+ s[len(s)-1] = parser.buffer[parser.buffer_pos]
526526+ parser.buffer_pos++
527527+ } else {
528528+ s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
529529+ parser.buffer_pos += w
530530+ }
531531+ parser.mark.index++
532532+ parser.mark.column++
533533+ parser.unread--
534534+ return s
535535+}
536536+537537+// Copy a line break character to a string buffer and advance pointers.
538538+func read_line(parser *yaml_parser_t, s []byte) []byte {
539539+ buf := parser.buffer
540540+ pos := parser.buffer_pos
541541+ switch {
542542+ case buf[pos] == '\r' && buf[pos+1] == '\n':
543543+ // CR LF . LF
544544+ s = append(s, '\n')
545545+ parser.buffer_pos += 2
546546+ parser.mark.index++
547547+ parser.unread--
548548+ case buf[pos] == '\r' || buf[pos] == '\n':
549549+ // CR|LF . LF
550550+ s = append(s, '\n')
551551+ parser.buffer_pos += 1
552552+ case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
553553+ // NEL . LF
554554+ s = append(s, '\n')
555555+ parser.buffer_pos += 2
556556+ case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
557557+ // LS|PS . LS|PS
558558+ s = append(s, buf[parser.buffer_pos:pos+3]...)
559559+ parser.buffer_pos += 3
560560+ default:
561561+ return s
562562+ }
563563+ parser.mark.index++
564564+ parser.mark.column = 0
565565+ parser.mark.line++
566566+ parser.unread--
567567+ return s
568568+}
569569+570570+// Get the next token.
571571+func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
572572+ // Erase the token object.
573573+ *token = yaml_token_t{} // [Go] Is this necessary?
574574+575575+ // No tokens after STREAM-END or error.
576576+ if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
577577+ return true
578578+ }
579579+580580+ // Ensure that the tokens queue contains enough tokens.
581581+ if !parser.token_available {
582582+ if !yaml_parser_fetch_more_tokens(parser) {
583583+ return false
584584+ }
585585+ }
586586+587587+ // Fetch the next token from the queue.
588588+ *token = parser.tokens[parser.tokens_head]
589589+ parser.tokens_head++
590590+ parser.tokens_parsed++
591591+ parser.token_available = false
592592+593593+ if token.typ == yaml_STREAM_END_TOKEN {
594594+ parser.stream_end_produced = true
595595+ }
596596+ return true
597597+}
598598+599599+// Set the scanner error and return false.
600600+func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
601601+ parser.error = yaml_SCANNER_ERROR
602602+ parser.context = context
603603+ parser.context_mark = context_mark
604604+ parser.problem = problem
605605+ parser.problem_mark = parser.mark
606606+ return false
607607+}
608608+609609+func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
610610+ context := "while parsing a tag"
611611+ if directive {
612612+ context = "while parsing a %TAG directive"
613613+ }
614614+ return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
615615+}
616616+617617+func trace(args ...interface{}) func() {
618618+ pargs := append([]interface{}{"+++"}, args...)
619619+ fmt.Println(pargs...)
620620+ pargs = append([]interface{}{"---"}, args...)
621621+ return func() { fmt.Println(pargs...) }
622622+}
623623+624624+// Ensure that the tokens queue contains at least one token which can be
625625+// returned to the Parser.
626626+func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
627627+ // While we need more tokens to fetch, do it.
628628+ for {
629629+ // Check if we really need to fetch more tokens.
630630+ need_more_tokens := false
631631+632632+ if parser.tokens_head == len(parser.tokens) {
633633+ // Queue is empty.
634634+ need_more_tokens = true
635635+ } else {
636636+ // Check if any potential simple key may occupy the head position.
637637+ if !yaml_parser_stale_simple_keys(parser) {
638638+ return false
639639+ }
640640+641641+ for i := range parser.simple_keys {
642642+ simple_key := &parser.simple_keys[i]
643643+ if simple_key.possible && simple_key.token_number == parser.tokens_parsed {
644644+ need_more_tokens = true
645645+ break
646646+ }
647647+ }
648648+ }
649649+650650+ // We are finished.
651651+ if !need_more_tokens {
652652+ break
653653+ }
654654+ // Fetch the next token.
655655+ if !yaml_parser_fetch_next_token(parser) {
656656+ return false
657657+ }
658658+ }
659659+660660+ parser.token_available = true
661661+ return true
662662+}
663663+664664+// The dispatcher for token fetchers.
665665+func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
666666+ // Ensure that the buffer is initialized.
667667+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
668668+ return false
669669+ }
670670+671671+ // Check if we just started scanning. Fetch STREAM-START then.
672672+ if !parser.stream_start_produced {
673673+ return yaml_parser_fetch_stream_start(parser)
674674+ }
675675+676676+ // Eat whitespaces and comments until we reach the next token.
677677+ if !yaml_parser_scan_to_next_token(parser) {
678678+ return false
679679+ }
680680+681681+ // Remove obsolete potential simple keys.
682682+ if !yaml_parser_stale_simple_keys(parser) {
683683+ return false
684684+ }
685685+686686+ // Check the indentation level against the current column.
687687+ if !yaml_parser_unroll_indent(parser, parser.mark.column) {
688688+ return false
689689+ }
690690+691691+ // Ensure that the buffer contains at least 4 characters. 4 is the length
692692+ // of the longest indicators ('--- ' and '... ').
693693+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
694694+ return false
695695+ }
696696+697697+ // Is it the end of the stream?
698698+ if is_z(parser.buffer, parser.buffer_pos) {
699699+ return yaml_parser_fetch_stream_end(parser)
700700+ }
701701+702702+ // Is it a directive?
703703+ if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
704704+ return yaml_parser_fetch_directive(parser)
705705+ }
706706+707707+ buf := parser.buffer
708708+ pos := parser.buffer_pos
709709+710710+ // Is it the document start indicator?
711711+ if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
712712+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
713713+ }
714714+715715+ // Is it the document end indicator?
716716+ if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
717717+ return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
718718+ }
719719+720720+ // Is it the flow sequence start indicator?
721721+ if buf[pos] == '[' {
722722+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
723723+ }
724724+725725+ // Is it the flow mapping start indicator?
726726+ if parser.buffer[parser.buffer_pos] == '{' {
727727+ return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
728728+ }
729729+730730+ // Is it the flow sequence end indicator?
731731+ if parser.buffer[parser.buffer_pos] == ']' {
732732+ return yaml_parser_fetch_flow_collection_end(parser,
733733+ yaml_FLOW_SEQUENCE_END_TOKEN)
734734+ }
735735+736736+ // Is it the flow mapping end indicator?
737737+ if parser.buffer[parser.buffer_pos] == '}' {
738738+ return yaml_parser_fetch_flow_collection_end(parser,
739739+ yaml_FLOW_MAPPING_END_TOKEN)
740740+ }
741741+742742+ // Is it the flow entry indicator?
743743+ if parser.buffer[parser.buffer_pos] == ',' {
744744+ return yaml_parser_fetch_flow_entry(parser)
745745+ }
746746+747747+ // Is it the block entry indicator?
748748+ if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
749749+ return yaml_parser_fetch_block_entry(parser)
750750+ }
751751+752752+ // Is it the key indicator?
753753+ if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
754754+ return yaml_parser_fetch_key(parser)
755755+ }
756756+757757+ // Is it the value indicator?
758758+ if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
759759+ return yaml_parser_fetch_value(parser)
760760+ }
761761+762762+ // Is it an alias?
763763+ if parser.buffer[parser.buffer_pos] == '*' {
764764+ return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
765765+ }
766766+767767+ // Is it an anchor?
768768+ if parser.buffer[parser.buffer_pos] == '&' {
769769+ return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
770770+ }
771771+772772+ // Is it a tag?
773773+ if parser.buffer[parser.buffer_pos] == '!' {
774774+ return yaml_parser_fetch_tag(parser)
775775+ }
776776+777777+ // Is it a literal scalar?
778778+ if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
779779+ return yaml_parser_fetch_block_scalar(parser, true)
780780+ }
781781+782782+ // Is it a folded scalar?
783783+ if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
784784+ return yaml_parser_fetch_block_scalar(parser, false)
785785+ }
786786+787787+ // Is it a single-quoted scalar?
788788+ if parser.buffer[parser.buffer_pos] == '\'' {
789789+ return yaml_parser_fetch_flow_scalar(parser, true)
790790+ }
791791+792792+ // Is it a double-quoted scalar?
793793+ if parser.buffer[parser.buffer_pos] == '"' {
794794+ return yaml_parser_fetch_flow_scalar(parser, false)
795795+ }
796796+797797+ // Is it a plain scalar?
798798+ //
799799+ // A plain scalar may start with any non-blank characters except
800800+ //
801801+ // '-', '?', ':', ',', '[', ']', '{', '}',
802802+ // '#', '&', '*', '!', '|', '>', '\'', '\"',
803803+ // '%', '@', '`'.
804804+ //
805805+ // In the block context (and, for the '-' indicator, in the flow context
806806+ // too), it may also start with the characters
807807+ //
808808+ // '-', '?', ':'
809809+ //
810810+ // if it is followed by a non-space character.
811811+ //
812812+ // The last rule is more restrictive than the specification requires.
813813+ // [Go] Make this logic more reasonable.
814814+ //switch parser.buffer[parser.buffer_pos] {
815815+ //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`':
816816+ //}
817817+ if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
818818+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
819819+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
820820+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
821821+ parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
822822+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
823823+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
824824+ parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
825825+ parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
826826+ parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
827827+ (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
828828+ (parser.flow_level == 0 &&
829829+ (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
830830+ !is_blankz(parser.buffer, parser.buffer_pos+1)) {
831831+ return yaml_parser_fetch_plain_scalar(parser)
832832+ }
833833+834834+ // If we don't determine the token type so far, it is an error.
835835+ return yaml_parser_set_scanner_error(parser,
836836+ "while scanning for the next token", parser.mark,
837837+ "found character that cannot start any token")
838838+}
839839+840840+// Check the list of potential simple keys and remove the positions that
841841+// cannot contain simple keys anymore.
842842+func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool {
843843+ // Check for a potential simple key for each flow level.
844844+ for i := range parser.simple_keys {
845845+ simple_key := &parser.simple_keys[i]
846846+847847+ // The specification requires that a simple key
848848+ //
849849+ // - is limited to a single line,
850850+ // - is shorter than 1024 characters.
851851+ if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) {
852852+853853+ // Check if the potential simple key to be removed is required.
854854+ if simple_key.required {
855855+ return yaml_parser_set_scanner_error(parser,
856856+ "while scanning a simple key", simple_key.mark,
857857+ "could not find expected ':'")
858858+ }
859859+ simple_key.possible = false
860860+ }
861861+ }
862862+ return true
863863+}
864864+865865+// Check if a simple key may start at the current position and add it if
866866+// needed.
867867+func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
868868+ // A simple key is required at the current position if the scanner is in
869869+ // the block context and the current column coincides with the indentation
870870+ // level.
871871+872872+ required := parser.flow_level == 0 && parser.indent == parser.mark.column
873873+874874+ //
875875+ // If the current position may start a simple key, save it.
876876+ //
877877+ if parser.simple_key_allowed {
878878+ simple_key := yaml_simple_key_t{
879879+ possible: true,
880880+ required: required,
881881+ token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
882882+ }
883883+ simple_key.mark = parser.mark
884884+885885+ if !yaml_parser_remove_simple_key(parser) {
886886+ return false
887887+ }
888888+ parser.simple_keys[len(parser.simple_keys)-1] = simple_key
889889+ }
890890+ return true
891891+}
892892+893893+// Remove a potential simple key at the current flow level.
894894+func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
895895+ i := len(parser.simple_keys) - 1
896896+ if parser.simple_keys[i].possible {
897897+ // If the key is required, it is an error.
898898+ if parser.simple_keys[i].required {
899899+ return yaml_parser_set_scanner_error(parser,
900900+ "while scanning a simple key", parser.simple_keys[i].mark,
901901+ "could not find expected ':'")
902902+ }
903903+ }
904904+ // Remove the key from the stack.
905905+ parser.simple_keys[i].possible = false
906906+ return true
907907+}
908908+909909+// Increase the flow level and resize the simple key list if needed.
910910+func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
911911+ // Reset the simple key on the next level.
912912+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
913913+914914+ // Increase the flow level.
915915+ parser.flow_level++
916916+ return true
917917+}
918918+919919+// Decrease the flow level.
920920+func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
921921+ if parser.flow_level > 0 {
922922+ parser.flow_level--
923923+ parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1]
924924+ }
925925+ return true
926926+}
927927+928928+// Push the current indentation level to the stack and set the new level
929929+// the current column is greater than the indentation level. In this case,
930930+// append or insert the specified token into the token queue.
931931+func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
932932+ // In the flow context, do nothing.
933933+ if parser.flow_level > 0 {
934934+ return true
935935+ }
936936+937937+ if parser.indent < column {
938938+ // Push the current indentation level to the stack and set the new
939939+ // indentation level.
940940+ parser.indents = append(parser.indents, parser.indent)
941941+ parser.indent = column
942942+943943+ // Create a token and insert it into the queue.
944944+ token := yaml_token_t{
945945+ typ: typ,
946946+ start_mark: mark,
947947+ end_mark: mark,
948948+ }
949949+ if number > -1 {
950950+ number -= parser.tokens_parsed
951951+ }
952952+ yaml_insert_token(parser, number, &token)
953953+ }
954954+ return true
955955+}
956956+957957+// Pop indentation levels from the indents stack until the current level
958958+// becomes less or equal to the column. For each indentation level, append
959959+// the BLOCK-END token.
960960+func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
961961+ // In the flow context, do nothing.
962962+ if parser.flow_level > 0 {
963963+ return true
964964+ }
965965+966966+ // Loop through the indentation levels in the stack.
967967+ for parser.indent > column {
968968+ // Create a token and append it to the queue.
969969+ token := yaml_token_t{
970970+ typ: yaml_BLOCK_END_TOKEN,
971971+ start_mark: parser.mark,
972972+ end_mark: parser.mark,
973973+ }
974974+ yaml_insert_token(parser, -1, &token)
975975+976976+ // Pop the indentation level.
977977+ parser.indent = parser.indents[len(parser.indents)-1]
978978+ parser.indents = parser.indents[:len(parser.indents)-1]
979979+ }
980980+ return true
981981+}
982982+983983+// Initialize the scanner and produce the STREAM-START token.
984984+func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
985985+986986+ // Set the initial indentation.
987987+ parser.indent = -1
988988+989989+ // Initialize the simple key stack.
990990+ parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
991991+992992+ // A simple key is allowed at the beginning of the stream.
993993+ parser.simple_key_allowed = true
994994+995995+ // We have started.
996996+ parser.stream_start_produced = true
997997+998998+ // Create the STREAM-START token and append it to the queue.
999999+ token := yaml_token_t{
10001000+ typ: yaml_STREAM_START_TOKEN,
10011001+ start_mark: parser.mark,
10021002+ end_mark: parser.mark,
10031003+ encoding: parser.encoding,
10041004+ }
10051005+ yaml_insert_token(parser, -1, &token)
10061006+ return true
10071007+}
10081008+10091009+// Produce the STREAM-END token and shut down the scanner.
10101010+func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
10111011+10121012+ // Force new line.
10131013+ if parser.mark.column != 0 {
10141014+ parser.mark.column = 0
10151015+ parser.mark.line++
10161016+ }
10171017+10181018+ // Reset the indentation level.
10191019+ if !yaml_parser_unroll_indent(parser, -1) {
10201020+ return false
10211021+ }
10221022+10231023+ // Reset simple keys.
10241024+ if !yaml_parser_remove_simple_key(parser) {
10251025+ return false
10261026+ }
10271027+10281028+ parser.simple_key_allowed = false
10291029+10301030+ // Create the STREAM-END token and append it to the queue.
10311031+ token := yaml_token_t{
10321032+ typ: yaml_STREAM_END_TOKEN,
10331033+ start_mark: parser.mark,
10341034+ end_mark: parser.mark,
10351035+ }
10361036+ yaml_insert_token(parser, -1, &token)
10371037+ return true
10381038+}
10391039+10401040+// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
10411041+func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
10421042+ // Reset the indentation level.
10431043+ if !yaml_parser_unroll_indent(parser, -1) {
10441044+ return false
10451045+ }
10461046+10471047+ // Reset simple keys.
10481048+ if !yaml_parser_remove_simple_key(parser) {
10491049+ return false
10501050+ }
10511051+10521052+ parser.simple_key_allowed = false
10531053+10541054+ // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.
10551055+ token := yaml_token_t{}
10561056+ if !yaml_parser_scan_directive(parser, &token) {
10571057+ return false
10581058+ }
10591059+ // Append the token to the queue.
10601060+ yaml_insert_token(parser, -1, &token)
10611061+ return true
10621062+}
10631063+10641064+// Produce the DOCUMENT-START or DOCUMENT-END token.
10651065+func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
10661066+ // Reset the indentation level.
10671067+ if !yaml_parser_unroll_indent(parser, -1) {
10681068+ return false
10691069+ }
10701070+10711071+ // Reset simple keys.
10721072+ if !yaml_parser_remove_simple_key(parser) {
10731073+ return false
10741074+ }
10751075+10761076+ parser.simple_key_allowed = false
10771077+10781078+ // Consume the token.
10791079+ start_mark := parser.mark
10801080+10811081+ skip(parser)
10821082+ skip(parser)
10831083+ skip(parser)
10841084+10851085+ end_mark := parser.mark
10861086+10871087+ // Create the DOCUMENT-START or DOCUMENT-END token.
10881088+ token := yaml_token_t{
10891089+ typ: typ,
10901090+ start_mark: start_mark,
10911091+ end_mark: end_mark,
10921092+ }
10931093+ // Append the token to the queue.
10941094+ yaml_insert_token(parser, -1, &token)
10951095+ return true
10961096+}
10971097+10981098+// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
10991099+func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
11001100+ // The indicators '[' and '{' may start a simple key.
11011101+ if !yaml_parser_save_simple_key(parser) {
11021102+ return false
11031103+ }
11041104+11051105+ // Increase the flow level.
11061106+ if !yaml_parser_increase_flow_level(parser) {
11071107+ return false
11081108+ }
11091109+11101110+ // A simple key may follow the indicators '[' and '{'.
11111111+ parser.simple_key_allowed = true
11121112+11131113+ // Consume the token.
11141114+ start_mark := parser.mark
11151115+ skip(parser)
11161116+ end_mark := parser.mark
11171117+11181118+ // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.
11191119+ token := yaml_token_t{
11201120+ typ: typ,
11211121+ start_mark: start_mark,
11221122+ end_mark: end_mark,
11231123+ }
11241124+ // Append the token to the queue.
11251125+ yaml_insert_token(parser, -1, &token)
11261126+ return true
11271127+}
11281128+11291129+// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
11301130+func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
11311131+ // Reset any potential simple key on the current flow level.
11321132+ if !yaml_parser_remove_simple_key(parser) {
11331133+ return false
11341134+ }
11351135+11361136+ // Decrease the flow level.
11371137+ if !yaml_parser_decrease_flow_level(parser) {
11381138+ return false
11391139+ }
11401140+11411141+ // No simple keys after the indicators ']' and '}'.
11421142+ parser.simple_key_allowed = false
11431143+11441144+ // Consume the token.
11451145+11461146+ start_mark := parser.mark
11471147+ skip(parser)
11481148+ end_mark := parser.mark
11491149+11501150+ // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.
11511151+ token := yaml_token_t{
11521152+ typ: typ,
11531153+ start_mark: start_mark,
11541154+ end_mark: end_mark,
11551155+ }
11561156+ // Append the token to the queue.
11571157+ yaml_insert_token(parser, -1, &token)
11581158+ return true
11591159+}
11601160+11611161+// Produce the FLOW-ENTRY token.
11621162+func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
11631163+ // Reset any potential simple keys on the current flow level.
11641164+ if !yaml_parser_remove_simple_key(parser) {
11651165+ return false
11661166+ }
11671167+11681168+ // Simple keys are allowed after ','.
11691169+ parser.simple_key_allowed = true
11701170+11711171+ // Consume the token.
11721172+ start_mark := parser.mark
11731173+ skip(parser)
11741174+ end_mark := parser.mark
11751175+11761176+ // Create the FLOW-ENTRY token and append it to the queue.
11771177+ token := yaml_token_t{
11781178+ typ: yaml_FLOW_ENTRY_TOKEN,
11791179+ start_mark: start_mark,
11801180+ end_mark: end_mark,
11811181+ }
11821182+ yaml_insert_token(parser, -1, &token)
11831183+ return true
11841184+}
11851185+11861186+// Produce the BLOCK-ENTRY token.
11871187+func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
11881188+ // Check if the scanner is in the block context.
11891189+ if parser.flow_level == 0 {
11901190+ // Check if we are allowed to start a new entry.
11911191+ if !parser.simple_key_allowed {
11921192+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
11931193+ "block sequence entries are not allowed in this context")
11941194+ }
11951195+ // Add the BLOCK-SEQUENCE-START token if needed.
11961196+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
11971197+ return false
11981198+ }
11991199+ } else {
12001200+ // It is an error for the '-' indicator to occur in the flow context,
12011201+ // but we let the Parser detect and report about it because the Parser
12021202+ // is able to point to the context.
12031203+ }
12041204+12051205+ // Reset any potential simple keys on the current flow level.
12061206+ if !yaml_parser_remove_simple_key(parser) {
12071207+ return false
12081208+ }
12091209+12101210+ // Simple keys are allowed after '-'.
12111211+ parser.simple_key_allowed = true
12121212+12131213+ // Consume the token.
12141214+ start_mark := parser.mark
12151215+ skip(parser)
12161216+ end_mark := parser.mark
12171217+12181218+ // Create the BLOCK-ENTRY token and append it to the queue.
12191219+ token := yaml_token_t{
12201220+ typ: yaml_BLOCK_ENTRY_TOKEN,
12211221+ start_mark: start_mark,
12221222+ end_mark: end_mark,
12231223+ }
12241224+ yaml_insert_token(parser, -1, &token)
12251225+ return true
12261226+}
12271227+12281228+// Produce the KEY token.
12291229+func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
12301230+12311231+ // In the block context, additional checks are required.
12321232+ if parser.flow_level == 0 {
12331233+ // Check if we are allowed to start a new key (not nessesary simple).
12341234+ if !parser.simple_key_allowed {
12351235+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
12361236+ "mapping keys are not allowed in this context")
12371237+ }
12381238+ // Add the BLOCK-MAPPING-START token if needed.
12391239+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
12401240+ return false
12411241+ }
12421242+ }
12431243+12441244+ // Reset any potential simple keys on the current flow level.
12451245+ if !yaml_parser_remove_simple_key(parser) {
12461246+ return false
12471247+ }
12481248+12491249+ // Simple keys are allowed after '?' in the block context.
12501250+ parser.simple_key_allowed = parser.flow_level == 0
12511251+12521252+ // Consume the token.
12531253+ start_mark := parser.mark
12541254+ skip(parser)
12551255+ end_mark := parser.mark
12561256+12571257+ // Create the KEY token and append it to the queue.
12581258+ token := yaml_token_t{
12591259+ typ: yaml_KEY_TOKEN,
12601260+ start_mark: start_mark,
12611261+ end_mark: end_mark,
12621262+ }
12631263+ yaml_insert_token(parser, -1, &token)
12641264+ return true
12651265+}
12661266+12671267+// Produce the VALUE token.
12681268+func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
12691269+12701270+ simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
12711271+12721272+ // Have we found a simple key?
12731273+ if simple_key.possible {
12741274+ // Create the KEY token and insert it into the queue.
12751275+ token := yaml_token_t{
12761276+ typ: yaml_KEY_TOKEN,
12771277+ start_mark: simple_key.mark,
12781278+ end_mark: simple_key.mark,
12791279+ }
12801280+ yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
12811281+12821282+ // In the block context, we may need to add the BLOCK-MAPPING-START token.
12831283+ if !yaml_parser_roll_indent(parser, simple_key.mark.column,
12841284+ simple_key.token_number,
12851285+ yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
12861286+ return false
12871287+ }
12881288+12891289+ // Remove the simple key.
12901290+ simple_key.possible = false
12911291+12921292+ // A simple key cannot follow another simple key.
12931293+ parser.simple_key_allowed = false
12941294+12951295+ } else {
12961296+ // The ':' indicator follows a complex key.
12971297+12981298+ // In the block context, extra checks are required.
12991299+ if parser.flow_level == 0 {
13001300+13011301+ // Check if we are allowed to start a complex value.
13021302+ if !parser.simple_key_allowed {
13031303+ return yaml_parser_set_scanner_error(parser, "", parser.mark,
13041304+ "mapping values are not allowed in this context")
13051305+ }
13061306+13071307+ // Add the BLOCK-MAPPING-START token if needed.
13081308+ if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
13091309+ return false
13101310+ }
13111311+ }
13121312+13131313+ // Simple keys after ':' are allowed in the block context.
13141314+ parser.simple_key_allowed = parser.flow_level == 0
13151315+ }
13161316+13171317+ // Consume the token.
13181318+ start_mark := parser.mark
13191319+ skip(parser)
13201320+ end_mark := parser.mark
13211321+13221322+ // Create the VALUE token and append it to the queue.
13231323+ token := yaml_token_t{
13241324+ typ: yaml_VALUE_TOKEN,
13251325+ start_mark: start_mark,
13261326+ end_mark: end_mark,
13271327+ }
13281328+ yaml_insert_token(parser, -1, &token)
13291329+ return true
13301330+}
13311331+13321332+// Produce the ALIAS or ANCHOR token.
13331333+func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
13341334+ // An anchor or an alias could be a simple key.
13351335+ if !yaml_parser_save_simple_key(parser) {
13361336+ return false
13371337+ }
13381338+13391339+ // A simple key cannot follow an anchor or an alias.
13401340+ parser.simple_key_allowed = false
13411341+13421342+ // Create the ALIAS or ANCHOR token and append it to the queue.
13431343+ var token yaml_token_t
13441344+ if !yaml_parser_scan_anchor(parser, &token, typ) {
13451345+ return false
13461346+ }
13471347+ yaml_insert_token(parser, -1, &token)
13481348+ return true
13491349+}
13501350+13511351+// Produce the TAG token.
13521352+func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
13531353+ // A tag could be a simple key.
13541354+ if !yaml_parser_save_simple_key(parser) {
13551355+ return false
13561356+ }
13571357+13581358+ // A simple key cannot follow a tag.
13591359+ parser.simple_key_allowed = false
13601360+13611361+ // Create the TAG token and append it to the queue.
13621362+ var token yaml_token_t
13631363+ if !yaml_parser_scan_tag(parser, &token) {
13641364+ return false
13651365+ }
13661366+ yaml_insert_token(parser, -1, &token)
13671367+ return true
13681368+}
13691369+13701370+// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
13711371+func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
13721372+ // Remove any potential simple keys.
13731373+ if !yaml_parser_remove_simple_key(parser) {
13741374+ return false
13751375+ }
13761376+13771377+ // A simple key may follow a block scalar.
13781378+ parser.simple_key_allowed = true
13791379+13801380+ // Create the SCALAR token and append it to the queue.
13811381+ var token yaml_token_t
13821382+ if !yaml_parser_scan_block_scalar(parser, &token, literal) {
13831383+ return false
13841384+ }
13851385+ yaml_insert_token(parser, -1, &token)
13861386+ return true
13871387+}
13881388+13891389+// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
13901390+func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
13911391+ // A plain scalar could be a simple key.
13921392+ if !yaml_parser_save_simple_key(parser) {
13931393+ return false
13941394+ }
13951395+13961396+ // A simple key cannot follow a flow scalar.
13971397+ parser.simple_key_allowed = false
13981398+13991399+ // Create the SCALAR token and append it to the queue.
14001400+ var token yaml_token_t
14011401+ if !yaml_parser_scan_flow_scalar(parser, &token, single) {
14021402+ return false
14031403+ }
14041404+ yaml_insert_token(parser, -1, &token)
14051405+ return true
14061406+}
14071407+14081408+// Produce the SCALAR(...,plain) token.
14091409+func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
14101410+ // A plain scalar could be a simple key.
14111411+ if !yaml_parser_save_simple_key(parser) {
14121412+ return false
14131413+ }
14141414+14151415+ // A simple key cannot follow a flow scalar.
14161416+ parser.simple_key_allowed = false
14171417+14181418+ // Create the SCALAR token and append it to the queue.
14191419+ var token yaml_token_t
14201420+ if !yaml_parser_scan_plain_scalar(parser, &token) {
14211421+ return false
14221422+ }
14231423+ yaml_insert_token(parser, -1, &token)
14241424+ return true
14251425+}
14261426+14271427+// Eat whitespaces and comments until the next token is found.
14281428+func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
14291429+14301430+ // Until the next token is not found.
14311431+ for {
14321432+ // Allow the BOM mark to start a line.
14331433+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
14341434+ return false
14351435+ }
14361436+ if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
14371437+ skip(parser)
14381438+ }
14391439+14401440+ // Eat whitespaces.
14411441+ // Tabs are allowed:
14421442+ // - in the flow context
14431443+ // - in the block context, but not at the beginning of the line or
14441444+ // after '-', '?', or ':' (complex value).
14451445+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
14461446+ return false
14471447+ }
14481448+14491449+ for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
14501450+ skip(parser)
14511451+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
14521452+ return false
14531453+ }
14541454+ }
14551455+14561456+ // Eat a comment until a line break.
14571457+ if parser.buffer[parser.buffer_pos] == '#' {
14581458+ for !is_breakz(parser.buffer, parser.buffer_pos) {
14591459+ skip(parser)
14601460+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
14611461+ return false
14621462+ }
14631463+ }
14641464+ }
14651465+14661466+ // If it is a line break, eat it.
14671467+ if is_break(parser.buffer, parser.buffer_pos) {
14681468+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
14691469+ return false
14701470+ }
14711471+ skip_line(parser)
14721472+14731473+ // In the block context, a new line may start a simple key.
14741474+ if parser.flow_level == 0 {
14751475+ parser.simple_key_allowed = true
14761476+ }
14771477+ } else {
14781478+ break // We have found a token.
14791479+ }
14801480+ }
14811481+14821482+ return true
14831483+}
14841484+14851485+// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
14861486+//
14871487+// Scope:
14881488+// %YAML 1.1 # a comment \n
14891489+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14901490+// %TAG !yaml! tag:yaml.org,2002: \n
14911491+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14921492+//
14931493+func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
14941494+ // Eat '%'.
14951495+ start_mark := parser.mark
14961496+ skip(parser)
14971497+14981498+ // Scan the directive name.
14991499+ var name []byte
15001500+ if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
15011501+ return false
15021502+ }
15031503+15041504+ // Is it a YAML directive?
15051505+ if bytes.Equal(name, []byte("YAML")) {
15061506+ // Scan the VERSION directive value.
15071507+ var major, minor int8
15081508+ if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
15091509+ return false
15101510+ }
15111511+ end_mark := parser.mark
15121512+15131513+ // Create a VERSION-DIRECTIVE token.
15141514+ *token = yaml_token_t{
15151515+ typ: yaml_VERSION_DIRECTIVE_TOKEN,
15161516+ start_mark: start_mark,
15171517+ end_mark: end_mark,
15181518+ major: major,
15191519+ minor: minor,
15201520+ }
15211521+15221522+ // Is it a TAG directive?
15231523+ } else if bytes.Equal(name, []byte("TAG")) {
15241524+ // Scan the TAG directive value.
15251525+ var handle, prefix []byte
15261526+ if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
15271527+ return false
15281528+ }
15291529+ end_mark := parser.mark
15301530+15311531+ // Create a TAG-DIRECTIVE token.
15321532+ *token = yaml_token_t{
15331533+ typ: yaml_TAG_DIRECTIVE_TOKEN,
15341534+ start_mark: start_mark,
15351535+ end_mark: end_mark,
15361536+ value: handle,
15371537+ prefix: prefix,
15381538+ }
15391539+15401540+ // Unknown directive.
15411541+ } else {
15421542+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
15431543+ start_mark, "found unknown directive name")
15441544+ return false
15451545+ }
15461546+15471547+ // Eat the rest of the line including any comments.
15481548+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
15491549+ return false
15501550+ }
15511551+15521552+ for is_blank(parser.buffer, parser.buffer_pos) {
15531553+ skip(parser)
15541554+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
15551555+ return false
15561556+ }
15571557+ }
15581558+15591559+ if parser.buffer[parser.buffer_pos] == '#' {
15601560+ for !is_breakz(parser.buffer, parser.buffer_pos) {
15611561+ skip(parser)
15621562+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
15631563+ return false
15641564+ }
15651565+ }
15661566+ }
15671567+15681568+ // Check if we are at the end of the line.
15691569+ if !is_breakz(parser.buffer, parser.buffer_pos) {
15701570+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
15711571+ start_mark, "did not find expected comment or line break")
15721572+ return false
15731573+ }
15741574+15751575+ // Eat a line break.
15761576+ if is_break(parser.buffer, parser.buffer_pos) {
15771577+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
15781578+ return false
15791579+ }
15801580+ skip_line(parser)
15811581+ }
15821582+15831583+ return true
15841584+}
15851585+15861586+// Scan the directive name.
15871587+//
15881588+// Scope:
15891589+// %YAML 1.1 # a comment \n
15901590+// ^^^^
15911591+// %TAG !yaml! tag:yaml.org,2002: \n
15921592+// ^^^
15931593+//
15941594+func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
15951595+ // Consume the directive name.
15961596+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
15971597+ return false
15981598+ }
15991599+16001600+ var s []byte
16011601+ for is_alpha(parser.buffer, parser.buffer_pos) {
16021602+ s = read(parser, s)
16031603+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
16041604+ return false
16051605+ }
16061606+ }
16071607+16081608+ // Check if the name is empty.
16091609+ if len(s) == 0 {
16101610+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
16111611+ start_mark, "could not find expected directive name")
16121612+ return false
16131613+ }
16141614+16151615+ // Check for an blank character after the name.
16161616+ if !is_blankz(parser.buffer, parser.buffer_pos) {
16171617+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
16181618+ start_mark, "found unexpected non-alphabetical character")
16191619+ return false
16201620+ }
16211621+ *name = s
16221622+ return true
16231623+}
16241624+16251625+// Scan the value of VERSION-DIRECTIVE.
16261626+//
16271627+// Scope:
16281628+// %YAML 1.1 # a comment \n
16291629+// ^^^^^^
16301630+func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
16311631+ // Eat whitespaces.
16321632+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
16331633+ return false
16341634+ }
16351635+ for is_blank(parser.buffer, parser.buffer_pos) {
16361636+ skip(parser)
16371637+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
16381638+ return false
16391639+ }
16401640+ }
16411641+16421642+ // Consume the major version number.
16431643+ if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
16441644+ return false
16451645+ }
16461646+16471647+ // Eat '.'.
16481648+ if parser.buffer[parser.buffer_pos] != '.' {
16491649+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
16501650+ start_mark, "did not find expected digit or '.' character")
16511651+ }
16521652+16531653+ skip(parser)
16541654+16551655+ // Consume the minor version number.
16561656+ if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
16571657+ return false
16581658+ }
16591659+ return true
16601660+}
16611661+16621662+const max_number_length = 2
16631663+16641664+// Scan the version number of VERSION-DIRECTIVE.
16651665+//
16661666+// Scope:
16671667+// %YAML 1.1 # a comment \n
16681668+// ^
16691669+// %YAML 1.1 # a comment \n
16701670+// ^
16711671+func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
16721672+16731673+ // Repeat while the next character is digit.
16741674+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
16751675+ return false
16761676+ }
16771677+ var value, length int8
16781678+ for is_digit(parser.buffer, parser.buffer_pos) {
16791679+ // Check if the number is too long.
16801680+ length++
16811681+ if length > max_number_length {
16821682+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
16831683+ start_mark, "found extremely long version number")
16841684+ }
16851685+ value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
16861686+ skip(parser)
16871687+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
16881688+ return false
16891689+ }
16901690+ }
16911691+16921692+ // Check if the number was present.
16931693+ if length == 0 {
16941694+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
16951695+ start_mark, "did not find expected version number")
16961696+ }
16971697+ *number = value
16981698+ return true
16991699+}
17001700+17011701+// Scan the value of a TAG-DIRECTIVE token.
17021702+//
17031703+// Scope:
17041704+// %TAG !yaml! tag:yaml.org,2002: \n
17051705+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17061706+//
17071707+func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
17081708+ var handle_value, prefix_value []byte
17091709+17101710+ // Eat whitespaces.
17111711+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17121712+ return false
17131713+ }
17141714+17151715+ for is_blank(parser.buffer, parser.buffer_pos) {
17161716+ skip(parser)
17171717+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17181718+ return false
17191719+ }
17201720+ }
17211721+17221722+ // Scan a handle.
17231723+ if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
17241724+ return false
17251725+ }
17261726+17271727+ // Expect a whitespace.
17281728+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17291729+ return false
17301730+ }
17311731+ if !is_blank(parser.buffer, parser.buffer_pos) {
17321732+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
17331733+ start_mark, "did not find expected whitespace")
17341734+ return false
17351735+ }
17361736+17371737+ // Eat whitespaces.
17381738+ for is_blank(parser.buffer, parser.buffer_pos) {
17391739+ skip(parser)
17401740+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17411741+ return false
17421742+ }
17431743+ }
17441744+17451745+ // Scan a prefix.
17461746+ if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
17471747+ return false
17481748+ }
17491749+17501750+ // Expect a whitespace or line break.
17511751+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17521752+ return false
17531753+ }
17541754+ if !is_blankz(parser.buffer, parser.buffer_pos) {
17551755+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
17561756+ start_mark, "did not find expected whitespace or line break")
17571757+ return false
17581758+ }
17591759+17601760+ *handle = handle_value
17611761+ *prefix = prefix_value
17621762+ return true
17631763+}
17641764+17651765+func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
17661766+ var s []byte
17671767+17681768+ // Eat the indicator character.
17691769+ start_mark := parser.mark
17701770+ skip(parser)
17711771+17721772+ // Consume the value.
17731773+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17741774+ return false
17751775+ }
17761776+17771777+ for is_alpha(parser.buffer, parser.buffer_pos) {
17781778+ s = read(parser, s)
17791779+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
17801780+ return false
17811781+ }
17821782+ }
17831783+17841784+ end_mark := parser.mark
17851785+17861786+ /*
17871787+ * Check if length of the anchor is greater than 0 and it is followed by
17881788+ * a whitespace character or one of the indicators:
17891789+ *
17901790+ * '?', ':', ',', ']', '}', '%', '@', '`'.
17911791+ */
17921792+17931793+ if len(s) == 0 ||
17941794+ !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
17951795+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
17961796+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
17971797+ parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
17981798+ parser.buffer[parser.buffer_pos] == '`') {
17991799+ context := "while scanning an alias"
18001800+ if typ == yaml_ANCHOR_TOKEN {
18011801+ context = "while scanning an anchor"
18021802+ }
18031803+ yaml_parser_set_scanner_error(parser, context, start_mark,
18041804+ "did not find expected alphabetic or numeric character")
18051805+ return false
18061806+ }
18071807+18081808+ // Create a token.
18091809+ *token = yaml_token_t{
18101810+ typ: typ,
18111811+ start_mark: start_mark,
18121812+ end_mark: end_mark,
18131813+ value: s,
18141814+ }
18151815+18161816+ return true
18171817+}
18181818+18191819+/*
18201820+ * Scan a TAG token.
18211821+ */
18221822+18231823+func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
18241824+ var handle, suffix []byte
18251825+18261826+ start_mark := parser.mark
18271827+18281828+ // Check if the tag is in the canonical form.
18291829+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
18301830+ return false
18311831+ }
18321832+18331833+ if parser.buffer[parser.buffer_pos+1] == '<' {
18341834+ // Keep the handle as ''
18351835+18361836+ // Eat '!<'
18371837+ skip(parser)
18381838+ skip(parser)
18391839+18401840+ // Consume the tag value.
18411841+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
18421842+ return false
18431843+ }
18441844+18451845+ // Check for '>' and eat it.
18461846+ if parser.buffer[parser.buffer_pos] != '>' {
18471847+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
18481848+ start_mark, "did not find the expected '>'")
18491849+ return false
18501850+ }
18511851+18521852+ skip(parser)
18531853+ } else {
18541854+ // The tag has either the '!suffix' or the '!handle!suffix' form.
18551855+18561856+ // First, try to scan a handle.
18571857+ if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
18581858+ return false
18591859+ }
18601860+18611861+ // Check if it is, indeed, handle.
18621862+ if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
18631863+ // Scan the suffix now.
18641864+ if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
18651865+ return false
18661866+ }
18671867+ } else {
18681868+ // It wasn't a handle after all. Scan the rest of the tag.
18691869+ if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
18701870+ return false
18711871+ }
18721872+18731873+ // Set the handle to '!'.
18741874+ handle = []byte{'!'}
18751875+18761876+ // A special case: the '!' tag. Set the handle to '' and the
18771877+ // suffix to '!'.
18781878+ if len(suffix) == 0 {
18791879+ handle, suffix = suffix, handle
18801880+ }
18811881+ }
18821882+ }
18831883+18841884+ // Check the character which ends the tag.
18851885+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
18861886+ return false
18871887+ }
18881888+ if !is_blankz(parser.buffer, parser.buffer_pos) {
18891889+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
18901890+ start_mark, "did not find expected whitespace or line break")
18911891+ return false
18921892+ }
18931893+18941894+ end_mark := parser.mark
18951895+18961896+ // Create a token.
18971897+ *token = yaml_token_t{
18981898+ typ: yaml_TAG_TOKEN,
18991899+ start_mark: start_mark,
19001900+ end_mark: end_mark,
19011901+ value: handle,
19021902+ suffix: suffix,
19031903+ }
19041904+ return true
19051905+}
19061906+19071907+// Scan a tag handle.
19081908+func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
19091909+ // Check the initial '!' character.
19101910+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
19111911+ return false
19121912+ }
19131913+ if parser.buffer[parser.buffer_pos] != '!' {
19141914+ yaml_parser_set_scanner_tag_error(parser, directive,
19151915+ start_mark, "did not find expected '!'")
19161916+ return false
19171917+ }
19181918+19191919+ var s []byte
19201920+19211921+ // Copy the '!' character.
19221922+ s = read(parser, s)
19231923+19241924+ // Copy all subsequent alphabetical and numerical characters.
19251925+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
19261926+ return false
19271927+ }
19281928+ for is_alpha(parser.buffer, parser.buffer_pos) {
19291929+ s = read(parser, s)
19301930+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
19311931+ return false
19321932+ }
19331933+ }
19341934+19351935+ // Check if the trailing character is '!' and copy it.
19361936+ if parser.buffer[parser.buffer_pos] == '!' {
19371937+ s = read(parser, s)
19381938+ } else {
19391939+ // It's either the '!' tag or not really a tag handle. If it's a %TAG
19401940+ // directive, it's an error. If it's a tag token, it must be a part of URI.
19411941+ if directive && string(s) != "!" {
19421942+ yaml_parser_set_scanner_tag_error(parser, directive,
19431943+ start_mark, "did not find expected '!'")
19441944+ return false
19451945+ }
19461946+ }
19471947+19481948+ *handle = s
19491949+ return true
19501950+}
19511951+19521952+// Scan a tag.
19531953+func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
19541954+ //size_t length = head ? strlen((char *)head) : 0
19551955+ var s []byte
19561956+ hasTag := len(head) > 0
19571957+19581958+ // Copy the head if needed.
19591959+ //
19601960+ // Note that we don't copy the leading '!' character.
19611961+ if len(head) > 1 {
19621962+ s = append(s, head[1:]...)
19631963+ }
19641964+19651965+ // Scan the tag.
19661966+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
19671967+ return false
19681968+ }
19691969+19701970+ // The set of characters that may appear in URI is as follows:
19711971+ //
19721972+ // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
19731973+ // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
19741974+ // '%'.
19751975+ // [Go] Convert this into more reasonable logic.
19761976+ for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
19771977+ parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
19781978+ parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
19791979+ parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
19801980+ parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
19811981+ parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
19821982+ parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
19831983+ parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
19841984+ parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
19851985+ parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
19861986+ parser.buffer[parser.buffer_pos] == '%' {
19871987+ // Check if it is a URI-escape sequence.
19881988+ if parser.buffer[parser.buffer_pos] == '%' {
19891989+ if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
19901990+ return false
19911991+ }
19921992+ } else {
19931993+ s = read(parser, s)
19941994+ }
19951995+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
19961996+ return false
19971997+ }
19981998+ hasTag = true
19991999+ }
20002000+20012001+ if !hasTag {
20022002+ yaml_parser_set_scanner_tag_error(parser, directive,
20032003+ start_mark, "did not find expected tag URI")
20042004+ return false
20052005+ }
20062006+ *uri = s
20072007+ return true
20082008+}
20092009+20102010+// Decode an URI-escape sequence corresponding to a single UTF-8 character.
20112011+func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
20122012+20132013+ // Decode the required number of characters.
20142014+ w := 1024
20152015+ for w > 0 {
20162016+ // Check for a URI-escaped octet.
20172017+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
20182018+ return false
20192019+ }
20202020+20212021+ if !(parser.buffer[parser.buffer_pos] == '%' &&
20222022+ is_hex(parser.buffer, parser.buffer_pos+1) &&
20232023+ is_hex(parser.buffer, parser.buffer_pos+2)) {
20242024+ return yaml_parser_set_scanner_tag_error(parser, directive,
20252025+ start_mark, "did not find URI escaped octet")
20262026+ }
20272027+20282028+ // Get the octet.
20292029+ octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
20302030+20312031+ // If it is the leading octet, determine the length of the UTF-8 sequence.
20322032+ if w == 1024 {
20332033+ w = width(octet)
20342034+ if w == 0 {
20352035+ return yaml_parser_set_scanner_tag_error(parser, directive,
20362036+ start_mark, "found an incorrect leading UTF-8 octet")
20372037+ }
20382038+ } else {
20392039+ // Check if the trailing octet is correct.
20402040+ if octet&0xC0 != 0x80 {
20412041+ return yaml_parser_set_scanner_tag_error(parser, directive,
20422042+ start_mark, "found an incorrect trailing UTF-8 octet")
20432043+ }
20442044+ }
20452045+20462046+ // Copy the octet and move the pointers.
20472047+ *s = append(*s, octet)
20482048+ skip(parser)
20492049+ skip(parser)
20502050+ skip(parser)
20512051+ w--
20522052+ }
20532053+ return true
20542054+}
20552055+20562056+// Scan a block scalar.
20572057+func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
20582058+ // Eat the indicator '|' or '>'.
20592059+ start_mark := parser.mark
20602060+ skip(parser)
20612061+20622062+ // Scan the additional block scalar indicators.
20632063+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
20642064+ return false
20652065+ }
20662066+20672067+ // Check for a chomping indicator.
20682068+ var chomping, increment int
20692069+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
20702070+ // Set the chomping method and eat the indicator.
20712071+ if parser.buffer[parser.buffer_pos] == '+' {
20722072+ chomping = +1
20732073+ } else {
20742074+ chomping = -1
20752075+ }
20762076+ skip(parser)
20772077+20782078+ // Check for an indentation indicator.
20792079+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
20802080+ return false
20812081+ }
20822082+ if is_digit(parser.buffer, parser.buffer_pos) {
20832083+ // Check that the indentation is greater than 0.
20842084+ if parser.buffer[parser.buffer_pos] == '0' {
20852085+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
20862086+ start_mark, "found an indentation indicator equal to 0")
20872087+ return false
20882088+ }
20892089+20902090+ // Get the indentation level and eat the indicator.
20912091+ increment = as_digit(parser.buffer, parser.buffer_pos)
20922092+ skip(parser)
20932093+ }
20942094+20952095+ } else if is_digit(parser.buffer, parser.buffer_pos) {
20962096+ // Do the same as above, but in the opposite order.
20972097+20982098+ if parser.buffer[parser.buffer_pos] == '0' {
20992099+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
21002100+ start_mark, "found an indentation indicator equal to 0")
21012101+ return false
21022102+ }
21032103+ increment = as_digit(parser.buffer, parser.buffer_pos)
21042104+ skip(parser)
21052105+21062106+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
21072107+ return false
21082108+ }
21092109+ if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
21102110+ if parser.buffer[parser.buffer_pos] == '+' {
21112111+ chomping = +1
21122112+ } else {
21132113+ chomping = -1
21142114+ }
21152115+ skip(parser)
21162116+ }
21172117+ }
21182118+21192119+ // Eat whitespaces and comments to the end of the line.
21202120+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
21212121+ return false
21222122+ }
21232123+ for is_blank(parser.buffer, parser.buffer_pos) {
21242124+ skip(parser)
21252125+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
21262126+ return false
21272127+ }
21282128+ }
21292129+ if parser.buffer[parser.buffer_pos] == '#' {
21302130+ for !is_breakz(parser.buffer, parser.buffer_pos) {
21312131+ skip(parser)
21322132+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
21332133+ return false
21342134+ }
21352135+ }
21362136+ }
21372137+21382138+ // Check if we are at the end of the line.
21392139+ if !is_breakz(parser.buffer, parser.buffer_pos) {
21402140+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
21412141+ start_mark, "did not find expected comment or line break")
21422142+ return false
21432143+ }
21442144+21452145+ // Eat a line break.
21462146+ if is_break(parser.buffer, parser.buffer_pos) {
21472147+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
21482148+ return false
21492149+ }
21502150+ skip_line(parser)
21512151+ }
21522152+21532153+ end_mark := parser.mark
21542154+21552155+ // Set the indentation level if it was specified.
21562156+ var indent int
21572157+ if increment > 0 {
21582158+ if parser.indent >= 0 {
21592159+ indent = parser.indent + increment
21602160+ } else {
21612161+ indent = increment
21622162+ }
21632163+ }
21642164+21652165+ // Scan the leading line breaks and determine the indentation level if needed.
21662166+ var s, leading_break, trailing_breaks []byte
21672167+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
21682168+ return false
21692169+ }
21702170+21712171+ // Scan the block scalar content.
21722172+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
21732173+ return false
21742174+ }
21752175+ var leading_blank, trailing_blank bool
21762176+ for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
21772177+ // We are at the beginning of a non-empty line.
21782178+21792179+ // Is it a trailing whitespace?
21802180+ trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
21812181+21822182+ // Check if we need to fold the leading line break.
21832183+ if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
21842184+ // Do we need to join the lines by space?
21852185+ if len(trailing_breaks) == 0 {
21862186+ s = append(s, ' ')
21872187+ }
21882188+ } else {
21892189+ s = append(s, leading_break...)
21902190+ }
21912191+ leading_break = leading_break[:0]
21922192+21932193+ // Append the remaining line breaks.
21942194+ s = append(s, trailing_breaks...)
21952195+ trailing_breaks = trailing_breaks[:0]
21962196+21972197+ // Is it a leading whitespace?
21982198+ leading_blank = is_blank(parser.buffer, parser.buffer_pos)
21992199+22002200+ // Consume the current line.
22012201+ for !is_breakz(parser.buffer, parser.buffer_pos) {
22022202+ s = read(parser, s)
22032203+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
22042204+ return false
22052205+ }
22062206+ }
22072207+22082208+ // Consume the line break.
22092209+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
22102210+ return false
22112211+ }
22122212+22132213+ leading_break = read_line(parser, leading_break)
22142214+22152215+ // Eat the following indentation spaces and line breaks.
22162216+ if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
22172217+ return false
22182218+ }
22192219+ }
22202220+22212221+ // Chomp the tail.
22222222+ if chomping != -1 {
22232223+ s = append(s, leading_break...)
22242224+ }
22252225+ if chomping == 1 {
22262226+ s = append(s, trailing_breaks...)
22272227+ }
22282228+22292229+ // Create a token.
22302230+ *token = yaml_token_t{
22312231+ typ: yaml_SCALAR_TOKEN,
22322232+ start_mark: start_mark,
22332233+ end_mark: end_mark,
22342234+ value: s,
22352235+ style: yaml_LITERAL_SCALAR_STYLE,
22362236+ }
22372237+ if !literal {
22382238+ token.style = yaml_FOLDED_SCALAR_STYLE
22392239+ }
22402240+ return true
22412241+}
22422242+22432243+// Scan indentation spaces and line breaks for a block scalar. Determine the
22442244+// indentation level if needed.
22452245+func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
22462246+ *end_mark = parser.mark
22472247+22482248+ // Eat the indentation spaces and line breaks.
22492249+ max_indent := 0
22502250+ for {
22512251+ // Eat the indentation spaces.
22522252+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
22532253+ return false
22542254+ }
22552255+ for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
22562256+ skip(parser)
22572257+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
22582258+ return false
22592259+ }
22602260+ }
22612261+ if parser.mark.column > max_indent {
22622262+ max_indent = parser.mark.column
22632263+ }
22642264+22652265+ // Check for a tab character messing the indentation.
22662266+ if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
22672267+ return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
22682268+ start_mark, "found a tab character where an indentation space is expected")
22692269+ }
22702270+22712271+ // Have we found a non-empty line?
22722272+ if !is_break(parser.buffer, parser.buffer_pos) {
22732273+ break
22742274+ }
22752275+22762276+ // Consume the line break.
22772277+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
22782278+ return false
22792279+ }
22802280+ // [Go] Should really be returning breaks instead.
22812281+ *breaks = read_line(parser, *breaks)
22822282+ *end_mark = parser.mark
22832283+ }
22842284+22852285+ // Determine the indentation level if needed.
22862286+ if *indent == 0 {
22872287+ *indent = max_indent
22882288+ if *indent < parser.indent+1 {
22892289+ *indent = parser.indent + 1
22902290+ }
22912291+ if *indent < 1 {
22922292+ *indent = 1
22932293+ }
22942294+ }
22952295+ return true
22962296+}
22972297+22982298+// Scan a quoted scalar.
22992299+func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
23002300+ // Eat the left quote.
23012301+ start_mark := parser.mark
23022302+ skip(parser)
23032303+23042304+ // Consume the content of the quoted scalar.
23052305+ var s, leading_break, trailing_breaks, whitespaces []byte
23062306+ for {
23072307+ // Check that there are no document indicators at the beginning of the line.
23082308+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
23092309+ return false
23102310+ }
23112311+23122312+ if parser.mark.column == 0 &&
23132313+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
23142314+ parser.buffer[parser.buffer_pos+1] == '-' &&
23152315+ parser.buffer[parser.buffer_pos+2] == '-') ||
23162316+ (parser.buffer[parser.buffer_pos+0] == '.' &&
23172317+ parser.buffer[parser.buffer_pos+1] == '.' &&
23182318+ parser.buffer[parser.buffer_pos+2] == '.')) &&
23192319+ is_blankz(parser.buffer, parser.buffer_pos+3) {
23202320+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
23212321+ start_mark, "found unexpected document indicator")
23222322+ return false
23232323+ }
23242324+23252325+ // Check for EOF.
23262326+ if is_z(parser.buffer, parser.buffer_pos) {
23272327+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
23282328+ start_mark, "found unexpected end of stream")
23292329+ return false
23302330+ }
23312331+23322332+ // Consume non-blank characters.
23332333+ leading_blanks := false
23342334+ for !is_blankz(parser.buffer, parser.buffer_pos) {
23352335+ if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
23362336+ // Is is an escaped single quote.
23372337+ s = append(s, '\'')
23382338+ skip(parser)
23392339+ skip(parser)
23402340+23412341+ } else if single && parser.buffer[parser.buffer_pos] == '\'' {
23422342+ // It is a right single quote.
23432343+ break
23442344+ } else if !single && parser.buffer[parser.buffer_pos] == '"' {
23452345+ // It is a right double quote.
23462346+ break
23472347+23482348+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
23492349+ // It is an escaped line break.
23502350+ if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
23512351+ return false
23522352+ }
23532353+ skip(parser)
23542354+ skip_line(parser)
23552355+ leading_blanks = true
23562356+ break
23572357+23582358+ } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
23592359+ // It is an escape sequence.
23602360+ code_length := 0
23612361+23622362+ // Check the escape character.
23632363+ switch parser.buffer[parser.buffer_pos+1] {
23642364+ case '0':
23652365+ s = append(s, 0)
23662366+ case 'a':
23672367+ s = append(s, '\x07')
23682368+ case 'b':
23692369+ s = append(s, '\x08')
23702370+ case 't', '\t':
23712371+ s = append(s, '\x09')
23722372+ case 'n':
23732373+ s = append(s, '\x0A')
23742374+ case 'v':
23752375+ s = append(s, '\x0B')
23762376+ case 'f':
23772377+ s = append(s, '\x0C')
23782378+ case 'r':
23792379+ s = append(s, '\x0D')
23802380+ case 'e':
23812381+ s = append(s, '\x1B')
23822382+ case ' ':
23832383+ s = append(s, '\x20')
23842384+ case '"':
23852385+ s = append(s, '"')
23862386+ case '\'':
23872387+ s = append(s, '\'')
23882388+ case '\\':
23892389+ s = append(s, '\\')
23902390+ case 'N': // NEL (#x85)
23912391+ s = append(s, '\xC2')
23922392+ s = append(s, '\x85')
23932393+ case '_': // #xA0
23942394+ s = append(s, '\xC2')
23952395+ s = append(s, '\xA0')
23962396+ case 'L': // LS (#x2028)
23972397+ s = append(s, '\xE2')
23982398+ s = append(s, '\x80')
23992399+ s = append(s, '\xA8')
24002400+ case 'P': // PS (#x2029)
24012401+ s = append(s, '\xE2')
24022402+ s = append(s, '\x80')
24032403+ s = append(s, '\xA9')
24042404+ case 'x':
24052405+ code_length = 2
24062406+ case 'u':
24072407+ code_length = 4
24082408+ case 'U':
24092409+ code_length = 8
24102410+ default:
24112411+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
24122412+ start_mark, "found unknown escape character")
24132413+ return false
24142414+ }
24152415+24162416+ skip(parser)
24172417+ skip(parser)
24182418+24192419+ // Consume an arbitrary escape code.
24202420+ if code_length > 0 {
24212421+ var value int
24222422+24232423+ // Scan the character value.
24242424+ if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
24252425+ return false
24262426+ }
24272427+ for k := 0; k < code_length; k++ {
24282428+ if !is_hex(parser.buffer, parser.buffer_pos+k) {
24292429+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
24302430+ start_mark, "did not find expected hexdecimal number")
24312431+ return false
24322432+ }
24332433+ value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
24342434+ }
24352435+24362436+ // Check the value and write the character.
24372437+ if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
24382438+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
24392439+ start_mark, "found invalid Unicode character escape code")
24402440+ return false
24412441+ }
24422442+ if value <= 0x7F {
24432443+ s = append(s, byte(value))
24442444+ } else if value <= 0x7FF {
24452445+ s = append(s, byte(0xC0+(value>>6)))
24462446+ s = append(s, byte(0x80+(value&0x3F)))
24472447+ } else if value <= 0xFFFF {
24482448+ s = append(s, byte(0xE0+(value>>12)))
24492449+ s = append(s, byte(0x80+((value>>6)&0x3F)))
24502450+ s = append(s, byte(0x80+(value&0x3F)))
24512451+ } else {
24522452+ s = append(s, byte(0xF0+(value>>18)))
24532453+ s = append(s, byte(0x80+((value>>12)&0x3F)))
24542454+ s = append(s, byte(0x80+((value>>6)&0x3F)))
24552455+ s = append(s, byte(0x80+(value&0x3F)))
24562456+ }
24572457+24582458+ // Advance the pointer.
24592459+ for k := 0; k < code_length; k++ {
24602460+ skip(parser)
24612461+ }
24622462+ }
24632463+ } else {
24642464+ // It is a non-escaped non-blank character.
24652465+ s = read(parser, s)
24662466+ }
24672467+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
24682468+ return false
24692469+ }
24702470+ }
24712471+24722472+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
24732473+ return false
24742474+ }
24752475+24762476+ // Check if we are at the end of the scalar.
24772477+ if single {
24782478+ if parser.buffer[parser.buffer_pos] == '\'' {
24792479+ break
24802480+ }
24812481+ } else {
24822482+ if parser.buffer[parser.buffer_pos] == '"' {
24832483+ break
24842484+ }
24852485+ }
24862486+24872487+ // Consume blank characters.
24882488+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
24892489+ if is_blank(parser.buffer, parser.buffer_pos) {
24902490+ // Consume a space or a tab character.
24912491+ if !leading_blanks {
24922492+ whitespaces = read(parser, whitespaces)
24932493+ } else {
24942494+ skip(parser)
24952495+ }
24962496+ } else {
24972497+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
24982498+ return false
24992499+ }
25002500+25012501+ // Check if it is a first line break.
25022502+ if !leading_blanks {
25032503+ whitespaces = whitespaces[:0]
25042504+ leading_break = read_line(parser, leading_break)
25052505+ leading_blanks = true
25062506+ } else {
25072507+ trailing_breaks = read_line(parser, trailing_breaks)
25082508+ }
25092509+ }
25102510+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
25112511+ return false
25122512+ }
25132513+ }
25142514+25152515+ // Join the whitespaces or fold line breaks.
25162516+ if leading_blanks {
25172517+ // Do we need to fold line breaks?
25182518+ if len(leading_break) > 0 && leading_break[0] == '\n' {
25192519+ if len(trailing_breaks) == 0 {
25202520+ s = append(s, ' ')
25212521+ } else {
25222522+ s = append(s, trailing_breaks...)
25232523+ }
25242524+ } else {
25252525+ s = append(s, leading_break...)
25262526+ s = append(s, trailing_breaks...)
25272527+ }
25282528+ trailing_breaks = trailing_breaks[:0]
25292529+ leading_break = leading_break[:0]
25302530+ } else {
25312531+ s = append(s, whitespaces...)
25322532+ whitespaces = whitespaces[:0]
25332533+ }
25342534+ }
25352535+25362536+ // Eat the right quote.
25372537+ skip(parser)
25382538+ end_mark := parser.mark
25392539+25402540+ // Create a token.
25412541+ *token = yaml_token_t{
25422542+ typ: yaml_SCALAR_TOKEN,
25432543+ start_mark: start_mark,
25442544+ end_mark: end_mark,
25452545+ value: s,
25462546+ style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
25472547+ }
25482548+ if !single {
25492549+ token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
25502550+ }
25512551+ return true
25522552+}
25532553+25542554+// Scan a plain scalar.
25552555+func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
25562556+25572557+ var s, leading_break, trailing_breaks, whitespaces []byte
25582558+ var leading_blanks bool
25592559+ var indent = parser.indent + 1
25602560+25612561+ start_mark := parser.mark
25622562+ end_mark := parser.mark
25632563+25642564+ // Consume the content of the plain scalar.
25652565+ for {
25662566+ // Check for a document indicator.
25672567+ if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
25682568+ return false
25692569+ }
25702570+ if parser.mark.column == 0 &&
25712571+ ((parser.buffer[parser.buffer_pos+0] == '-' &&
25722572+ parser.buffer[parser.buffer_pos+1] == '-' &&
25732573+ parser.buffer[parser.buffer_pos+2] == '-') ||
25742574+ (parser.buffer[parser.buffer_pos+0] == '.' &&
25752575+ parser.buffer[parser.buffer_pos+1] == '.' &&
25762576+ parser.buffer[parser.buffer_pos+2] == '.')) &&
25772577+ is_blankz(parser.buffer, parser.buffer_pos+3) {
25782578+ break
25792579+ }
25802580+25812581+ // Check for a comment.
25822582+ if parser.buffer[parser.buffer_pos] == '#' {
25832583+ break
25842584+ }
25852585+25862586+ // Consume non-blank characters.
25872587+ for !is_blankz(parser.buffer, parser.buffer_pos) {
25882588+25892589+ // Check for indicators that may end a plain scalar.
25902590+ if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
25912591+ (parser.flow_level > 0 &&
25922592+ (parser.buffer[parser.buffer_pos] == ',' ||
25932593+ parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
25942594+ parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
25952595+ parser.buffer[parser.buffer_pos] == '}')) {
25962596+ break
25972597+ }
25982598+25992599+ // Check if we need to join whitespaces and breaks.
26002600+ if leading_blanks || len(whitespaces) > 0 {
26012601+ if leading_blanks {
26022602+ // Do we need to fold line breaks?
26032603+ if leading_break[0] == '\n' {
26042604+ if len(trailing_breaks) == 0 {
26052605+ s = append(s, ' ')
26062606+ } else {
26072607+ s = append(s, trailing_breaks...)
26082608+ }
26092609+ } else {
26102610+ s = append(s, leading_break...)
26112611+ s = append(s, trailing_breaks...)
26122612+ }
26132613+ trailing_breaks = trailing_breaks[:0]
26142614+ leading_break = leading_break[:0]
26152615+ leading_blanks = false
26162616+ } else {
26172617+ s = append(s, whitespaces...)
26182618+ whitespaces = whitespaces[:0]
26192619+ }
26202620+ }
26212621+26222622+ // Copy the character.
26232623+ s = read(parser, s)
26242624+26252625+ end_mark = parser.mark
26262626+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
26272627+ return false
26282628+ }
26292629+ }
26302630+26312631+ // Is it the end?
26322632+ if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
26332633+ break
26342634+ }
26352635+26362636+ // Consume blank characters.
26372637+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
26382638+ return false
26392639+ }
26402640+26412641+ for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
26422642+ if is_blank(parser.buffer, parser.buffer_pos) {
26432643+26442644+ // Check for tab characters that abuse indentation.
26452645+ if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
26462646+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
26472647+ start_mark, "found a tab character that violates indentation")
26482648+ return false
26492649+ }
26502650+26512651+ // Consume a space or a tab character.
26522652+ if !leading_blanks {
26532653+ whitespaces = read(parser, whitespaces)
26542654+ } else {
26552655+ skip(parser)
26562656+ }
26572657+ } else {
26582658+ if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
26592659+ return false
26602660+ }
26612661+26622662+ // Check if it is a first line break.
26632663+ if !leading_blanks {
26642664+ whitespaces = whitespaces[:0]
26652665+ leading_break = read_line(parser, leading_break)
26662666+ leading_blanks = true
26672667+ } else {
26682668+ trailing_breaks = read_line(parser, trailing_breaks)
26692669+ }
26702670+ }
26712671+ if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
26722672+ return false
26732673+ }
26742674+ }
26752675+26762676+ // Check indentation level.
26772677+ if parser.flow_level == 0 && parser.mark.column < indent {
26782678+ break
26792679+ }
26802680+ }
26812681+26822682+ // Create a token.
26832683+ *token = yaml_token_t{
26842684+ typ: yaml_SCALAR_TOKEN,
26852685+ start_mark: start_mark,
26862686+ end_mark: end_mark,
26872687+ value: s,
26882688+ style: yaml_PLAIN_SCALAR_STYLE,
26892689+ }
26902690+26912691+ // Note that we change the 'simple_key_allowed' flag.
26922692+ if leading_blanks {
26932693+ parser.simple_key_allowed = true
26942694+ }
26952695+ return true
26962696+}
+113
internal/third_party/yaml/sorter.go
···11+package yaml
22+33+import (
44+ "reflect"
55+ "unicode"
66+)
77+88+type keyList []reflect.Value
99+1010+func (l keyList) Len() int { return len(l) }
1111+func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
1212+func (l keyList) Less(i, j int) bool {
1313+ a := l[i]
1414+ b := l[j]
1515+ ak := a.Kind()
1616+ bk := b.Kind()
1717+ for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
1818+ a = a.Elem()
1919+ ak = a.Kind()
2020+ }
2121+ for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
2222+ b = b.Elem()
2323+ bk = b.Kind()
2424+ }
2525+ af, aok := keyFloat(a)
2626+ bf, bok := keyFloat(b)
2727+ if aok && bok {
2828+ if af != bf {
2929+ return af < bf
3030+ }
3131+ if ak != bk {
3232+ return ak < bk
3333+ }
3434+ return numLess(a, b)
3535+ }
3636+ if ak != reflect.String || bk != reflect.String {
3737+ return ak < bk
3838+ }
3939+ ar, br := []rune(a.String()), []rune(b.String())
4040+ for i := 0; i < len(ar) && i < len(br); i++ {
4141+ if ar[i] == br[i] {
4242+ continue
4343+ }
4444+ al := unicode.IsLetter(ar[i])
4545+ bl := unicode.IsLetter(br[i])
4646+ if al && bl {
4747+ return ar[i] < br[i]
4848+ }
4949+ if al || bl {
5050+ return bl
5151+ }
5252+ var ai, bi int
5353+ var an, bn int64
5454+ if ar[i] == '0' || br[i] == '0' {
5555+ for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
5656+ if ar[j] != '0' {
5757+ an = 1
5858+ bn = 1
5959+ break
6060+ }
6161+ }
6262+ }
6363+ for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
6464+ an = an*10 + int64(ar[ai]-'0')
6565+ }
6666+ for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
6767+ bn = bn*10 + int64(br[bi]-'0')
6868+ }
6969+ if an != bn {
7070+ return an < bn
7171+ }
7272+ if ai != bi {
7373+ return ai < bi
7474+ }
7575+ return ar[i] < br[i]
7676+ }
7777+ return len(ar) < len(br)
7878+}
7979+8080+// keyFloat returns a float value for v if it is a number/bool
8181+// and whether it is a number/bool or not.
8282+func keyFloat(v reflect.Value) (f float64, ok bool) {
8383+ switch v.Kind() {
8484+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
8585+ return float64(v.Int()), true
8686+ case reflect.Float32, reflect.Float64:
8787+ return v.Float(), true
8888+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
8989+ return float64(v.Uint()), true
9090+ case reflect.Bool:
9191+ if v.Bool() {
9292+ return 1, true
9393+ }
9494+ return 0, true
9595+ }
9696+ return 0, false
9797+}
9898+9999+// numLess returns whether a < b.
100100+// a and b must necessarily have the same kind.
101101+func numLess(a, b reflect.Value) bool {
102102+ switch a.Kind() {
103103+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
104104+ return a.Int() < b.Int()
105105+ case reflect.Float32, reflect.Float64:
106106+ return a.Float() < b.Float()
107107+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
108108+ return a.Uint() < b.Uint()
109109+ case reflect.Bool:
110110+ return !a.Bool() && b.Bool()
111111+ }
112112+ panic("not a number")
113113+}
···11+package yaml
22+33+// Set the writer error and return false.
44+func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
55+ emitter.error = yaml_WRITER_ERROR
66+ emitter.problem = problem
77+ return false
88+}
99+1010+// Flush the output buffer.
1111+func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
1212+ if emitter.write_handler == nil {
1313+ panic("write handler not set")
1414+ }
1515+1616+ // Check if the buffer is empty.
1717+ if emitter.buffer_pos == 0 {
1818+ return true
1919+ }
2020+2121+ if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
2222+ return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
2323+ }
2424+ emitter.buffer_pos = 0
2525+ return true
2626+}
+466
internal/third_party/yaml/yaml.go
···11+// Package yaml implements YAML support for the Go language.
22+//
33+// Source code and other details for the project are available at GitHub:
44+//
55+// https://github.com/go-yaml/yaml
66+//
77+package yaml
88+99+import (
1010+ "errors"
1111+ "fmt"
1212+ "io"
1313+ "reflect"
1414+ "strings"
1515+ "sync"
1616+)
1717+1818+// MapSlice encodes and decodes as a YAML map.
1919+// The order of keys is preserved when encoding and decoding.
2020+type MapSlice []MapItem
2121+2222+// MapItem is an item in a MapSlice.
2323+type MapItem struct {
2424+ Key, Value interface{}
2525+}
2626+2727+// The Unmarshaler interface may be implemented by types to customize their
2828+// behavior when being unmarshaled from a YAML document. The UnmarshalYAML
2929+// method receives a function that may be called to unmarshal the original
3030+// YAML value into a field or variable. It is safe to call the unmarshal
3131+// function parameter more than once if necessary.
3232+type Unmarshaler interface {
3333+ UnmarshalYAML(unmarshal func(interface{}) error) error
3434+}
3535+3636+// The Marshaler interface may be implemented by types to customize their
3737+// behavior when being marshaled into a YAML document. The returned value
3838+// is marshaled in place of the original value implementing Marshaler.
3939+//
4040+// If an error is returned by MarshalYAML, the marshaling procedure stops
4141+// and returns with the provided error.
4242+type Marshaler interface {
4343+ MarshalYAML() (interface{}, error)
4444+}
4545+4646+// Unmarshal decodes the first document found within the in byte slice
4747+// and assigns decoded values into the out value.
4848+//
4949+// Maps and pointers (to a struct, string, int, etc) are accepted as out
5050+// values. If an internal pointer within a struct is not initialized,
5151+// the yaml package will initialize it if necessary for unmarshalling
5252+// the provided data. The out parameter must not be nil.
5353+//
5454+// The type of the decoded values should be compatible with the respective
5555+// values in out. If one or more values cannot be decoded due to a type
5656+// mismatches, decoding continues partially until the end of the YAML
5757+// content, and a *yaml.TypeError is returned with details for all
5858+// missed values.
5959+//
6060+// Struct fields are only unmarshalled if they are exported (have an
6161+// upper case first letter), and are unmarshalled using the field name
6262+// lowercased as the default key. Custom keys may be defined via the
6363+// "yaml" name in the field tag: the content preceding the first comma
6464+// is used as the key, and the following comma-separated options are
6565+// used to tweak the marshalling process (see Marshal).
6666+// Conflicting names result in a runtime error.
6767+//
6868+// For example:
6969+//
7070+// type T struct {
7171+// F int `yaml:"a,omitempty"`
7272+// B int
7373+// }
7474+// var t T
7575+// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t)
7676+//
7777+// See the documentation of Marshal for the format of tags and a list of
7878+// supported tag options.
7979+//
8080+func Unmarshal(in []byte, out interface{}) (err error) {
8181+ return unmarshal(in, out, false)
8282+}
8383+8484+// UnmarshalStrict is like Unmarshal except that any fields that are found
8585+// in the data that do not have corresponding struct members, or mapping
8686+// keys that are duplicates, will result in
8787+// an error.
8888+func UnmarshalStrict(in []byte, out interface{}) (err error) {
8989+ return unmarshal(in, out, true)
9090+}
9191+9292+// A Decorder reads and decodes YAML values from an input stream.
9393+type Decoder struct {
9494+ strict bool
9595+ parser *parser
9696+}
9797+9898+// NewDecoder returns a new decoder that reads from r.
9999+//
100100+// The decoder introduces its own buffering and may read
101101+// data from r beyond the YAML values requested.
102102+func NewDecoder(r io.Reader) *Decoder {
103103+ return &Decoder{
104104+ parser: newParserFromReader(r),
105105+ }
106106+}
107107+108108+// SetStrict sets whether strict decoding behaviour is enabled when
109109+// decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
110110+func (dec *Decoder) SetStrict(strict bool) {
111111+ dec.strict = strict
112112+}
113113+114114+// Decode reads the next YAML-encoded value from its input
115115+// and stores it in the value pointed to by v.
116116+//
117117+// See the documentation for Unmarshal for details about the
118118+// conversion of YAML into a Go value.
119119+func (dec *Decoder) Decode(v interface{}) (err error) {
120120+ d := newDecoder(dec.strict)
121121+ defer handleErr(&err)
122122+ node := dec.parser.parse()
123123+ if node == nil {
124124+ return io.EOF
125125+ }
126126+ out := reflect.ValueOf(v)
127127+ if out.Kind() == reflect.Ptr && !out.IsNil() {
128128+ out = out.Elem()
129129+ }
130130+ d.unmarshal(node, out)
131131+ if len(d.terrors) > 0 {
132132+ return &TypeError{d.terrors}
133133+ }
134134+ return nil
135135+}
136136+137137+func unmarshal(in []byte, out interface{}, strict bool) (err error) {
138138+ defer handleErr(&err)
139139+ d := newDecoder(strict)
140140+ p := newParser(in)
141141+ defer p.destroy()
142142+ node := p.parse()
143143+ if node != nil {
144144+ v := reflect.ValueOf(out)
145145+ if v.Kind() == reflect.Ptr && !v.IsNil() {
146146+ v = v.Elem()
147147+ }
148148+ d.unmarshal(node, v)
149149+ }
150150+ if len(d.terrors) > 0 {
151151+ return &TypeError{d.terrors}
152152+ }
153153+ return nil
154154+}
155155+156156+// Marshal serializes the value provided into a YAML document. The structure
157157+// of the generated document will reflect the structure of the value itself.
158158+// Maps and pointers (to struct, string, int, etc) are accepted as the in value.
159159+//
160160+// Struct fields are only marshalled if they are exported (have an upper case
161161+// first letter), and are marshalled using the field name lowercased as the
162162+// default key. Custom keys may be defined via the "yaml" name in the field
163163+// tag: the content preceding the first comma is used as the key, and the
164164+// following comma-separated options are used to tweak the marshalling process.
165165+// Conflicting names result in a runtime error.
166166+//
167167+// The field tag format accepted is:
168168+//
169169+// `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)`
170170+//
171171+// The following flags are currently supported:
172172+//
173173+// omitempty Only include the field if it's not set to the zero
174174+// value for the type or to empty slices or maps.
175175+// Zero valued structs will be omitted if all their public
176176+// fields are zero, unless they implement an IsZero
177177+// method (see the IsZeroer interface type), in which
178178+// case the field will be included if that method returns true.
179179+//
180180+// flow Marshal using a flow style (useful for structs,
181181+// sequences and maps).
182182+//
183183+// inline Inline the field, which must be a struct or a map,
184184+// causing all of its fields or keys to be processed as if
185185+// they were part of the outer struct. For maps, keys must
186186+// not conflict with the yaml keys of other struct fields.
187187+//
188188+// In addition, if the key is "-", the field is ignored.
189189+//
190190+// For example:
191191+//
192192+// type T struct {
193193+// F int `yaml:"a,omitempty"`
194194+// B int
195195+// }
196196+// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
197197+// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n"
198198+//
199199+func Marshal(in interface{}) (out []byte, err error) {
200200+ defer handleErr(&err)
201201+ e := newEncoder()
202202+ defer e.destroy()
203203+ e.marshalDoc("", reflect.ValueOf(in))
204204+ e.finish()
205205+ out = e.out
206206+ return
207207+}
208208+209209+// An Encoder writes YAML values to an output stream.
210210+type Encoder struct {
211211+ encoder *encoder
212212+}
213213+214214+// NewEncoder returns a new encoder that writes to w.
215215+// The Encoder should be closed after use to flush all data
216216+// to w.
217217+func NewEncoder(w io.Writer) *Encoder {
218218+ return &Encoder{
219219+ encoder: newEncoderWithWriter(w),
220220+ }
221221+}
222222+223223+// Encode writes the YAML encoding of v to the stream.
224224+// If multiple items are encoded to the stream, the
225225+// second and subsequent document will be preceded
226226+// with a "---" document separator, but the first will not.
227227+//
228228+// See the documentation for Marshal for details about the conversion of Go
229229+// values to YAML.
230230+func (e *Encoder) Encode(v interface{}) (err error) {
231231+ defer handleErr(&err)
232232+ e.encoder.marshalDoc("", reflect.ValueOf(v))
233233+ return nil
234234+}
235235+236236+// Close closes the encoder by writing any remaining data.
237237+// It does not write a stream terminating string "...".
238238+func (e *Encoder) Close() (err error) {
239239+ defer handleErr(&err)
240240+ e.encoder.finish()
241241+ return nil
242242+}
243243+244244+func handleErr(err *error) {
245245+ if v := recover(); v != nil {
246246+ if e, ok := v.(yamlError); ok {
247247+ *err = e.err
248248+ } else {
249249+ panic(v)
250250+ }
251251+ }
252252+}
253253+254254+type yamlError struct {
255255+ err error
256256+}
257257+258258+func fail(err error) {
259259+ panic(yamlError{err})
260260+}
261261+262262+func failf(format string, args ...interface{}) {
263263+ panic(yamlError{fmt.Errorf("yaml: "+format, args...)})
264264+}
265265+266266+// A TypeError is returned by Unmarshal when one or more fields in
267267+// the YAML document cannot be properly decoded into the requested
268268+// types. When this error is returned, the value is still
269269+// unmarshaled partially.
270270+type TypeError struct {
271271+ Errors []string
272272+}
273273+274274+func (e *TypeError) Error() string {
275275+ return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n "))
276276+}
277277+278278+// --------------------------------------------------------------------------
279279+// Maintain a mapping of keys to structure field indexes
280280+281281+// The code in this section was copied from mgo/bson.
282282+283283+// structInfo holds details for the serialization of fields of
284284+// a given struct.
285285+type structInfo struct {
286286+ FieldsMap map[string]fieldInfo
287287+ FieldsList []fieldInfo
288288+289289+ // InlineMap is the number of the field in the struct that
290290+ // contains an ,inline map, or -1 if there's none.
291291+ InlineMap int
292292+}
293293+294294+type fieldInfo struct {
295295+ Key string
296296+ Num int
297297+ OmitEmpty bool
298298+ Flow bool
299299+ // Id holds the unique field identifier, so we can cheaply
300300+ // check for field duplicates without maintaining an extra map.
301301+ Id int
302302+303303+ // Inline holds the field index if the field is part of an inlined struct.
304304+ Inline []int
305305+}
306306+307307+var structMap = make(map[reflect.Type]*structInfo)
308308+var fieldMapMutex sync.RWMutex
309309+310310+func getStructInfo(st reflect.Type) (*structInfo, error) {
311311+ fieldMapMutex.RLock()
312312+ sinfo, found := structMap[st]
313313+ fieldMapMutex.RUnlock()
314314+ if found {
315315+ return sinfo, nil
316316+ }
317317+318318+ n := st.NumField()
319319+ fieldsMap := make(map[string]fieldInfo)
320320+ fieldsList := make([]fieldInfo, 0, n)
321321+ inlineMap := -1
322322+ for i := 0; i != n; i++ {
323323+ field := st.Field(i)
324324+ if field.PkgPath != "" && !field.Anonymous {
325325+ continue // Private field
326326+ }
327327+328328+ info := fieldInfo{Num: i}
329329+330330+ tag := field.Tag.Get("yaml")
331331+ if tag == "" && strings.Index(string(field.Tag), ":") < 0 {
332332+ tag = string(field.Tag)
333333+ }
334334+ if tag == "-" {
335335+ continue
336336+ }
337337+338338+ inline := false
339339+ fields := strings.Split(tag, ",")
340340+ if len(fields) > 1 {
341341+ for _, flag := range fields[1:] {
342342+ switch flag {
343343+ case "omitempty":
344344+ info.OmitEmpty = true
345345+ case "flow":
346346+ info.Flow = true
347347+ case "inline":
348348+ inline = true
349349+ default:
350350+ return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st))
351351+ }
352352+ }
353353+ tag = fields[0]
354354+ }
355355+356356+ if inline {
357357+ switch field.Type.Kind() {
358358+ case reflect.Map:
359359+ if inlineMap >= 0 {
360360+ return nil, errors.New("Multiple ,inline maps in struct " + st.String())
361361+ }
362362+ if field.Type.Key() != reflect.TypeOf("") {
363363+ return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String())
364364+ }
365365+ inlineMap = info.Num
366366+ case reflect.Struct:
367367+ sinfo, err := getStructInfo(field.Type)
368368+ if err != nil {
369369+ return nil, err
370370+ }
371371+ for _, finfo := range sinfo.FieldsList {
372372+ if _, found := fieldsMap[finfo.Key]; found {
373373+ msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String()
374374+ return nil, errors.New(msg)
375375+ }
376376+ if finfo.Inline == nil {
377377+ finfo.Inline = []int{i, finfo.Num}
378378+ } else {
379379+ finfo.Inline = append([]int{i}, finfo.Inline...)
380380+ }
381381+ finfo.Id = len(fieldsList)
382382+ fieldsMap[finfo.Key] = finfo
383383+ fieldsList = append(fieldsList, finfo)
384384+ }
385385+ default:
386386+ //return nil, errors.New("Option ,inline needs a struct value or map field")
387387+ return nil, errors.New("Option ,inline needs a struct value field")
388388+ }
389389+ continue
390390+ }
391391+392392+ if tag != "" {
393393+ info.Key = tag
394394+ } else {
395395+ info.Key = strings.ToLower(field.Name)
396396+ }
397397+398398+ if _, found = fieldsMap[info.Key]; found {
399399+ msg := "Duplicated key '" + info.Key + "' in struct " + st.String()
400400+ return nil, errors.New(msg)
401401+ }
402402+403403+ info.Id = len(fieldsList)
404404+ fieldsList = append(fieldsList, info)
405405+ fieldsMap[info.Key] = info
406406+ }
407407+408408+ sinfo = &structInfo{
409409+ FieldsMap: fieldsMap,
410410+ FieldsList: fieldsList,
411411+ InlineMap: inlineMap,
412412+ }
413413+414414+ fieldMapMutex.Lock()
415415+ structMap[st] = sinfo
416416+ fieldMapMutex.Unlock()
417417+ return sinfo, nil
418418+}
419419+420420+// IsZeroer is used to check whether an object is zero to
421421+// determine whether it should be omitted when marshaling
422422+// with the omitempty flag. One notable implementation
423423+// is time.Time.
424424+type IsZeroer interface {
425425+ IsZero() bool
426426+}
427427+428428+func isZero(v reflect.Value) bool {
429429+ kind := v.Kind()
430430+ if z, ok := v.Interface().(IsZeroer); ok {
431431+ if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
432432+ return true
433433+ }
434434+ return z.IsZero()
435435+ }
436436+ switch kind {
437437+ case reflect.String:
438438+ return len(v.String()) == 0
439439+ case reflect.Interface, reflect.Ptr:
440440+ return v.IsNil()
441441+ case reflect.Slice:
442442+ return v.Len() == 0
443443+ case reflect.Map:
444444+ return v.Len() == 0
445445+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
446446+ return v.Int() == 0
447447+ case reflect.Float32, reflect.Float64:
448448+ return v.Float() == 0
449449+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
450450+ return v.Uint() == 0
451451+ case reflect.Bool:
452452+ return !v.Bool()
453453+ case reflect.Struct:
454454+ vt := v.Type()
455455+ for i := v.NumField() - 1; i >= 0; i-- {
456456+ if vt.Field(i).PkgPath != "" {
457457+ continue // Private field
458458+ }
459459+ if !isZero(v.Field(i)) {
460460+ return false
461461+ }
462462+ }
463463+ return true
464464+ }
465465+ return false
466466+}
+738
internal/third_party/yaml/yamlh.go
···11+package yaml
22+33+import (
44+ "fmt"
55+ "io"
66+)
77+88+// The version directive data.
99+type yaml_version_directive_t struct {
1010+ major int8 // The major version number.
1111+ minor int8 // The minor version number.
1212+}
1313+1414+// The tag directive data.
1515+type yaml_tag_directive_t struct {
1616+ handle []byte // The tag handle.
1717+ prefix []byte // The tag prefix.
1818+}
1919+2020+type yaml_encoding_t int
2121+2222+// The stream encoding.
2323+const (
2424+ // Let the parser choose the encoding.
2525+ yaml_ANY_ENCODING yaml_encoding_t = iota
2626+2727+ yaml_UTF8_ENCODING // The default UTF-8 encoding.
2828+ yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.
2929+ yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.
3030+)
3131+3232+type yaml_break_t int
3333+3434+// Line break types.
3535+const (
3636+ // Let the parser choose the break type.
3737+ yaml_ANY_BREAK yaml_break_t = iota
3838+3939+ yaml_CR_BREAK // Use CR for line breaks (Mac style).
4040+ yaml_LN_BREAK // Use LN for line breaks (Unix style).
4141+ yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).
4242+)
4343+4444+type yaml_error_type_t int
4545+4646+// Many bad things could happen with the parser and emitter.
4747+const (
4848+ // No error is produced.
4949+ yaml_NO_ERROR yaml_error_type_t = iota
5050+5151+ yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory.
5252+ yaml_READER_ERROR // Cannot read or decode the input stream.
5353+ yaml_SCANNER_ERROR // Cannot scan the input stream.
5454+ yaml_PARSER_ERROR // Cannot parse the input stream.
5555+ yaml_COMPOSER_ERROR // Cannot compose a YAML document.
5656+ yaml_WRITER_ERROR // Cannot write to the output stream.
5757+ yaml_EMITTER_ERROR // Cannot emit a YAML stream.
5858+)
5959+6060+// The pointer position.
6161+type yaml_mark_t struct {
6262+ index int // The position index.
6363+ line int // The position line.
6464+ column int // The position column.
6565+}
6666+6767+// Node Styles
6868+6969+type yaml_style_t int8
7070+7171+type yaml_scalar_style_t yaml_style_t
7272+7373+// Scalar styles.
7474+const (
7575+ // Let the emitter choose the style.
7676+ yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota
7777+7878+ yaml_PLAIN_SCALAR_STYLE // The plain scalar style.
7979+ yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style.
8080+ yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style.
8181+ yaml_LITERAL_SCALAR_STYLE // The literal scalar style.
8282+ yaml_FOLDED_SCALAR_STYLE // The folded scalar style.
8383+)
8484+8585+type yaml_sequence_style_t yaml_style_t
8686+8787+// Sequence styles.
8888+const (
8989+ // Let the emitter choose the style.
9090+ yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota
9191+9292+ yaml_BLOCK_SEQUENCE_STYLE // The block sequence style.
9393+ yaml_FLOW_SEQUENCE_STYLE // The flow sequence style.
9494+)
9595+9696+type yaml_mapping_style_t yaml_style_t
9797+9898+// Mapping styles.
9999+const (
100100+ // Let the emitter choose the style.
101101+ yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota
102102+103103+ yaml_BLOCK_MAPPING_STYLE // The block mapping style.
104104+ yaml_FLOW_MAPPING_STYLE // The flow mapping style.
105105+)
106106+107107+// Tokens
108108+109109+type yaml_token_type_t int
110110+111111+// Token types.
112112+const (
113113+ // An empty token.
114114+ yaml_NO_TOKEN yaml_token_type_t = iota
115115+116116+ yaml_STREAM_START_TOKEN // A STREAM-START token.
117117+ yaml_STREAM_END_TOKEN // A STREAM-END token.
118118+119119+ yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.
120120+ yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token.
121121+ yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token.
122122+ yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token.
123123+124124+ yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.
125125+ yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token.
126126+ yaml_BLOCK_END_TOKEN // A BLOCK-END token.
127127+128128+ yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.
129129+ yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token.
130130+ yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token.
131131+ yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token.
132132+133133+ yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.
134134+ yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token.
135135+ yaml_KEY_TOKEN // A KEY token.
136136+ yaml_VALUE_TOKEN // A VALUE token.
137137+138138+ yaml_ALIAS_TOKEN // An ALIAS token.
139139+ yaml_ANCHOR_TOKEN // An ANCHOR token.
140140+ yaml_TAG_TOKEN // A TAG token.
141141+ yaml_SCALAR_TOKEN // A SCALAR token.
142142+)
143143+144144+func (tt yaml_token_type_t) String() string {
145145+ switch tt {
146146+ case yaml_NO_TOKEN:
147147+ return "yaml_NO_TOKEN"
148148+ case yaml_STREAM_START_TOKEN:
149149+ return "yaml_STREAM_START_TOKEN"
150150+ case yaml_STREAM_END_TOKEN:
151151+ return "yaml_STREAM_END_TOKEN"
152152+ case yaml_VERSION_DIRECTIVE_TOKEN:
153153+ return "yaml_VERSION_DIRECTIVE_TOKEN"
154154+ case yaml_TAG_DIRECTIVE_TOKEN:
155155+ return "yaml_TAG_DIRECTIVE_TOKEN"
156156+ case yaml_DOCUMENT_START_TOKEN:
157157+ return "yaml_DOCUMENT_START_TOKEN"
158158+ case yaml_DOCUMENT_END_TOKEN:
159159+ return "yaml_DOCUMENT_END_TOKEN"
160160+ case yaml_BLOCK_SEQUENCE_START_TOKEN:
161161+ return "yaml_BLOCK_SEQUENCE_START_TOKEN"
162162+ case yaml_BLOCK_MAPPING_START_TOKEN:
163163+ return "yaml_BLOCK_MAPPING_START_TOKEN"
164164+ case yaml_BLOCK_END_TOKEN:
165165+ return "yaml_BLOCK_END_TOKEN"
166166+ case yaml_FLOW_SEQUENCE_START_TOKEN:
167167+ return "yaml_FLOW_SEQUENCE_START_TOKEN"
168168+ case yaml_FLOW_SEQUENCE_END_TOKEN:
169169+ return "yaml_FLOW_SEQUENCE_END_TOKEN"
170170+ case yaml_FLOW_MAPPING_START_TOKEN:
171171+ return "yaml_FLOW_MAPPING_START_TOKEN"
172172+ case yaml_FLOW_MAPPING_END_TOKEN:
173173+ return "yaml_FLOW_MAPPING_END_TOKEN"
174174+ case yaml_BLOCK_ENTRY_TOKEN:
175175+ return "yaml_BLOCK_ENTRY_TOKEN"
176176+ case yaml_FLOW_ENTRY_TOKEN:
177177+ return "yaml_FLOW_ENTRY_TOKEN"
178178+ case yaml_KEY_TOKEN:
179179+ return "yaml_KEY_TOKEN"
180180+ case yaml_VALUE_TOKEN:
181181+ return "yaml_VALUE_TOKEN"
182182+ case yaml_ALIAS_TOKEN:
183183+ return "yaml_ALIAS_TOKEN"
184184+ case yaml_ANCHOR_TOKEN:
185185+ return "yaml_ANCHOR_TOKEN"
186186+ case yaml_TAG_TOKEN:
187187+ return "yaml_TAG_TOKEN"
188188+ case yaml_SCALAR_TOKEN:
189189+ return "yaml_SCALAR_TOKEN"
190190+ }
191191+ return "<unknown token>"
192192+}
193193+194194+// The token structure.
195195+type yaml_token_t struct {
196196+ // The token type.
197197+ typ yaml_token_type_t
198198+199199+ // The start/end of the token.
200200+ start_mark, end_mark yaml_mark_t
201201+202202+ // The stream encoding (for yaml_STREAM_START_TOKEN).
203203+ encoding yaml_encoding_t
204204+205205+ // The alias/anchor/scalar value or tag/tag directive handle
206206+ // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).
207207+ value []byte
208208+209209+ // The tag suffix (for yaml_TAG_TOKEN).
210210+ suffix []byte
211211+212212+ // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).
213213+ prefix []byte
214214+215215+ // The scalar style (for yaml_SCALAR_TOKEN).
216216+ style yaml_scalar_style_t
217217+218218+ // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).
219219+ major, minor int8
220220+}
221221+222222+// Events
223223+224224+type yaml_event_type_t int8
225225+226226+// Event types.
227227+const (
228228+ // An empty event.
229229+ yaml_NO_EVENT yaml_event_type_t = iota
230230+231231+ yaml_STREAM_START_EVENT // A STREAM-START event.
232232+ yaml_STREAM_END_EVENT // A STREAM-END event.
233233+ yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.
234234+ yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event.
235235+ yaml_ALIAS_EVENT // An ALIAS event.
236236+ yaml_SCALAR_EVENT // A SCALAR event.
237237+ yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.
238238+ yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event.
239239+ yaml_MAPPING_START_EVENT // A MAPPING-START event.
240240+ yaml_MAPPING_END_EVENT // A MAPPING-END event.
241241+)
242242+243243+var eventStrings = []string{
244244+ yaml_NO_EVENT: "none",
245245+ yaml_STREAM_START_EVENT: "stream start",
246246+ yaml_STREAM_END_EVENT: "stream end",
247247+ yaml_DOCUMENT_START_EVENT: "document start",
248248+ yaml_DOCUMENT_END_EVENT: "document end",
249249+ yaml_ALIAS_EVENT: "alias",
250250+ yaml_SCALAR_EVENT: "scalar",
251251+ yaml_SEQUENCE_START_EVENT: "sequence start",
252252+ yaml_SEQUENCE_END_EVENT: "sequence end",
253253+ yaml_MAPPING_START_EVENT: "mapping start",
254254+ yaml_MAPPING_END_EVENT: "mapping end",
255255+}
256256+257257+func (e yaml_event_type_t) String() string {
258258+ if e < 0 || int(e) >= len(eventStrings) {
259259+ return fmt.Sprintf("unknown event %d", e)
260260+ }
261261+ return eventStrings[e]
262262+}
263263+264264+// The event structure.
265265+type yaml_event_t struct {
266266+267267+ // The event type.
268268+ typ yaml_event_type_t
269269+270270+ // The start and end of the event.
271271+ start_mark, end_mark yaml_mark_t
272272+273273+ // The document encoding (for yaml_STREAM_START_EVENT).
274274+ encoding yaml_encoding_t
275275+276276+ // The version directive (for yaml_DOCUMENT_START_EVENT).
277277+ version_directive *yaml_version_directive_t
278278+279279+ // The list of tag directives (for yaml_DOCUMENT_START_EVENT).
280280+ tag_directives []yaml_tag_directive_t
281281+282282+ // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).
283283+ anchor []byte
284284+285285+ // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
286286+ tag []byte
287287+288288+ // The scalar value (for yaml_SCALAR_EVENT).
289289+ value []byte
290290+291291+ // Is the document start/end indicator implicit, or the tag optional?
292292+ // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).
293293+ implicit bool
294294+295295+ // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).
296296+ quoted_implicit bool
297297+298298+ // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).
299299+ style yaml_style_t
300300+}
301301+302302+func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) }
303303+func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }
304304+func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) }
305305+306306+// Nodes
307307+308308+const (
309309+ yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null.
310310+ yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false.
311311+ yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values.
312312+ yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values.
313313+ yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values.
314314+ yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values.
315315+316316+ yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences.
317317+ yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping.
318318+319319+ // Not in original libyaml.
320320+ yaml_BINARY_TAG = "tag:yaml.org,2002:binary"
321321+ yaml_MERGE_TAG = "tag:yaml.org,2002:merge"
322322+323323+ yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str.
324324+ yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.
325325+ yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map.
326326+)
327327+328328+type yaml_node_type_t int
329329+330330+// Node types.
331331+const (
332332+ // An empty node.
333333+ yaml_NO_NODE yaml_node_type_t = iota
334334+335335+ yaml_SCALAR_NODE // A scalar node.
336336+ yaml_SEQUENCE_NODE // A sequence node.
337337+ yaml_MAPPING_NODE // A mapping node.
338338+)
339339+340340+// An element of a sequence node.
341341+type yaml_node_item_t int
342342+343343+// An element of a mapping node.
344344+type yaml_node_pair_t struct {
345345+ key int // The key of the element.
346346+ value int // The value of the element.
347347+}
348348+349349+// The node structure.
350350+type yaml_node_t struct {
351351+ typ yaml_node_type_t // The node type.
352352+ tag []byte // The node tag.
353353+354354+ // The node data.
355355+356356+ // The scalar parameters (for yaml_SCALAR_NODE).
357357+ scalar struct {
358358+ value []byte // The scalar value.
359359+ length int // The length of the scalar value.
360360+ style yaml_scalar_style_t // The scalar style.
361361+ }
362362+363363+ // The sequence parameters (for YAML_SEQUENCE_NODE).
364364+ sequence struct {
365365+ items_data []yaml_node_item_t // The stack of sequence items.
366366+ style yaml_sequence_style_t // The sequence style.
367367+ }
368368+369369+ // The mapping parameters (for yaml_MAPPING_NODE).
370370+ mapping struct {
371371+ pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value).
372372+ pairs_start *yaml_node_pair_t // The beginning of the stack.
373373+ pairs_end *yaml_node_pair_t // The end of the stack.
374374+ pairs_top *yaml_node_pair_t // The top of the stack.
375375+ style yaml_mapping_style_t // The mapping style.
376376+ }
377377+378378+ start_mark yaml_mark_t // The beginning of the node.
379379+ end_mark yaml_mark_t // The end of the node.
380380+381381+}
382382+383383+// The document structure.
384384+type yaml_document_t struct {
385385+386386+ // The document nodes.
387387+ nodes []yaml_node_t
388388+389389+ // The version directive.
390390+ version_directive *yaml_version_directive_t
391391+392392+ // The list of tag directives.
393393+ tag_directives_data []yaml_tag_directive_t
394394+ tag_directives_start int // The beginning of the tag directives list.
395395+ tag_directives_end int // The end of the tag directives list.
396396+397397+ start_implicit int // Is the document start indicator implicit?
398398+ end_implicit int // Is the document end indicator implicit?
399399+400400+ // The start/end of the document.
401401+ start_mark, end_mark yaml_mark_t
402402+}
403403+404404+// The prototype of a read handler.
405405+//
406406+// The read handler is called when the parser needs to read more bytes from the
407407+// source. The handler should write not more than size bytes to the buffer.
408408+// The number of written bytes should be set to the size_read variable.
409409+//
410410+// [in,out] data A pointer to an application data specified by
411411+// yaml_parser_set_input().
412412+// [out] buffer The buffer to write the data from the source.
413413+// [in] size The size of the buffer.
414414+// [out] size_read The actual number of bytes read from the source.
415415+//
416416+// On success, the handler should return 1. If the handler failed,
417417+// the returned value should be 0. On EOF, the handler should set the
418418+// size_read to 0 and return 1.
419419+type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)
420420+421421+// This structure holds information about a potential simple key.
422422+type yaml_simple_key_t struct {
423423+ possible bool // Is a simple key possible?
424424+ required bool // Is a simple key required?
425425+ token_number int // The number of the token.
426426+ mark yaml_mark_t // The position mark.
427427+}
428428+429429+// The states of the parser.
430430+type yaml_parser_state_t int
431431+432432+const (
433433+ yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota
434434+435435+ yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document.
436436+ yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START.
437437+ yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document.
438438+ yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END.
439439+ yaml_PARSE_BLOCK_NODE_STATE // Expect a block node.
440440+ yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.
441441+ yaml_PARSE_FLOW_NODE_STATE // Expect a flow node.
442442+ yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence.
443443+ yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence.
444444+ yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence.
445445+ yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
446446+ yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key.
447447+ yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value.
448448+ yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence.
449449+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence.
450450+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping.
451451+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.
452452+ yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry.
453453+ yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
454454+ yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
455455+ yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
456456+ yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping.
457457+ yaml_PARSE_END_STATE // Expect nothing.
458458+)
459459+460460+func (ps yaml_parser_state_t) String() string {
461461+ switch ps {
462462+ case yaml_PARSE_STREAM_START_STATE:
463463+ return "yaml_PARSE_STREAM_START_STATE"
464464+ case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
465465+ return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE"
466466+ case yaml_PARSE_DOCUMENT_START_STATE:
467467+ return "yaml_PARSE_DOCUMENT_START_STATE"
468468+ case yaml_PARSE_DOCUMENT_CONTENT_STATE:
469469+ return "yaml_PARSE_DOCUMENT_CONTENT_STATE"
470470+ case yaml_PARSE_DOCUMENT_END_STATE:
471471+ return "yaml_PARSE_DOCUMENT_END_STATE"
472472+ case yaml_PARSE_BLOCK_NODE_STATE:
473473+ return "yaml_PARSE_BLOCK_NODE_STATE"
474474+ case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
475475+ return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE"
476476+ case yaml_PARSE_FLOW_NODE_STATE:
477477+ return "yaml_PARSE_FLOW_NODE_STATE"
478478+ case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
479479+ return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE"
480480+ case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
481481+ return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE"
482482+ case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
483483+ return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE"
484484+ case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
485485+ return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE"
486486+ case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
487487+ return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE"
488488+ case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
489489+ return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE"
490490+ case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
491491+ return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE"
492492+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
493493+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE"
494494+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
495495+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE"
496496+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
497497+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE"
498498+ case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
499499+ return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE"
500500+ case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
501501+ return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE"
502502+ case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
503503+ return "yaml_PARSE_FLOW_MAPPING_KEY_STATE"
504504+ case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
505505+ return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE"
506506+ case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
507507+ return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE"
508508+ case yaml_PARSE_END_STATE:
509509+ return "yaml_PARSE_END_STATE"
510510+ }
511511+ return "<unknown parser state>"
512512+}
513513+514514+// This structure holds aliases data.
515515+type yaml_alias_data_t struct {
516516+ anchor []byte // The anchor.
517517+ index int // The node id.
518518+ mark yaml_mark_t // The anchor mark.
519519+}
520520+521521+// The parser structure.
522522+//
523523+// All members are internal. Manage the structure using the
524524+// yaml_parser_ family of functions.
525525+type yaml_parser_t struct {
526526+527527+ // Error handling
528528+529529+ error yaml_error_type_t // Error type.
530530+531531+ problem string // Error description.
532532+533533+ // The byte about which the problem occurred.
534534+ problem_offset int
535535+ problem_value int
536536+ problem_mark yaml_mark_t
537537+538538+ // The error context.
539539+ context string
540540+ context_mark yaml_mark_t
541541+542542+ // Reader stuff
543543+544544+ read_handler yaml_read_handler_t // Read handler.
545545+546546+ input_reader io.Reader // File input data.
547547+ input []byte // String input data.
548548+ input_pos int
549549+550550+ eof bool // EOF flag
551551+552552+ buffer []byte // The working buffer.
553553+ buffer_pos int // The current position of the buffer.
554554+555555+ unread int // The number of unread characters in the buffer.
556556+557557+ raw_buffer []byte // The raw buffer.
558558+ raw_buffer_pos int // The current position of the buffer.
559559+560560+ encoding yaml_encoding_t // The input encoding.
561561+562562+ offset int // The offset of the current position (in bytes).
563563+ mark yaml_mark_t // The mark of the current position.
564564+565565+ // Scanner stuff
566566+567567+ stream_start_produced bool // Have we started to scan the input stream?
568568+ stream_end_produced bool // Have we reached the end of the input stream?
569569+570570+ flow_level int // The number of unclosed '[' and '{' indicators.
571571+572572+ tokens []yaml_token_t // The tokens queue.
573573+ tokens_head int // The head of the tokens queue.
574574+ tokens_parsed int // The number of tokens fetched from the queue.
575575+ token_available bool // Does the tokens queue contain a token ready for dequeueing.
576576+577577+ indent int // The current indentation level.
578578+ indents []int // The indentation levels stack.
579579+580580+ simple_key_allowed bool // May a simple key occur at the current position?
581581+ simple_keys []yaml_simple_key_t // The stack of simple keys.
582582+583583+ // Parser stuff
584584+585585+ state yaml_parser_state_t // The current parser state.
586586+ states []yaml_parser_state_t // The parser states stack.
587587+ marks []yaml_mark_t // The stack of marks.
588588+ tag_directives []yaml_tag_directive_t // The list of TAG directives.
589589+590590+ // Dumper stuff
591591+592592+ aliases []yaml_alias_data_t // The alias data.
593593+594594+ document *yaml_document_t // The currently parsed document.
595595+}
596596+597597+// Emitter Definitions
598598+599599+// The prototype of a write handler.
600600+//
601601+// The write handler is called when the emitter needs to flush the accumulated
602602+// characters to the output. The handler should write @a size bytes of the
603603+// @a buffer to the output.
604604+//
605605+// @param[in,out] data A pointer to an application data specified by
606606+// yaml_emitter_set_output().
607607+// @param[in] buffer The buffer with bytes to be written.
608608+// @param[in] size The size of the buffer.
609609+//
610610+// @returns On success, the handler should return @c 1. If the handler failed,
611611+// the returned value should be @c 0.
612612+//
613613+type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error
614614+615615+type yaml_emitter_state_t int
616616+617617+// The emitter states.
618618+const (
619619+ // Expect STREAM-START.
620620+ yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota
621621+622622+ yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END.
623623+ yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END.
624624+ yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document.
625625+ yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END.
626626+ yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence.
627627+ yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence.
628628+ yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping.
629629+ yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping.
630630+ yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping.
631631+ yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping.
632632+ yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence.
633633+ yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence.
634634+ yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping.
635635+ yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping.
636636+ yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.
637637+ yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping.
638638+ yaml_EMIT_END_STATE // Expect nothing.
639639+)
640640+641641+// The emitter structure.
642642+//
643643+// All members are internal. Manage the structure using the @c yaml_emitter_
644644+// family of functions.
645645+type yaml_emitter_t struct {
646646+647647+ // Error handling
648648+649649+ error yaml_error_type_t // Error type.
650650+ problem string // Error description.
651651+652652+ // Writer stuff
653653+654654+ write_handler yaml_write_handler_t // Write handler.
655655+656656+ output_buffer *[]byte // String output data.
657657+ output_writer io.Writer // File output data.
658658+659659+ buffer []byte // The working buffer.
660660+ buffer_pos int // The current position of the buffer.
661661+662662+ raw_buffer []byte // The raw buffer.
663663+ raw_buffer_pos int // The current position of the buffer.
664664+665665+ encoding yaml_encoding_t // The stream encoding.
666666+667667+ // Emitter stuff
668668+669669+ canonical bool // If the output is in the canonical style?
670670+ best_indent int // The number of indentation spaces.
671671+ best_width int // The preferred width of the output lines.
672672+ unicode bool // Allow unescaped non-ASCII characters?
673673+ line_break yaml_break_t // The preferred line break.
674674+675675+ state yaml_emitter_state_t // The current emitter state.
676676+ states []yaml_emitter_state_t // The stack of states.
677677+678678+ events []yaml_event_t // The event queue.
679679+ events_head int // The head of the event queue.
680680+681681+ indents []int // The stack of indentation levels.
682682+683683+ tag_directives []yaml_tag_directive_t // The list of tag directives.
684684+685685+ indent int // The current indentation level.
686686+687687+ flow_level int // The current flow level.
688688+689689+ root_context bool // Is it the document root context?
690690+ sequence_context bool // Is it a sequence context?
691691+ mapping_context bool // Is it a mapping context?
692692+ simple_key_context bool // Is it a simple mapping key context?
693693+694694+ line int // The current line.
695695+ column int // The current column.
696696+ whitespace bool // If the last character was a whitespace?
697697+ indention bool // If the last character was an indentation character (' ', '-', '?', ':')?
698698+ open_ended bool // If an explicit document end is required?
699699+700700+ // Anchor analysis.
701701+ anchor_data struct {
702702+ anchor []byte // The anchor value.
703703+ alias bool // Is it an alias?
704704+ }
705705+706706+ // Tag analysis.
707707+ tag_data struct {
708708+ handle []byte // The tag handle.
709709+ suffix []byte // The tag suffix.
710710+ }
711711+712712+ // Scalar analysis.
713713+ scalar_data struct {
714714+ value []byte // The scalar value.
715715+ multiline bool // Does the scalar contain line breaks?
716716+ flow_plain_allowed bool // Can the scalar be expessed in the flow plain style?
717717+ block_plain_allowed bool // Can the scalar be expressed in the block plain style?
718718+ single_quoted_allowed bool // Can the scalar be expressed in the single quoted style?
719719+ block_allowed bool // Can the scalar be expressed in the literal or folded styles?
720720+ style yaml_scalar_style_t // The output style.
721721+ }
722722+723723+ // Dumper stuff
724724+725725+ opened bool // If the stream was already opened?
726726+ closed bool // If the stream was already closed?
727727+728728+ // The information associated with the document nodes.
729729+ anchors *struct {
730730+ references int // The number of references.
731731+ anchor int // The anchor id.
732732+ serialized bool // If the node has been emitted?
733733+ }
734734+735735+ last_anchor_id int // The last assigned anchor id.
736736+737737+ document *yaml_document_t // The currently emitted document.
738738+}
+173
internal/third_party/yaml/yamlprivateh.go
···11+package yaml
22+33+const (
44+ // The size of the input raw buffer.
55+ input_raw_buffer_size = 512
66+77+ // The size of the input buffer.
88+ // It should be possible to decode the whole raw buffer.
99+ input_buffer_size = input_raw_buffer_size * 3
1010+1111+ // The size of the output buffer.
1212+ output_buffer_size = 128
1313+1414+ // The size of the output raw buffer.
1515+ // It should be possible to encode the whole output buffer.
1616+ output_raw_buffer_size = (output_buffer_size*2 + 2)
1717+1818+ // The size of other stacks and queues.
1919+ initial_stack_size = 16
2020+ initial_queue_size = 16
2121+ initial_string_size = 16
2222+)
2323+2424+// Check if the character at the specified position is an alphabetical
2525+// character, a digit, '_', or '-'.
2626+func is_alpha(b []byte, i int) bool {
2727+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
2828+}
2929+3030+// Check if the character at the specified position is a digit.
3131+func is_digit(b []byte, i int) bool {
3232+ return b[i] >= '0' && b[i] <= '9'
3333+}
3434+3535+// Get the value of a digit.
3636+func as_digit(b []byte, i int) int {
3737+ return int(b[i]) - '0'
3838+}
3939+4040+// Check if the character at the specified position is a hex-digit.
4141+func is_hex(b []byte, i int) bool {
4242+ return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
4343+}
4444+4545+// Get the value of a hex-digit.
4646+func as_hex(b []byte, i int) int {
4747+ bi := b[i]
4848+ if bi >= 'A' && bi <= 'F' {
4949+ return int(bi) - 'A' + 10
5050+ }
5151+ if bi >= 'a' && bi <= 'f' {
5252+ return int(bi) - 'a' + 10
5353+ }
5454+ return int(bi) - '0'
5555+}
5656+5757+// Check if the character is ASCII.
5858+func is_ascii(b []byte, i int) bool {
5959+ return b[i] <= 0x7F
6060+}
6161+6262+// Check if the character at the start of the buffer can be printed unescaped.
6363+func is_printable(b []byte, i int) bool {
6464+ return ((b[i] == 0x0A) || // . == #x0A
6565+ (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
6666+ (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
6767+ (b[i] > 0xC2 && b[i] < 0xED) ||
6868+ (b[i] == 0xED && b[i+1] < 0xA0) ||
6969+ (b[i] == 0xEE) ||
7070+ (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
7171+ !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
7272+ !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
7373+}
7474+7575+// Check if the character at the specified position is NUL.
7676+func is_z(b []byte, i int) bool {
7777+ return b[i] == 0x00
7878+}
7979+8080+// Check if the beginning of the buffer is a BOM.
8181+func is_bom(b []byte, i int) bool {
8282+ return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
8383+}
8484+8585+// Check if the character at the specified position is space.
8686+func is_space(b []byte, i int) bool {
8787+ return b[i] == ' '
8888+}
8989+9090+// Check if the character at the specified position is tab.
9191+func is_tab(b []byte, i int) bool {
9292+ return b[i] == '\t'
9393+}
9494+9595+// Check if the character at the specified position is blank (space or tab).
9696+func is_blank(b []byte, i int) bool {
9797+ //return is_space(b, i) || is_tab(b, i)
9898+ return b[i] == ' ' || b[i] == '\t'
9999+}
100100+101101+// Check if the character at the specified position is a line break.
102102+func is_break(b []byte, i int) bool {
103103+ return (b[i] == '\r' || // CR (#xD)
104104+ b[i] == '\n' || // LF (#xA)
105105+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
106106+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
107107+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
108108+}
109109+110110+func is_crlf(b []byte, i int) bool {
111111+ return b[i] == '\r' && b[i+1] == '\n'
112112+}
113113+114114+// Check if the character is a line break or NUL.
115115+func is_breakz(b []byte, i int) bool {
116116+ //return is_break(b, i) || is_z(b, i)
117117+ return ( // is_break:
118118+ b[i] == '\r' || // CR (#xD)
119119+ b[i] == '\n' || // LF (#xA)
120120+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
121121+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
122122+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
123123+ // is_z:
124124+ b[i] == 0)
125125+}
126126+127127+// Check if the character is a line break, space, or NUL.
128128+func is_spacez(b []byte, i int) bool {
129129+ //return is_space(b, i) || is_breakz(b, i)
130130+ return ( // is_space:
131131+ b[i] == ' ' ||
132132+ // is_breakz:
133133+ b[i] == '\r' || // CR (#xD)
134134+ b[i] == '\n' || // LF (#xA)
135135+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
136136+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
137137+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
138138+ b[i] == 0)
139139+}
140140+141141+// Check if the character is a line break, space, tab, or NUL.
142142+func is_blankz(b []byte, i int) bool {
143143+ //return is_blank(b, i) || is_breakz(b, i)
144144+ return ( // is_blank:
145145+ b[i] == ' ' || b[i] == '\t' ||
146146+ // is_breakz:
147147+ b[i] == '\r' || // CR (#xD)
148148+ b[i] == '\n' || // LF (#xA)
149149+ b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
150150+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
151151+ b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
152152+ b[i] == 0)
153153+}
154154+155155+// Determine the width of the character.
156156+func width(b byte) int {
157157+ // Don't replace these by a switch without first
158158+ // confirming that it is being inlined.
159159+ if b&0x80 == 0x00 {
160160+ return 1
161161+ }
162162+ if b&0xE0 == 0xC0 {
163163+ return 2
164164+ }
165165+ if b&0xF0 == 0xE0 {
166166+ return 3
167167+ }
168168+ if b&0xF8 == 0xF0 {
169169+ return 4
170170+ }
171171+ return 0
172172+173173+}