this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/third_party/yaml: parse into CUE ast

Also:
- remove support for parsing into Go-structs
- remove support for encoding
- add comment parsing
- port non-standard test harness to standard go
- add testdata
- fix some bugs related to merging

Change-Id: I7fbd2bed6f76bb5da8a309f8d3fb3fb6228048ab

+927 -4308
+3 -125
internal/third_party/yaml/README.md
··· 1 - # YAML support for the Go language 2 - 3 - Introduction 4 - ------------ 5 - 6 - The yaml package enables Go programs to comfortably encode and decode YAML 7 - values. It was developed within [Canonical](https://www.canonical.com) as 8 - part of the [juju](https://juju.ubuntu.com) project, and is based on a 9 - pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) 10 - C library to parse and generate YAML data quickly and reliably. 11 - 12 - Compatibility 13 - ------------- 14 - 15 - The yaml package supports most of YAML 1.1 and 1.2, including support for 16 - anchors, tags, map merging, etc. Multi-document unmarshalling is not yet 17 - implemented, and base-60 floats from YAML 1.1 are purposefully not 18 - supported since they're a poor design and are gone in YAML 1.2. 19 - 20 - Installation and usage 21 - ---------------------- 22 - 23 - The import path for the package is *gopkg.in/yaml.v2*. 24 - 25 - To install it, run: 26 - 27 - go get gopkg.in/yaml.v2 28 - 29 - API documentation 30 - ----------------- 31 - 32 - If opened in a browser, the import path itself leads to the API documentation: 33 - 34 - * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) 35 - 36 - API stability 37 - ------------- 1 + # YAML reader for CUE 38 2 39 - The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). 3 + This yaml parser is a heavily modified version of Canonical's go-yaml parser, 4 + which in turn is a port of the [libyaml](http://pyyaml.org/wiki/LibYAML) parser. 40 5 41 6 42 7 License ··· 44 9 45 10 The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. 46 11 47 - 48 - Example 49 - ------- 50 - 51 - ```Go 52 - package main 53 - 54 - import ( 55 - "fmt" 56 - "log" 57 - 58 - "gopkg.in/yaml.v2" 59 - ) 60 - 61 - var data = ` 62 - a: Easy! 63 - b: 64 - c: 2 65 - d: [3, 4] 66 - ` 67 - 68 - // Note: struct fields must be public in order for unmarshal to 69 - // correctly populate the data. 70 - type T struct { 71 - A string 72 - B struct { 73 - RenamedC int `yaml:"c"` 74 - D []int `yaml:",flow"` 75 - } 76 - } 77 - 78 - func main() { 79 - t := T{} 80 - 81 - err := yaml.Unmarshal([]byte(data), &t) 82 - if err != nil { 83 - log.Fatalf("error: %v", err) 84 - } 85 - fmt.Printf("--- t:\n%v\n\n", t) 86 - 87 - d, err := yaml.Marshal(&t) 88 - if err != nil { 89 - log.Fatalf("error: %v", err) 90 - } 91 - fmt.Printf("--- t dump:\n%s\n\n", string(d)) 92 - 93 - m := make(map[interface{}]interface{}) 94 - 95 - err = yaml.Unmarshal([]byte(data), &m) 96 - if err != nil { 97 - log.Fatalf("error: %v", err) 98 - } 99 - fmt.Printf("--- m:\n%v\n\n", m) 100 - 101 - d, err = yaml.Marshal(&m) 102 - if err != nil { 103 - log.Fatalf("error: %v", err) 104 - } 105 - fmt.Printf("--- m dump:\n%s\n\n", string(d)) 106 - } 107 - ``` 108 - 109 - This example will generate the following output: 110 - 111 - ``` 112 - --- t: 113 - {Easy! {2 [3 4]}} 114 - 115 - --- t dump: 116 - a: Easy! 117 - b: 118 - c: 2 119 - d: [3, 4] 120 - 121 - 122 - --- m: 123 - map[a:Easy! b:map[c:2 d:[3 4]]] 124 - 125 - --- m dump: 126 - a: Easy! 127 - b: 128 - c: 2 129 - d: 130 - - 3 131 - - 4 132 - ``` 133 -
+2 -1
internal/third_party/yaml/apic.go
··· 24 24 } 25 25 26 26 // Create a new parser object. 27 - func yaml_parser_initialize(parser *yaml_parser_t) bool { 27 + func yaml_parser_initialize(parser *yaml_parser_t, filename string) bool { 28 28 *parser = yaml_parser_t{ 29 + filename: filename, 29 30 raw_buffer: make([]byte, 0, input_raw_buffer_size), 30 31 buffer: make([]byte, 0, input_buffer_size), 31 32 }
+364 -440
internal/third_party/yaml/decode.go
··· 1 1 package yaml 2 2 3 3 import ( 4 - "encoding" 4 + "bytes" 5 5 "encoding/base64" 6 + "errors" 6 7 "fmt" 7 8 "io" 9 + "io/ioutil" 8 10 "math" 9 11 "reflect" 10 12 "strconv" 13 + "strings" 11 14 "time" 15 + "unicode" 16 + 17 + "cuelang.org/go/cue/ast" 18 + "cuelang.org/go/cue/token" 12 19 ) 13 20 14 21 const ( ··· 20 27 ) 21 28 22 29 type node struct { 23 - kind int 24 - line, column int 25 - tag string 30 + kind int 31 + startPos yaml_mark_t 32 + endPos yaml_mark_t 33 + tag string 26 34 // For an alias node, alias holds the resolved alias. 27 35 alias *node 28 36 value string ··· 38 46 parser yaml_parser_t 39 47 event yaml_event_t 40 48 doc *node 49 + info *token.File 50 + last *node 41 51 doneInit bool 42 52 } 43 53 44 - func newParser(b []byte) *parser { 45 - p := parser{} 46 - if !yaml_parser_initialize(&p.parser) { 54 + func readSource(filename string, src interface{}) ([]byte, error) { 55 + if src != nil { 56 + switch s := src.(type) { 57 + case string: 58 + return []byte(s), nil 59 + case []byte: 60 + return s, nil 61 + case *bytes.Buffer: 62 + // is io.Reader, but src is already available in []byte form 63 + if s != nil { 64 + return s.Bytes(), nil 65 + } 66 + case io.Reader: 67 + var buf bytes.Buffer 68 + if _, err := io.Copy(&buf, s); err != nil { 69 + return nil, err 70 + } 71 + return buf.Bytes(), nil 72 + } 73 + return nil, errors.New("invalid source") 74 + } 75 + return ioutil.ReadFile(filename) 76 + } 77 + 78 + func newParser(fset *token.FileSet, filename string, src interface{}) (*parser, error) { 79 + b, err := readSource(filename, src) 80 + if err != nil { 81 + return nil, err 82 + } 83 + info := fset.AddFile(filename, -1, len(b)) 84 + info.SetLinesForContent(b) 85 + p := parser{info: info} 86 + if !yaml_parser_initialize(&p.parser, filename) { 47 87 panic("failed to initialize YAML emitter") 48 88 } 49 89 if len(b) == 0 { 50 90 b = []byte{'\n'} 51 91 } 52 92 yaml_parser_set_input_string(&p.parser, b) 53 - return &p 54 - } 55 - 56 - func newParserFromReader(r io.Reader) *parser { 57 - p := parser{} 58 - if !yaml_parser_initialize(&p.parser) { 59 - panic("failed to initialize YAML emitter") 60 - } 61 - yaml_parser_set_input_reader(&p.parser, r) 62 - return &p 93 + return &p, nil 63 94 } 64 95 65 96 func (p *parser) init() { ··· 86 117 } 87 118 } 88 119 if p.event.typ == yaml_STREAM_END_EVENT { 89 - failf("attempted to go past the end of stream; corrupted value?") 120 + p.failf(p.event.end_mark.line, "attempted to go past the end of stream; corrupted value?") 90 121 } 91 122 if p.event.typ != e { 92 123 p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ) ··· 109 140 } 110 141 111 142 func (p *parser) fail() { 112 - var where string 113 143 var line int 114 144 if p.parser.problem_mark.line != 0 { 115 145 line = p.parser.problem_mark.line 116 146 // Scanner errors don't iterate line before returning error 117 - if p.parser.error == yaml_SCANNER_ERROR { 118 - line++ 147 + if p.parser.error != yaml_SCANNER_ERROR { 148 + line-- 119 149 } 120 150 } else if p.parser.context_mark.line != 0 { 121 - line = p.parser.context_mark.line 122 - } 123 - if line != 0 { 124 - where = "line " + strconv.Itoa(line) + ": " 151 + line = p.parser.context_mark.line - 1 125 152 } 126 153 var msg string 127 154 if len(p.parser.problem) > 0 { ··· 129 156 } else { 130 157 msg = "unknown problem parsing YAML content" 131 158 } 132 - failf("%s%s", where, msg) 159 + p.failf(line, msg) 133 160 } 134 161 135 162 func (p *parser) anchor(n *node, anchor []byte) { ··· 160 187 } 161 188 162 189 func (p *parser) node(kind int) *node { 163 - return &node{ 164 - kind: kind, 165 - line: p.event.start_mark.line, 166 - column: p.event.start_mark.column, 190 + n := &node{ 191 + kind: kind, 192 + startPos: p.event.start_mark, 193 + endPos: p.event.end_mark, 167 194 } 195 + return n 168 196 } 169 197 170 198 func (p *parser) document() *node { ··· 182 210 n.value = string(p.event.anchor) 183 211 n.alias = p.doc.anchors[n.value] 184 212 if n.alias == nil { 185 - failf("unknown anchor '%s' referenced", n.value) 213 + p.failf(n.startPos.line, "unknown anchor '%s' referenced", n.value) 186 214 } 187 215 p.expect(yaml_ALIAS_EVENT) 188 216 return n ··· 224 252 // Decoder, unmarshals a node into a provided value. 225 253 226 254 type decoder struct { 227 - doc *node 228 - aliases map[*node]bool 229 - mapType reflect.Type 230 - terrors []string 231 - strict bool 255 + p *parser 256 + doc *node 257 + aliases map[*node]bool 258 + mapType reflect.Type 259 + terrors []string 260 + prev token.Pos 261 + lastNode ast.Node 232 262 } 233 263 234 264 var ( 235 265 mapItemType = reflect.TypeOf(MapItem{}) 236 266 durationType = reflect.TypeOf(time.Duration(0)) 237 267 defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) 238 - ifaceType = defaultMapType.Elem() 239 268 timeType = reflect.TypeOf(time.Time{}) 240 269 ptrTimeType = reflect.TypeOf(&time.Time{}) 241 270 ) 242 271 243 - func newDecoder(strict bool) *decoder { 244 - d := &decoder{mapType: defaultMapType, strict: strict} 272 + func newDecoder(p *parser) *decoder { 273 + d := &decoder{p: p, mapType: defaultMapType} 245 274 d.aliases = make(map[*node]bool) 246 275 return d 247 276 } 248 277 249 - func (d *decoder) terror(n *node, tag string, out reflect.Value) { 278 + func (d *decoder) terror(n *node, tag string) string { 250 279 if n.tag != "" { 251 280 tag = n.tag 252 281 } ··· 258 287 value = " `" + value + "`" 259 288 } 260 289 } 261 - d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) 290 + msg := fmt.Sprintf("line %d: cannot unmarshal %s%s", n.startPos.line+1, shortTag(tag), value) 291 + d.terrors = append(d.terrors, msg) 292 + return msg 262 293 } 263 294 264 - func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { 265 - terrlen := len(d.terrors) 266 - err := u.UnmarshalYAML(func(v interface{}) (err error) { 267 - defer handleErr(&err) 268 - d.unmarshal(n, reflect.ValueOf(v)) 269 - if len(d.terrors) > terrlen { 270 - issues := d.terrors[terrlen:] 271 - d.terrors = d.terrors[:terrlen] 272 - return &TypeError{issues} 295 + func (d *decoder) unmarshal(n *node) (node ast.Expr) { 296 + switch n.kind { 297 + case documentNode: 298 + node = d.document(n) 299 + case aliasNode: 300 + node = d.alias(n) 301 + default: 302 + switch n.kind { 303 + case scalarNode: 304 + node = d.scalar(n) 305 + case mappingNode: 306 + node = d.mapping(n) 307 + case sequenceNode: 308 + node = d.sequence(n) 309 + default: 310 + panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) 273 311 } 274 - return nil 275 - }) 276 - if e, ok := err.(*TypeError); ok { 277 - d.terrors = append(d.terrors, e.Errors...) 278 - return false 279 312 } 280 - if err != nil { 281 - fail(err) 282 - } 283 - return true 313 + return node 284 314 } 285 315 286 - // d.prepare initializes and dereferences pointers and calls UnmarshalYAML 287 - // if a value is found to implement it. 288 - // It returns the initialized and dereferenced out value, whether 289 - // unmarshalling was already done by UnmarshalYAML, and if so whether 290 - // its types unmarshalled appropriately. 291 - // 292 - // If n holds a null value, prepare returns before doing anything. 293 - func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { 294 - if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) { 295 - return out, false, false 296 - } 297 - again := true 298 - for again { 299 - again = false 300 - if out.Kind() == reflect.Ptr { 301 - if out.IsNil() { 302 - out.Set(reflect.New(out.Type().Elem())) 303 - } 304 - out = out.Elem() 305 - again = true 306 - } 307 - if out.CanAddr() { 308 - if u, ok := out.Addr().Interface().(Unmarshaler); ok { 309 - good = d.callUnmarshaler(n, u) 310 - return out, true, good 311 - } 316 + func (d *decoder) attachDocComments(m yaml_mark_t, pos int8, expr ast.Node) { 317 + comments := []*ast.Comment{} 318 + for len(d.p.parser.comments) > 0 { 319 + c := d.p.parser.comments[0] 320 + if c.mark.index >= m.index { 321 + break 312 322 } 323 + // fp := d.p.info.Pos(c.mark.index, 0) 324 + comments = append(comments, &ast.Comment{ 325 + token.Pos(c.pos), 326 + "//" + c.text[1:], 327 + }) 328 + d.p.parser.comments = d.p.parser.comments[1:] 313 329 } 314 - return out, false, false 330 + if len(comments) > 0 { 331 + expr.AddComment(&ast.CommentGroup{ 332 + Doc: pos == 0, 333 + Position: pos, 334 + List: comments, 335 + }) 336 + } 315 337 } 316 338 317 - func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { 318 - switch n.kind { 319 - case documentNode: 320 - return d.document(n, out) 321 - case aliasNode: 322 - return d.alias(n, out) 339 + func (d *decoder) attachLineComment(m yaml_mark_t, pos int8, expr ast.Node) { 340 + if len(d.p.parser.comments) == 0 { 341 + return 323 342 } 324 - out, unmarshaled, good := d.prepare(n, out) 325 - if unmarshaled { 326 - return good 343 + c := d.p.parser.comments[0] 344 + if c.mark.index == m.index { 345 + comment := &ast.Comment{ 346 + token.Pos(c.pos), 347 + // d.p.info.Pos(m.index+1, 0), 348 + "//" + c.text[1:], 349 + } 350 + // expr.AddComment(pos, false) 351 + expr.AddComment(&ast.CommentGroup{ 352 + Line: true, 353 + Position: pos, 354 + List: []*ast.Comment{comment}, 355 + }) 327 356 } 328 - switch n.kind { 329 - case scalarNode: 330 - good = d.scalar(n, out) 331 - case mappingNode: 332 - good = d.mapping(n, out) 333 - case sequenceNode: 334 - good = d.sequence(n, out) 335 - default: 336 - panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) 357 + } 358 + 359 + func (d *decoder) pos(m yaml_mark_t) token.Pos { 360 + return token.NoPos 361 + // TODO: reenable once we have better spacing. 362 + // pos := d.p.info.Pos(m.index) 363 + // if pos <= d.prev+1 { 364 + // return token.NoPos 365 + // } 366 + // d.prev = pos 367 + // return pos 368 + } 369 + 370 + func (d *decoder) start(n *node) token.Pos { 371 + return d.pos(n.startPos) 372 + } 373 + 374 + func (d *decoder) ident(n *node, name string) *ast.Ident { 375 + return &ast.Ident{ 376 + // NamePos: d.pos(n.startPos), 377 + NamePos: token.Pos(d.p.parser.relPos()), 378 + Name: name, 337 379 } 338 - return good 339 380 } 340 381 341 - func (d *decoder) document(n *node, out reflect.Value) (good bool) { 382 + func (d *decoder) document(n *node) ast.Expr { 342 383 if len(n.children) == 1 { 343 384 d.doc = n 344 - d.unmarshal(n.children[0], out) 345 - return true 385 + return d.unmarshal(n.children[0]) 346 386 } 347 - return false 387 + return &ast.BottomLit{} // TODO: more informatives 348 388 } 349 389 350 - func (d *decoder) alias(n *node, out reflect.Value) (good bool) { 390 + func (d *decoder) alias(n *node) ast.Expr { 351 391 if d.aliases[n] { 352 392 // TODO this could actually be allowed in some circumstances. 353 - failf("anchor '%s' value contains itself", n.value) 393 + d.p.failf(n.startPos.line, "anchor '%s' value contains itself", n.value) 354 394 } 355 395 d.aliases[n] = true 356 - good = d.unmarshal(n.alias, out) 396 + node := d.unmarshal(n.alias) 357 397 delete(d.aliases, n) 358 - return good 398 + return node 359 399 } 360 400 361 401 var zeroValue reflect.Value 362 402 363 - func resetMap(out reflect.Value) { 364 - for _, k := range out.MapKeys() { 365 - out.SetMapIndex(k, zeroValue) 366 - } 367 - } 368 - 369 - func (d *decoder) scalar(n *node, out reflect.Value) bool { 403 + func (d *decoder) scalar(n *node) ast.Expr { 370 404 var tag string 371 405 var resolved interface{} 372 406 if n.tag == "" && !n.implicit { 373 407 tag = yaml_STR_TAG 374 408 resolved = n.value 375 409 } else { 376 - tag, resolved = resolve(n.tag, n.value) 410 + tag, resolved = d.resolve(n) 377 411 if tag == yaml_BINARY_TAG { 378 412 data, err := base64.StdEncoding.DecodeString(resolved.(string)) 379 413 if err != nil { 380 - failf("!!binary value contains invalid base64 data") 414 + d.p.failf(n.startPos.line, "!!binary value contains invalid base64 data") 381 415 } 382 416 resolved = string(data) 383 417 } 384 418 } 385 419 if resolved == nil { 386 - if out.Kind() == reflect.Map && !out.CanAddr() { 387 - resetMap(out) 388 - } else { 389 - out.Set(reflect.Zero(out.Type())) 390 - } 391 - return true 420 + return d.ident(n, "null") 392 421 } 393 - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 394 - // We've resolved to exactly the type we want, so use that. 395 - out.Set(resolvedv) 396 - return true 397 - } 398 - // Perhaps we can use the value as a TextUnmarshaler to 399 - // set its value. 400 - if out.CanAddr() { 401 - u, ok := out.Addr().Interface().(encoding.TextUnmarshaler) 402 - if ok { 403 - var text []byte 404 - if tag == yaml_BINARY_TAG { 405 - text = []byte(resolved.(string)) 406 - } else { 407 - // We let any value be unmarshaled into TextUnmarshaler. 408 - // That might be more lax than we'd like, but the 409 - // TextUnmarshaler itself should bowl out any dubious values. 410 - text = []byte(n.value) 411 - } 412 - err := u.UnmarshalText(text) 413 - if err != nil { 414 - fail(err) 415 - } 416 - return true 422 + switch tag { 423 + // TODO: use parse literal or parse expression instead. 424 + case yaml_TIMESTAMP_TAG: 425 + return &ast.BasicLit{ 426 + // ValuePos: d.start(n), 427 + ValuePos: token.Pos(d.p.parser.relPos()), 428 + Kind: token.STRING, 429 + Value: strconv.Quote(n.value), 417 430 } 418 - } 419 - switch out.Kind() { 420 - case reflect.String: 421 - if tag == yaml_BINARY_TAG { 422 - out.SetString(resolved.(string)) 423 - return true 431 + 432 + case yaml_STR_TAG: 433 + return &ast.BasicLit{ 434 + // ValuePos: d.start(n), 435 + ValuePos: token.Pos(d.p.parser.relPos()), 436 + Kind: token.STRING, 437 + Value: d.quoteString(n.value), 424 438 } 425 - if resolved != nil { 426 - out.SetString(n.value) 427 - return true 439 + 440 + case yaml_BINARY_TAG: 441 + buf := strconv.AppendQuote(nil, resolved.(string)) 442 + buf[0] = '\'' 443 + buf[len(buf)-1] = '\'' 444 + return &ast.BasicLit{ 445 + // ValuePos: d.start(n), 446 + ValuePos: token.Pos(d.p.parser.relPos()), 447 + Kind: token.STRING, 448 + Value: string(buf), 428 449 } 429 - case reflect.Interface: 430 - if resolved == nil { 431 - out.Set(reflect.Zero(out.Type())) 432 - } else if tag == yaml_TIMESTAMP_TAG { 433 - // It looks like a timestamp but for backward compatibility 434 - // reasons we set it as a string, so that code that unmarshals 435 - // timestamp-like values into interface{} will continue to 436 - // see a string and not a time.Time. 437 - // TODO(v3) Drop this. 438 - out.Set(reflect.ValueOf(n.value)) 439 - } else { 440 - out.Set(reflect.ValueOf(resolved)) 450 + 451 + case yaml_BOOL_TAG: 452 + str := "false" 453 + if b, _ := resolved.(bool); b { 454 + str = "true" 441 455 } 442 - return true 443 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 444 - switch resolved := resolved.(type) { 445 - case int: 446 - if !out.OverflowInt(int64(resolved)) { 447 - out.SetInt(int64(resolved)) 448 - return true 449 - } 450 - case int64: 451 - if !out.OverflowInt(resolved) { 452 - out.SetInt(resolved) 453 - return true 454 - } 455 - case uint64: 456 - if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 457 - out.SetInt(int64(resolved)) 458 - return true 459 - } 460 - case float64: 461 - if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { 462 - out.SetInt(int64(resolved)) 463 - return true 464 - } 465 - case string: 466 - if out.Type() == durationType { 467 - d, err := time.ParseDuration(resolved) 468 - if err == nil { 469 - out.SetInt(int64(d)) 470 - return true 471 - } 456 + return d.ident(n, str) 457 + 458 + case yaml_INT_TAG: 459 + return d.makeNum(n, n.value, token.INT) 460 + 461 + case yaml_FLOAT_TAG: 462 + value := n.value 463 + if f, ok := resolved.(float64); ok { 464 + switch { 465 + case math.IsInf(f, -1), 466 + math.IsInf(f, 1), 467 + math.IsNaN(f): 468 + value = fmt.Sprint(f) 472 469 } 473 470 } 474 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 475 - switch resolved := resolved.(type) { 476 - case int: 477 - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 478 - out.SetUint(uint64(resolved)) 479 - return true 480 - } 481 - case int64: 482 - if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { 483 - out.SetUint(uint64(resolved)) 484 - return true 485 - } 486 - case uint64: 487 - if !out.OverflowUint(uint64(resolved)) { 488 - out.SetUint(uint64(resolved)) 489 - return true 490 - } 491 - case float64: 492 - if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { 493 - out.SetUint(uint64(resolved)) 494 - return true 471 + if n.tag != "" { 472 + if p := strings.IndexAny(value, ".eEiInN"); p == -1 { 473 + // TODO: float(v) when we have conversions 474 + value = fmt.Sprintf("float & %s", value) 495 475 } 496 476 } 497 - case reflect.Bool: 498 - switch resolved := resolved.(type) { 499 - case bool: 500 - out.SetBool(resolved) 501 - return true 502 - } 503 - case reflect.Float32, reflect.Float64: 504 - switch resolved := resolved.(type) { 505 - case int: 506 - out.SetFloat(float64(resolved)) 507 - return true 508 - case int64: 509 - out.SetFloat(float64(resolved)) 510 - return true 511 - case uint64: 512 - out.SetFloat(float64(resolved)) 513 - return true 514 - case float64: 515 - out.SetFloat(resolved) 516 - return true 517 - } 518 - case reflect.Struct: 519 - if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() { 520 - out.Set(resolvedv) 521 - return true 522 - } 523 - case reflect.Ptr: 524 - if out.Type().Elem() == reflect.TypeOf(resolved) { 525 - // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? 526 - elem := reflect.New(out.Type().Elem()) 527 - elem.Elem().Set(reflect.ValueOf(resolved)) 528 - out.Set(elem) 529 - return true 530 - } 531 - } 532 - d.terror(n, tag, out) 533 - return false 534 - } 477 + return d.makeNum(n, value, token.FLOAT) 535 478 536 - func settableValueOf(i interface{}) reflect.Value { 537 - v := reflect.ValueOf(i) 538 - sv := reflect.New(v.Type()).Elem() 539 - sv.Set(v) 540 - return sv 541 - } 542 - 543 - func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { 544 - l := len(n.children) 545 - 546 - var iface reflect.Value 547 - switch out.Kind() { 548 - case reflect.Slice: 549 - out.Set(reflect.MakeSlice(out.Type(), l, l)) 550 - case reflect.Array: 551 - if l != out.Len() { 552 - failf("invalid array: want %d elements but got %d", out.Len(), l) 553 - } 554 - case reflect.Interface: 555 - // No type hints. Will have to use a generic sequence. 556 - iface = out 557 - out = settableValueOf(make([]interface{}, l)) 558 - default: 559 - d.terror(n, yaml_SEQ_TAG, out) 560 - return false 479 + case yaml_NULL_TAG: 480 + return d.ident(n, "null") 561 481 } 562 - et := out.Type().Elem() 563 - 564 - j := 0 565 - for i := 0; i < l; i++ { 566 - e := reflect.New(et).Elem() 567 - if ok := d.unmarshal(n.children[i], e); ok { 568 - out.Index(j).Set(e) 569 - j++ 570 - } 482 + err := &ast.BottomLit{ 483 + // Bottom: d.pos(n.startPos) 484 + Bottom: token.Pos(d.p.parser.relPos()), 571 485 } 572 - if out.Kind() != reflect.Array { 573 - out.Set(out.Slice(0, j)) 486 + comment := &ast.Comment{ 487 + // Slash: d.start(n), 488 + Slash: token.Pos(token.Blank), 489 + Text: "// " + d.terror(n, tag), 574 490 } 575 - if iface.IsValid() { 576 - iface.Set(out) 577 - } 578 - return true 491 + err.AddComment(&ast.CommentGroup{ 492 + Line: true, 493 + Position: 1, 494 + List: []*ast.Comment{comment}, 495 + }) 496 + return err 579 497 } 580 498 581 - func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { 582 - switch out.Kind() { 583 - case reflect.Struct: 584 - return d.mappingStruct(n, out) 585 - case reflect.Slice: 586 - return d.mappingSlice(n, out) 587 - case reflect.Map: 588 - // okay 589 - case reflect.Interface: 590 - if d.mapType.Kind() == reflect.Map { 591 - iface := out 592 - out = reflect.MakeMap(d.mapType) 593 - iface.Set(out) 594 - } else { 595 - slicev := reflect.New(d.mapType).Elem() 596 - if !d.mappingSlice(n, slicev) { 597 - return false 499 + func (d *decoder) label(n *node) ast.Label { 500 + var tag string 501 + if n.tag == "" && !n.implicit { 502 + tag = yaml_STR_TAG 503 + } else { 504 + tag, _ = d.resolve(n) 505 + } 506 + if tag == yaml_STR_TAG { 507 + // TODO: improve 508 + for i, r := range n.value { 509 + if !unicode.In(r, unicode.L) && r != '_' { 510 + if i == 0 || !unicode.In(r, unicode.N) { 511 + goto stringLabel 512 + } 598 513 } 599 - out.Set(slicev) 600 - return true 601 514 } 602 - default: 603 - d.terror(n, yaml_MAP_TAG, out) 604 - return false 515 + return d.ident(n, n.value) 605 516 } 606 - outt := out.Type() 607 - kt := outt.Key() 608 - et := outt.Elem() 609 - 610 - mapType := d.mapType 611 - if outt.Key() == ifaceType && outt.Elem() == ifaceType { 612 - d.mapType = outt 517 + stringLabel: 518 + return &ast.BasicLit{ 519 + ValuePos: token.Pos(d.p.parser.relPos()), 520 + // ValuePos: d.start(n), 521 + Kind: token.STRING, 522 + Value: strconv.Quote(n.value), 613 523 } 524 + } 614 525 615 - if out.IsNil() { 616 - out.Set(reflect.MakeMap(outt)) 526 + func (d *decoder) makeNum(n *node, val string, kind token.Token) (expr ast.Expr) { 527 + minuses := 0 528 + for ; val[0] == '-'; val = val[1:] { 529 + minuses++ 617 530 } 618 - l := len(n.children) 619 - for i := 0; i < l; i += 2 { 620 - if isMerge(n.children[i]) { 621 - d.merge(n.children[i+1], out) 622 - continue 531 + expr = &ast.BasicLit{ 532 + // ValuePos: d.start(n) + token.Pos(minuses), 533 + ValuePos: token.Pos(d.p.parser.relPos()), 534 + Kind: kind, 535 + Value: val, 536 + } 537 + if minuses > 0 { 538 + expr = &ast.UnaryExpr{ 539 + // OpPos: d.start(n), 540 + OpPos: token.Pos(d.p.parser.relPos()), 541 + Op: token.SUB, 542 + X: expr, 623 543 } 624 - k := reflect.New(kt).Elem() 625 - if d.unmarshal(n.children[i], k) { 626 - kkind := k.Kind() 627 - if kkind == reflect.Interface { 628 - kkind = k.Elem().Kind() 629 - } 630 - if kkind == reflect.Map || kkind == reflect.Slice { 631 - failf("invalid map key: %#v", k.Interface()) 544 + } 545 + return expr 546 + } 547 + 548 + // quoteString converts a string to a CUE multiline string if needed. 549 + func (d *decoder) quoteString(s string) string { 550 + lines := []string{} 551 + last := 0 552 + for i, c := range s { 553 + if c == '\n' { 554 + lines = append(lines, s[last:i]) 555 + last = i + 1 556 + } 557 + if c == '\r' { 558 + goto quoted 559 + } 560 + } 561 + lines = append(lines, s[last:]) 562 + if len(lines) >= 2 { 563 + buf := []byte{} 564 + buf = append(buf, `"""`+"\n"...) 565 + for _, l := range lines { 566 + if l == "" { 567 + // no indentation for empty lines 568 + buf = append(buf, '\n') 569 + continue 632 570 } 633 - e := reflect.New(et).Elem() 634 - if d.unmarshal(n.children[i+1], e) { 635 - d.setMapIndex(n.children[i+1], out, k, e) 636 - } 571 + buf = append(buf, '\t') 572 + p := len(buf) 573 + buf = strconv.AppendQuote(buf, l) 574 + // remove quotes 575 + buf[p] = '\t' 576 + buf[len(buf)-1] = '\n' 637 577 } 578 + buf = append(buf, "\t\t"+`"""`...) 579 + return string(buf) 638 580 } 639 - d.mapType = mapType 640 - return true 581 + quoted: 582 + return strconv.Quote(s) 641 583 } 642 584 643 - func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) { 644 - if d.strict && out.MapIndex(k) != zeroValue { 645 - d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface())) 646 - return 585 + func (d *decoder) sequence(n *node) ast.Expr { 586 + list := &ast.ListLit{} 587 + if n.startPos.line != n.endPos.line || len(n.children) != 1 { 588 + list.Lbrack = d.pos(n.startPos) 589 + list.Rbrack = d.pos(n.endPos) 590 + } 591 + for _, c := range n.children { 592 + list.Elts = append(list.Elts, d.unmarshal(c)) 647 593 } 648 - out.SetMapIndex(k, v) 594 + return list 649 595 } 650 596 651 - func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { 652 - outt := out.Type() 653 - if outt.Elem() != mapItemType { 654 - d.terror(n, yaml_MAP_TAG, out) 655 - return false 597 + func (d *decoder) mapping(n *node) ast.Expr { 598 + structure := &ast.StructLit{} 599 + d.insertMap(n, structure, false) 600 + if len(structure.Elts) != 1 { 601 + structure.Lbrace = d.pos(n.startPos) 602 + structure.Rbrace = d.pos(n.endPos) 656 603 } 657 - 658 - mapType := d.mapType 659 - d.mapType = outt 604 + return structure 605 + } 660 606 661 - var slice []MapItem 662 - var l = len(n.children) 607 + func (d *decoder) insertMap(n *node, m *ast.StructLit, merge bool) { 608 + l := len(n.children) 609 + outer: 663 610 for i := 0; i < l; i += 2 { 664 611 if isMerge(n.children[i]) { 665 - d.merge(n.children[i+1], out) 612 + merge = true 613 + d.merge(n.children[i+1], m) 666 614 continue 667 615 } 668 - item := MapItem{} 669 - k := reflect.ValueOf(&item.Key).Elem() 670 - if d.unmarshal(n.children[i], k) { 671 - v := reflect.ValueOf(&item.Value).Elem() 672 - if d.unmarshal(n.children[i+1], v) { 673 - slice = append(slice, item) 674 - } 616 + switch n.children[i].kind { 617 + case mappingNode: 618 + d.p.failf(n.startPos.line, "invalid map key: map") 619 + case sequenceNode: 620 + d.p.failf(n.startPos.line, "invalid map key: sequence") 675 621 } 676 - } 677 - out.Set(reflect.ValueOf(slice)) 678 - d.mapType = mapType 679 - return true 680 - } 681 622 682 - func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { 683 - sinfo, err := getStructInfo(out.Type()) 684 - if err != nil { 685 - panic(err) 686 - } 687 - name := settableValueOf("") 688 - l := len(n.children) 623 + field := &ast.Field{} 624 + d.attachDocComments(n.children[i].startPos, 0, field) 689 625 690 - var inlineMap reflect.Value 691 - var elemType reflect.Type 692 - if sinfo.InlineMap != -1 { 693 - inlineMap = out.Field(sinfo.InlineMap) 694 - inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) 695 - elemType = inlineMap.Type().Elem() 696 - } 626 + label := d.label(n.children[i]) 627 + field.Label = label 628 + d.attachLineComment(n.children[i].endPos, 1, label) 697 629 698 - var doneFields []bool 699 - if d.strict { 700 - doneFields = make([]bool, len(sinfo.FieldsList)) 701 - } 702 - for i := 0; i < l; i += 2 { 703 - ni := n.children[i] 704 - if isMerge(ni) { 705 - d.merge(n.children[i+1], out) 706 - continue 707 - } 708 - if !d.unmarshal(ni, name) { 709 - continue 710 - } 711 - if info, ok := sinfo.FieldsMap[name.String()]; ok { 712 - if d.strict { 713 - if doneFields[info.Id] { 714 - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type())) 715 - continue 630 + if merge { 631 + key := labelStr(label) 632 + for _, decl := range m.Elts { 633 + f := decl.(*ast.Field) 634 + name, _ := ast.LabelName(f.Label) 635 + if name == key { 636 + f.Value = d.unmarshal(n.children[i+1]) 637 + continue outer 716 638 } 717 - doneFields[info.Id] = true 718 639 } 719 - var field reflect.Value 720 - if info.Inline == nil { 721 - field = out.Field(info.Num) 722 - } else { 723 - field = out.FieldByIndex(info.Inline) 724 - } 725 - d.unmarshal(n.children[i+1], field) 726 - } else if sinfo.InlineMap != -1 { 727 - if inlineMap.IsNil() { 728 - inlineMap.Set(reflect.MakeMap(inlineMap.Type())) 729 - } 730 - value := reflect.New(elemType).Elem() 731 - d.unmarshal(n.children[i+1], value) 732 - d.setMapIndex(n.children[i+1], inlineMap, name, value) 733 - } else if d.strict { 734 - d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type())) 735 640 } 641 + 642 + value := d.unmarshal(n.children[i+1]) 643 + field.Value = value 644 + d.attachDocComments(n.children[i+1].startPos, 0, value) 645 + d.attachLineComment(n.children[i+1].endPos, 10, value) 646 + 647 + m.Elts = append(m.Elts, field) 736 648 } 737 - return true 738 649 } 739 650 740 - func failWantMap() { 741 - failf("map merge requires map or sequence of maps as the value") 651 + func labelStr(l ast.Label) string { 652 + switch x := l.(type) { 653 + case *ast.Ident: 654 + return x.Name 655 + case *ast.BasicLit: 656 + s, _ := strconv.Unquote(x.Value) 657 + return s 658 + } 659 + return "" 660 + } 661 + 662 + func (d *decoder) failWantMap(n *node) { 663 + d.p.failf(n.startPos.line, "map merge requires map or sequence of maps as the value") 742 664 } 743 665 744 - func (d *decoder) merge(n *node, out reflect.Value) { 666 + func (d *decoder) merge(n *node, m *ast.StructLit) { 745 667 switch n.kind { 746 668 case mappingNode: 747 - d.unmarshal(n, out) 669 + d.insertMap(n, m, true) 748 670 case aliasNode: 749 671 an, ok := d.doc.anchors[n.value] 750 672 if ok && an.kind != mappingNode { 751 - failWantMap() 673 + d.failWantMap(n) 752 674 } 753 - d.unmarshal(n, out) 675 + d.insertMap(an, m, true) 754 676 case sequenceNode: 755 677 // Step backwards as earlier nodes take precedence. 756 678 for i := len(n.children) - 1; i >= 0; i-- { ··· 758 680 if ni.kind == aliasNode { 759 681 an, ok := d.doc.anchors[ni.value] 760 682 if ok && an.kind != mappingNode { 761 - failWantMap() 683 + d.failWantMap(n) 762 684 } 685 + d.insertMap(an, m, true) 686 + continue 763 687 } else if ni.kind != mappingNode { 764 - failWantMap() 688 + d.failWantMap(n) 765 689 } 766 - d.unmarshal(ni, out) 690 + d.insertMap(ni, m, true) 767 691 } 768 692 default: 769 - failWantMap() 693 + d.failWantMap(n) 770 694 } 771 695 } 772 696
+326 -768
internal/third_party/yaml/decode_test.go
··· 1 1 package yaml_test 2 2 3 3 import ( 4 + "bytes" 4 5 "errors" 6 + "flag" 7 + "fmt" 5 8 "io" 6 - "math" 7 - "reflect" 9 + "io/ioutil" 10 + "strconv" 8 11 "strings" 9 - "time" 12 + "testing" 10 13 11 - . "gopkg.in/check.v1" 12 - "gopkg.in/yaml.v2" 14 + "cuelang.org/go/cue/ast" 15 + "cuelang.org/go/cue/format" 16 + "cuelang.org/go/cue/token" 17 + "cuelang.org/go/internal/third_party/yaml" 13 18 ) 19 + 20 + var update = flag.Bool("update", false, "update test data") 14 21 15 22 var unmarshalIntTest = 123 16 23 17 24 var unmarshalTests = []struct { 18 - data string 19 - value interface{} 25 + data string 26 + want string 20 27 }{ 21 28 { 22 29 "", 23 - (*struct{})(nil), 30 + "", 24 31 }, 25 32 { 26 - "{}", &struct{}{}, 33 + "{}", 34 + "", 27 35 }, { 28 36 "v: hi", 29 - map[string]string{"v": "hi"}, 37 + `v: "hi"`, 30 38 }, { 31 - "v: hi", map[string]interface{}{"v": "hi"}, 39 + "v: hi", 40 + `v: "hi"`, 32 41 }, { 33 42 "v: true", 34 - map[string]string{"v": "true"}, 35 - }, { 36 43 "v: true", 37 - map[string]interface{}{"v": true}, 38 44 }, { 39 45 "v: 10", 40 - map[string]interface{}{"v": 10}, 46 + "v: 10", 41 47 }, { 42 48 "v: 0b10", 43 - map[string]interface{}{"v": 2}, 49 + "v: 0b10", 44 50 }, { 45 51 "v: 0xA", 46 - map[string]interface{}{"v": 10}, 52 + "v: 0xA", 47 53 }, { 48 54 "v: 4294967296", 49 - map[string]int64{"v": 4294967296}, 55 + "v: 4294967296", 50 56 }, { 51 57 "v: 0.1", 52 - map[string]interface{}{"v": 0.1}, 58 + "v: 0.1", 53 59 }, { 54 60 "v: .1", 55 - map[string]interface{}{"v": 0.1}, 61 + "v: .1", 56 62 }, { 57 63 "v: .Inf", 58 - map[string]interface{}{"v": math.Inf(+1)}, 64 + "v: +Inf", 59 65 }, { 60 66 "v: -.Inf", 61 - map[string]interface{}{"v": math.Inf(-1)}, 67 + "v: -Inf", 62 68 }, { 63 69 "v: -10", 64 - map[string]interface{}{"v": -10}, 70 + "v: -10", 65 71 }, { 66 72 "v: -.1", 67 - map[string]interface{}{"v": -0.1}, 73 + "v: -.1", 68 74 }, 69 75 70 76 // Simple values. 71 77 { 72 78 "123", 73 - &unmarshalIntTest, 79 + "123", 74 80 }, 75 81 76 82 // Floats from spec 77 83 { 78 84 "canonical: 6.8523e+5", 79 - map[string]interface{}{"canonical": 6.8523e+5}, 85 + "canonical: 6.8523e+5", 80 86 }, { 81 87 "expo: 685.230_15e+03", 82 - map[string]interface{}{"expo": 685.23015e+03}, 88 + "expo: 685.230_15e+03", 83 89 }, { 84 90 "fixed: 685_230.15", 85 - map[string]interface{}{"fixed": 685230.15}, 91 + "fixed: 685_230.15", 86 92 }, { 87 93 "neginf: -.inf", 88 - map[string]interface{}{"neginf": math.Inf(-1)}, 94 + "neginf: -Inf", 89 95 }, { 90 96 "fixed: 685_230.15", 91 - map[string]float64{"fixed": 685230.15}, 97 + "fixed: 685_230.15", 92 98 }, 93 99 //{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported 94 100 //{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails. ··· 96 102 // Bools from spec 97 103 { 98 104 "canonical: y", 99 - map[string]interface{}{"canonical": true}, 105 + "canonical: true", 100 106 }, { 101 107 "answer: NO", 102 - map[string]interface{}{"answer": false}, 108 + "answer: false", 103 109 }, { 104 110 "logical: True", 105 - map[string]interface{}{"logical": true}, 111 + "logical: true", 106 112 }, { 107 113 "option: on", 108 - map[string]interface{}{"option": true}, 109 - }, { 110 - "option: on", 111 - map[string]bool{"option": true}, 114 + "option: true", 112 115 }, 113 116 // Ints from spec 114 117 { 115 118 "canonical: 685230", 116 - map[string]interface{}{"canonical": 685230}, 119 + "canonical: 685230", 117 120 }, { 118 121 "decimal: +685_230", 119 - map[string]interface{}{"decimal": 685230}, 122 + "decimal: +685_230", 120 123 }, { 121 124 "octal: 02472256", 122 - map[string]interface{}{"octal": 685230}, 125 + "octal: 02472256", 123 126 }, { 124 127 "hexa: 0x_0A_74_AE", 125 - map[string]interface{}{"hexa": 685230}, 128 + "hexa: 0x_0A_74_AE", 126 129 }, { 127 130 "bin: 0b1010_0111_0100_1010_1110", 128 - map[string]interface{}{"bin": 685230}, 131 + "bin: 0b1010_0111_0100_1010_1110", 129 132 }, { 130 133 "bin: -0b101010", 131 - map[string]interface{}{"bin": -42}, 134 + "bin: -0b101010", 132 135 }, { 133 136 "bin: -0b1000000000000000000000000000000000000000000000000000000000000000", 134 - map[string]interface{}{"bin": -9223372036854775808}, 137 + "bin: -0b1000000000000000000000000000000000000000000000000000000000000000", 135 138 }, { 136 139 "decimal: +685_230", 137 - map[string]int{"decimal": 685230}, 140 + "decimal: +685_230", 138 141 }, 139 142 140 143 //{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported ··· 142 145 // Nulls from spec 143 146 { 144 147 "empty:", 145 - map[string]interface{}{"empty": nil}, 148 + "empty: null", 146 149 }, { 147 150 "canonical: ~", 148 - map[string]interface{}{"canonical": nil}, 151 + "canonical: null", 149 152 }, { 150 153 "english: null", 151 - map[string]interface{}{"english": nil}, 154 + "english: null", 152 155 }, { 153 156 "~: null key", 154 - map[interface{}]string{nil: "null key"}, 155 - }, { 156 - "empty:", 157 - map[string]*bool{"empty": nil}, 157 + `"~": "null key"`, 158 158 }, 159 159 160 160 // Flow sequence 161 161 { 162 162 "seq: [A,B]", 163 - map[string]interface{}{"seq": []interface{}{"A", "B"}}, 163 + `seq: ["A", "B"]`, 164 164 }, { 165 165 "seq: [A,B,C,]", 166 - map[string][]string{"seq": []string{"A", "B", "C"}}, 166 + `seq: ["A", "B", "C"]`, 167 167 }, { 168 168 "seq: [A,1,C]", 169 - map[string][]string{"seq": []string{"A", "1", "C"}}, 170 - }, { 171 - "seq: [A,1,C]", 172 - map[string][]int{"seq": []int{1}}, 173 - }, { 174 - "seq: [A,1,C]", 175 - map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 169 + `seq: ["A", 1, "C"]`, 176 170 }, 177 171 // Block sequence 178 172 { 179 173 "seq:\n - A\n - B", 180 - map[string]interface{}{"seq": []interface{}{"A", "B"}}, 174 + `seq: ["A", "B"]`, 181 175 }, { 182 176 "seq:\n - A\n - B\n - C", 183 - map[string][]string{"seq": []string{"A", "B", "C"}}, 184 - }, { 185 - "seq:\n - A\n - 1\n - C", 186 - map[string][]string{"seq": []string{"A", "1", "C"}}, 177 + `seq: ["A", "B", "C"]`, 187 178 }, { 188 179 "seq:\n - A\n - 1\n - C", 189 - map[string][]int{"seq": []int{1}}, 190 - }, { 191 - "seq:\n - A\n - 1\n - C", 192 - map[string]interface{}{"seq": []interface{}{"A", 1, "C"}}, 180 + `seq: ["A", 1, "C"]`, 193 181 }, 194 182 195 183 // Literal block scalar 196 184 { 197 185 "scalar: | # Comment\n\n literal\n\n \ttext\n\n", 198 - map[string]string{"scalar": "\nliteral\n\n\ttext\n"}, 186 + `scalar: """ 187 + 188 + literal 189 + 190 + \ttext 191 + 192 + """`, 199 193 }, 200 194 201 195 // Folded block scalar 202 196 { 203 197 "scalar: > # Comment\n\n folded\n line\n \n next\n line\n * one\n * two\n\n last\n line\n\n", 204 - map[string]string{"scalar": "\nfolded line\nnext line\n * one\n * two\n\nlast line\n"}, 198 + `scalar: """ 199 + 200 + folded line 201 + next line 202 + * one 203 + * two 204 + 205 + last line 206 + 207 + """`, 205 208 }, 206 209 207 - // Map inside interface with no type hints. 210 + // Structs 208 211 { 209 212 "a: {b: c}", 210 - map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, 213 + `a b: "c"`, 211 214 }, 212 - 213 - // Structs and type conversions. 214 215 { 215 216 "hello: world", 216 - &struct{ Hello string }{"world"}, 217 - }, { 218 - "a: {b: c}", 219 - &struct{ A struct{ B string } }{struct{ B string }{"c"}}, 220 - }, { 221 - "a: {b: c}", 222 - &struct{ A *struct{ B string } }{&struct{ B string }{"c"}}, 223 - }, { 224 - "a: {b: c}", 225 - &struct{ A map[string]string }{map[string]string{"b": "c"}}, 226 - }, { 227 - "a: {b: c}", 228 - &struct{ A *map[string]string }{&map[string]string{"b": "c"}}, 217 + `hello: "world"`, 229 218 }, { 230 219 "a:", 231 - &struct{ A map[string]string }{}, 220 + "a: null", 232 221 }, { 233 222 "a: 1", 234 - &struct{ A int }{1}, 235 - }, { 236 223 "a: 1", 237 - &struct{ A float64 }{1}, 238 224 }, { 239 225 "a: 1.0", 240 - &struct{ A int }{1}, 241 - }, { 242 226 "a: 1.0", 243 - &struct{ A uint }{1}, 244 227 }, { 245 228 "a: [1, 2]", 246 - &struct{ A []int }{[]int{1, 2}}, 247 - }, { 248 229 "a: [1, 2]", 249 - &struct{ A [2]int }{[2]int{1, 2}}, 250 230 }, { 251 - "a: 1", 252 - &struct{ B int }{0}, 231 + "a: y", 232 + "a: true", 253 233 }, { 254 - "a: 1", 255 - &struct { 256 - B int "a" 257 - }{1}, 258 - }, { 259 - "a: y", 260 - &struct{ A bool }{true}, 234 + "{ a: 1, b: {c: 1} }", 235 + "a: 1\nb c: 1", 261 236 }, 262 237 263 238 // Some cross type conversions 264 239 { 265 240 "v: 42", 266 - map[string]uint{"v": 42}, 241 + "v: 42", 267 242 }, { 268 243 "v: -42", 269 - map[string]uint{}, 244 + "v: -42", 270 245 }, { 271 246 "v: 4294967296", 272 - map[string]uint64{"v": 4294967296}, 247 + "v: 4294967296", 273 248 }, { 274 249 "v: -4294967296", 275 - map[string]uint64{}, 250 + "v: -4294967296", 276 251 }, 277 252 278 253 // int 279 254 { 280 255 "int_max: 2147483647", 281 - map[string]int{"int_max": math.MaxInt32}, 256 + "int_max: 2147483647", 282 257 }, 283 258 { 284 259 "int_min: -2147483648", 285 - map[string]int{"int_min": math.MinInt32}, 260 + "int_min: -2147483648", 286 261 }, 287 262 { 288 263 "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 289 - map[string]int{}, 264 + "int_overflow: 9223372036854775808", // math.MaxInt64 + 1 290 265 }, 291 266 292 267 // int64 293 268 { 294 269 "int64_max: 9223372036854775807", 295 - map[string]int64{"int64_max": math.MaxInt64}, 270 + "int64_max: 9223372036854775807", 296 271 }, 297 272 { 298 273 "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 299 - map[string]int64{"int64_max_base2": math.MaxInt64}, 274 + "int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111", 300 275 }, 301 276 { 302 277 "int64_min: -9223372036854775808", 303 - map[string]int64{"int64_min": math.MinInt64}, 278 + "int64_min: -9223372036854775808", 304 279 }, 305 280 { 306 281 "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 307 - map[string]int64{"int64_neg_base2": -math.MaxInt64}, 282 + "int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111", 308 283 }, 309 284 { 310 285 "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 311 - map[string]int64{}, 286 + "int64_overflow: 9223372036854775808", // math.MaxInt64 + 1 312 287 }, 313 288 314 289 // uint 315 290 { 316 - "uint_min: 0", 317 - map[string]uint{"uint_min": 0}, 318 - }, 319 - { 320 291 "uint_max: 4294967295", 321 - map[string]uint{"uint_max": math.MaxUint32}, 322 - }, 323 - { 324 - "uint_underflow: -1", 325 - map[string]uint{}, 292 + "uint_max: 4294967295", 326 293 }, 327 294 328 295 // uint64 329 296 { 330 - "uint64_min: 0", 331 - map[string]uint{"uint64_min": 0}, 332 - }, 333 - { 297 + "uint64_max: 18446744073709551615", 334 298 "uint64_max: 18446744073709551615", 335 - map[string]uint64{"uint64_max": math.MaxUint64}, 336 299 }, 337 300 { 338 301 "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 339 - map[string]uint64{"uint64_max_base2": math.MaxUint64}, 302 + "uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111", 340 303 }, 341 304 { 342 305 "uint64_maxint64: 9223372036854775807", 343 - map[string]uint64{"uint64_maxint64": math.MaxInt64}, 344 - }, 345 - { 346 - "uint64_underflow: -1", 347 - map[string]uint64{}, 306 + "uint64_maxint64: 9223372036854775807", 348 307 }, 349 308 350 309 // float32 351 310 { 352 311 "float32_max: 3.40282346638528859811704183484516925440e+38", 353 - map[string]float32{"float32_max": math.MaxFloat32}, 312 + "float32_max: 3.40282346638528859811704183484516925440e+38", 354 313 }, 355 314 { 356 315 "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 357 - map[string]float32{"float32_nonzero": math.SmallestNonzeroFloat32}, 316 + "float32_nonzero: 1.401298464324817070923729583289916131280e-45", 358 317 }, 359 318 { 360 319 "float32_maxuint64: 18446744073709551615", 361 - map[string]float32{"float32_maxuint64": float32(math.MaxUint64)}, 320 + "float32_maxuint64: 18446744073709551615", 362 321 }, 363 322 { 364 323 "float32_maxuint64+1: 18446744073709551616", 365 - map[string]float32{"float32_maxuint64+1": float32(math.MaxUint64 + 1)}, 324 + `"float32_maxuint64+1": 18446744073709551616`, 366 325 }, 367 326 368 327 // float64 369 328 { 370 329 "float64_max: 1.797693134862315708145274237317043567981e+308", 371 - map[string]float64{"float64_max": math.MaxFloat64}, 330 + "float64_max: 1.797693134862315708145274237317043567981e+308", 372 331 }, 373 332 { 374 333 "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 375 - map[string]float64{"float64_nonzero": math.SmallestNonzeroFloat64}, 334 + "float64_nonzero: 4.940656458412465441765687928682213723651e-324", 376 335 }, 377 336 { 378 337 "float64_maxuint64: 18446744073709551615", 379 - map[string]float64{"float64_maxuint64": float64(math.MaxUint64)}, 338 + "float64_maxuint64: 18446744073709551615", 380 339 }, 381 340 { 382 341 "float64_maxuint64+1: 18446744073709551616", 383 - map[string]float64{"float64_maxuint64+1": float64(math.MaxUint64 + 1)}, 342 + `"float64_maxuint64+1": 18446744073709551616`, 384 343 }, 385 344 386 345 // Overflow cases. 387 346 { 388 347 "v: 4294967297", 389 - map[string]int32{}, 348 + "v: 4294967297", 390 349 }, { 391 350 "v: 128", 392 - map[string]int8{}, 351 + "v: 128", 393 352 }, 394 353 395 354 // Quoted values. 396 355 { 397 356 "'1': '\"2\"'", 398 - map[interface{}]interface{}{"1": "\"2\""}, 357 + `"1": "\"2\""`, 399 358 }, { 400 359 "v:\n- A\n- 'B\n\n C'\n", 401 - map[string][]string{"v": []string{"A", "B\nC"}}, 360 + `v: ["A", """ 361 + B 362 + C 363 + """]`, 402 364 }, 403 365 404 366 // Explicit tags. 405 367 { 406 368 "v: !!float '1.1'", 407 - map[string]interface{}{"v": 1.1}, 369 + "v: 1.1", 408 370 }, { 409 371 "v: !!float 0", 410 - map[string]interface{}{"v": float64(0)}, 372 + "v: float & 0", // Should this be 0.0? 411 373 }, { 412 374 "v: !!float -1", 413 - map[string]interface{}{"v": float64(-1)}, 375 + "v: float & -1", // Should this be -1.0? 414 376 }, { 415 377 "v: !!null ''", 416 - map[string]interface{}{"v": nil}, 378 + "v: null", 417 379 }, { 418 380 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'", 419 - map[string]interface{}{"v": 1}, 381 + "v: 1", 420 382 }, 421 383 422 384 // Non-specific tag (Issue #75) 423 385 { 424 386 "v: ! test", 425 - map[string]interface{}{"v": "test"}, 387 + // TODO: map[string]interface{}{"v": "test"}, 388 + "", 426 389 }, 427 390 428 391 // Anchors and aliases. 429 392 { 430 393 "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", 431 - &struct{ A, B, C, D int }{1, 2, 1, 2}, 394 + `a: 1 395 + b: 2 396 + c: 1 397 + d: 2`, 432 398 }, { 433 399 "a: &a {c: 1}\nb: *a", 434 - &struct { 435 - A, B struct { 436 - C int 437 - } 438 - }{struct{ C int }{1}, struct{ C int }{1}}, 400 + "a c: 1\nb c: 1", 439 401 }, { 440 402 "a: &a [1, 2]\nb: *a", 441 - &struct{ B []int }{[]int{1, 2}}, 403 + "a: [1, 2]\nb: [1, 2]", // TODO: a: [1, 2], b: a 442 404 }, 443 405 444 - // Bug #1133337 445 406 { 446 407 "foo: ''", 447 - map[string]*string{"foo": new(string)}, 408 + `foo: ""`, 448 409 }, { 449 410 "foo: null", 450 - map[string]*string{"foo": nil}, 451 - }, { 452 411 "foo: null", 453 - map[string]string{"foo": ""}, 454 - }, { 455 - "foo: null", 456 - map[string]interface{}{"foo": nil}, 457 412 }, 458 413 459 414 // Support for ~ 460 415 { 461 416 "foo: ~", 462 - map[string]*string{"foo": nil}, 463 - }, { 464 - "foo: ~", 465 - map[string]string{"foo": ""}, 466 - }, { 467 - "foo: ~", 468 - map[string]interface{}{"foo": nil}, 469 - }, 470 - 471 - // Ignored field 472 - { 473 - "a: 1\nb: 2\n", 474 - &struct { 475 - A int 476 - B int "-" 477 - }{1, 0}, 417 + "foo: null", 478 418 }, 479 419 480 420 // Bug #1191981 ··· 486 426 ` Generic line break (glyphed)\n\` + "\n" + 487 427 ` Line separator\u2028\` + "\n" + 488 428 ` Paragraph separator\u2029"` + "\n", 489 - "" + 490 - "Generic line break (no glyph)\n" + 491 - "Generic line break (glyphed)\n" + 492 - "Line separator\u2028Paragraph separator\u2029", 493 - }, 494 - 495 - // Struct inlining 496 - { 497 - "a: 1\nb: 2\nc: 3\n", 498 - &struct { 499 - A int 500 - C inlineB `yaml:",inline"` 501 - }{1, inlineB{2, inlineC{3}}}, 502 - }, 503 - 504 - // Map inlining 505 - { 506 - "a: 1\nb: 2\nc: 3\n", 507 - &struct { 508 - A int 509 - C map[string]int `yaml:",inline"` 510 - }{1, map[string]int{"b": 2, "c": 3}}, 429 + `""" 430 + Generic line break (no glyph) 431 + Generic line break (glyphed) 432 + Line separator\u2028Paragraph separator\u2029 433 + """`, 511 434 }, 512 435 513 436 // bug 1243827 514 437 { 515 438 "a: -b_c", 516 - map[string]interface{}{"a": "-b_c"}, 439 + `a: "-b_c"`, 517 440 }, 518 441 { 519 442 "a: +b_c", 520 - map[string]interface{}{"a": "+b_c"}, 443 + `a: "+b_c"`, 521 444 }, 522 445 { 523 446 "a: 50cent_of_dollar", 524 - map[string]interface{}{"a": "50cent_of_dollar"}, 447 + `a: "50cent_of_dollar"`, 525 448 }, 526 449 527 450 // issue #295 (allow scalars with colons in flow mappings and sequences) 528 451 { 529 452 "a: {b: https://github.com/go-yaml/yaml}", 530 - map[string]interface{}{"a": map[interface{}]interface{}{ 531 - "b": "https://github.com/go-yaml/yaml", 532 - }}, 453 + `a b: "https://github.com/go-yaml/yaml"`, 533 454 }, 534 455 { 535 456 "a: [https://github.com/go-yaml/yaml]", 536 - map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}}, 457 + `a: ["https://github.com/go-yaml/yaml"]`, 537 458 }, 538 459 539 460 // Duration 540 461 { 541 462 "a: 3s", 542 - map[string]time.Duration{"a": 3 * time.Second}, 463 + `a: "3s"`, // for now 543 464 }, 544 465 545 466 // Issue #24. 546 467 { 547 468 "a: <foo>", 548 - map[string]string{"a": "<foo>"}, 469 + `a: "<foo>"`, 549 470 }, 550 471 551 472 // Base 60 floats are obsolete and unsupported. 552 473 { 553 474 "a: 1:1\n", 554 - map[string]string{"a": "1:1"}, 475 + `a: "1:1"`, 555 476 }, 556 477 557 478 // Binary data. 558 479 { 559 480 "a: !!binary gIGC\n", 560 - map[string]string{"a": "\x80\x81\x82"}, 481 + `a: '\x80\x81\x82'`, 561 482 }, { 562 483 "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 563 - map[string]string{"a": strings.Repeat("\x90", 54)}, 484 + "a: '" + strings.Repeat(`\x90`, 54) + "'", 564 485 }, { 565 486 "a: !!binary |\n " + strings.Repeat("A", 70) + "\n ==\n", 566 - map[string]string{"a": strings.Repeat("\x00", 52)}, 487 + "a: '" + strings.Repeat(`\x00`, 52) + "'", 567 488 }, 568 489 569 490 // Ordered maps. 570 491 { 571 492 "{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}", 572 - &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}}, 493 + `b: 2 494 + a: 1 495 + d: 4 496 + c: 3 497 + sub e: 5`, 573 498 }, 574 499 575 500 // Issue #39. 576 501 { 577 502 "a:\n b:\n c: d\n", 578 - map[string]struct{ B interface{} }{"a": {map[interface{}]interface{}{"c": "d"}}}, 579 - }, 580 - 581 - // Custom map type. 582 - { 583 - "a: {b: c}", 584 - M{"a": M{"b": "c"}}, 585 - }, 586 - 587 - // Support encoding.TextUnmarshaler. 588 - { 589 - "a: 1.2.3.4\n", 590 - map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}}, 591 - }, 592 - { 593 - "a: 2015-02-24T18:19:39Z\n", 594 - map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}}, 503 + `a b c: "d"`, 595 504 }, 596 505 597 506 // Timestamps 598 507 { 599 508 // Date only. 600 509 "a: 2015-01-01\n", 601 - map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 510 + `a: "2015-01-01"`, 602 511 }, 603 512 { 604 513 // RFC3339 605 514 "a: 2015-02-24T18:19:39.12Z\n", 606 - map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)}, 515 + `a: "2015-02-24T18:19:39.12Z"`, 607 516 }, 608 517 { 609 518 // RFC3339 with short dates. 610 519 "a: 2015-2-3T3:4:5Z", 611 - map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)}, 520 + `a: "2015-2-3T3:4:5Z"`, 612 521 }, 613 522 { 614 523 // ISO8601 lower case t 615 524 "a: 2015-02-24t18:19:39Z\n", 616 - map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 525 + `a: "2015-02-24t18:19:39Z"`, 617 526 }, 618 527 { 619 528 // space separate, no time zone 620 529 "a: 2015-02-24 18:19:39\n", 621 - map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 530 + `a: "2015-02-24 18:19:39"`, 622 531 }, 623 532 // Some cases not currently handled. Uncomment these when 624 533 // the code is fixed. ··· 635 544 { 636 545 // explicit string tag 637 546 "a: !!str 2015-01-01", 638 - map[string]interface{}{"a": "2015-01-01"}, 547 + `a: "2015-01-01"`, 639 548 }, 640 549 { 641 550 // explicit timestamp tag on quoted string 642 551 "a: !!timestamp \"2015-01-01\"", 643 - map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 552 + `a: "2015-01-01"`, 644 553 }, 645 554 { 646 555 // explicit timestamp tag on unquoted string 647 556 "a: !!timestamp 2015-01-01", 648 - map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 557 + `a: "2015-01-01"`, 649 558 }, 650 559 { 651 560 // quoted string that's a valid timestamp 652 561 "a: \"2015-01-01\"", 653 - map[string]interface{}{"a": "2015-01-01"}, 654 - }, 655 - { 656 - // explicit timestamp tag into interface. 657 - "a: !!timestamp \"2015-01-01\"", 658 - map[string]interface{}{"a": "2015-01-01"}, 659 - }, 660 - { 661 - // implicit timestamp tag into interface. 662 - "a: 2015-01-01", 663 - map[string]interface{}{"a": "2015-01-01"}, 562 + "a: \"2015-01-01\"", 664 563 }, 665 564 666 - // Encode empty lists as zero-length slices. 565 + // Empty list 667 566 { 668 567 "a: []", 669 - &struct{ A []int }{[]int{}}, 568 + "a: []", 670 569 }, 671 570 672 571 // UTF-16-LE 673 572 { 674 573 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00", 675 - M{"ñoño": "very yes"}, 574 + `ñoño: "very yes"`, 676 575 }, 677 576 // UTF-16-LE with surrogate. 678 577 { 679 578 "\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00", 680 - M{"ñoño": "very yes 🟔"}, 579 + `ñoño: "very yes 🟔"`, 681 580 }, 682 581 683 582 // UTF-16-BE 684 583 { 685 584 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n", 686 - M{"ñoño": "very yes"}, 585 + `ñoño: "very yes"`, 687 586 }, 688 587 // UTF-16-BE with surrogate. 689 588 { 690 589 "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n", 691 - M{"ñoño": "very yes 🟔"}, 590 + `ñoño: "very yes 🟔"`, 692 591 }, 693 592 694 593 // YAML Float regex shouldn't match this 695 594 { 696 595 "a: 123456e1\n", 697 - M{"a": "123456e1"}, 596 + `a: "123456e1"`, 698 597 }, { 699 598 "a: 123456E1\n", 700 - M{"a": "123456E1"}, 599 + `a: "123456E1"`, 701 600 }, 702 601 // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes 703 602 { 704 603 "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n", 705 - map[interface{}]interface{}{ 706 - "Reuse anchor": "Bar", 707 - "First occurrence": "Foo", 708 - "Second occurrence": "Foo", 709 - "Override anchor": "Bar", 710 - }, 604 + `"First occurrence": "Foo" 605 + "Second occurrence": "Foo" 606 + "Override anchor": "Bar" 607 + "Reuse anchor": "Bar"`, 711 608 }, 712 609 // Single document with garbage following it. 713 610 { 714 611 "---\nhello\n...\n}not yaml", 715 - "hello", 612 + `"hello"`, 716 613 }, 717 614 } 718 615 ··· 727 624 C int 728 625 } 729 626 730 - func (s *S) TestUnmarshal(c *C) { 731 - for i, item := range unmarshalTests { 732 - c.Logf("test %d: %q", i, item.data) 733 - t := reflect.ValueOf(item.value).Type() 734 - value := reflect.New(t) 735 - err := yaml.Unmarshal([]byte(item.data), value.Interface()) 736 - if _, ok := err.(*yaml.TypeError); !ok { 737 - c.Assert(err, IsNil) 627 + var fset = token.NewFileSet() 628 + 629 + func cueStr(node ast.Node) string { 630 + if s, ok := node.(*ast.StructLit); ok { 631 + node = &ast.File{ 632 + Decls: s.Elts, 738 633 } 739 - c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err)) 740 634 } 635 + buf := bytes.Buffer{} 636 + format.Node(&buf, node) 637 + return strings.TrimSpace(buf.String()) 741 638 } 742 639 743 - // TODO(v3): This test should also work when unmarshaling onto an interface{}. 744 - func (s *S) TestUnmarshalFullTimestamp(c *C) { 745 - // Full timestamp in same format as encoded. This is confirmed to be 746 - // properly decoded by Python as a timestamp as well. 747 - var str = "2015-02-24T18:19:39.123456789-03:00" 748 - var t time.Time 749 - err := yaml.Unmarshal([]byte(str), &t) 750 - c.Assert(err, IsNil) 751 - c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location())) 752 - c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC)) 640 + func newDecoder(t *testing.T, data string) *yaml.Decoder { 641 + dec, err := yaml.NewDecoder(fset, "test.yaml", strings.NewReader(data)) 642 + if err != nil { 643 + t.Fatal(err) 644 + } 645 + return dec 753 646 } 754 647 755 - func (s *S) TestDecoderSingleDocument(c *C) { 648 + func callUnmarshal(t *testing.T, data string) (ast.Expr, error) { 649 + return yaml.Unmarshal(fset, "test.yaml", []byte(data)) 650 + } 651 + 652 + func TestUnmarshal(t *testing.T) { 653 + for i, item := range unmarshalTests { 654 + t.Run(strconv.Itoa(i), func(t *testing.T) { 655 + t.Logf("test %d: %q", i, item.data) 656 + expr, err := callUnmarshal(t, item.data) 657 + if _, ok := err.(*yaml.TypeError); !ok && err != nil { 658 + t.Fatal("expected error to be nil") 659 + } 660 + if got := cueStr(expr); got != item.want { 661 + t.Errorf("\n got: %v;\nwant: %v", got, item.want) 662 + } 663 + }) 664 + } 665 + } 666 + 667 + // // TODO(v3): This test should also work when unmarshaling onto an interface{}. 668 + // func (s *S) TestUnmarshalFullTimestamp(c *C) { 669 + // // Full timestamp in same format as encoded. This is confirmed to be 670 + // // properly decoded by Python as a timestamp as well. 671 + // var str = "2015-02-24T18:19:39.123456789-03:00" 672 + // expr, err := yaml.Unmarshal([]byte(str)) 673 + // c.Assert(err, IsNil) 674 + // c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location())) 675 + // c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC)) 676 + // } 677 + 678 + func TestDecoderSingleDocument(t *testing.T) { 756 679 // Test that Decoder.Decode works as expected on 757 680 // all the unmarshal tests. 758 681 for i, item := range unmarshalTests { 759 - c.Logf("test %d: %q", i, item.data) 760 - if item.data == "" { 761 - // Behaviour differs when there's no YAML. 762 - continue 763 - } 764 - t := reflect.ValueOf(item.value).Type() 765 - value := reflect.New(t) 766 - err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface()) 767 - if _, ok := err.(*yaml.TypeError); !ok { 768 - c.Assert(err, IsNil) 769 - } 770 - c.Assert(value.Elem().Interface(), DeepEquals, item.value) 682 + t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 683 + if item.data == "" { 684 + // Behaviour differs when there's no YAML. 685 + return 686 + } 687 + expr, err := newDecoder(t, item.data).Decode() 688 + if _, ok := err.(*yaml.TypeError); !ok && err != nil { 689 + t.Errorf("err should be nil, was %v", err) 690 + } 691 + if got := cueStr(expr); got != item.want { 692 + t.Errorf("\n got: %v;\nwant: %v", got, item.want) 693 + } 694 + }) 771 695 } 772 696 } 773 697 774 698 var decoderTests = []struct { 775 - data string 776 - values []interface{} 699 + data string 700 + want string 777 701 }{{ 778 702 "", 779 - nil, 703 + "", 780 704 }, { 781 705 "a: b", 782 - []interface{}{ 783 - map[interface{}]interface{}{"a": "b"}, 784 - }, 706 + `a: "b"`, 785 707 }, { 786 708 "---\na: b\n...\n", 787 - []interface{}{ 788 - map[interface{}]interface{}{"a": "b"}, 789 - }, 709 + `a: "b"`, 790 710 }, { 791 711 "---\n'hello'\n...\n---\ngoodbye\n...\n", 792 - []interface{}{ 793 - "hello", 794 - "goodbye", 795 - }, 712 + `"hello"` + "\n" + `"goodbye"`, 796 713 }} 797 714 798 - func (s *S) TestDecoder(c *C) { 715 + func TestDecoder(t *testing.T) { 799 716 for i, item := range decoderTests { 800 - c.Logf("test %d: %q", i, item.data) 801 - var values []interface{} 802 - dec := yaml.NewDecoder(strings.NewReader(item.data)) 803 - for { 804 - var value interface{} 805 - err := dec.Decode(&value) 806 - if err == io.EOF { 807 - break 717 + t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 718 + var values []string 719 + dec := newDecoder(t, item.data) 720 + for { 721 + expr, err := dec.Decode() 722 + if err == io.EOF { 723 + break 724 + } 725 + if err != nil { 726 + t.Errorf("err should be nil, was %v", err) 727 + } 728 + values = append(values, cueStr(expr)) 729 + } 730 + got := strings.Join(values, "\n") 731 + if got != item.want { 732 + t.Errorf("\n got: %v;\nwant: %v", got, item.want) 808 733 } 809 - c.Assert(err, IsNil) 810 - values = append(values, value) 811 - } 812 - c.Assert(values, DeepEquals, item.values) 734 + }) 813 735 } 814 736 } 815 737 ··· 819 741 return 0, errors.New("some read error") 820 742 } 821 743 822 - func (s *S) TestDecoderReadError(c *C) { 823 - err := yaml.NewDecoder(errReader{}).Decode(&struct{}{}) 824 - c.Assert(err, ErrorMatches, `yaml: input error: some read error`) 825 - } 826 - 827 - func (s *S) TestUnmarshalNaN(c *C) { 828 - value := map[string]interface{}{} 829 - err := yaml.Unmarshal([]byte("notanum: .NaN"), &value) 830 - c.Assert(err, IsNil) 831 - c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true) 744 + func TestUnmarshalNaN(t *testing.T) { 745 + expr, err := callUnmarshal(t, "notanum: .NaN") 746 + if err != nil { 747 + t.Fatal("unexpected error", err) 748 + } 749 + got := cueStr(expr) 750 + want := "notanum: NaN" 751 + if got != want { 752 + t.Errorf("got %v; want %v", got, want) 753 + } 832 754 } 833 755 834 756 var unmarshalErrorTests = []struct { 835 757 data, error string 836 758 }{ 837 - {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"}, 838 - {"v: [A,", "yaml: line 1: did not find expected node content"}, 839 - {"v:\n- [A,", "yaml: line 2: did not find expected node content"}, 840 - {"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"}, 841 - {"a: *b\n", "yaml: unknown anchor 'b' referenced"}, 842 - {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"}, 843 - {"value: -", "yaml: block sequence entries are not allowed in this context"}, 844 - {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"}, 845 - {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`}, 846 - {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`}, 847 - {"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`}, 848 - {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"}, 759 + {"\nv: !!float 'error'", "test.yaml:2: cannot decode !!str `error` as a !!float"}, 760 + {"v: [A,", "test.yaml:1: did not find expected node content"}, 761 + {"v:\n- [A,", "test.yaml:2: did not find expected node content"}, 762 + {"a:\n- b: *,", "test.yaml:2: did not find expected alphabetic or numeric character"}, 763 + {"a: *b\n", "test.yaml:1: unknown anchor 'b' referenced"}, 764 + {"a: &a\n b: *a\n", "test.yaml:2: anchor 'a' value contains itself"}, 765 + {"value: -", "test.yaml:1: block sequence entries are not allowed in this context"}, 766 + {"a: !!binary ==", "test.yaml:1: !!binary value contains invalid base64 data"}, 767 + {"{[.]}", `test.yaml:1: invalid map key: sequence`}, 768 + {"{{.}}", `test.yaml:1: invalid map key: map`}, 769 + {"b: *a\na: &a {c: 1}", `test.yaml:1: unknown anchor 'a' referenced`}, 770 + {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "test.yaml:1: did not find expected whitespace"}, 849 771 } 850 772 851 - func (s *S) TestUnmarshalErrors(c *C) { 773 + func TestUnmarshalErrors(t *testing.T) { 852 774 for i, item := range unmarshalErrorTests { 853 - c.Logf("test %d: %q", i, item.data) 854 - var value interface{} 855 - err := yaml.Unmarshal([]byte(item.data), &value) 856 - c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 857 - } 858 - } 859 - 860 - func (s *S) TestDecoderErrors(c *C) { 861 - for _, item := range unmarshalErrorTests { 862 - var value interface{} 863 - err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value) 864 - c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value)) 865 - } 866 - } 867 - 868 - var unmarshalerTests = []struct { 869 - data, tag string 870 - value interface{} 871 - }{ 872 - {"_: {hi: there}", "!!map", map[interface{}]interface{}{"hi": "there"}}, 873 - {"_: [1,A]", "!!seq", []interface{}{1, "A"}}, 874 - {"_: 10", "!!int", 10}, 875 - {"_: null", "!!null", nil}, 876 - {`_: BAR!`, "!!str", "BAR!"}, 877 - {`_: "BAR!"`, "!!str", "BAR!"}, 878 - {"_: !!foo 'BAR!'", "!!foo", "BAR!"}, 879 - {`_: ""`, "!!str", ""}, 880 - } 881 - 882 - var unmarshalerResult = map[int]error{} 883 - 884 - type unmarshalerType struct { 885 - value interface{} 886 - } 887 - 888 - func (o *unmarshalerType) UnmarshalYAML(unmarshal func(v interface{}) error) error { 889 - if err := unmarshal(&o.value); err != nil { 890 - return err 891 - } 892 - if i, ok := o.value.(int); ok { 893 - if result, ok := unmarshalerResult[i]; ok { 894 - return result 895 - } 896 - } 897 - return nil 898 - } 899 - 900 - type unmarshalerPointer struct { 901 - Field *unmarshalerType "_" 902 - } 903 - 904 - type unmarshalerValue struct { 905 - Field unmarshalerType "_" 906 - } 907 - 908 - func (s *S) TestUnmarshalerPointerField(c *C) { 909 - for _, item := range unmarshalerTests { 910 - obj := &unmarshalerPointer{} 911 - err := yaml.Unmarshal([]byte(item.data), obj) 912 - c.Assert(err, IsNil) 913 - if item.value == nil { 914 - c.Assert(obj.Field, IsNil) 915 - } else { 916 - c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 917 - c.Assert(obj.Field.value, DeepEquals, item.value) 918 - } 775 + t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 776 + expr, err := callUnmarshal(t, item.data) 777 + val := "" 778 + if expr != nil { 779 + val = cueStr(expr) 780 + } 781 + if err == nil || err.Error() != item.error { 782 + t.Errorf("got %v; want %v; (value %v)", err, item.error, val) 783 + } 784 + }) 919 785 } 920 786 } 921 787 922 - func (s *S) TestUnmarshalerValueField(c *C) { 923 - for _, item := range unmarshalerTests { 924 - obj := &unmarshalerValue{} 925 - err := yaml.Unmarshal([]byte(item.data), obj) 926 - c.Assert(err, IsNil) 927 - c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value)) 928 - c.Assert(obj.Field.value, DeepEquals, item.value) 788 + func TestDecoderErrors(t *testing.T) { 789 + for i, item := range unmarshalErrorTests { 790 + t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) { 791 + _, err := newDecoder(t, item.data).Decode() 792 + if err == nil || err.Error() != item.error { 793 + t.Errorf("got %v; want %v", err, item.error) 794 + } 795 + }) 929 796 } 930 797 } 931 798 932 - func (s *S) TestUnmarshalerWholeDocument(c *C) { 933 - obj := &unmarshalerType{} 934 - err := yaml.Unmarshal([]byte(unmarshalerTests[0].data), obj) 935 - c.Assert(err, IsNil) 936 - value, ok := obj.value.(map[interface{}]interface{}) 937 - c.Assert(ok, Equals, true, Commentf("value: %#v", obj.value)) 938 - c.Assert(value["_"], DeepEquals, unmarshalerTests[0].value) 939 - } 940 - 941 - func (s *S) TestUnmarshalerTypeError(c *C) { 942 - unmarshalerResult[2] = &yaml.TypeError{[]string{"foo"}} 943 - unmarshalerResult[4] = &yaml.TypeError{[]string{"bar"}} 944 - defer func() { 945 - delete(unmarshalerResult, 2) 946 - delete(unmarshalerResult, 4) 947 - }() 948 - 949 - type T struct { 950 - Before int 951 - After int 952 - M map[string]*unmarshalerType 953 - } 954 - var v T 955 - data := `{before: A, m: {abc: 1, def: 2, ghi: 3, jkl: 4}, after: B}` 956 - err := yaml.Unmarshal([]byte(data), &v) 957 - c.Assert(err, ErrorMatches, ""+ 958 - "yaml: unmarshal errors:\n"+ 959 - " line 1: cannot unmarshal !!str `A` into int\n"+ 960 - " foo\n"+ 961 - " bar\n"+ 962 - " line 1: cannot unmarshal !!str `B` into int") 963 - c.Assert(v.M["abc"], NotNil) 964 - c.Assert(v.M["def"], IsNil) 965 - c.Assert(v.M["ghi"], NotNil) 966 - c.Assert(v.M["jkl"], IsNil) 967 - 968 - c.Assert(v.M["abc"].value, Equals, 1) 969 - c.Assert(v.M["ghi"].value, Equals, 3) 970 - } 971 - 972 - type proxyTypeError struct{} 973 - 974 - func (v *proxyTypeError) UnmarshalYAML(unmarshal func(interface{}) error) error { 975 - var s string 976 - var a int32 977 - var b int64 978 - if err := unmarshal(&s); err != nil { 979 - panic(err) 980 - } 981 - if s == "a" { 982 - if err := unmarshal(&b); err == nil { 983 - panic("should have failed") 984 - } 985 - return unmarshal(&a) 799 + func TestFiles(t *testing.T) { 800 + files := []string{"merge"} 801 + for _, test := range files { 802 + t.Run(test, func(t *testing.T) { 803 + testname := fmt.Sprintf("testdata/%s.test", test) 804 + filename := fmt.Sprintf("testdata/%s.out", test) 805 + mergeTests, err := ioutil.ReadFile(testname) 806 + if err != nil { 807 + t.Fatal(err) 808 + } 809 + expr, err := yaml.Unmarshal(fset, "test.yaml", mergeTests) 810 + if err != nil { 811 + t.Fatal(err) 812 + } 813 + got := cueStr(expr) 814 + if *update { 815 + ioutil.WriteFile(filename, []byte(got), 0644) 816 + return 817 + } 818 + b, err := ioutil.ReadFile(filename) 819 + if err != nil { 820 + t.Fatal(err) 821 + } 822 + if want := string(b); got != want { 823 + t.Errorf("\n got: %v;\nwant: %v", got, want) 824 + } 825 + }) 986 826 } 987 - if err := unmarshal(&a); err == nil { 988 - panic("should have failed") 989 - } 990 - return unmarshal(&b) 991 827 } 992 828 993 - func (s *S) TestUnmarshalerTypeErrorProxying(c *C) { 994 - type T struct { 995 - Before int 996 - After int 997 - M map[string]*proxyTypeError 998 - } 999 - var v T 1000 - data := `{before: A, m: {abc: a, def: b}, after: B}` 1001 - err := yaml.Unmarshal([]byte(data), &v) 1002 - c.Assert(err, ErrorMatches, ""+ 1003 - "yaml: unmarshal errors:\n"+ 1004 - " line 1: cannot unmarshal !!str `A` into int\n"+ 1005 - " line 1: cannot unmarshal !!str `a` into int32\n"+ 1006 - " line 1: cannot unmarshal !!str `b` into int64\n"+ 1007 - " line 1: cannot unmarshal !!str `B` into int") 1008 - } 1009 - 1010 - type failingUnmarshaler struct{} 1011 - 1012 - var failingErr = errors.New("failingErr") 1013 - 1014 - func (ft *failingUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 1015 - return failingErr 1016 - } 1017 - 1018 - func (s *S) TestUnmarshalerError(c *C) { 1019 - err := yaml.Unmarshal([]byte("a: b"), &failingUnmarshaler{}) 1020 - c.Assert(err, Equals, failingErr) 1021 - } 1022 - 1023 - type sliceUnmarshaler []int 1024 - 1025 - func (su *sliceUnmarshaler) UnmarshalYAML(unmarshal func(interface{}) error) error { 1026 - var slice []int 1027 - err := unmarshal(&slice) 1028 - if err == nil { 1029 - *su = slice 1030 - return nil 1031 - } 1032 - 1033 - var intVal int 1034 - err = unmarshal(&intVal) 1035 - if err == nil { 1036 - *su = []int{intVal} 1037 - return nil 1038 - } 1039 - 1040 - return err 1041 - } 1042 - 1043 - func (s *S) TestUnmarshalerRetry(c *C) { 1044 - var su sliceUnmarshaler 1045 - err := yaml.Unmarshal([]byte("[1, 2, 3]"), &su) 1046 - c.Assert(err, IsNil) 1047 - c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1, 2, 3})) 1048 - 1049 - err = yaml.Unmarshal([]byte("1"), &su) 1050 - c.Assert(err, IsNil) 1051 - c.Assert(su, DeepEquals, sliceUnmarshaler([]int{1})) 1052 - } 1053 - 1054 - // From http://yaml.org/type/merge.html 1055 - var mergeTests = ` 1056 - anchors: 1057 - list: 1058 - - &CENTER { "x": 1, "y": 2 } 1059 - - &LEFT { "x": 0, "y": 2 } 1060 - - &BIG { "r": 10 } 1061 - - &SMALL { "r": 1 } 1062 - 1063 - # All the following maps are equal: 1064 - 1065 - plain: 1066 - # Explicit keys 1067 - "x": 1 1068 - "y": 2 1069 - "r": 10 1070 - label: center/big 1071 - 1072 - mergeOne: 1073 - # Merge one map 1074 - << : *CENTER 1075 - "r": 10 1076 - label: center/big 1077 - 1078 - mergeMultiple: 1079 - # Merge multiple maps 1080 - << : [ *CENTER, *BIG ] 1081 - label: center/big 1082 - 1083 - override: 1084 - # Override 1085 - << : [ *BIG, *LEFT, *SMALL ] 1086 - "x": 1 1087 - label: center/big 1088 - 1089 - shortTag: 1090 - # Explicit short merge tag 1091 - !!merge "<<" : [ *CENTER, *BIG ] 1092 - label: center/big 1093 - 1094 - longTag: 1095 - # Explicit merge long tag 1096 - !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ] 1097 - label: center/big 1098 - 1099 - inlineMap: 1100 - # Inlined map 1101 - << : {"x": 1, "y": 2, "r": 10} 1102 - label: center/big 1103 - 1104 - inlineSequenceMap: 1105 - # Inlined map in sequence 1106 - << : [ *CENTER, {"r": 10} ] 1107 - label: center/big 1108 - ` 1109 - 1110 - func (s *S) TestMerge(c *C) { 1111 - var want = map[interface{}]interface{}{ 1112 - "x": 1, 1113 - "y": 2, 1114 - "r": 10, 1115 - "label": "center/big", 1116 - } 1117 - 1118 - var m map[interface{}]interface{} 1119 - err := yaml.Unmarshal([]byte(mergeTests), &m) 1120 - c.Assert(err, IsNil) 1121 - for name, test := range m { 1122 - if name == "anchors" { 1123 - continue 1124 - } 1125 - c.Assert(test, DeepEquals, want, Commentf("test %q failed", name)) 1126 - } 1127 - } 1128 - 1129 - func (s *S) TestMergeStruct(c *C) { 1130 - type Data struct { 1131 - X, Y, R int 1132 - Label string 1133 - } 1134 - want := Data{1, 2, 10, "center/big"} 1135 - 1136 - var m map[string]Data 1137 - err := yaml.Unmarshal([]byte(mergeTests), &m) 1138 - c.Assert(err, IsNil) 1139 - for name, test := range m { 1140 - if name == "anchors" { 1141 - continue 1142 - } 1143 - c.Assert(test, Equals, want, Commentf("test %q failed", name)) 1144 - } 1145 - } 1146 - 1147 - var unmarshalNullTests = []func() interface{}{ 1148 - func() interface{} { var v interface{}; v = "v"; return &v }, 1149 - func() interface{} { var s = "s"; return &s }, 1150 - func() interface{} { var s = "s"; sptr := &s; return &sptr }, 1151 - func() interface{} { var i = 1; return &i }, 1152 - func() interface{} { var i = 1; iptr := &i; return &iptr }, 1153 - func() interface{} { m := map[string]int{"s": 1}; return &m }, 1154 - func() interface{} { m := map[string]int{"s": 1}; return m }, 1155 - } 1156 - 1157 - func (s *S) TestUnmarshalNull(c *C) { 1158 - for _, test := range unmarshalNullTests { 1159 - item := test() 1160 - zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface() 1161 - err := yaml.Unmarshal([]byte("null"), item) 1162 - c.Assert(err, IsNil) 1163 - if reflect.TypeOf(item).Kind() == reflect.Map { 1164 - c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface()) 1165 - } else { 1166 - c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero) 1167 - } 1168 - } 1169 - } 1170 - 1171 - func (s *S) TestUnmarshalSliceOnPreset(c *C) { 1172 - // Issue #48. 1173 - v := struct{ A []int }{[]int{1}} 1174 - yaml.Unmarshal([]byte("a: [2]"), &v) 1175 - c.Assert(v.A, DeepEquals, []int{2}) 1176 - } 1177 - 1178 - var unmarshalStrictTests = []struct { 1179 - data string 1180 - value interface{} 1181 - error string 1182 - }{{ 1183 - data: "a: 1\nc: 2\n", 1184 - value: struct{ A, B int }{A: 1}, 1185 - error: `yaml: unmarshal errors:\n line 2: field c not found in type struct { A int; B int }`, 1186 - }, { 1187 - data: "a: 1\nb: 2\na: 3\n", 1188 - value: struct{ A, B int }{A: 3, B: 2}, 1189 - error: `yaml: unmarshal errors:\n line 3: field a already set in type struct { A int; B int }`, 1190 - }, { 1191 - data: "c: 3\na: 1\nb: 2\nc: 4\n", 1192 - value: struct { 1193 - A int 1194 - inlineB `yaml:",inline"` 1195 - }{ 1196 - A: 1, 1197 - inlineB: inlineB{ 1198 - B: 2, 1199 - inlineC: inlineC{ 1200 - C: 4, 1201 - }, 1202 - }, 1203 - }, 1204 - error: `yaml: unmarshal errors:\n line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`, 1205 - }, { 1206 - data: "c: 0\na: 1\nb: 2\nc: 1\n", 1207 - value: struct { 1208 - A int 1209 - inlineB `yaml:",inline"` 1210 - }{ 1211 - A: 1, 1212 - inlineB: inlineB{ 1213 - B: 2, 1214 - inlineC: inlineC{ 1215 - C: 1, 1216 - }, 1217 - }, 1218 - }, 1219 - error: `yaml: unmarshal errors:\n line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`, 1220 - }, { 1221 - data: "c: 1\na: 1\nb: 2\nc: 3\n", 1222 - value: struct { 1223 - A int 1224 - M map[string]interface{} `yaml:",inline"` 1225 - }{ 1226 - A: 1, 1227 - M: map[string]interface{}{ 1228 - "b": 2, 1229 - "c": 3, 1230 - }, 1231 - }, 1232 - error: `yaml: unmarshal errors:\n line 4: key "c" already set in map`, 1233 - }, { 1234 - data: "a: 1\n9: 2\nnull: 3\n9: 4", 1235 - value: map[interface{}]interface{}{ 1236 - "a": 1, 1237 - nil: 3, 1238 - 9: 4, 1239 - }, 1240 - error: `yaml: unmarshal errors:\n line 4: key 9 already set in map`, 1241 - }} 1242 - 1243 - func (s *S) TestUnmarshalStrict(c *C) { 1244 - for i, item := range unmarshalStrictTests { 1245 - c.Logf("test %d: %q", i, item.data) 1246 - // First test that normal Unmarshal unmarshals to the expected value. 1247 - t := reflect.ValueOf(item.value).Type() 1248 - value := reflect.New(t) 1249 - err := yaml.Unmarshal([]byte(item.data), value.Interface()) 1250 - c.Assert(err, Equals, nil) 1251 - c.Assert(value.Elem().Interface(), DeepEquals, item.value) 1252 - 1253 - // Then test that UnmarshalStrict fails on the same thing. 1254 - t = reflect.ValueOf(item.value).Type() 1255 - value = reflect.New(t) 1256 - err = yaml.UnmarshalStrict([]byte(item.data), value.Interface()) 1257 - c.Assert(err, ErrorMatches, item.error) 1258 - } 1259 - } 1260 - 1261 - type textUnmarshaler struct { 1262 - S string 1263 - } 1264 - 1265 - func (t *textUnmarshaler) UnmarshalText(s []byte) error { 1266 - t.S = string(s) 1267 - return nil 1268 - } 1269 - 1270 - func (s *S) TestFuzzCrashers(c *C) { 829 + func TestFuzzCrashers(t *testing.T) { 1271 830 cases := []string{ 1272 831 // runtime error: index out of range 1273 832 "\"\\0\\\r\n", ··· 1291 850 "? \ufeff: \ufeff\n", 1292 851 } 1293 852 for _, data := range cases { 1294 - var v interface{} 1295 - _ = yaml.Unmarshal([]byte(data), &v) 853 + _, _ = callUnmarshal(t, data) 1296 854 } 1297 855 } 1298 856
-1685
internal/third_party/yaml/emitterc.go
··· 1 - package yaml 2 - 3 - import ( 4 - "bytes" 5 - "fmt" 6 - ) 7 - 8 - // Flush the buffer if needed. 9 - func flush(emitter *yaml_emitter_t) bool { 10 - if emitter.buffer_pos+5 >= len(emitter.buffer) { 11 - return yaml_emitter_flush(emitter) 12 - } 13 - return true 14 - } 15 - 16 - // Put a character to the output buffer. 17 - func put(emitter *yaml_emitter_t, value byte) bool { 18 - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 19 - return false 20 - } 21 - emitter.buffer[emitter.buffer_pos] = value 22 - emitter.buffer_pos++ 23 - emitter.column++ 24 - return true 25 - } 26 - 27 - // Put a line break to the output buffer. 28 - func put_break(emitter *yaml_emitter_t) bool { 29 - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 30 - return false 31 - } 32 - switch emitter.line_break { 33 - case yaml_CR_BREAK: 34 - emitter.buffer[emitter.buffer_pos] = '\r' 35 - emitter.buffer_pos += 1 36 - case yaml_LN_BREAK: 37 - emitter.buffer[emitter.buffer_pos] = '\n' 38 - emitter.buffer_pos += 1 39 - case yaml_CRLN_BREAK: 40 - emitter.buffer[emitter.buffer_pos+0] = '\r' 41 - emitter.buffer[emitter.buffer_pos+1] = '\n' 42 - emitter.buffer_pos += 2 43 - default: 44 - panic("unknown line break setting") 45 - } 46 - emitter.column = 0 47 - emitter.line++ 48 - return true 49 - } 50 - 51 - // Copy a character from a string into buffer. 52 - func write(emitter *yaml_emitter_t, s []byte, i *int) bool { 53 - if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { 54 - return false 55 - } 56 - p := emitter.buffer_pos 57 - w := width(s[*i]) 58 - switch w { 59 - case 4: 60 - emitter.buffer[p+3] = s[*i+3] 61 - fallthrough 62 - case 3: 63 - emitter.buffer[p+2] = s[*i+2] 64 - fallthrough 65 - case 2: 66 - emitter.buffer[p+1] = s[*i+1] 67 - fallthrough 68 - case 1: 69 - emitter.buffer[p+0] = s[*i+0] 70 - default: 71 - panic("unknown character width") 72 - } 73 - emitter.column++ 74 - emitter.buffer_pos += w 75 - *i += w 76 - return true 77 - } 78 - 79 - // Write a whole string into buffer. 80 - func write_all(emitter *yaml_emitter_t, s []byte) bool { 81 - for i := 0; i < len(s); { 82 - if !write(emitter, s, &i) { 83 - return false 84 - } 85 - } 86 - return true 87 - } 88 - 89 - // Copy a line break character from a string into buffer. 90 - func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { 91 - if s[*i] == '\n' { 92 - if !put_break(emitter) { 93 - return false 94 - } 95 - *i++ 96 - } else { 97 - if !write(emitter, s, i) { 98 - return false 99 - } 100 - emitter.column = 0 101 - emitter.line++ 102 - } 103 - return true 104 - } 105 - 106 - // Set an emitter error and return false. 107 - func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { 108 - emitter.error = yaml_EMITTER_ERROR 109 - emitter.problem = problem 110 - return false 111 - } 112 - 113 - // Emit an event. 114 - func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { 115 - emitter.events = append(emitter.events, *event) 116 - for !yaml_emitter_need_more_events(emitter) { 117 - event := &emitter.events[emitter.events_head] 118 - if !yaml_emitter_analyze_event(emitter, event) { 119 - return false 120 - } 121 - if !yaml_emitter_state_machine(emitter, event) { 122 - return false 123 - } 124 - yaml_event_delete(event) 125 - emitter.events_head++ 126 - } 127 - return true 128 - } 129 - 130 - // Check if we need to accumulate more events before emitting. 131 - // 132 - // We accumulate extra 133 - // - 1 event for DOCUMENT-START 134 - // - 2 events for SEQUENCE-START 135 - // - 3 events for MAPPING-START 136 - // 137 - func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { 138 - if emitter.events_head == len(emitter.events) { 139 - return true 140 - } 141 - var accumulate int 142 - switch emitter.events[emitter.events_head].typ { 143 - case yaml_DOCUMENT_START_EVENT: 144 - accumulate = 1 145 - break 146 - case yaml_SEQUENCE_START_EVENT: 147 - accumulate = 2 148 - break 149 - case yaml_MAPPING_START_EVENT: 150 - accumulate = 3 151 - break 152 - default: 153 - return false 154 - } 155 - if len(emitter.events)-emitter.events_head > accumulate { 156 - return false 157 - } 158 - var level int 159 - for i := emitter.events_head; i < len(emitter.events); i++ { 160 - switch emitter.events[i].typ { 161 - case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: 162 - level++ 163 - case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: 164 - level-- 165 - } 166 - if level == 0 { 167 - return false 168 - } 169 - } 170 - return true 171 - } 172 - 173 - // Append a directive to the directives stack. 174 - func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { 175 - for i := 0; i < len(emitter.tag_directives); i++ { 176 - if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { 177 - if allow_duplicates { 178 - return true 179 - } 180 - return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") 181 - } 182 - } 183 - 184 - // [Go] Do we actually need to copy this given garbage collection 185 - // and the lack of deallocating destructors? 186 - tag_copy := yaml_tag_directive_t{ 187 - handle: make([]byte, len(value.handle)), 188 - prefix: make([]byte, len(value.prefix)), 189 - } 190 - copy(tag_copy.handle, value.handle) 191 - copy(tag_copy.prefix, value.prefix) 192 - emitter.tag_directives = append(emitter.tag_directives, tag_copy) 193 - return true 194 - } 195 - 196 - // Increase the indentation level. 197 - func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { 198 - emitter.indents = append(emitter.indents, emitter.indent) 199 - if emitter.indent < 0 { 200 - if flow { 201 - emitter.indent = emitter.best_indent 202 - } else { 203 - emitter.indent = 0 204 - } 205 - } else if !indentless { 206 - emitter.indent += emitter.best_indent 207 - } 208 - return true 209 - } 210 - 211 - // State dispatcher. 212 - func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { 213 - switch emitter.state { 214 - default: 215 - case yaml_EMIT_STREAM_START_STATE: 216 - return yaml_emitter_emit_stream_start(emitter, event) 217 - 218 - case yaml_EMIT_FIRST_DOCUMENT_START_STATE: 219 - return yaml_emitter_emit_document_start(emitter, event, true) 220 - 221 - case yaml_EMIT_DOCUMENT_START_STATE: 222 - return yaml_emitter_emit_document_start(emitter, event, false) 223 - 224 - case yaml_EMIT_DOCUMENT_CONTENT_STATE: 225 - return yaml_emitter_emit_document_content(emitter, event) 226 - 227 - case yaml_EMIT_DOCUMENT_END_STATE: 228 - return yaml_emitter_emit_document_end(emitter, event) 229 - 230 - case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: 231 - return yaml_emitter_emit_flow_sequence_item(emitter, event, true) 232 - 233 - case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: 234 - return yaml_emitter_emit_flow_sequence_item(emitter, event, false) 235 - 236 - case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: 237 - return yaml_emitter_emit_flow_mapping_key(emitter, event, true) 238 - 239 - case yaml_EMIT_FLOW_MAPPING_KEY_STATE: 240 - return yaml_emitter_emit_flow_mapping_key(emitter, event, false) 241 - 242 - case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: 243 - return yaml_emitter_emit_flow_mapping_value(emitter, event, true) 244 - 245 - case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: 246 - return yaml_emitter_emit_flow_mapping_value(emitter, event, false) 247 - 248 - case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: 249 - return yaml_emitter_emit_block_sequence_item(emitter, event, true) 250 - 251 - case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: 252 - return yaml_emitter_emit_block_sequence_item(emitter, event, false) 253 - 254 - case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: 255 - return yaml_emitter_emit_block_mapping_key(emitter, event, true) 256 - 257 - case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: 258 - return yaml_emitter_emit_block_mapping_key(emitter, event, false) 259 - 260 - case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: 261 - return yaml_emitter_emit_block_mapping_value(emitter, event, true) 262 - 263 - case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: 264 - return yaml_emitter_emit_block_mapping_value(emitter, event, false) 265 - 266 - case yaml_EMIT_END_STATE: 267 - return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") 268 - } 269 - panic("invalid emitter state") 270 - } 271 - 272 - // Expect STREAM-START. 273 - func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 274 - if event.typ != yaml_STREAM_START_EVENT { 275 - return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") 276 - } 277 - if emitter.encoding == yaml_ANY_ENCODING { 278 - emitter.encoding = event.encoding 279 - if emitter.encoding == yaml_ANY_ENCODING { 280 - emitter.encoding = yaml_UTF8_ENCODING 281 - } 282 - } 283 - if emitter.best_indent < 2 || emitter.best_indent > 9 { 284 - emitter.best_indent = 2 285 - } 286 - if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { 287 - emitter.best_width = 80 288 - } 289 - if emitter.best_width < 0 { 290 - emitter.best_width = 1<<31 - 1 291 - } 292 - if emitter.line_break == yaml_ANY_BREAK { 293 - emitter.line_break = yaml_LN_BREAK 294 - } 295 - 296 - emitter.indent = -1 297 - emitter.line = 0 298 - emitter.column = 0 299 - emitter.whitespace = true 300 - emitter.indention = true 301 - 302 - if emitter.encoding != yaml_UTF8_ENCODING { 303 - if !yaml_emitter_write_bom(emitter) { 304 - return false 305 - } 306 - } 307 - emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE 308 - return true 309 - } 310 - 311 - // Expect DOCUMENT-START or STREAM-END. 312 - func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 313 - 314 - if event.typ == yaml_DOCUMENT_START_EVENT { 315 - 316 - if event.version_directive != nil { 317 - if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { 318 - return false 319 - } 320 - } 321 - 322 - for i := 0; i < len(event.tag_directives); i++ { 323 - tag_directive := &event.tag_directives[i] 324 - if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { 325 - return false 326 - } 327 - if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { 328 - return false 329 - } 330 - } 331 - 332 - for i := 0; i < len(default_tag_directives); i++ { 333 - tag_directive := &default_tag_directives[i] 334 - if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { 335 - return false 336 - } 337 - } 338 - 339 - implicit := event.implicit 340 - if !first || emitter.canonical { 341 - implicit = false 342 - } 343 - 344 - if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { 345 - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 346 - return false 347 - } 348 - if !yaml_emitter_write_indent(emitter) { 349 - return false 350 - } 351 - } 352 - 353 - if event.version_directive != nil { 354 - implicit = false 355 - if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { 356 - return false 357 - } 358 - if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { 359 - return false 360 - } 361 - if !yaml_emitter_write_indent(emitter) { 362 - return false 363 - } 364 - } 365 - 366 - if len(event.tag_directives) > 0 { 367 - implicit = false 368 - for i := 0; i < len(event.tag_directives); i++ { 369 - tag_directive := &event.tag_directives[i] 370 - if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { 371 - return false 372 - } 373 - if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { 374 - return false 375 - } 376 - if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { 377 - return false 378 - } 379 - if !yaml_emitter_write_indent(emitter) { 380 - return false 381 - } 382 - } 383 - } 384 - 385 - if yaml_emitter_check_empty_document(emitter) { 386 - implicit = false 387 - } 388 - if !implicit { 389 - if !yaml_emitter_write_indent(emitter) { 390 - return false 391 - } 392 - if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { 393 - return false 394 - } 395 - if emitter.canonical { 396 - if !yaml_emitter_write_indent(emitter) { 397 - return false 398 - } 399 - } 400 - } 401 - 402 - emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE 403 - return true 404 - } 405 - 406 - if event.typ == yaml_STREAM_END_EVENT { 407 - if emitter.open_ended { 408 - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 409 - return false 410 - } 411 - if !yaml_emitter_write_indent(emitter) { 412 - return false 413 - } 414 - } 415 - if !yaml_emitter_flush(emitter) { 416 - return false 417 - } 418 - emitter.state = yaml_EMIT_END_STATE 419 - return true 420 - } 421 - 422 - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") 423 - } 424 - 425 - // Expect the root node. 426 - func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { 427 - emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) 428 - return yaml_emitter_emit_node(emitter, event, true, false, false, false) 429 - } 430 - 431 - // Expect DOCUMENT-END. 432 - func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { 433 - if event.typ != yaml_DOCUMENT_END_EVENT { 434 - return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") 435 - } 436 - if !yaml_emitter_write_indent(emitter) { 437 - return false 438 - } 439 - if !event.implicit { 440 - // [Go] Allocate the slice elsewhere. 441 - if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { 442 - return false 443 - } 444 - if !yaml_emitter_write_indent(emitter) { 445 - return false 446 - } 447 - } 448 - if !yaml_emitter_flush(emitter) { 449 - return false 450 - } 451 - emitter.state = yaml_EMIT_DOCUMENT_START_STATE 452 - emitter.tag_directives = emitter.tag_directives[:0] 453 - return true 454 - } 455 - 456 - // Expect a flow item node. 457 - func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 458 - if first { 459 - if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { 460 - return false 461 - } 462 - if !yaml_emitter_increase_indent(emitter, true, false) { 463 - return false 464 - } 465 - emitter.flow_level++ 466 - } 467 - 468 - if event.typ == yaml_SEQUENCE_END_EVENT { 469 - emitter.flow_level-- 470 - emitter.indent = emitter.indents[len(emitter.indents)-1] 471 - emitter.indents = emitter.indents[:len(emitter.indents)-1] 472 - if emitter.canonical && !first { 473 - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 474 - return false 475 - } 476 - if !yaml_emitter_write_indent(emitter) { 477 - return false 478 - } 479 - } 480 - if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { 481 - return false 482 - } 483 - emitter.state = emitter.states[len(emitter.states)-1] 484 - emitter.states = emitter.states[:len(emitter.states)-1] 485 - 486 - return true 487 - } 488 - 489 - if !first { 490 - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 491 - return false 492 - } 493 - } 494 - 495 - if emitter.canonical || emitter.column > emitter.best_width { 496 - if !yaml_emitter_write_indent(emitter) { 497 - return false 498 - } 499 - } 500 - emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) 501 - return yaml_emitter_emit_node(emitter, event, false, true, false, false) 502 - } 503 - 504 - // Expect a flow key node. 505 - func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 506 - if first { 507 - if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { 508 - return false 509 - } 510 - if !yaml_emitter_increase_indent(emitter, true, false) { 511 - return false 512 - } 513 - emitter.flow_level++ 514 - } 515 - 516 - if event.typ == yaml_MAPPING_END_EVENT { 517 - emitter.flow_level-- 518 - emitter.indent = emitter.indents[len(emitter.indents)-1] 519 - emitter.indents = emitter.indents[:len(emitter.indents)-1] 520 - if emitter.canonical && !first { 521 - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 522 - return false 523 - } 524 - if !yaml_emitter_write_indent(emitter) { 525 - return false 526 - } 527 - } 528 - if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { 529 - return false 530 - } 531 - emitter.state = emitter.states[len(emitter.states)-1] 532 - emitter.states = emitter.states[:len(emitter.states)-1] 533 - return true 534 - } 535 - 536 - if !first { 537 - if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { 538 - return false 539 - } 540 - } 541 - if emitter.canonical || emitter.column > emitter.best_width { 542 - if !yaml_emitter_write_indent(emitter) { 543 - return false 544 - } 545 - } 546 - 547 - if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { 548 - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) 549 - return yaml_emitter_emit_node(emitter, event, false, false, true, true) 550 - } 551 - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { 552 - return false 553 - } 554 - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) 555 - return yaml_emitter_emit_node(emitter, event, false, false, true, false) 556 - } 557 - 558 - // Expect a flow value node. 559 - func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { 560 - if simple { 561 - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { 562 - return false 563 - } 564 - } else { 565 - if emitter.canonical || emitter.column > emitter.best_width { 566 - if !yaml_emitter_write_indent(emitter) { 567 - return false 568 - } 569 - } 570 - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { 571 - return false 572 - } 573 - } 574 - emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) 575 - return yaml_emitter_emit_node(emitter, event, false, false, true, false) 576 - } 577 - 578 - // Expect a block item node. 579 - func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 580 - if first { 581 - if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) { 582 - return false 583 - } 584 - } 585 - if event.typ == yaml_SEQUENCE_END_EVENT { 586 - emitter.indent = emitter.indents[len(emitter.indents)-1] 587 - emitter.indents = emitter.indents[:len(emitter.indents)-1] 588 - emitter.state = emitter.states[len(emitter.states)-1] 589 - emitter.states = emitter.states[:len(emitter.states)-1] 590 - return true 591 - } 592 - if !yaml_emitter_write_indent(emitter) { 593 - return false 594 - } 595 - if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { 596 - return false 597 - } 598 - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) 599 - return yaml_emitter_emit_node(emitter, event, false, true, false, false) 600 - } 601 - 602 - // Expect a block key node. 603 - func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { 604 - if first { 605 - if !yaml_emitter_increase_indent(emitter, false, false) { 606 - return false 607 - } 608 - } 609 - if event.typ == yaml_MAPPING_END_EVENT { 610 - emitter.indent = emitter.indents[len(emitter.indents)-1] 611 - emitter.indents = emitter.indents[:len(emitter.indents)-1] 612 - emitter.state = emitter.states[len(emitter.states)-1] 613 - emitter.states = emitter.states[:len(emitter.states)-1] 614 - return true 615 - } 616 - if !yaml_emitter_write_indent(emitter) { 617 - return false 618 - } 619 - if yaml_emitter_check_simple_key(emitter) { 620 - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) 621 - return yaml_emitter_emit_node(emitter, event, false, false, true, true) 622 - } 623 - if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { 624 - return false 625 - } 626 - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) 627 - return yaml_emitter_emit_node(emitter, event, false, false, true, false) 628 - } 629 - 630 - // Expect a block value node. 631 - func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { 632 - if simple { 633 - if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { 634 - return false 635 - } 636 - } else { 637 - if !yaml_emitter_write_indent(emitter) { 638 - return false 639 - } 640 - if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { 641 - return false 642 - } 643 - } 644 - emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) 645 - return yaml_emitter_emit_node(emitter, event, false, false, true, false) 646 - } 647 - 648 - // Expect a node. 649 - func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, 650 - root bool, sequence bool, mapping bool, simple_key bool) bool { 651 - 652 - emitter.root_context = root 653 - emitter.sequence_context = sequence 654 - emitter.mapping_context = mapping 655 - emitter.simple_key_context = simple_key 656 - 657 - switch event.typ { 658 - case yaml_ALIAS_EVENT: 659 - return yaml_emitter_emit_alias(emitter, event) 660 - case yaml_SCALAR_EVENT: 661 - return yaml_emitter_emit_scalar(emitter, event) 662 - case yaml_SEQUENCE_START_EVENT: 663 - return yaml_emitter_emit_sequence_start(emitter, event) 664 - case yaml_MAPPING_START_EVENT: 665 - return yaml_emitter_emit_mapping_start(emitter, event) 666 - default: 667 - return yaml_emitter_set_emitter_error(emitter, 668 - fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ)) 669 - } 670 - } 671 - 672 - // Expect ALIAS. 673 - func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { 674 - if !yaml_emitter_process_anchor(emitter) { 675 - return false 676 - } 677 - emitter.state = emitter.states[len(emitter.states)-1] 678 - emitter.states = emitter.states[:len(emitter.states)-1] 679 - return true 680 - } 681 - 682 - // Expect SCALAR. 683 - func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { 684 - if !yaml_emitter_select_scalar_style(emitter, event) { 685 - return false 686 - } 687 - if !yaml_emitter_process_anchor(emitter) { 688 - return false 689 - } 690 - if !yaml_emitter_process_tag(emitter) { 691 - return false 692 - } 693 - if !yaml_emitter_increase_indent(emitter, true, false) { 694 - return false 695 - } 696 - if !yaml_emitter_process_scalar(emitter) { 697 - return false 698 - } 699 - emitter.indent = emitter.indents[len(emitter.indents)-1] 700 - emitter.indents = emitter.indents[:len(emitter.indents)-1] 701 - emitter.state = emitter.states[len(emitter.states)-1] 702 - emitter.states = emitter.states[:len(emitter.states)-1] 703 - return true 704 - } 705 - 706 - // Expect SEQUENCE-START. 707 - func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 708 - if !yaml_emitter_process_anchor(emitter) { 709 - return false 710 - } 711 - if !yaml_emitter_process_tag(emitter) { 712 - return false 713 - } 714 - if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || 715 - yaml_emitter_check_empty_sequence(emitter) { 716 - emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE 717 - } else { 718 - emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE 719 - } 720 - return true 721 - } 722 - 723 - // Expect MAPPING-START. 724 - func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { 725 - if !yaml_emitter_process_anchor(emitter) { 726 - return false 727 - } 728 - if !yaml_emitter_process_tag(emitter) { 729 - return false 730 - } 731 - if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || 732 - yaml_emitter_check_empty_mapping(emitter) { 733 - emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE 734 - } else { 735 - emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE 736 - } 737 - return true 738 - } 739 - 740 - // Check if the document content is an empty scalar. 741 - func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { 742 - return false // [Go] Huh? 743 - } 744 - 745 - // Check if the next events represent an empty sequence. 746 - func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { 747 - if len(emitter.events)-emitter.events_head < 2 { 748 - return false 749 - } 750 - return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && 751 - emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT 752 - } 753 - 754 - // Check if the next events represent an empty mapping. 755 - func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { 756 - if len(emitter.events)-emitter.events_head < 2 { 757 - return false 758 - } 759 - return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && 760 - emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT 761 - } 762 - 763 - // Check if the next node can be expressed as a simple key. 764 - func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { 765 - length := 0 766 - switch emitter.events[emitter.events_head].typ { 767 - case yaml_ALIAS_EVENT: 768 - length += len(emitter.anchor_data.anchor) 769 - case yaml_SCALAR_EVENT: 770 - if emitter.scalar_data.multiline { 771 - return false 772 - } 773 - length += len(emitter.anchor_data.anchor) + 774 - len(emitter.tag_data.handle) + 775 - len(emitter.tag_data.suffix) + 776 - len(emitter.scalar_data.value) 777 - case yaml_SEQUENCE_START_EVENT: 778 - if !yaml_emitter_check_empty_sequence(emitter) { 779 - return false 780 - } 781 - length += len(emitter.anchor_data.anchor) + 782 - len(emitter.tag_data.handle) + 783 - len(emitter.tag_data.suffix) 784 - case yaml_MAPPING_START_EVENT: 785 - if !yaml_emitter_check_empty_mapping(emitter) { 786 - return false 787 - } 788 - length += len(emitter.anchor_data.anchor) + 789 - len(emitter.tag_data.handle) + 790 - len(emitter.tag_data.suffix) 791 - default: 792 - return false 793 - } 794 - return length <= 128 795 - } 796 - 797 - // Determine an acceptable scalar style. 798 - func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { 799 - 800 - no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 801 - if no_tag && !event.implicit && !event.quoted_implicit { 802 - return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") 803 - } 804 - 805 - style := event.scalar_style() 806 - if style == yaml_ANY_SCALAR_STYLE { 807 - style = yaml_PLAIN_SCALAR_STYLE 808 - } 809 - if emitter.canonical { 810 - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 811 - } 812 - if emitter.simple_key_context && emitter.scalar_data.multiline { 813 - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 814 - } 815 - 816 - if style == yaml_PLAIN_SCALAR_STYLE { 817 - if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || 818 - emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { 819 - style = yaml_SINGLE_QUOTED_SCALAR_STYLE 820 - } 821 - if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { 822 - style = yaml_SINGLE_QUOTED_SCALAR_STYLE 823 - } 824 - if no_tag && !event.implicit { 825 - style = yaml_SINGLE_QUOTED_SCALAR_STYLE 826 - } 827 - } 828 - if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { 829 - if !emitter.scalar_data.single_quoted_allowed { 830 - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 831 - } 832 - } 833 - if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { 834 - if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { 835 - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 836 - } 837 - } 838 - 839 - if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { 840 - emitter.tag_data.handle = []byte{'!'} 841 - } 842 - emitter.scalar_data.style = style 843 - return true 844 - } 845 - 846 - // Write an anchor. 847 - func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { 848 - if emitter.anchor_data.anchor == nil { 849 - return true 850 - } 851 - c := []byte{'&'} 852 - if emitter.anchor_data.alias { 853 - c[0] = '*' 854 - } 855 - if !yaml_emitter_write_indicator(emitter, c, true, false, false) { 856 - return false 857 - } 858 - return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) 859 - } 860 - 861 - // Write a tag. 862 - func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { 863 - if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { 864 - return true 865 - } 866 - if len(emitter.tag_data.handle) > 0 { 867 - if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { 868 - return false 869 - } 870 - if len(emitter.tag_data.suffix) > 0 { 871 - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { 872 - return false 873 - } 874 - } 875 - } else { 876 - // [Go] Allocate these slices elsewhere. 877 - if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { 878 - return false 879 - } 880 - if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { 881 - return false 882 - } 883 - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { 884 - return false 885 - } 886 - } 887 - return true 888 - } 889 - 890 - // Write a scalar. 891 - func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { 892 - switch emitter.scalar_data.style { 893 - case yaml_PLAIN_SCALAR_STYLE: 894 - return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 895 - 896 - case yaml_SINGLE_QUOTED_SCALAR_STYLE: 897 - return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 898 - 899 - case yaml_DOUBLE_QUOTED_SCALAR_STYLE: 900 - return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) 901 - 902 - case yaml_LITERAL_SCALAR_STYLE: 903 - return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) 904 - 905 - case yaml_FOLDED_SCALAR_STYLE: 906 - return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) 907 - } 908 - panic("unknown scalar style") 909 - } 910 - 911 - // Check if a %YAML directive is valid. 912 - func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { 913 - if version_directive.major != 1 || version_directive.minor != 1 { 914 - return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") 915 - } 916 - return true 917 - } 918 - 919 - // Check if a %TAG directive is valid. 920 - func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { 921 - handle := tag_directive.handle 922 - prefix := tag_directive.prefix 923 - if len(handle) == 0 { 924 - return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") 925 - } 926 - if handle[0] != '!' { 927 - return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") 928 - } 929 - if handle[len(handle)-1] != '!' { 930 - return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") 931 - } 932 - for i := 1; i < len(handle)-1; i += width(handle[i]) { 933 - if !is_alpha(handle, i) { 934 - return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") 935 - } 936 - } 937 - if len(prefix) == 0 { 938 - return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") 939 - } 940 - return true 941 - } 942 - 943 - // Check if an anchor is valid. 944 - func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { 945 - if len(anchor) == 0 { 946 - problem := "anchor value must not be empty" 947 - if alias { 948 - problem = "alias value must not be empty" 949 - } 950 - return yaml_emitter_set_emitter_error(emitter, problem) 951 - } 952 - for i := 0; i < len(anchor); i += width(anchor[i]) { 953 - if !is_alpha(anchor, i) { 954 - problem := "anchor value must contain alphanumerical characters only" 955 - if alias { 956 - problem = "alias value must contain alphanumerical characters only" 957 - } 958 - return yaml_emitter_set_emitter_error(emitter, problem) 959 - } 960 - } 961 - emitter.anchor_data.anchor = anchor 962 - emitter.anchor_data.alias = alias 963 - return true 964 - } 965 - 966 - // Check if a tag is valid. 967 - func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { 968 - if len(tag) == 0 { 969 - return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") 970 - } 971 - for i := 0; i < len(emitter.tag_directives); i++ { 972 - tag_directive := &emitter.tag_directives[i] 973 - if bytes.HasPrefix(tag, tag_directive.prefix) { 974 - emitter.tag_data.handle = tag_directive.handle 975 - emitter.tag_data.suffix = tag[len(tag_directive.prefix):] 976 - return true 977 - } 978 - } 979 - emitter.tag_data.suffix = tag 980 - return true 981 - } 982 - 983 - // Check if a scalar is valid. 984 - func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { 985 - var ( 986 - block_indicators = false 987 - flow_indicators = false 988 - line_breaks = false 989 - special_characters = false 990 - 991 - leading_space = false 992 - leading_break = false 993 - trailing_space = false 994 - trailing_break = false 995 - break_space = false 996 - space_break = false 997 - 998 - preceded_by_whitespace = false 999 - followed_by_whitespace = false 1000 - previous_space = false 1001 - previous_break = false 1002 - ) 1003 - 1004 - emitter.scalar_data.value = value 1005 - 1006 - if len(value) == 0 { 1007 - emitter.scalar_data.multiline = false 1008 - emitter.scalar_data.flow_plain_allowed = false 1009 - emitter.scalar_data.block_plain_allowed = true 1010 - emitter.scalar_data.single_quoted_allowed = true 1011 - emitter.scalar_data.block_allowed = false 1012 - return true 1013 - } 1014 - 1015 - if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { 1016 - block_indicators = true 1017 - flow_indicators = true 1018 - } 1019 - 1020 - preceded_by_whitespace = true 1021 - for i, w := 0, 0; i < len(value); i += w { 1022 - w = width(value[i]) 1023 - followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) 1024 - 1025 - if i == 0 { 1026 - switch value[i] { 1027 - case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': 1028 - flow_indicators = true 1029 - block_indicators = true 1030 - case '?', ':': 1031 - flow_indicators = true 1032 - if followed_by_whitespace { 1033 - block_indicators = true 1034 - } 1035 - case '-': 1036 - if followed_by_whitespace { 1037 - flow_indicators = true 1038 - block_indicators = true 1039 - } 1040 - } 1041 - } else { 1042 - switch value[i] { 1043 - case ',', '?', '[', ']', '{', '}': 1044 - flow_indicators = true 1045 - case ':': 1046 - flow_indicators = true 1047 - if followed_by_whitespace { 1048 - block_indicators = true 1049 - } 1050 - case '#': 1051 - if preceded_by_whitespace { 1052 - flow_indicators = true 1053 - block_indicators = true 1054 - } 1055 - } 1056 - } 1057 - 1058 - if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { 1059 - special_characters = true 1060 - } 1061 - if is_space(value, i) { 1062 - if i == 0 { 1063 - leading_space = true 1064 - } 1065 - if i+width(value[i]) == len(value) { 1066 - trailing_space = true 1067 - } 1068 - if previous_break { 1069 - break_space = true 1070 - } 1071 - previous_space = true 1072 - previous_break = false 1073 - } else if is_break(value, i) { 1074 - line_breaks = true 1075 - if i == 0 { 1076 - leading_break = true 1077 - } 1078 - if i+width(value[i]) == len(value) { 1079 - trailing_break = true 1080 - } 1081 - if previous_space { 1082 - space_break = true 1083 - } 1084 - previous_space = false 1085 - previous_break = true 1086 - } else { 1087 - previous_space = false 1088 - previous_break = false 1089 - } 1090 - 1091 - // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. 1092 - preceded_by_whitespace = is_blankz(value, i) 1093 - } 1094 - 1095 - emitter.scalar_data.multiline = line_breaks 1096 - emitter.scalar_data.flow_plain_allowed = true 1097 - emitter.scalar_data.block_plain_allowed = true 1098 - emitter.scalar_data.single_quoted_allowed = true 1099 - emitter.scalar_data.block_allowed = true 1100 - 1101 - if leading_space || leading_break || trailing_space || trailing_break { 1102 - emitter.scalar_data.flow_plain_allowed = false 1103 - emitter.scalar_data.block_plain_allowed = false 1104 - } 1105 - if trailing_space { 1106 - emitter.scalar_data.block_allowed = false 1107 - } 1108 - if break_space { 1109 - emitter.scalar_data.flow_plain_allowed = false 1110 - emitter.scalar_data.block_plain_allowed = false 1111 - emitter.scalar_data.single_quoted_allowed = false 1112 - } 1113 - if space_break || special_characters { 1114 - emitter.scalar_data.flow_plain_allowed = false 1115 - emitter.scalar_data.block_plain_allowed = false 1116 - emitter.scalar_data.single_quoted_allowed = false 1117 - emitter.scalar_data.block_allowed = false 1118 - } 1119 - if line_breaks { 1120 - emitter.scalar_data.flow_plain_allowed = false 1121 - emitter.scalar_data.block_plain_allowed = false 1122 - } 1123 - if flow_indicators { 1124 - emitter.scalar_data.flow_plain_allowed = false 1125 - } 1126 - if block_indicators { 1127 - emitter.scalar_data.block_plain_allowed = false 1128 - } 1129 - return true 1130 - } 1131 - 1132 - // Check if the event data is valid. 1133 - func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { 1134 - 1135 - emitter.anchor_data.anchor = nil 1136 - emitter.tag_data.handle = nil 1137 - emitter.tag_data.suffix = nil 1138 - emitter.scalar_data.value = nil 1139 - 1140 - switch event.typ { 1141 - case yaml_ALIAS_EVENT: 1142 - if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { 1143 - return false 1144 - } 1145 - 1146 - case yaml_SCALAR_EVENT: 1147 - if len(event.anchor) > 0 { 1148 - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1149 - return false 1150 - } 1151 - } 1152 - if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { 1153 - if !yaml_emitter_analyze_tag(emitter, event.tag) { 1154 - return false 1155 - } 1156 - } 1157 - if !yaml_emitter_analyze_scalar(emitter, event.value) { 1158 - return false 1159 - } 1160 - 1161 - case yaml_SEQUENCE_START_EVENT: 1162 - if len(event.anchor) > 0 { 1163 - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1164 - return false 1165 - } 1166 - } 1167 - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { 1168 - if !yaml_emitter_analyze_tag(emitter, event.tag) { 1169 - return false 1170 - } 1171 - } 1172 - 1173 - case yaml_MAPPING_START_EVENT: 1174 - if len(event.anchor) > 0 { 1175 - if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { 1176 - return false 1177 - } 1178 - } 1179 - if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { 1180 - if !yaml_emitter_analyze_tag(emitter, event.tag) { 1181 - return false 1182 - } 1183 - } 1184 - } 1185 - return true 1186 - } 1187 - 1188 - // Write the BOM character. 1189 - func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { 1190 - if !flush(emitter) { 1191 - return false 1192 - } 1193 - pos := emitter.buffer_pos 1194 - emitter.buffer[pos+0] = '\xEF' 1195 - emitter.buffer[pos+1] = '\xBB' 1196 - emitter.buffer[pos+2] = '\xBF' 1197 - emitter.buffer_pos += 3 1198 - return true 1199 - } 1200 - 1201 - func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { 1202 - indent := emitter.indent 1203 - if indent < 0 { 1204 - indent = 0 1205 - } 1206 - if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { 1207 - if !put_break(emitter) { 1208 - return false 1209 - } 1210 - } 1211 - for emitter.column < indent { 1212 - if !put(emitter, ' ') { 1213 - return false 1214 - } 1215 - } 1216 - emitter.whitespace = true 1217 - emitter.indention = true 1218 - return true 1219 - } 1220 - 1221 - func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { 1222 - if need_whitespace && !emitter.whitespace { 1223 - if !put(emitter, ' ') { 1224 - return false 1225 - } 1226 - } 1227 - if !write_all(emitter, indicator) { 1228 - return false 1229 - } 1230 - emitter.whitespace = is_whitespace 1231 - emitter.indention = (emitter.indention && is_indention) 1232 - emitter.open_ended = false 1233 - return true 1234 - } 1235 - 1236 - func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { 1237 - if !write_all(emitter, value) { 1238 - return false 1239 - } 1240 - emitter.whitespace = false 1241 - emitter.indention = false 1242 - return true 1243 - } 1244 - 1245 - func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { 1246 - if !emitter.whitespace { 1247 - if !put(emitter, ' ') { 1248 - return false 1249 - } 1250 - } 1251 - if !write_all(emitter, value) { 1252 - return false 1253 - } 1254 - emitter.whitespace = false 1255 - emitter.indention = false 1256 - return true 1257 - } 1258 - 1259 - func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { 1260 - if need_whitespace && !emitter.whitespace { 1261 - if !put(emitter, ' ') { 1262 - return false 1263 - } 1264 - } 1265 - for i := 0; i < len(value); { 1266 - var must_write bool 1267 - switch value[i] { 1268 - case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': 1269 - must_write = true 1270 - default: 1271 - must_write = is_alpha(value, i) 1272 - } 1273 - if must_write { 1274 - if !write(emitter, value, &i) { 1275 - return false 1276 - } 1277 - } else { 1278 - w := width(value[i]) 1279 - for k := 0; k < w; k++ { 1280 - octet := value[i] 1281 - i++ 1282 - if !put(emitter, '%') { 1283 - return false 1284 - } 1285 - 1286 - c := octet >> 4 1287 - if c < 10 { 1288 - c += '0' 1289 - } else { 1290 - c += 'A' - 10 1291 - } 1292 - if !put(emitter, c) { 1293 - return false 1294 - } 1295 - 1296 - c = octet & 0x0f 1297 - if c < 10 { 1298 - c += '0' 1299 - } else { 1300 - c += 'A' - 10 1301 - } 1302 - if !put(emitter, c) { 1303 - return false 1304 - } 1305 - } 1306 - } 1307 - } 1308 - emitter.whitespace = false 1309 - emitter.indention = false 1310 - return true 1311 - } 1312 - 1313 - func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1314 - if !emitter.whitespace { 1315 - if !put(emitter, ' ') { 1316 - return false 1317 - } 1318 - } 1319 - 1320 - spaces := false 1321 - breaks := false 1322 - for i := 0; i < len(value); { 1323 - if is_space(value, i) { 1324 - if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { 1325 - if !yaml_emitter_write_indent(emitter) { 1326 - return false 1327 - } 1328 - i += width(value[i]) 1329 - } else { 1330 - if !write(emitter, value, &i) { 1331 - return false 1332 - } 1333 - } 1334 - spaces = true 1335 - } else if is_break(value, i) { 1336 - if !breaks && value[i] == '\n' { 1337 - if !put_break(emitter) { 1338 - return false 1339 - } 1340 - } 1341 - if !write_break(emitter, value, &i) { 1342 - return false 1343 - } 1344 - emitter.indention = true 1345 - breaks = true 1346 - } else { 1347 - if breaks { 1348 - if !yaml_emitter_write_indent(emitter) { 1349 - return false 1350 - } 1351 - } 1352 - if !write(emitter, value, &i) { 1353 - return false 1354 - } 1355 - emitter.indention = false 1356 - spaces = false 1357 - breaks = false 1358 - } 1359 - } 1360 - 1361 - emitter.whitespace = false 1362 - emitter.indention = false 1363 - if emitter.root_context { 1364 - emitter.open_ended = true 1365 - } 1366 - 1367 - return true 1368 - } 1369 - 1370 - func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1371 - 1372 - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { 1373 - return false 1374 - } 1375 - 1376 - spaces := false 1377 - breaks := false 1378 - for i := 0; i < len(value); { 1379 - if is_space(value, i) { 1380 - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { 1381 - if !yaml_emitter_write_indent(emitter) { 1382 - return false 1383 - } 1384 - i += width(value[i]) 1385 - } else { 1386 - if !write(emitter, value, &i) { 1387 - return false 1388 - } 1389 - } 1390 - spaces = true 1391 - } else if is_break(value, i) { 1392 - if !breaks && value[i] == '\n' { 1393 - if !put_break(emitter) { 1394 - return false 1395 - } 1396 - } 1397 - if !write_break(emitter, value, &i) { 1398 - return false 1399 - } 1400 - emitter.indention = true 1401 - breaks = true 1402 - } else { 1403 - if breaks { 1404 - if !yaml_emitter_write_indent(emitter) { 1405 - return false 1406 - } 1407 - } 1408 - if value[i] == '\'' { 1409 - if !put(emitter, '\'') { 1410 - return false 1411 - } 1412 - } 1413 - if !write(emitter, value, &i) { 1414 - return false 1415 - } 1416 - emitter.indention = false 1417 - spaces = false 1418 - breaks = false 1419 - } 1420 - } 1421 - if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { 1422 - return false 1423 - } 1424 - emitter.whitespace = false 1425 - emitter.indention = false 1426 - return true 1427 - } 1428 - 1429 - func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { 1430 - spaces := false 1431 - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { 1432 - return false 1433 - } 1434 - 1435 - for i := 0; i < len(value); { 1436 - if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || 1437 - is_bom(value, i) || is_break(value, i) || 1438 - value[i] == '"' || value[i] == '\\' { 1439 - 1440 - octet := value[i] 1441 - 1442 - var w int 1443 - var v rune 1444 - switch { 1445 - case octet&0x80 == 0x00: 1446 - w, v = 1, rune(octet&0x7F) 1447 - case octet&0xE0 == 0xC0: 1448 - w, v = 2, rune(octet&0x1F) 1449 - case octet&0xF0 == 0xE0: 1450 - w, v = 3, rune(octet&0x0F) 1451 - case octet&0xF8 == 0xF0: 1452 - w, v = 4, rune(octet&0x07) 1453 - } 1454 - for k := 1; k < w; k++ { 1455 - octet = value[i+k] 1456 - v = (v << 6) + (rune(octet) & 0x3F) 1457 - } 1458 - i += w 1459 - 1460 - if !put(emitter, '\\') { 1461 - return false 1462 - } 1463 - 1464 - var ok bool 1465 - switch v { 1466 - case 0x00: 1467 - ok = put(emitter, '0') 1468 - case 0x07: 1469 - ok = put(emitter, 'a') 1470 - case 0x08: 1471 - ok = put(emitter, 'b') 1472 - case 0x09: 1473 - ok = put(emitter, 't') 1474 - case 0x0A: 1475 - ok = put(emitter, 'n') 1476 - case 0x0b: 1477 - ok = put(emitter, 'v') 1478 - case 0x0c: 1479 - ok = put(emitter, 'f') 1480 - case 0x0d: 1481 - ok = put(emitter, 'r') 1482 - case 0x1b: 1483 - ok = put(emitter, 'e') 1484 - case 0x22: 1485 - ok = put(emitter, '"') 1486 - case 0x5c: 1487 - ok = put(emitter, '\\') 1488 - case 0x85: 1489 - ok = put(emitter, 'N') 1490 - case 0xA0: 1491 - ok = put(emitter, '_') 1492 - case 0x2028: 1493 - ok = put(emitter, 'L') 1494 - case 0x2029: 1495 - ok = put(emitter, 'P') 1496 - default: 1497 - if v <= 0xFF { 1498 - ok = put(emitter, 'x') 1499 - w = 2 1500 - } else if v <= 0xFFFF { 1501 - ok = put(emitter, 'u') 1502 - w = 4 1503 - } else { 1504 - ok = put(emitter, 'U') 1505 - w = 8 1506 - } 1507 - for k := (w - 1) * 4; ok && k >= 0; k -= 4 { 1508 - digit := byte((v >> uint(k)) & 0x0F) 1509 - if digit < 10 { 1510 - ok = put(emitter, digit+'0') 1511 - } else { 1512 - ok = put(emitter, digit+'A'-10) 1513 - } 1514 - } 1515 - } 1516 - if !ok { 1517 - return false 1518 - } 1519 - spaces = false 1520 - } else if is_space(value, i) { 1521 - if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { 1522 - if !yaml_emitter_write_indent(emitter) { 1523 - return false 1524 - } 1525 - if is_space(value, i+1) { 1526 - if !put(emitter, '\\') { 1527 - return false 1528 - } 1529 - } 1530 - i += width(value[i]) 1531 - } else if !write(emitter, value, &i) { 1532 - return false 1533 - } 1534 - spaces = true 1535 - } else { 1536 - if !write(emitter, value, &i) { 1537 - return false 1538 - } 1539 - spaces = false 1540 - } 1541 - } 1542 - if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { 1543 - return false 1544 - } 1545 - emitter.whitespace = false 1546 - emitter.indention = false 1547 - return true 1548 - } 1549 - 1550 - func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { 1551 - if is_space(value, 0) || is_break(value, 0) { 1552 - indent_hint := []byte{'0' + byte(emitter.best_indent)} 1553 - if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { 1554 - return false 1555 - } 1556 - } 1557 - 1558 - emitter.open_ended = false 1559 - 1560 - var chomp_hint [1]byte 1561 - if len(value) == 0 { 1562 - chomp_hint[0] = '-' 1563 - } else { 1564 - i := len(value) - 1 1565 - for value[i]&0xC0 == 0x80 { 1566 - i-- 1567 - } 1568 - if !is_break(value, i) { 1569 - chomp_hint[0] = '-' 1570 - } else if i == 0 { 1571 - chomp_hint[0] = '+' 1572 - emitter.open_ended = true 1573 - } else { 1574 - i-- 1575 - for value[i]&0xC0 == 0x80 { 1576 - i-- 1577 - } 1578 - if is_break(value, i) { 1579 - chomp_hint[0] = '+' 1580 - emitter.open_ended = true 1581 - } 1582 - } 1583 - } 1584 - if chomp_hint[0] != 0 { 1585 - if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { 1586 - return false 1587 - } 1588 - } 1589 - return true 1590 - } 1591 - 1592 - func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { 1593 - if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { 1594 - return false 1595 - } 1596 - if !yaml_emitter_write_block_scalar_hints(emitter, value) { 1597 - return false 1598 - } 1599 - if !put_break(emitter) { 1600 - return false 1601 - } 1602 - emitter.indention = true 1603 - emitter.whitespace = true 1604 - breaks := true 1605 - for i := 0; i < len(value); { 1606 - if is_break(value, i) { 1607 - if !write_break(emitter, value, &i) { 1608 - return false 1609 - } 1610 - emitter.indention = true 1611 - breaks = true 1612 - } else { 1613 - if breaks { 1614 - if !yaml_emitter_write_indent(emitter) { 1615 - return false 1616 - } 1617 - } 1618 - if !write(emitter, value, &i) { 1619 - return false 1620 - } 1621 - emitter.indention = false 1622 - breaks = false 1623 - } 1624 - } 1625 - 1626 - return true 1627 - } 1628 - 1629 - func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { 1630 - if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { 1631 - return false 1632 - } 1633 - if !yaml_emitter_write_block_scalar_hints(emitter, value) { 1634 - return false 1635 - } 1636 - 1637 - if !put_break(emitter) { 1638 - return false 1639 - } 1640 - emitter.indention = true 1641 - emitter.whitespace = true 1642 - 1643 - breaks := true 1644 - leading_spaces := true 1645 - for i := 0; i < len(value); { 1646 - if is_break(value, i) { 1647 - if !breaks && !leading_spaces && value[i] == '\n' { 1648 - k := 0 1649 - for is_break(value, k) { 1650 - k += width(value[k]) 1651 - } 1652 - if !is_blankz(value, k) { 1653 - if !put_break(emitter) { 1654 - return false 1655 - } 1656 - } 1657 - } 1658 - if !write_break(emitter, value, &i) { 1659 - return false 1660 - } 1661 - emitter.indention = true 1662 - breaks = true 1663 - } else { 1664 - if breaks { 1665 - if !yaml_emitter_write_indent(emitter) { 1666 - return false 1667 - } 1668 - leading_spaces = is_blank(value, i) 1669 - } 1670 - if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { 1671 - if !yaml_emitter_write_indent(emitter) { 1672 - return false 1673 - } 1674 - i += width(value[i]) 1675 - } else { 1676 - if !write(emitter, value, &i) { 1677 - return false 1678 - } 1679 - } 1680 - emitter.indention = false 1681 - breaks = false 1682 - } 1683 - } 1684 - return true 1685 - }
-362
internal/third_party/yaml/encode.go
··· 1 - package yaml 2 - 3 - import ( 4 - "encoding" 5 - "fmt" 6 - "io" 7 - "reflect" 8 - "regexp" 9 - "sort" 10 - "strconv" 11 - "strings" 12 - "time" 13 - "unicode/utf8" 14 - ) 15 - 16 - type encoder struct { 17 - emitter yaml_emitter_t 18 - event yaml_event_t 19 - out []byte 20 - flow bool 21 - // doneInit holds whether the initial stream_start_event has been 22 - // emitted. 23 - doneInit bool 24 - } 25 - 26 - func newEncoder() *encoder { 27 - e := &encoder{} 28 - yaml_emitter_initialize(&e.emitter) 29 - yaml_emitter_set_output_string(&e.emitter, &e.out) 30 - yaml_emitter_set_unicode(&e.emitter, true) 31 - return e 32 - } 33 - 34 - func newEncoderWithWriter(w io.Writer) *encoder { 35 - e := &encoder{} 36 - yaml_emitter_initialize(&e.emitter) 37 - yaml_emitter_set_output_writer(&e.emitter, w) 38 - yaml_emitter_set_unicode(&e.emitter, true) 39 - return e 40 - } 41 - 42 - func (e *encoder) init() { 43 - if e.doneInit { 44 - return 45 - } 46 - yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING) 47 - e.emit() 48 - e.doneInit = true 49 - } 50 - 51 - func (e *encoder) finish() { 52 - e.emitter.open_ended = false 53 - yaml_stream_end_event_initialize(&e.event) 54 - e.emit() 55 - } 56 - 57 - func (e *encoder) destroy() { 58 - yaml_emitter_delete(&e.emitter) 59 - } 60 - 61 - func (e *encoder) emit() { 62 - // This will internally delete the e.event value. 63 - e.must(yaml_emitter_emit(&e.emitter, &e.event)) 64 - } 65 - 66 - func (e *encoder) must(ok bool) { 67 - if !ok { 68 - msg := e.emitter.problem 69 - if msg == "" { 70 - msg = "unknown problem generating YAML content" 71 - } 72 - failf("%s", msg) 73 - } 74 - } 75 - 76 - func (e *encoder) marshalDoc(tag string, in reflect.Value) { 77 - e.init() 78 - yaml_document_start_event_initialize(&e.event, nil, nil, true) 79 - e.emit() 80 - e.marshal(tag, in) 81 - yaml_document_end_event_initialize(&e.event, true) 82 - e.emit() 83 - } 84 - 85 - func (e *encoder) marshal(tag string, in reflect.Value) { 86 - if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() { 87 - e.nilv() 88 - return 89 - } 90 - iface := in.Interface() 91 - switch m := iface.(type) { 92 - case time.Time, *time.Time: 93 - // Although time.Time implements TextMarshaler, 94 - // we don't want to treat it as a string for YAML 95 - // purposes because YAML has special support for 96 - // timestamps. 97 - case Marshaler: 98 - v, err := m.MarshalYAML() 99 - if err != nil { 100 - fail(err) 101 - } 102 - if v == nil { 103 - e.nilv() 104 - return 105 - } 106 - in = reflect.ValueOf(v) 107 - case encoding.TextMarshaler: 108 - text, err := m.MarshalText() 109 - if err != nil { 110 - fail(err) 111 - } 112 - in = reflect.ValueOf(string(text)) 113 - case nil: 114 - e.nilv() 115 - return 116 - } 117 - switch in.Kind() { 118 - case reflect.Interface: 119 - e.marshal(tag, in.Elem()) 120 - case reflect.Map: 121 - e.mapv(tag, in) 122 - case reflect.Ptr: 123 - if in.Type() == ptrTimeType { 124 - e.timev(tag, in.Elem()) 125 - } else { 126 - e.marshal(tag, in.Elem()) 127 - } 128 - case reflect.Struct: 129 - if in.Type() == timeType { 130 - e.timev(tag, in) 131 - } else { 132 - e.structv(tag, in) 133 - } 134 - case reflect.Slice, reflect.Array: 135 - if in.Type().Elem() == mapItemType { 136 - e.itemsv(tag, in) 137 - } else { 138 - e.slicev(tag, in) 139 - } 140 - case reflect.String: 141 - e.stringv(tag, in) 142 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 143 - if in.Type() == durationType { 144 - e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String())) 145 - } else { 146 - e.intv(tag, in) 147 - } 148 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 149 - e.uintv(tag, in) 150 - case reflect.Float32, reflect.Float64: 151 - e.floatv(tag, in) 152 - case reflect.Bool: 153 - e.boolv(tag, in) 154 - default: 155 - panic("cannot marshal type: " + in.Type().String()) 156 - } 157 - } 158 - 159 - func (e *encoder) mapv(tag string, in reflect.Value) { 160 - e.mappingv(tag, func() { 161 - keys := keyList(in.MapKeys()) 162 - sort.Sort(keys) 163 - for _, k := range keys { 164 - e.marshal("", k) 165 - e.marshal("", in.MapIndex(k)) 166 - } 167 - }) 168 - } 169 - 170 - func (e *encoder) itemsv(tag string, in reflect.Value) { 171 - e.mappingv(tag, func() { 172 - slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem) 173 - for _, item := range slice { 174 - e.marshal("", reflect.ValueOf(item.Key)) 175 - e.marshal("", reflect.ValueOf(item.Value)) 176 - } 177 - }) 178 - } 179 - 180 - func (e *encoder) structv(tag string, in reflect.Value) { 181 - sinfo, err := getStructInfo(in.Type()) 182 - if err != nil { 183 - panic(err) 184 - } 185 - e.mappingv(tag, func() { 186 - for _, info := range sinfo.FieldsList { 187 - var value reflect.Value 188 - if info.Inline == nil { 189 - value = in.Field(info.Num) 190 - } else { 191 - value = in.FieldByIndex(info.Inline) 192 - } 193 - if info.OmitEmpty && isZero(value) { 194 - continue 195 - } 196 - e.marshal("", reflect.ValueOf(info.Key)) 197 - e.flow = info.Flow 198 - e.marshal("", value) 199 - } 200 - if sinfo.InlineMap >= 0 { 201 - m := in.Field(sinfo.InlineMap) 202 - if m.Len() > 0 { 203 - e.flow = false 204 - keys := keyList(m.MapKeys()) 205 - sort.Sort(keys) 206 - for _, k := range keys { 207 - if _, found := sinfo.FieldsMap[k.String()]; found { 208 - panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String())) 209 - } 210 - e.marshal("", k) 211 - e.flow = false 212 - e.marshal("", m.MapIndex(k)) 213 - } 214 - } 215 - } 216 - }) 217 - } 218 - 219 - func (e *encoder) mappingv(tag string, f func()) { 220 - implicit := tag == "" 221 - style := yaml_BLOCK_MAPPING_STYLE 222 - if e.flow { 223 - e.flow = false 224 - style = yaml_FLOW_MAPPING_STYLE 225 - } 226 - yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style) 227 - e.emit() 228 - f() 229 - yaml_mapping_end_event_initialize(&e.event) 230 - e.emit() 231 - } 232 - 233 - func (e *encoder) slicev(tag string, in reflect.Value) { 234 - implicit := tag == "" 235 - style := yaml_BLOCK_SEQUENCE_STYLE 236 - if e.flow { 237 - e.flow = false 238 - style = yaml_FLOW_SEQUENCE_STYLE 239 - } 240 - e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) 241 - e.emit() 242 - n := in.Len() 243 - for i := 0; i < n; i++ { 244 - e.marshal("", in.Index(i)) 245 - } 246 - e.must(yaml_sequence_end_event_initialize(&e.event)) 247 - e.emit() 248 - } 249 - 250 - // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. 251 - // 252 - // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported 253 - // in YAML 1.2 and by this package, but these should be marshalled quoted for 254 - // the time being for compatibility with other parsers. 255 - func isBase60Float(s string) (result bool) { 256 - // Fast path. 257 - if s == "" { 258 - return false 259 - } 260 - c := s[0] 261 - if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { 262 - return false 263 - } 264 - // Do the full match. 265 - return base60float.MatchString(s) 266 - } 267 - 268 - // From http://yaml.org/type/float.html, except the regular expression there 269 - // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. 270 - var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) 271 - 272 - func (e *encoder) stringv(tag string, in reflect.Value) { 273 - var style yaml_scalar_style_t 274 - s := in.String() 275 - canUsePlain := true 276 - switch { 277 - case !utf8.ValidString(s): 278 - if tag == yaml_BINARY_TAG { 279 - failf("explicitly tagged !!binary data must be base64-encoded") 280 - } 281 - if tag != "" { 282 - failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) 283 - } 284 - // It can't be encoded directly as YAML so use a binary tag 285 - // and encode it as base64. 286 - tag = yaml_BINARY_TAG 287 - s = encodeBase64(s) 288 - case tag == "": 289 - // Check to see if it would resolve to a specific 290 - // tag when encoded unquoted. If it doesn't, 291 - // there's no need to quote it. 292 - rtag, _ := resolve("", s) 293 - canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s) 294 - } 295 - // Note: it's possible for user code to emit invalid YAML 296 - // if they explicitly specify a tag and a string containing 297 - // text that's incompatible with that tag. 298 - switch { 299 - case strings.Contains(s, "\n"): 300 - style = yaml_LITERAL_SCALAR_STYLE 301 - case canUsePlain: 302 - style = yaml_PLAIN_SCALAR_STYLE 303 - default: 304 - style = yaml_DOUBLE_QUOTED_SCALAR_STYLE 305 - } 306 - e.emitScalar(s, "", tag, style) 307 - } 308 - 309 - func (e *encoder) boolv(tag string, in reflect.Value) { 310 - var s string 311 - if in.Bool() { 312 - s = "true" 313 - } else { 314 - s = "false" 315 - } 316 - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) 317 - } 318 - 319 - func (e *encoder) intv(tag string, in reflect.Value) { 320 - s := strconv.FormatInt(in.Int(), 10) 321 - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) 322 - } 323 - 324 - func (e *encoder) uintv(tag string, in reflect.Value) { 325 - s := strconv.FormatUint(in.Uint(), 10) 326 - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) 327 - } 328 - 329 - func (e *encoder) timev(tag string, in reflect.Value) { 330 - t := in.Interface().(time.Time) 331 - s := t.Format(time.RFC3339Nano) 332 - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) 333 - } 334 - 335 - func (e *encoder) floatv(tag string, in reflect.Value) { 336 - // Issue #352: When formatting, use the precision of the underlying value 337 - precision := 64 338 - if in.Kind() == reflect.Float32 { 339 - precision = 32 340 - } 341 - 342 - s := strconv.FormatFloat(in.Float(), 'g', -1, precision) 343 - switch s { 344 - case "+Inf": 345 - s = ".inf" 346 - case "-Inf": 347 - s = "-.inf" 348 - case "NaN": 349 - s = ".nan" 350 - } 351 - e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) 352 - } 353 - 354 - func (e *encoder) nilv() { 355 - e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE) 356 - } 357 - 358 - func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) { 359 - implicit := tag == "" 360 - e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) 361 - e.emit() 362 - }
-595
internal/third_party/yaml/encode_test.go
··· 1 - package yaml_test 2 - 3 - import ( 4 - "bytes" 5 - "fmt" 6 - "math" 7 - "strconv" 8 - "strings" 9 - "time" 10 - 11 - "net" 12 - "os" 13 - 14 - . "gopkg.in/check.v1" 15 - "gopkg.in/yaml.v2" 16 - ) 17 - 18 - var marshalIntTest = 123 19 - 20 - var marshalTests = []struct { 21 - value interface{} 22 - data string 23 - }{ 24 - { 25 - nil, 26 - "null\n", 27 - }, { 28 - (*marshalerType)(nil), 29 - "null\n", 30 - }, { 31 - &struct{}{}, 32 - "{}\n", 33 - }, { 34 - map[string]string{"v": "hi"}, 35 - "v: hi\n", 36 - }, { 37 - map[string]interface{}{"v": "hi"}, 38 - "v: hi\n", 39 - }, { 40 - map[string]string{"v": "true"}, 41 - "v: \"true\"\n", 42 - }, { 43 - map[string]string{"v": "false"}, 44 - "v: \"false\"\n", 45 - }, { 46 - map[string]interface{}{"v": true}, 47 - "v: true\n", 48 - }, { 49 - map[string]interface{}{"v": false}, 50 - "v: false\n", 51 - }, { 52 - map[string]interface{}{"v": 10}, 53 - "v: 10\n", 54 - }, { 55 - map[string]interface{}{"v": -10}, 56 - "v: -10\n", 57 - }, { 58 - map[string]uint{"v": 42}, 59 - "v: 42\n", 60 - }, { 61 - map[string]interface{}{"v": int64(4294967296)}, 62 - "v: 4294967296\n", 63 - }, { 64 - map[string]int64{"v": int64(4294967296)}, 65 - "v: 4294967296\n", 66 - }, { 67 - map[string]uint64{"v": 4294967296}, 68 - "v: 4294967296\n", 69 - }, { 70 - map[string]interface{}{"v": "10"}, 71 - "v: \"10\"\n", 72 - }, { 73 - map[string]interface{}{"v": 0.1}, 74 - "v: 0.1\n", 75 - }, { 76 - map[string]interface{}{"v": float64(0.1)}, 77 - "v: 0.1\n", 78 - }, { 79 - map[string]interface{}{"v": float32(0.99)}, 80 - "v: 0.99\n", 81 - }, { 82 - map[string]interface{}{"v": -0.1}, 83 - "v: -0.1\n", 84 - }, { 85 - map[string]interface{}{"v": math.Inf(+1)}, 86 - "v: .inf\n", 87 - }, { 88 - map[string]interface{}{"v": math.Inf(-1)}, 89 - "v: -.inf\n", 90 - }, { 91 - map[string]interface{}{"v": math.NaN()}, 92 - "v: .nan\n", 93 - }, { 94 - map[string]interface{}{"v": nil}, 95 - "v: null\n", 96 - }, { 97 - map[string]interface{}{"v": ""}, 98 - "v: \"\"\n", 99 - }, { 100 - map[string][]string{"v": []string{"A", "B"}}, 101 - "v:\n- A\n- B\n", 102 - }, { 103 - map[string][]string{"v": []string{"A", "B\nC"}}, 104 - "v:\n- A\n- |-\n B\n C\n", 105 - }, { 106 - map[string][]interface{}{"v": []interface{}{"A", 1, map[string][]int{"B": []int{2, 3}}}}, 107 - "v:\n- A\n- 1\n- B:\n - 2\n - 3\n", 108 - }, { 109 - map[string]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, 110 - "a:\n b: c\n", 111 - }, { 112 - map[string]interface{}{"a": "-"}, 113 - "a: '-'\n", 114 - }, 115 - 116 - // Simple values. 117 - { 118 - &marshalIntTest, 119 - "123\n", 120 - }, 121 - 122 - // Structures 123 - { 124 - &struct{ Hello string }{"world"}, 125 - "hello: world\n", 126 - }, { 127 - &struct { 128 - A struct { 129 - B string 130 - } 131 - }{struct{ B string }{"c"}}, 132 - "a:\n b: c\n", 133 - }, { 134 - &struct { 135 - A *struct { 136 - B string 137 - } 138 - }{&struct{ B string }{"c"}}, 139 - "a:\n b: c\n", 140 - }, { 141 - &struct { 142 - A *struct { 143 - B string 144 - } 145 - }{}, 146 - "a: null\n", 147 - }, { 148 - &struct{ A int }{1}, 149 - "a: 1\n", 150 - }, { 151 - &struct{ A []int }{[]int{1, 2}}, 152 - "a:\n- 1\n- 2\n", 153 - }, { 154 - &struct{ A [2]int }{[2]int{1, 2}}, 155 - "a:\n- 1\n- 2\n", 156 - }, { 157 - &struct { 158 - B int "a" 159 - }{1}, 160 - "a: 1\n", 161 - }, { 162 - &struct{ A bool }{true}, 163 - "a: true\n", 164 - }, 165 - 166 - // Conditional flag 167 - { 168 - &struct { 169 - A int "a,omitempty" 170 - B int "b,omitempty" 171 - }{1, 0}, 172 - "a: 1\n", 173 - }, { 174 - &struct { 175 - A int "a,omitempty" 176 - B int "b,omitempty" 177 - }{0, 0}, 178 - "{}\n", 179 - }, { 180 - &struct { 181 - A *struct{ X, y int } "a,omitempty,flow" 182 - }{&struct{ X, y int }{1, 2}}, 183 - "a: {x: 1}\n", 184 - }, { 185 - &struct { 186 - A *struct{ X, y int } "a,omitempty,flow" 187 - }{nil}, 188 - "{}\n", 189 - }, { 190 - &struct { 191 - A *struct{ X, y int } "a,omitempty,flow" 192 - }{&struct{ X, y int }{}}, 193 - "a: {x: 0}\n", 194 - }, { 195 - &struct { 196 - A struct{ X, y int } "a,omitempty,flow" 197 - }{struct{ X, y int }{1, 2}}, 198 - "a: {x: 1}\n", 199 - }, { 200 - &struct { 201 - A struct{ X, y int } "a,omitempty,flow" 202 - }{struct{ X, y int }{0, 1}}, 203 - "{}\n", 204 - }, { 205 - &struct { 206 - A float64 "a,omitempty" 207 - B float64 "b,omitempty" 208 - }{1, 0}, 209 - "a: 1\n", 210 - }, 211 - { 212 - &struct { 213 - T1 time.Time "t1,omitempty" 214 - T2 time.Time "t2,omitempty" 215 - T3 *time.Time "t3,omitempty" 216 - T4 *time.Time "t4,omitempty" 217 - }{ 218 - T2: time.Date(2018, 1, 9, 10, 40, 47, 0, time.UTC), 219 - T4: newTime(time.Date(2098, 1, 9, 10, 40, 47, 0, time.UTC)), 220 - }, 221 - "t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n", 222 - }, 223 - // Nil interface that implements Marshaler. 224 - { 225 - map[string]yaml.Marshaler{ 226 - "a": nil, 227 - }, 228 - "a: null\n", 229 - }, 230 - 231 - // Flow flag 232 - { 233 - &struct { 234 - A []int "a,flow" 235 - }{[]int{1, 2}}, 236 - "a: [1, 2]\n", 237 - }, { 238 - &struct { 239 - A map[string]string "a,flow" 240 - }{map[string]string{"b": "c", "d": "e"}}, 241 - "a: {b: c, d: e}\n", 242 - }, { 243 - &struct { 244 - A struct { 245 - B, D string 246 - } "a,flow" 247 - }{struct{ B, D string }{"c", "e"}}, 248 - "a: {b: c, d: e}\n", 249 - }, 250 - 251 - // Unexported field 252 - { 253 - &struct { 254 - u int 255 - A int 256 - }{0, 1}, 257 - "a: 1\n", 258 - }, 259 - 260 - // Ignored field 261 - { 262 - &struct { 263 - A int 264 - B int "-" 265 - }{1, 2}, 266 - "a: 1\n", 267 - }, 268 - 269 - // Struct inlining 270 - { 271 - &struct { 272 - A int 273 - C inlineB `yaml:",inline"` 274 - }{1, inlineB{2, inlineC{3}}}, 275 - "a: 1\nb: 2\nc: 3\n", 276 - }, 277 - 278 - // Map inlining 279 - { 280 - &struct { 281 - A int 282 - C map[string]int `yaml:",inline"` 283 - }{1, map[string]int{"b": 2, "c": 3}}, 284 - "a: 1\nb: 2\nc: 3\n", 285 - }, 286 - 287 - // Duration 288 - { 289 - map[string]time.Duration{"a": 3 * time.Second}, 290 - "a: 3s\n", 291 - }, 292 - 293 - // Issue #24: bug in map merging logic. 294 - { 295 - map[string]string{"a": "<foo>"}, 296 - "a: <foo>\n", 297 - }, 298 - 299 - // Issue #34: marshal unsupported base 60 floats quoted for compatibility 300 - // with old YAML 1.1 parsers. 301 - { 302 - map[string]string{"a": "1:1"}, 303 - "a: \"1:1\"\n", 304 - }, 305 - 306 - // Binary data. 307 - { 308 - map[string]string{"a": "\x00"}, 309 - "a: \"\\0\"\n", 310 - }, { 311 - map[string]string{"a": "\x80\x81\x82"}, 312 - "a: !!binary gIGC\n", 313 - }, { 314 - map[string]string{"a": strings.Repeat("\x90", 54)}, 315 - "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", 316 - }, 317 - 318 - // Ordered maps. 319 - { 320 - &yaml.MapSlice{{"b", 2}, {"a", 1}, {"d", 4}, {"c", 3}, {"sub", yaml.MapSlice{{"e", 5}}}}, 321 - "b: 2\na: 1\nd: 4\nc: 3\nsub:\n e: 5\n", 322 - }, 323 - 324 - // Encode unicode as utf-8 rather than in escaped form. 325 - { 326 - map[string]string{"a": "你好"}, 327 - "a: 你好\n", 328 - }, 329 - 330 - // Support encoding.TextMarshaler. 331 - { 332 - map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)}, 333 - "a: 1.2.3.4\n", 334 - }, 335 - // time.Time gets a timestamp tag. 336 - { 337 - map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, 338 - "a: 2015-02-24T18:19:39Z\n", 339 - }, 340 - { 341 - map[string]*time.Time{"a": newTime(time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC))}, 342 - "a: 2015-02-24T18:19:39Z\n", 343 - }, 344 - { 345 - // This is confirmed to be properly decoded in Python (libyaml) without a timestamp tag. 346 - map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 123456789, time.FixedZone("FOO", -3*60*60))}, 347 - "a: 2015-02-24T18:19:39.123456789-03:00\n", 348 - }, 349 - // Ensure timestamp-like strings are quoted. 350 - { 351 - map[string]string{"a": "2015-02-24T18:19:39Z"}, 352 - "a: \"2015-02-24T18:19:39Z\"\n", 353 - }, 354 - 355 - // Ensure strings containing ": " are quoted (reported as PR #43, but not reproducible). 356 - { 357 - map[string]string{"a": "b: c"}, 358 - "a: 'b: c'\n", 359 - }, 360 - 361 - // Containing hash mark ('#') in string should be quoted 362 - { 363 - map[string]string{"a": "Hello #comment"}, 364 - "a: 'Hello #comment'\n", 365 - }, 366 - { 367 - map[string]string{"a": "你好 #comment"}, 368 - "a: '你好 #comment'\n", 369 - }, 370 - } 371 - 372 - func (s *S) TestMarshal(c *C) { 373 - defer os.Setenv("TZ", os.Getenv("TZ")) 374 - os.Setenv("TZ", "UTC") 375 - for i, item := range marshalTests { 376 - c.Logf("test %d: %q", i, item.data) 377 - data, err := yaml.Marshal(item.value) 378 - c.Assert(err, IsNil) 379 - c.Assert(string(data), Equals, item.data) 380 - } 381 - } 382 - 383 - func (s *S) TestEncoderSingleDocument(c *C) { 384 - for i, item := range marshalTests { 385 - c.Logf("test %d. %q", i, item.data) 386 - var buf bytes.Buffer 387 - enc := yaml.NewEncoder(&buf) 388 - err := enc.Encode(item.value) 389 - c.Assert(err, Equals, nil) 390 - err = enc.Close() 391 - c.Assert(err, Equals, nil) 392 - c.Assert(buf.String(), Equals, item.data) 393 - } 394 - } 395 - 396 - func (s *S) TestEncoderMultipleDocuments(c *C) { 397 - var buf bytes.Buffer 398 - enc := yaml.NewEncoder(&buf) 399 - err := enc.Encode(map[string]string{"a": "b"}) 400 - c.Assert(err, Equals, nil) 401 - err = enc.Encode(map[string]string{"c": "d"}) 402 - c.Assert(err, Equals, nil) 403 - err = enc.Close() 404 - c.Assert(err, Equals, nil) 405 - c.Assert(buf.String(), Equals, "a: b\n---\nc: d\n") 406 - } 407 - 408 - func (s *S) TestEncoderWriteError(c *C) { 409 - enc := yaml.NewEncoder(errorWriter{}) 410 - err := enc.Encode(map[string]string{"a": "b"}) 411 - c.Assert(err, ErrorMatches, `yaml: write error: some write error`) // Data not flushed yet 412 - } 413 - 414 - type errorWriter struct{} 415 - 416 - func (errorWriter) Write([]byte) (int, error) { 417 - return 0, fmt.Errorf("some write error") 418 - } 419 - 420 - var marshalErrorTests = []struct { 421 - value interface{} 422 - error string 423 - panic string 424 - }{{ 425 - value: &struct { 426 - B int 427 - inlineB ",inline" 428 - }{1, inlineB{2, inlineC{3}}}, 429 - panic: `Duplicated key 'b' in struct struct \{ B int; .*`, 430 - }, { 431 - value: &struct { 432 - A int 433 - B map[string]int ",inline" 434 - }{1, map[string]int{"a": 2}}, 435 - panic: `Can't have key "a" in inlined map; conflicts with struct field`, 436 - }} 437 - 438 - func (s *S) TestMarshalErrors(c *C) { 439 - for _, item := range marshalErrorTests { 440 - if item.panic != "" { 441 - c.Assert(func() { yaml.Marshal(item.value) }, PanicMatches, item.panic) 442 - } else { 443 - _, err := yaml.Marshal(item.value) 444 - c.Assert(err, ErrorMatches, item.error) 445 - } 446 - } 447 - } 448 - 449 - func (s *S) TestMarshalTypeCache(c *C) { 450 - var data []byte 451 - var err error 452 - func() { 453 - type T struct{ A int } 454 - data, err = yaml.Marshal(&T{}) 455 - c.Assert(err, IsNil) 456 - }() 457 - func() { 458 - type T struct{ B int } 459 - data, err = yaml.Marshal(&T{}) 460 - c.Assert(err, IsNil) 461 - }() 462 - c.Assert(string(data), Equals, "b: 0\n") 463 - } 464 - 465 - var marshalerTests = []struct { 466 - data string 467 - value interface{} 468 - }{ 469 - {"_:\n hi: there\n", map[interface{}]interface{}{"hi": "there"}}, 470 - {"_:\n- 1\n- A\n", []interface{}{1, "A"}}, 471 - {"_: 10\n", 10}, 472 - {"_: null\n", nil}, 473 - {"_: BAR!\n", "BAR!"}, 474 - } 475 - 476 - type marshalerType struct { 477 - value interface{} 478 - } 479 - 480 - func (o marshalerType) MarshalText() ([]byte, error) { 481 - panic("MarshalText called on type with MarshalYAML") 482 - } 483 - 484 - func (o marshalerType) MarshalYAML() (interface{}, error) { 485 - return o.value, nil 486 - } 487 - 488 - type marshalerValue struct { 489 - Field marshalerType "_" 490 - } 491 - 492 - func (s *S) TestMarshaler(c *C) { 493 - for _, item := range marshalerTests { 494 - obj := &marshalerValue{} 495 - obj.Field.value = item.value 496 - data, err := yaml.Marshal(obj) 497 - c.Assert(err, IsNil) 498 - c.Assert(string(data), Equals, string(item.data)) 499 - } 500 - } 501 - 502 - func (s *S) TestMarshalerWholeDocument(c *C) { 503 - obj := &marshalerType{} 504 - obj.value = map[string]string{"hello": "world!"} 505 - data, err := yaml.Marshal(obj) 506 - c.Assert(err, IsNil) 507 - c.Assert(string(data), Equals, "hello: world!\n") 508 - } 509 - 510 - type failingMarshaler struct{} 511 - 512 - func (ft *failingMarshaler) MarshalYAML() (interface{}, error) { 513 - return nil, failingErr 514 - } 515 - 516 - func (s *S) TestMarshalerError(c *C) { 517 - _, err := yaml.Marshal(&failingMarshaler{}) 518 - c.Assert(err, Equals, failingErr) 519 - } 520 - 521 - func (s *S) TestSortedOutput(c *C) { 522 - order := []interface{}{ 523 - false, 524 - true, 525 - 1, 526 - uint(1), 527 - 1.0, 528 - 1.1, 529 - 1.2, 530 - 2, 531 - uint(2), 532 - 2.0, 533 - 2.1, 534 - "", 535 - ".1", 536 - ".2", 537 - ".a", 538 - "1", 539 - "2", 540 - "a!10", 541 - "a/0001", 542 - "a/002", 543 - "a/3", 544 - "a/10", 545 - "a/11", 546 - "a/0012", 547 - "a/100", 548 - "a~10", 549 - "ab/1", 550 - "b/1", 551 - "b/01", 552 - "b/2", 553 - "b/02", 554 - "b/3", 555 - "b/03", 556 - "b1", 557 - "b01", 558 - "b3", 559 - "c2.10", 560 - "c10.2", 561 - "d1", 562 - "d7", 563 - "d7abc", 564 - "d12", 565 - "d12a", 566 - } 567 - m := make(map[interface{}]int) 568 - for _, k := range order { 569 - m[k] = 1 570 - } 571 - data, err := yaml.Marshal(m) 572 - c.Assert(err, IsNil) 573 - out := "\n" + string(data) 574 - last := 0 575 - for i, k := range order { 576 - repr := fmt.Sprint(k) 577 - if s, ok := k.(string); ok { 578 - if _, err = strconv.ParseFloat(repr, 32); s == "" || err == nil { 579 - repr = `"` + repr + `"` 580 - } 581 - } 582 - index := strings.Index(out, "\n"+repr+":") 583 - if index == -1 { 584 - c.Fatalf("%#v is not in the output: %#v", k, out) 585 - } 586 - if index < last { 587 - c.Fatalf("%#v was generated before %#v: %q", k, order[i-1], out) 588 - } 589 - last = index 590 - } 591 - } 592 - 593 - func newTime(t time.Time) *time.Time { 594 - return &t 595 - }
-41
internal/third_party/yaml/example_embedded_test.go
··· 1 - package yaml_test 2 - 3 - import ( 4 - "fmt" 5 - "log" 6 - 7 - "gopkg.in/yaml.v2" 8 - ) 9 - 10 - // An example showing how to unmarshal embedded 11 - // structs from YAML. 12 - 13 - type StructA struct { 14 - A string `yaml:"a"` 15 - } 16 - 17 - type StructB struct { 18 - // Embedded structs are not treated as embedded in YAML by default. To do that, 19 - // add the ",inline" annotation below 20 - StructA `yaml:",inline"` 21 - B string `yaml:"b"` 22 - } 23 - 24 - var data = ` 25 - a: a string from struct A 26 - b: a string from struct B 27 - ` 28 - 29 - func ExampleUnmarshal_embedded() { 30 - var b StructB 31 - 32 - err := yaml.Unmarshal([]byte(data), &b) 33 - if err != nil { 34 - log.Fatalf("cannot unmarshal data: %v", err) 35 - } 36 - fmt.Println(b.A) 37 - fmt.Println(b.B) 38 - // Output: 39 - // a string from struct A 40 - // a string from struct B 41 - }
+11 -2
internal/third_party/yaml/parserc.go
··· 2 2 3 3 import ( 4 4 "bytes" 5 + 6 + "cuelang.org/go/cue/token" 5 7 ) 6 8 7 9 // The parser implements the following grammar: ··· 56 58 parser.tokens_parsed++ 57 59 parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN 58 60 parser.tokens_head++ 61 + } 62 + 63 + func add_comment(parser *yaml_parser_t, p token.RelPos, m yaml_mark_t, text string) { 64 + parser.comments = append(parser.comments, yaml_comment_t{ 65 + pos: p, 66 + mark: m, 67 + text: text, 68 + }) 59 69 } 60 70 61 71 // Get the next event. ··· 1010 1020 } 1011 1021 1012 1022 // Parse directives. 1013 - func yaml_parser_process_directives(parser *yaml_parser_t, 1014 - version_directive_ref **yaml_version_directive_t, 1023 + func yaml_parser_process_directives(parser *yaml_parser_t, version_directive_ref **yaml_version_directive_t, 1015 1024 tag_directives_ref *[]yaml_tag_directive_t) bool { 1016 1025 1017 1026 var version_directive *yaml_version_directive_t
+1 -1
internal/third_party/yaml/readerc.go
··· 95 95 96 96 // [Go] This function was changed to guarantee the requested length size at EOF. 97 97 // The fact we need to do this is pretty awful, but the description above implies 98 - // for that to be the case, and there are tests 98 + // for that to be the case, and there are tests 99 99 100 100 // If the EOF flag is set and the raw buffer is empty, do nothing. 101 101 if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
+5 -3
internal/third_party/yaml/resolve.go
··· 83 83 84 84 var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`) 85 85 86 - func resolve(tag string, in string) (rtag string, out interface{}) { 86 + func (d *decoder) resolve(n *node) (rtag string, out interface{}) { 87 + tag := n.tag 88 + in := n.value 87 89 if !resolvableTag(tag) { 88 90 return tag, in 89 91 } ··· 106 108 } 107 109 } 108 110 } 109 - failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) 111 + d.p.failf(n.startPos.line, "cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) 110 112 }() 111 113 112 114 // Any data is accepted as a !!str or !!binary. ··· 180 182 return yaml_INT_TAG, uintv 181 183 } 182 184 } else if strings.HasPrefix(plain, "-0b") { 183 - intv, err := strconv.ParseInt("-" + plain[3:], 2, 64) 185 + intv, err := strconv.ParseInt("-"+plain[3:], 2, 64) 184 186 if err == nil { 185 187 if true || intv == int64(int(intv)) { 186 188 return yaml_INT_TAG, int(intv)
+26
internal/third_party/yaml/scannerc.go
··· 1427 1427 // Eat whitespaces and comments until the next token is found. 1428 1428 func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { 1429 1429 1430 + parser.linesSinceLast = 0 1431 + parser.spacesSinceLast = 0 1432 + 1430 1433 // Until the next token is not found. 1431 1434 for { 1432 1435 // Allow the BOM mark to start a line. ··· 1448 1451 1449 1452 for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { 1450 1453 skip(parser) 1454 + parser.spacesSinceLast++ 1451 1455 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { 1452 1456 return false 1453 1457 } ··· 1455 1459 1456 1460 // Eat a comment until a line break. 1457 1461 if parser.buffer[parser.buffer_pos] == '#' { 1462 + rel := parser.relPos() 1463 + m := parser.mark 1464 + parser.comment_buffer = parser.comment_buffer[:0] 1458 1465 for !is_breakz(parser.buffer, parser.buffer_pos) { 1466 + p := parser.buffer_pos 1459 1467 skip(parser) 1468 + parser.comment_buffer = append(parser.comment_buffer, 1469 + parser.buffer[p:parser.buffer_pos]...) 1460 1470 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { 1461 1471 return false 1462 1472 } 1463 1473 } 1474 + add_comment(parser, rel, m, string(parser.comment_buffer)) 1464 1475 } 1465 1476 1466 1477 // If it is a line break, eat it. ··· 1469 1480 return false 1470 1481 } 1471 1482 skip_line(parser) 1483 + parser.linesSinceLast++ 1472 1484 1473 1485 // In the block context, a new line may start a simple key. 1474 1486 if parser.flow_level == 0 { ··· 1557 1569 } 1558 1570 1559 1571 if parser.buffer[parser.buffer_pos] == '#' { 1572 + rel := parser.relPos() 1573 + m := parser.mark 1574 + parser.comment_buffer = parser.comment_buffer[:0] 1560 1575 for !is_breakz(parser.buffer, parser.buffer_pos) { 1576 + p := parser.buffer_pos 1561 1577 skip(parser) 1578 + parser.comment_buffer = append(parser.comment_buffer, 1579 + parser.buffer[p:parser.buffer_pos]...) 1562 1580 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { 1563 1581 return false 1564 1582 } 1565 1583 } 1584 + add_comment(parser, rel, m, string(parser.comment_buffer)) 1566 1585 } 1567 1586 1568 1587 // Check if we are at the end of the line. ··· 2127 2146 } 2128 2147 } 2129 2148 if parser.buffer[parser.buffer_pos] == '#' { 2149 + rel := parser.relPos() 2150 + m := parser.mark 2151 + parser.comment_buffer = parser.comment_buffer[:0] 2130 2152 for !is_breakz(parser.buffer, parser.buffer_pos) { 2153 + p := parser.buffer_pos 2131 2154 skip(parser) 2155 + parser.comment_buffer = append(parser.comment_buffer, 2156 + parser.buffer[p:parser.buffer_pos]...) 2132 2157 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { 2133 2158 return false 2134 2159 } 2135 2160 } 2161 + add_comment(parser, rel, m, string(parser.comment_buffer)) 2136 2162 } 2137 2163 2138 2164 // Check if we are at the end of the line.
-113
internal/third_party/yaml/sorter.go
··· 1 - package yaml 2 - 3 - import ( 4 - "reflect" 5 - "unicode" 6 - ) 7 - 8 - type keyList []reflect.Value 9 - 10 - func (l keyList) Len() int { return len(l) } 11 - func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } 12 - func (l keyList) Less(i, j int) bool { 13 - a := l[i] 14 - b := l[j] 15 - ak := a.Kind() 16 - bk := b.Kind() 17 - for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { 18 - a = a.Elem() 19 - ak = a.Kind() 20 - } 21 - for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { 22 - b = b.Elem() 23 - bk = b.Kind() 24 - } 25 - af, aok := keyFloat(a) 26 - bf, bok := keyFloat(b) 27 - if aok && bok { 28 - if af != bf { 29 - return af < bf 30 - } 31 - if ak != bk { 32 - return ak < bk 33 - } 34 - return numLess(a, b) 35 - } 36 - if ak != reflect.String || bk != reflect.String { 37 - return ak < bk 38 - } 39 - ar, br := []rune(a.String()), []rune(b.String()) 40 - for i := 0; i < len(ar) && i < len(br); i++ { 41 - if ar[i] == br[i] { 42 - continue 43 - } 44 - al := unicode.IsLetter(ar[i]) 45 - bl := unicode.IsLetter(br[i]) 46 - if al && bl { 47 - return ar[i] < br[i] 48 - } 49 - if al || bl { 50 - return bl 51 - } 52 - var ai, bi int 53 - var an, bn int64 54 - if ar[i] == '0' || br[i] == '0' { 55 - for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- { 56 - if ar[j] != '0' { 57 - an = 1 58 - bn = 1 59 - break 60 - } 61 - } 62 - } 63 - for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { 64 - an = an*10 + int64(ar[ai]-'0') 65 - } 66 - for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { 67 - bn = bn*10 + int64(br[bi]-'0') 68 - } 69 - if an != bn { 70 - return an < bn 71 - } 72 - if ai != bi { 73 - return ai < bi 74 - } 75 - return ar[i] < br[i] 76 - } 77 - return len(ar) < len(br) 78 - } 79 - 80 - // keyFloat returns a float value for v if it is a number/bool 81 - // and whether it is a number/bool or not. 82 - func keyFloat(v reflect.Value) (f float64, ok bool) { 83 - switch v.Kind() { 84 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 85 - return float64(v.Int()), true 86 - case reflect.Float32, reflect.Float64: 87 - return v.Float(), true 88 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 89 - return float64(v.Uint()), true 90 - case reflect.Bool: 91 - if v.Bool() { 92 - return 1, true 93 - } 94 - return 0, true 95 - } 96 - return 0, false 97 - } 98 - 99 - // numLess returns whether a < b. 100 - // a and b must necessarily have the same kind. 101 - func numLess(a, b reflect.Value) bool { 102 - switch a.Kind() { 103 - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 104 - return a.Int() < b.Int() 105 - case reflect.Float32, reflect.Float64: 106 - return a.Float() < b.Float() 107 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 108 - return a.Uint() < b.Uint() 109 - case reflect.Bool: 110 - return !a.Bool() && b.Bool() 111 - } 112 - panic("not a number") 113 - }
-12
internal/third_party/yaml/suite_test.go
··· 1 - package yaml_test 2 - 3 - import ( 4 - . "gopkg.in/check.v1" 5 - "testing" 6 - ) 7 - 8 - func Test(t *testing.T) { TestingT(t) } 9 - 10 - type S struct{} 11 - 12 - var _ = Suite(&S{})
+69
internal/third_party/yaml/testdata/merge.out
··· 1 + // From http://yaml.org/type/merge.html 2 + // Test 3 + anchors list: [{ 4 + x: 1 5 + y: 2 6 + }, { 7 + x: 0 8 + y: 2 9 + }, { 10 + r: 10 11 + }, { 12 + r: 1 13 + }] 14 + // All the following maps are equal: 15 + plain: { 16 + // Explicit keys 17 + x: 1 18 + y: 2 19 + r: 10 20 + label: "center/big" 21 + } 22 + mergeOne: { 23 + x: 1 24 + y: 2 25 + // Merge one map 26 + r: 10 27 + label: "center/big" 28 + } 29 + mergeMultiple: { 30 + r: 10 31 + x: 1 32 + y: 2 33 + // Merge multiple maps 34 + label: "center/big" 35 + } 36 + override: { 37 + r: 10 38 + x: 1 39 + y: 2 40 + label: "center/big" 41 + } 42 + shortTag: { 43 + r: 10 44 + x: 1 45 + y: 2 46 + // Explicit short merge tag 47 + label: "center/big" 48 + } 49 + longTag: { 50 + r: 10 51 + x: 1 52 + y: 2 53 + // Explicit merge long tag 54 + label: "center/big" 55 + } 56 + inlineMap: { 57 + // Inlined map 58 + x: 1 59 + y: 2 60 + r: 10 61 + label: "center/big" 62 + } 63 + inlineSequenceMap: { 64 + // Inlined map in sequence 65 + r: 10 66 + x: 1 67 + y: 2 68 + label: "center/big" 69 + }
+54
internal/third_party/yaml/testdata/merge.test
··· 1 + # From http://yaml.org/type/merge.html 2 + # Test 3 + anchors: 4 + list: 5 + - &CENTER { "x": 1, "y": 2 } 6 + - &LEFT { "x": 0, "y": 2 } 7 + - &BIG { "r": 10 } 8 + - &SMALL { "r": 1 } 9 + 10 + # All the following maps are equal: 11 + 12 + plain: 13 + # Explicit keys 14 + "x": 1 15 + "y": 2 16 + "r": 10 17 + label: center/big 18 + 19 + mergeOne: 20 + # Merge one map 21 + << : *CENTER 22 + "r": 10 23 + label: center/big 24 + 25 + mergeMultiple: 26 + # Merge multiple maps 27 + << : [ *CENTER, *BIG ] 28 + label: center/big 29 + 30 + override: 31 + # Override 32 + << : [ *BIG, *LEFT, *SMALL ] 33 + "x": 1 34 + label: center/big 35 + 36 + shortTag: 37 + # Explicit short merge tag 38 + !!merge "<<" : [ *CENTER, *BIG ] 39 + label: center/big 40 + 41 + longTag: 42 + # Explicit merge long tag 43 + !<tag:yaml.org,2002:merge> "<<" : [ *CENTER, *BIG ] 44 + label: center/big 45 + 46 + inlineMap: 47 + # Inlined map 48 + << : {"x": 1, "y": 2, "r": 10} 49 + label: center/big 50 + 51 + inlineSequenceMap: 52 + # Inlined map in sequence 53 + << : [ *CENTER, {"r": 10} ] 54 + label: center/big
-26
internal/third_party/yaml/writerc.go
··· 1 - package yaml 2 - 3 - // Set the writer error and return false. 4 - func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { 5 - emitter.error = yaml_WRITER_ERROR 6 - emitter.problem = problem 7 - return false 8 - } 9 - 10 - // Flush the output buffer. 11 - func yaml_emitter_flush(emitter *yaml_emitter_t) bool { 12 - if emitter.write_handler == nil { 13 - panic("write handler not set") 14 - } 15 - 16 - // Check if the buffer is empty. 17 - if emitter.buffer_pos == 0 { 18 - return true 19 - } 20 - 21 - if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { 22 - return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 23 - } 24 - emitter.buffer_pos = 0 25 - return true 26 - }
+32 -134
internal/third_party/yaml/yaml.go
··· 4 4 // 5 5 // https://github.com/go-yaml/yaml 6 6 // 7 - package yaml 7 + package yaml // import "cuelang.org/go/internal/third_party/yaml" 8 8 9 9 import ( 10 10 "errors" 11 11 "fmt" 12 12 "io" 13 13 "reflect" 14 + "strconv" 14 15 "strings" 15 16 "sync" 17 + 18 + "cuelang.org/go/cue/ast" 19 + "cuelang.org/go/cue/token" 16 20 ) 17 21 18 22 // MapSlice encodes and decodes as a YAML map. ··· 77 81 // See the documentation of Marshal for the format of tags and a list of 78 82 // supported tag options. 79 83 // 80 - func Unmarshal(in []byte, out interface{}) (err error) { 81 - return unmarshal(in, out, false) 82 - } 83 - 84 - // UnmarshalStrict is like Unmarshal except that any fields that are found 85 - // in the data that do not have corresponding struct members, or mapping 86 - // keys that are duplicates, will result in 87 - // an error. 88 - func UnmarshalStrict(in []byte, out interface{}) (err error) { 89 - return unmarshal(in, out, true) 84 + func Unmarshal(fset *token.FileSet, filename string, in []byte) (expr ast.Expr, err error) { 85 + return unmarshal(fset, filename, in) 90 86 } 91 87 92 88 // A Decorder reads and decodes YAML values from an input stream. ··· 99 95 // 100 96 // The decoder introduces its own buffering and may read 101 97 // data from r beyond the YAML values requested. 102 - func NewDecoder(r io.Reader) *Decoder { 103 - return &Decoder{ 104 - parser: newParserFromReader(r), 98 + func NewDecoder(fset *token.FileSet, filename string, r io.Reader) (*Decoder, error) { 99 + d, err := newParser(fset, filename, r) 100 + if err != nil { 101 + return nil, err 105 102 } 106 - } 107 - 108 - // SetStrict sets whether strict decoding behaviour is enabled when 109 - // decoding items in the data (see UnmarshalStrict). By default, decoding is not strict. 110 - func (dec *Decoder) SetStrict(strict bool) { 111 - dec.strict = strict 103 + return &Decoder{parser: d}, nil 112 104 } 113 105 114 106 // Decode reads the next YAML-encoded value from its input ··· 116 108 // 117 109 // See the documentation for Unmarshal for details about the 118 110 // conversion of YAML into a Go value. 119 - func (dec *Decoder) Decode(v interface{}) (err error) { 120 - d := newDecoder(dec.strict) 111 + func (dec *Decoder) Decode() (expr ast.Expr, err error) { 112 + d := newDecoder(dec.parser) 121 113 defer handleErr(&err) 122 114 node := dec.parser.parse() 123 115 if node == nil { 124 - return io.EOF 116 + return nil, io.EOF 125 117 } 126 - out := reflect.ValueOf(v) 127 - if out.Kind() == reflect.Ptr && !out.IsNil() { 128 - out = out.Elem() 129 - } 130 - d.unmarshal(node, out) 118 + expr = d.unmarshal(node) 131 119 if len(d.terrors) > 0 { 132 - return &TypeError{d.terrors} 120 + return nil, &TypeError{d.terrors} 133 121 } 134 - return nil 122 + return expr, nil 135 123 } 136 124 137 - func unmarshal(in []byte, out interface{}, strict bool) (err error) { 125 + func unmarshal(fset *token.FileSet, filename string, in []byte) (expr ast.Expr, err error) { 138 126 defer handleErr(&err) 139 - d := newDecoder(strict) 140 - p := newParser(in) 127 + p, err := newParser(fset, filename, in) 128 + if err != nil { 129 + return nil, err 130 + } 141 131 defer p.destroy() 142 132 node := p.parse() 133 + d := newDecoder(p) 143 134 if node != nil { 144 - v := reflect.ValueOf(out) 145 - if v.Kind() == reflect.Ptr && !v.IsNil() { 146 - v = v.Elem() 147 - } 148 - d.unmarshal(node, v) 135 + expr = d.unmarshal(node) 149 136 } 150 137 if len(d.terrors) > 0 { 151 - return &TypeError{d.terrors} 152 - } 153 - return nil 154 - } 155 - 156 - // Marshal serializes the value provided into a YAML document. The structure 157 - // of the generated document will reflect the structure of the value itself. 158 - // Maps and pointers (to struct, string, int, etc) are accepted as the in value. 159 - // 160 - // Struct fields are only marshalled if they are exported (have an upper case 161 - // first letter), and are marshalled using the field name lowercased as the 162 - // default key. Custom keys may be defined via the "yaml" name in the field 163 - // tag: the content preceding the first comma is used as the key, and the 164 - // following comma-separated options are used to tweak the marshalling process. 165 - // Conflicting names result in a runtime error. 166 - // 167 - // The field tag format accepted is: 168 - // 169 - // `(...) yaml:"[<key>][,<flag1>[,<flag2>]]" (...)` 170 - // 171 - // The following flags are currently supported: 172 - // 173 - // omitempty Only include the field if it's not set to the zero 174 - // value for the type or to empty slices or maps. 175 - // Zero valued structs will be omitted if all their public 176 - // fields are zero, unless they implement an IsZero 177 - // method (see the IsZeroer interface type), in which 178 - // case the field will be included if that method returns true. 179 - // 180 - // flow Marshal using a flow style (useful for structs, 181 - // sequences and maps). 182 - // 183 - // inline Inline the field, which must be a struct or a map, 184 - // causing all of its fields or keys to be processed as if 185 - // they were part of the outer struct. For maps, keys must 186 - // not conflict with the yaml keys of other struct fields. 187 - // 188 - // In addition, if the key is "-", the field is ignored. 189 - // 190 - // For example: 191 - // 192 - // type T struct { 193 - // F int `yaml:"a,omitempty"` 194 - // B int 195 - // } 196 - // yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" 197 - // yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" 198 - // 199 - func Marshal(in interface{}) (out []byte, err error) { 200 - defer handleErr(&err) 201 - e := newEncoder() 202 - defer e.destroy() 203 - e.marshalDoc("", reflect.ValueOf(in)) 204 - e.finish() 205 - out = e.out 206 - return 207 - } 208 - 209 - // An Encoder writes YAML values to an output stream. 210 - type Encoder struct { 211 - encoder *encoder 212 - } 213 - 214 - // NewEncoder returns a new encoder that writes to w. 215 - // The Encoder should be closed after use to flush all data 216 - // to w. 217 - func NewEncoder(w io.Writer) *Encoder { 218 - return &Encoder{ 219 - encoder: newEncoderWithWriter(w), 138 + return nil, &TypeError{d.terrors} 220 139 } 221 - } 222 - 223 - // Encode writes the YAML encoding of v to the stream. 224 - // If multiple items are encoded to the stream, the 225 - // second and subsequent document will be preceded 226 - // with a "---" document separator, but the first will not. 227 - // 228 - // See the documentation for Marshal for details about the conversion of Go 229 - // values to YAML. 230 - func (e *Encoder) Encode(v interface{}) (err error) { 231 - defer handleErr(&err) 232 - e.encoder.marshalDoc("", reflect.ValueOf(v)) 233 - return nil 234 - } 235 - 236 - // Close closes the encoder by writing any remaining data. 237 - // It does not write a stream terminating string "...". 238 - func (e *Encoder) Close() (err error) { 239 - defer handleErr(&err) 240 - e.encoder.finish() 241 - return nil 140 + return expr, nil 242 141 } 243 142 244 143 func handleErr(err *error) { ··· 255 154 err error 256 155 } 257 156 258 - func fail(err error) { 259 - panic(yamlError{err}) 260 - } 261 - 262 - func failf(format string, args ...interface{}) { 263 - panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) 157 + func (p *parser) failf(line int, format string, args ...interface{}) { 158 + where := p.parser.filename + ":" 159 + line++ 160 + where += strconv.Itoa(line) + ": " 161 + panic(yamlError{fmt.Errorf(where+format, args...)}) 264 162 } 265 163 266 164 // A TypeError is returned by Unmarshal when one or more fields in
+34
internal/third_party/yaml/yamlh.go
··· 3 3 import ( 4 4 "fmt" 5 5 "io" 6 + 7 + "cuelang.org/go/cue/token" 6 8 ) 7 9 8 10 // The version directive data. ··· 518 520 mark yaml_mark_t // The anchor mark. 519 521 } 520 522 523 + type yaml_comment_t struct { 524 + pos token.RelPos 525 + mark yaml_mark_t 526 + text string 527 + } 528 + 529 + func (p *yaml_parser_t) relPos() (pos token.RelPos) { 530 + switch { 531 + case p.linesSinceLast > 1: 532 + pos = token.NewSection 533 + case p.linesSinceLast == 1: 534 + pos = token.Newline 535 + case p.spacesSinceLast > 0: 536 + pos = token.Blank 537 + default: 538 + pos = token.NoSpace 539 + } 540 + p.linesSinceLast = 0 541 + p.spacesSinceLast = 0 542 + // fmt.Println("REL", pos) 543 + return token.NoRelPos 544 + } 545 + 521 546 // The parser structure. 522 547 // 523 548 // All members are internal. Manage the structure using the ··· 526 551 527 552 // Error handling 528 553 554 + filename string 555 + 529 556 error yaml_error_type_t // Error type. 530 557 531 558 problem string // Error description. ··· 557 584 raw_buffer []byte // The raw buffer. 558 585 raw_buffer_pos int // The current position of the buffer. 559 586 587 + comment_buffer []byte 588 + 560 589 encoding yaml_encoding_t // The input encoding. 561 590 562 591 offset int // The offset of the current position (in bytes). 563 592 mark yaml_mark_t // The mark of the current position. 593 + 594 + linesSinceLast int 595 + spacesSinceLast int 564 596 565 597 // Scanner stuff 566 598 ··· 573 605 tokens_head int // The head of the tokens queue. 574 606 tokens_parsed int // The number of tokens fetched from the queue. 575 607 token_available bool // Does the tokens queue contain a token ready for dequeueing. 608 + 609 + comments []yaml_comment_t 576 610 577 611 indent int // The current indentation level. 578 612 indents []int // The indentation levels stack.