]>
Commit | Line | Data |
---|---|---|
863486a6 AG |
1 | package yaml |
2 | ||
3 | import ( | |
4 | "bytes" | |
5 | ) | |
6 | ||
7 | // The parser implements the following grammar: | |
8 | // | |
9 | // stream ::= STREAM-START implicit_document? explicit_document* STREAM-END | |
10 | // implicit_document ::= block_node DOCUMENT-END* | |
11 | // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | |
12 | // block_node_or_indentless_sequence ::= | |
13 | // ALIAS | |
14 | // | properties (block_content | indentless_block_sequence)? | |
15 | // | block_content | |
16 | // | indentless_block_sequence | |
17 | // block_node ::= ALIAS | |
18 | // | properties block_content? | |
19 | // | block_content | |
20 | // flow_node ::= ALIAS | |
21 | // | properties flow_content? | |
22 | // | flow_content | |
23 | // properties ::= TAG ANCHOR? | ANCHOR TAG? | |
24 | // block_content ::= block_collection | flow_collection | SCALAR | |
25 | // flow_content ::= flow_collection | SCALAR | |
26 | // block_collection ::= block_sequence | block_mapping | |
27 | // flow_collection ::= flow_sequence | flow_mapping | |
28 | // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END | |
29 | // indentless_sequence ::= (BLOCK-ENTRY block_node?)+ | |
30 | // block_mapping ::= BLOCK-MAPPING_START | |
31 | // ((KEY block_node_or_indentless_sequence?)? | |
32 | // (VALUE block_node_or_indentless_sequence?)?)* | |
33 | // BLOCK-END | |
34 | // flow_sequence ::= FLOW-SEQUENCE-START | |
35 | // (flow_sequence_entry FLOW-ENTRY)* | |
36 | // flow_sequence_entry? | |
37 | // FLOW-SEQUENCE-END | |
38 | // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
39 | // flow_mapping ::= FLOW-MAPPING-START | |
40 | // (flow_mapping_entry FLOW-ENTRY)* | |
41 | // flow_mapping_entry? | |
42 | // FLOW-MAPPING-END | |
43 | // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
44 | ||
45 | // Peek the next token in the token queue. | |
46 | func peek_token(parser *yaml_parser_t) *yaml_token_t { | |
47 | if parser.token_available || yaml_parser_fetch_more_tokens(parser) { | |
48 | return &parser.tokens[parser.tokens_head] | |
49 | } | |
50 | return nil | |
51 | } | |
52 | ||
53 | // Remove the next token from the queue (must be called after peek_token). | |
54 | func skip_token(parser *yaml_parser_t) { | |
55 | parser.token_available = false | |
56 | parser.tokens_parsed++ | |
57 | parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN | |
58 | parser.tokens_head++ | |
59 | } | |
60 | ||
61 | // Get the next event. | |
62 | func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { | |
63 | // Erase the event object. | |
64 | *event = yaml_event_t{} | |
65 | ||
66 | // No events after the end of the stream or error. | |
67 | if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { | |
68 | return true | |
69 | } | |
70 | ||
71 | // Generate the next event. | |
72 | return yaml_parser_state_machine(parser, event) | |
73 | } | |
74 | ||
75 | // Set parser error. | |
76 | func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { | |
77 | parser.error = yaml_PARSER_ERROR | |
78 | parser.problem = problem | |
79 | parser.problem_mark = problem_mark | |
80 | return false | |
81 | } | |
82 | ||
83 | func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { | |
84 | parser.error = yaml_PARSER_ERROR | |
85 | parser.context = context | |
86 | parser.context_mark = context_mark | |
87 | parser.problem = problem | |
88 | parser.problem_mark = problem_mark | |
89 | return false | |
90 | } | |
91 | ||
92 | // State dispatcher. | |
93 | func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { | |
94 | //trace("yaml_parser_state_machine", "state:", parser.state.String()) | |
95 | ||
96 | switch parser.state { | |
97 | case yaml_PARSE_STREAM_START_STATE: | |
98 | return yaml_parser_parse_stream_start(parser, event) | |
99 | ||
100 | case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: | |
101 | return yaml_parser_parse_document_start(parser, event, true) | |
102 | ||
103 | case yaml_PARSE_DOCUMENT_START_STATE: | |
104 | return yaml_parser_parse_document_start(parser, event, false) | |
105 | ||
106 | case yaml_PARSE_DOCUMENT_CONTENT_STATE: | |
107 | return yaml_parser_parse_document_content(parser, event) | |
108 | ||
109 | case yaml_PARSE_DOCUMENT_END_STATE: | |
110 | return yaml_parser_parse_document_end(parser, event) | |
111 | ||
112 | case yaml_PARSE_BLOCK_NODE_STATE: | |
113 | return yaml_parser_parse_node(parser, event, true, false) | |
114 | ||
115 | case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: | |
116 | return yaml_parser_parse_node(parser, event, true, true) | |
117 | ||
118 | case yaml_PARSE_FLOW_NODE_STATE: | |
119 | return yaml_parser_parse_node(parser, event, false, false) | |
120 | ||
121 | case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: | |
122 | return yaml_parser_parse_block_sequence_entry(parser, event, true) | |
123 | ||
124 | case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: | |
125 | return yaml_parser_parse_block_sequence_entry(parser, event, false) | |
126 | ||
127 | case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: | |
128 | return yaml_parser_parse_indentless_sequence_entry(parser, event) | |
129 | ||
130 | case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: | |
131 | return yaml_parser_parse_block_mapping_key(parser, event, true) | |
132 | ||
133 | case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: | |
134 | return yaml_parser_parse_block_mapping_key(parser, event, false) | |
135 | ||
136 | case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: | |
137 | return yaml_parser_parse_block_mapping_value(parser, event) | |
138 | ||
139 | case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: | |
140 | return yaml_parser_parse_flow_sequence_entry(parser, event, true) | |
141 | ||
142 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: | |
143 | return yaml_parser_parse_flow_sequence_entry(parser, event, false) | |
144 | ||
145 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: | |
146 | return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) | |
147 | ||
148 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: | |
149 | return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) | |
150 | ||
151 | case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: | |
152 | return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) | |
153 | ||
154 | case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: | |
155 | return yaml_parser_parse_flow_mapping_key(parser, event, true) | |
156 | ||
157 | case yaml_PARSE_FLOW_MAPPING_KEY_STATE: | |
158 | return yaml_parser_parse_flow_mapping_key(parser, event, false) | |
159 | ||
160 | case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: | |
161 | return yaml_parser_parse_flow_mapping_value(parser, event, false) | |
162 | ||
163 | case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: | |
164 | return yaml_parser_parse_flow_mapping_value(parser, event, true) | |
165 | ||
166 | default: | |
167 | panic("invalid parser state") | |
168 | } | |
169 | } | |
170 | ||
171 | // Parse the production: | |
172 | // stream ::= STREAM-START implicit_document? explicit_document* STREAM-END | |
173 | // ************ | |
174 | func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { | |
175 | token := peek_token(parser) | |
176 | if token == nil { | |
177 | return false | |
178 | } | |
179 | if token.typ != yaml_STREAM_START_TOKEN { | |
180 | return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark) | |
181 | } | |
182 | parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE | |
183 | *event = yaml_event_t{ | |
184 | typ: yaml_STREAM_START_EVENT, | |
185 | start_mark: token.start_mark, | |
186 | end_mark: token.end_mark, | |
187 | encoding: token.encoding, | |
188 | } | |
189 | skip_token(parser) | |
190 | return true | |
191 | } | |
192 | ||
193 | // Parse the productions: | |
194 | // implicit_document ::= block_node DOCUMENT-END* | |
195 | // * | |
196 | // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | |
197 | // ************************* | |
198 | func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { | |
199 | ||
200 | token := peek_token(parser) | |
201 | if token == nil { | |
202 | return false | |
203 | } | |
204 | ||
205 | // Parse extra document end indicators. | |
206 | if !implicit { | |
207 | for token.typ == yaml_DOCUMENT_END_TOKEN { | |
208 | skip_token(parser) | |
209 | token = peek_token(parser) | |
210 | if token == nil { | |
211 | return false | |
212 | } | |
213 | } | |
214 | } | |
215 | ||
216 | if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && | |
217 | token.typ != yaml_TAG_DIRECTIVE_TOKEN && | |
218 | token.typ != yaml_DOCUMENT_START_TOKEN && | |
219 | token.typ != yaml_STREAM_END_TOKEN { | |
220 | // Parse an implicit document. | |
221 | if !yaml_parser_process_directives(parser, nil, nil) { | |
222 | return false | |
223 | } | |
224 | parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) | |
225 | parser.state = yaml_PARSE_BLOCK_NODE_STATE | |
226 | ||
227 | *event = yaml_event_t{ | |
228 | typ: yaml_DOCUMENT_START_EVENT, | |
229 | start_mark: token.start_mark, | |
230 | end_mark: token.end_mark, | |
231 | } | |
232 | ||
233 | } else if token.typ != yaml_STREAM_END_TOKEN { | |
234 | // Parse an explicit document. | |
235 | var version_directive *yaml_version_directive_t | |
236 | var tag_directives []yaml_tag_directive_t | |
237 | start_mark := token.start_mark | |
238 | if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { | |
239 | return false | |
240 | } | |
241 | token = peek_token(parser) | |
242 | if token == nil { | |
243 | return false | |
244 | } | |
245 | if token.typ != yaml_DOCUMENT_START_TOKEN { | |
246 | yaml_parser_set_parser_error(parser, | |
247 | "did not find expected <document start>", token.start_mark) | |
248 | return false | |
249 | } | |
250 | parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) | |
251 | parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE | |
252 | end_mark := token.end_mark | |
253 | ||
254 | *event = yaml_event_t{ | |
255 | typ: yaml_DOCUMENT_START_EVENT, | |
256 | start_mark: start_mark, | |
257 | end_mark: end_mark, | |
258 | version_directive: version_directive, | |
259 | tag_directives: tag_directives, | |
260 | implicit: false, | |
261 | } | |
262 | skip_token(parser) | |
263 | ||
264 | } else { | |
265 | // Parse the stream end. | |
266 | parser.state = yaml_PARSE_END_STATE | |
267 | *event = yaml_event_t{ | |
268 | typ: yaml_STREAM_END_EVENT, | |
269 | start_mark: token.start_mark, | |
270 | end_mark: token.end_mark, | |
271 | } | |
272 | skip_token(parser) | |
273 | } | |
274 | ||
275 | return true | |
276 | } | |
277 | ||
278 | // Parse the productions: | |
279 | // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | |
280 | // *********** | |
281 | // | |
282 | func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { | |
283 | token := peek_token(parser) | |
284 | if token == nil { | |
285 | return false | |
286 | } | |
287 | if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || | |
288 | token.typ == yaml_TAG_DIRECTIVE_TOKEN || | |
289 | token.typ == yaml_DOCUMENT_START_TOKEN || | |
290 | token.typ == yaml_DOCUMENT_END_TOKEN || | |
291 | token.typ == yaml_STREAM_END_TOKEN { | |
292 | parser.state = parser.states[len(parser.states)-1] | |
293 | parser.states = parser.states[:len(parser.states)-1] | |
294 | return yaml_parser_process_empty_scalar(parser, event, | |
295 | token.start_mark) | |
296 | } | |
297 | return yaml_parser_parse_node(parser, event, true, false) | |
298 | } | |
299 | ||
300 | // Parse the productions: | |
301 | // implicit_document ::= block_node DOCUMENT-END* | |
302 | // ************* | |
303 | // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | |
304 | // | |
305 | func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { | |
306 | token := peek_token(parser) | |
307 | if token == nil { | |
308 | return false | |
309 | } | |
310 | ||
311 | start_mark := token.start_mark | |
312 | end_mark := token.start_mark | |
313 | ||
314 | implicit := true | |
315 | if token.typ == yaml_DOCUMENT_END_TOKEN { | |
316 | end_mark = token.end_mark | |
317 | skip_token(parser) | |
318 | implicit = false | |
319 | } | |
320 | ||
321 | parser.tag_directives = parser.tag_directives[:0] | |
322 | ||
323 | parser.state = yaml_PARSE_DOCUMENT_START_STATE | |
324 | *event = yaml_event_t{ | |
325 | typ: yaml_DOCUMENT_END_EVENT, | |
326 | start_mark: start_mark, | |
327 | end_mark: end_mark, | |
328 | implicit: implicit, | |
329 | } | |
330 | return true | |
331 | } | |
332 | ||
333 | // Parse the productions: | |
334 | // block_node_or_indentless_sequence ::= | |
335 | // ALIAS | |
336 | // ***** | |
337 | // | properties (block_content | indentless_block_sequence)? | |
338 | // ********** * | |
339 | // | block_content | indentless_block_sequence | |
340 | // * | |
341 | // block_node ::= ALIAS | |
342 | // ***** | |
343 | // | properties block_content? | |
344 | // ********** * | |
345 | // | block_content | |
346 | // * | |
347 | // flow_node ::= ALIAS | |
348 | // ***** | |
349 | // | properties flow_content? | |
350 | // ********** * | |
351 | // | flow_content | |
352 | // * | |
353 | // properties ::= TAG ANCHOR? | ANCHOR TAG? | |
354 | // ************************* | |
355 | // block_content ::= block_collection | flow_collection | SCALAR | |
356 | // ****** | |
357 | // flow_content ::= flow_collection | SCALAR | |
358 | // ****** | |
359 | func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { | |
360 | //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() | |
361 | ||
362 | token := peek_token(parser) | |
363 | if token == nil { | |
364 | return false | |
365 | } | |
366 | ||
367 | if token.typ == yaml_ALIAS_TOKEN { | |
368 | parser.state = parser.states[len(parser.states)-1] | |
369 | parser.states = parser.states[:len(parser.states)-1] | |
370 | *event = yaml_event_t{ | |
371 | typ: yaml_ALIAS_EVENT, | |
372 | start_mark: token.start_mark, | |
373 | end_mark: token.end_mark, | |
374 | anchor: token.value, | |
375 | } | |
376 | skip_token(parser) | |
377 | return true | |
378 | } | |
379 | ||
380 | start_mark := token.start_mark | |
381 | end_mark := token.start_mark | |
382 | ||
383 | var tag_token bool | |
384 | var tag_handle, tag_suffix, anchor []byte | |
385 | var tag_mark yaml_mark_t | |
386 | if token.typ == yaml_ANCHOR_TOKEN { | |
387 | anchor = token.value | |
388 | start_mark = token.start_mark | |
389 | end_mark = token.end_mark | |
390 | skip_token(parser) | |
391 | token = peek_token(parser) | |
392 | if token == nil { | |
393 | return false | |
394 | } | |
395 | if token.typ == yaml_TAG_TOKEN { | |
396 | tag_token = true | |
397 | tag_handle = token.value | |
398 | tag_suffix = token.suffix | |
399 | tag_mark = token.start_mark | |
400 | end_mark = token.end_mark | |
401 | skip_token(parser) | |
402 | token = peek_token(parser) | |
403 | if token == nil { | |
404 | return false | |
405 | } | |
406 | } | |
407 | } else if token.typ == yaml_TAG_TOKEN { | |
408 | tag_token = true | |
409 | tag_handle = token.value | |
410 | tag_suffix = token.suffix | |
411 | start_mark = token.start_mark | |
412 | tag_mark = token.start_mark | |
413 | end_mark = token.end_mark | |
414 | skip_token(parser) | |
415 | token = peek_token(parser) | |
416 | if token == nil { | |
417 | return false | |
418 | } | |
419 | if token.typ == yaml_ANCHOR_TOKEN { | |
420 | anchor = token.value | |
421 | end_mark = token.end_mark | |
422 | skip_token(parser) | |
423 | token = peek_token(parser) | |
424 | if token == nil { | |
425 | return false | |
426 | } | |
427 | } | |
428 | } | |
429 | ||
430 | var tag []byte | |
431 | if tag_token { | |
432 | if len(tag_handle) == 0 { | |
433 | tag = tag_suffix | |
434 | tag_suffix = nil | |
435 | } else { | |
436 | for i := range parser.tag_directives { | |
437 | if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { | |
438 | tag = append([]byte(nil), parser.tag_directives[i].prefix...) | |
439 | tag = append(tag, tag_suffix...) | |
440 | break | |
441 | } | |
442 | } | |
443 | if len(tag) == 0 { | |
444 | yaml_parser_set_parser_error_context(parser, | |
445 | "while parsing a node", start_mark, | |
446 | "found undefined tag handle", tag_mark) | |
447 | return false | |
448 | } | |
449 | } | |
450 | } | |
451 | ||
452 | implicit := len(tag) == 0 | |
453 | if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { | |
454 | end_mark = token.end_mark | |
455 | parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE | |
456 | *event = yaml_event_t{ | |
457 | typ: yaml_SEQUENCE_START_EVENT, | |
458 | start_mark: start_mark, | |
459 | end_mark: end_mark, | |
460 | anchor: anchor, | |
461 | tag: tag, | |
462 | implicit: implicit, | |
463 | style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), | |
464 | } | |
465 | return true | |
466 | } | |
467 | if token.typ == yaml_SCALAR_TOKEN { | |
468 | var plain_implicit, quoted_implicit bool | |
469 | end_mark = token.end_mark | |
470 | if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { | |
471 | plain_implicit = true | |
472 | } else if len(tag) == 0 { | |
473 | quoted_implicit = true | |
474 | } | |
475 | parser.state = parser.states[len(parser.states)-1] | |
476 | parser.states = parser.states[:len(parser.states)-1] | |
477 | ||
478 | *event = yaml_event_t{ | |
479 | typ: yaml_SCALAR_EVENT, | |
480 | start_mark: start_mark, | |
481 | end_mark: end_mark, | |
482 | anchor: anchor, | |
483 | tag: tag, | |
484 | value: token.value, | |
485 | implicit: plain_implicit, | |
486 | quoted_implicit: quoted_implicit, | |
487 | style: yaml_style_t(token.style), | |
488 | } | |
489 | skip_token(parser) | |
490 | return true | |
491 | } | |
492 | if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { | |
493 | // [Go] Some of the events below can be merged as they differ only on style. | |
494 | end_mark = token.end_mark | |
495 | parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE | |
496 | *event = yaml_event_t{ | |
497 | typ: yaml_SEQUENCE_START_EVENT, | |
498 | start_mark: start_mark, | |
499 | end_mark: end_mark, | |
500 | anchor: anchor, | |
501 | tag: tag, | |
502 | implicit: implicit, | |
503 | style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), | |
504 | } | |
505 | return true | |
506 | } | |
507 | if token.typ == yaml_FLOW_MAPPING_START_TOKEN { | |
508 | end_mark = token.end_mark | |
509 | parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE | |
510 | *event = yaml_event_t{ | |
511 | typ: yaml_MAPPING_START_EVENT, | |
512 | start_mark: start_mark, | |
513 | end_mark: end_mark, | |
514 | anchor: anchor, | |
515 | tag: tag, | |
516 | implicit: implicit, | |
517 | style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), | |
518 | } | |
519 | return true | |
520 | } | |
521 | if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { | |
522 | end_mark = token.end_mark | |
523 | parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE | |
524 | *event = yaml_event_t{ | |
525 | typ: yaml_SEQUENCE_START_EVENT, | |
526 | start_mark: start_mark, | |
527 | end_mark: end_mark, | |
528 | anchor: anchor, | |
529 | tag: tag, | |
530 | implicit: implicit, | |
531 | style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), | |
532 | } | |
533 | return true | |
534 | } | |
535 | if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { | |
536 | end_mark = token.end_mark | |
537 | parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE | |
538 | *event = yaml_event_t{ | |
539 | typ: yaml_MAPPING_START_EVENT, | |
540 | start_mark: start_mark, | |
541 | end_mark: end_mark, | |
542 | anchor: anchor, | |
543 | tag: tag, | |
544 | implicit: implicit, | |
545 | style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), | |
546 | } | |
547 | return true | |
548 | } | |
549 | if len(anchor) > 0 || len(tag) > 0 { | |
550 | parser.state = parser.states[len(parser.states)-1] | |
551 | parser.states = parser.states[:len(parser.states)-1] | |
552 | ||
553 | *event = yaml_event_t{ | |
554 | typ: yaml_SCALAR_EVENT, | |
555 | start_mark: start_mark, | |
556 | end_mark: end_mark, | |
557 | anchor: anchor, | |
558 | tag: tag, | |
559 | implicit: implicit, | |
560 | quoted_implicit: false, | |
561 | style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), | |
562 | } | |
563 | return true | |
564 | } | |
565 | ||
566 | context := "while parsing a flow node" | |
567 | if block { | |
568 | context = "while parsing a block node" | |
569 | } | |
570 | yaml_parser_set_parser_error_context(parser, context, start_mark, | |
571 | "did not find expected node content", token.start_mark) | |
572 | return false | |
573 | } | |
574 | ||
575 | // Parse the productions: | |
576 | // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END | |
577 | // ******************** *********** * ********* | |
578 | // | |
579 | func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { | |
580 | if first { | |
581 | token := peek_token(parser) | |
582 | parser.marks = append(parser.marks, token.start_mark) | |
583 | skip_token(parser) | |
584 | } | |
585 | ||
586 | token := peek_token(parser) | |
587 | if token == nil { | |
588 | return false | |
589 | } | |
590 | ||
591 | if token.typ == yaml_BLOCK_ENTRY_TOKEN { | |
592 | mark := token.end_mark | |
593 | skip_token(parser) | |
594 | token = peek_token(parser) | |
595 | if token == nil { | |
596 | return false | |
597 | } | |
598 | if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { | |
599 | parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) | |
600 | return yaml_parser_parse_node(parser, event, true, false) | |
601 | } else { | |
602 | parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE | |
603 | return yaml_parser_process_empty_scalar(parser, event, mark) | |
604 | } | |
605 | } | |
606 | if token.typ == yaml_BLOCK_END_TOKEN { | |
607 | parser.state = parser.states[len(parser.states)-1] | |
608 | parser.states = parser.states[:len(parser.states)-1] | |
609 | parser.marks = parser.marks[:len(parser.marks)-1] | |
610 | ||
611 | *event = yaml_event_t{ | |
612 | typ: yaml_SEQUENCE_END_EVENT, | |
613 | start_mark: token.start_mark, | |
614 | end_mark: token.end_mark, | |
615 | } | |
616 | ||
617 | skip_token(parser) | |
618 | return true | |
619 | } | |
620 | ||
621 | context_mark := parser.marks[len(parser.marks)-1] | |
622 | parser.marks = parser.marks[:len(parser.marks)-1] | |
623 | return yaml_parser_set_parser_error_context(parser, | |
624 | "while parsing a block collection", context_mark, | |
625 | "did not find expected '-' indicator", token.start_mark) | |
626 | } | |
627 | ||
628 | // Parse the productions: | |
629 | // indentless_sequence ::= (BLOCK-ENTRY block_node?)+ | |
630 | // *********** * | |
631 | func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { | |
632 | token := peek_token(parser) | |
633 | if token == nil { | |
634 | return false | |
635 | } | |
636 | ||
637 | if token.typ == yaml_BLOCK_ENTRY_TOKEN { | |
638 | mark := token.end_mark | |
639 | skip_token(parser) | |
640 | token = peek_token(parser) | |
641 | if token == nil { | |
642 | return false | |
643 | } | |
644 | if token.typ != yaml_BLOCK_ENTRY_TOKEN && | |
645 | token.typ != yaml_KEY_TOKEN && | |
646 | token.typ != yaml_VALUE_TOKEN && | |
647 | token.typ != yaml_BLOCK_END_TOKEN { | |
648 | parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) | |
649 | return yaml_parser_parse_node(parser, event, true, false) | |
650 | } | |
651 | parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE | |
652 | return yaml_parser_process_empty_scalar(parser, event, mark) | |
653 | } | |
654 | parser.state = parser.states[len(parser.states)-1] | |
655 | parser.states = parser.states[:len(parser.states)-1] | |
656 | ||
657 | *event = yaml_event_t{ | |
658 | typ: yaml_SEQUENCE_END_EVENT, | |
659 | start_mark: token.start_mark, | |
660 | end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? | |
661 | } | |
662 | return true | |
663 | } | |
664 | ||
665 | // Parse the productions: | |
666 | // block_mapping ::= BLOCK-MAPPING_START | |
667 | // ******************* | |
668 | // ((KEY block_node_or_indentless_sequence?)? | |
669 | // *** * | |
670 | // (VALUE block_node_or_indentless_sequence?)?)* | |
671 | // | |
672 | // BLOCK-END | |
673 | // ********* | |
674 | // | |
675 | func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { | |
676 | if first { | |
677 | token := peek_token(parser) | |
678 | parser.marks = append(parser.marks, token.start_mark) | |
679 | skip_token(parser) | |
680 | } | |
681 | ||
682 | token := peek_token(parser) | |
683 | if token == nil { | |
684 | return false | |
685 | } | |
686 | ||
687 | if token.typ == yaml_KEY_TOKEN { | |
688 | mark := token.end_mark | |
689 | skip_token(parser) | |
690 | token = peek_token(parser) | |
691 | if token == nil { | |
692 | return false | |
693 | } | |
694 | if token.typ != yaml_KEY_TOKEN && | |
695 | token.typ != yaml_VALUE_TOKEN && | |
696 | token.typ != yaml_BLOCK_END_TOKEN { | |
697 | parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) | |
698 | return yaml_parser_parse_node(parser, event, true, true) | |
699 | } else { | |
700 | parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE | |
701 | return yaml_parser_process_empty_scalar(parser, event, mark) | |
702 | } | |
703 | } else if token.typ == yaml_BLOCK_END_TOKEN { | |
704 | parser.state = parser.states[len(parser.states)-1] | |
705 | parser.states = parser.states[:len(parser.states)-1] | |
706 | parser.marks = parser.marks[:len(parser.marks)-1] | |
707 | *event = yaml_event_t{ | |
708 | typ: yaml_MAPPING_END_EVENT, | |
709 | start_mark: token.start_mark, | |
710 | end_mark: token.end_mark, | |
711 | } | |
712 | skip_token(parser) | |
713 | return true | |
714 | } | |
715 | ||
716 | context_mark := parser.marks[len(parser.marks)-1] | |
717 | parser.marks = parser.marks[:len(parser.marks)-1] | |
718 | return yaml_parser_set_parser_error_context(parser, | |
719 | "while parsing a block mapping", context_mark, | |
720 | "did not find expected key", token.start_mark) | |
721 | } | |
722 | ||
723 | // Parse the productions: | |
724 | // block_mapping ::= BLOCK-MAPPING_START | |
725 | // | |
726 | // ((KEY block_node_or_indentless_sequence?)? | |
727 | // | |
728 | // (VALUE block_node_or_indentless_sequence?)?)* | |
729 | // ***** * | |
730 | // BLOCK-END | |
731 | // | |
732 | // | |
733 | func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { | |
734 | token := peek_token(parser) | |
735 | if token == nil { | |
736 | return false | |
737 | } | |
738 | if token.typ == yaml_VALUE_TOKEN { | |
739 | mark := token.end_mark | |
740 | skip_token(parser) | |
741 | token = peek_token(parser) | |
742 | if token == nil { | |
743 | return false | |
744 | } | |
745 | if token.typ != yaml_KEY_TOKEN && | |
746 | token.typ != yaml_VALUE_TOKEN && | |
747 | token.typ != yaml_BLOCK_END_TOKEN { | |
748 | parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) | |
749 | return yaml_parser_parse_node(parser, event, true, true) | |
750 | } | |
751 | parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE | |
752 | return yaml_parser_process_empty_scalar(parser, event, mark) | |
753 | } | |
754 | parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE | |
755 | return yaml_parser_process_empty_scalar(parser, event, token.start_mark) | |
756 | } | |
757 | ||
758 | // Parse the productions: | |
759 | // flow_sequence ::= FLOW-SEQUENCE-START | |
760 | // ******************* | |
761 | // (flow_sequence_entry FLOW-ENTRY)* | |
762 | // * ********** | |
763 | // flow_sequence_entry? | |
764 | // * | |
765 | // FLOW-SEQUENCE-END | |
766 | // ***************** | |
767 | // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
768 | // * | |
769 | // | |
770 | func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { | |
771 | if first { | |
772 | token := peek_token(parser) | |
773 | parser.marks = append(parser.marks, token.start_mark) | |
774 | skip_token(parser) | |
775 | } | |
776 | token := peek_token(parser) | |
777 | if token == nil { | |
778 | return false | |
779 | } | |
780 | if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { | |
781 | if !first { | |
782 | if token.typ == yaml_FLOW_ENTRY_TOKEN { | |
783 | skip_token(parser) | |
784 | token = peek_token(parser) | |
785 | if token == nil { | |
786 | return false | |
787 | } | |
788 | } else { | |
789 | context_mark := parser.marks[len(parser.marks)-1] | |
790 | parser.marks = parser.marks[:len(parser.marks)-1] | |
791 | return yaml_parser_set_parser_error_context(parser, | |
792 | "while parsing a flow sequence", context_mark, | |
793 | "did not find expected ',' or ']'", token.start_mark) | |
794 | } | |
795 | } | |
796 | ||
797 | if token.typ == yaml_KEY_TOKEN { | |
798 | parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE | |
799 | *event = yaml_event_t{ | |
800 | typ: yaml_MAPPING_START_EVENT, | |
801 | start_mark: token.start_mark, | |
802 | end_mark: token.end_mark, | |
803 | implicit: true, | |
804 | style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), | |
805 | } | |
806 | skip_token(parser) | |
807 | return true | |
808 | } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { | |
809 | parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) | |
810 | return yaml_parser_parse_node(parser, event, false, false) | |
811 | } | |
812 | } | |
813 | ||
814 | parser.state = parser.states[len(parser.states)-1] | |
815 | parser.states = parser.states[:len(parser.states)-1] | |
816 | parser.marks = parser.marks[:len(parser.marks)-1] | |
817 | ||
818 | *event = yaml_event_t{ | |
819 | typ: yaml_SEQUENCE_END_EVENT, | |
820 | start_mark: token.start_mark, | |
821 | end_mark: token.end_mark, | |
822 | } | |
823 | ||
824 | skip_token(parser) | |
825 | return true | |
826 | } | |
827 | ||
828 | // | |
829 | // Parse the productions: | |
830 | // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
831 | // *** * | |
832 | // | |
833 | func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { | |
834 | token := peek_token(parser) | |
835 | if token == nil { | |
836 | return false | |
837 | } | |
838 | if token.typ != yaml_VALUE_TOKEN && | |
839 | token.typ != yaml_FLOW_ENTRY_TOKEN && | |
840 | token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { | |
841 | parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) | |
842 | return yaml_parser_parse_node(parser, event, false, false) | |
843 | } | |
844 | mark := token.end_mark | |
845 | skip_token(parser) | |
846 | parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE | |
847 | return yaml_parser_process_empty_scalar(parser, event, mark) | |
848 | } | |
849 | ||
850 | // Parse the productions: | |
851 | // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
852 | // ***** * | |
853 | // | |
854 | func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { | |
855 | token := peek_token(parser) | |
856 | if token == nil { | |
857 | return false | |
858 | } | |
859 | if token.typ == yaml_VALUE_TOKEN { | |
860 | skip_token(parser) | |
861 | token := peek_token(parser) | |
862 | if token == nil { | |
863 | return false | |
864 | } | |
865 | if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { | |
866 | parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) | |
867 | return yaml_parser_parse_node(parser, event, false, false) | |
868 | } | |
869 | } | |
870 | parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE | |
871 | return yaml_parser_process_empty_scalar(parser, event, token.start_mark) | |
872 | } | |
873 | ||
874 | // Parse the productions: | |
875 | // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
876 | // * | |
877 | // | |
878 | func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { | |
879 | token := peek_token(parser) | |
880 | if token == nil { | |
881 | return false | |
882 | } | |
883 | parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE | |
884 | *event = yaml_event_t{ | |
885 | typ: yaml_MAPPING_END_EVENT, | |
886 | start_mark: token.start_mark, | |
887 | end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? | |
888 | } | |
889 | return true | |
890 | } | |
891 | ||
892 | // Parse the productions: | |
893 | // flow_mapping ::= FLOW-MAPPING-START | |
894 | // ****************** | |
895 | // (flow_mapping_entry FLOW-ENTRY)* | |
896 | // * ********** | |
897 | // flow_mapping_entry? | |
898 | // ****************** | |
899 | // FLOW-MAPPING-END | |
900 | // **************** | |
901 | // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
902 | // * *** * | |
903 | // | |
904 | func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { | |
905 | if first { | |
906 | token := peek_token(parser) | |
907 | parser.marks = append(parser.marks, token.start_mark) | |
908 | skip_token(parser) | |
909 | } | |
910 | ||
911 | token := peek_token(parser) | |
912 | if token == nil { | |
913 | return false | |
914 | } | |
915 | ||
916 | if token.typ != yaml_FLOW_MAPPING_END_TOKEN { | |
917 | if !first { | |
918 | if token.typ == yaml_FLOW_ENTRY_TOKEN { | |
919 | skip_token(parser) | |
920 | token = peek_token(parser) | |
921 | if token == nil { | |
922 | return false | |
923 | } | |
924 | } else { | |
925 | context_mark := parser.marks[len(parser.marks)-1] | |
926 | parser.marks = parser.marks[:len(parser.marks)-1] | |
927 | return yaml_parser_set_parser_error_context(parser, | |
928 | "while parsing a flow mapping", context_mark, | |
929 | "did not find expected ',' or '}'", token.start_mark) | |
930 | } | |
931 | } | |
932 | ||
933 | if token.typ == yaml_KEY_TOKEN { | |
934 | skip_token(parser) | |
935 | token = peek_token(parser) | |
936 | if token == nil { | |
937 | return false | |
938 | } | |
939 | if token.typ != yaml_VALUE_TOKEN && | |
940 | token.typ != yaml_FLOW_ENTRY_TOKEN && | |
941 | token.typ != yaml_FLOW_MAPPING_END_TOKEN { | |
942 | parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) | |
943 | return yaml_parser_parse_node(parser, event, false, false) | |
944 | } else { | |
945 | parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE | |
946 | return yaml_parser_process_empty_scalar(parser, event, token.start_mark) | |
947 | } | |
948 | } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { | |
949 | parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) | |
950 | return yaml_parser_parse_node(parser, event, false, false) | |
951 | } | |
952 | } | |
953 | ||
954 | parser.state = parser.states[len(parser.states)-1] | |
955 | parser.states = parser.states[:len(parser.states)-1] | |
956 | parser.marks = parser.marks[:len(parser.marks)-1] | |
957 | *event = yaml_event_t{ | |
958 | typ: yaml_MAPPING_END_EVENT, | |
959 | start_mark: token.start_mark, | |
960 | end_mark: token.end_mark, | |
961 | } | |
962 | skip_token(parser) | |
963 | return true | |
964 | } | |
965 | ||
966 | // Parse the productions: | |
967 | // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? | |
968 | // * ***** * | |
969 | // | |
970 | func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { | |
971 | token := peek_token(parser) | |
972 | if token == nil { | |
973 | return false | |
974 | } | |
975 | if empty { | |
976 | parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE | |
977 | return yaml_parser_process_empty_scalar(parser, event, token.start_mark) | |
978 | } | |
979 | if token.typ == yaml_VALUE_TOKEN { | |
980 | skip_token(parser) | |
981 | token = peek_token(parser) | |
982 | if token == nil { | |
983 | return false | |
984 | } | |
985 | if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { | |
986 | parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) | |
987 | return yaml_parser_parse_node(parser, event, false, false) | |
988 | } | |
989 | } | |
990 | parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE | |
991 | return yaml_parser_process_empty_scalar(parser, event, token.start_mark) | |
992 | } | |
993 | ||
994 | // Generate an empty scalar event. | |
995 | func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { | |
996 | *event = yaml_event_t{ | |
997 | typ: yaml_SCALAR_EVENT, | |
998 | start_mark: mark, | |
999 | end_mark: mark, | |
1000 | value: nil, // Empty | |
1001 | implicit: true, | |
1002 | style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), | |
1003 | } | |
1004 | return true | |
1005 | } | |
1006 | ||
1007 | var default_tag_directives = []yaml_tag_directive_t{ | |
1008 | {[]byte("!"), []byte("!")}, | |
1009 | {[]byte("!!"), []byte("tag:yaml.org,2002:")}, | |
1010 | } | |
1011 | ||
1012 | // Parse directives. | |
1013 | func yaml_parser_process_directives(parser *yaml_parser_t, | |
1014 | version_directive_ref **yaml_version_directive_t, | |
1015 | tag_directives_ref *[]yaml_tag_directive_t) bool { | |
1016 | ||
1017 | var version_directive *yaml_version_directive_t | |
1018 | var tag_directives []yaml_tag_directive_t | |
1019 | ||
1020 | token := peek_token(parser) | |
1021 | if token == nil { | |
1022 | return false | |
1023 | } | |
1024 | ||
1025 | for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { | |
1026 | if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { | |
1027 | if version_directive != nil { | |
1028 | yaml_parser_set_parser_error(parser, | |
1029 | "found duplicate %YAML directive", token.start_mark) | |
1030 | return false | |
1031 | } | |
1032 | if token.major != 1 || token.minor != 1 { | |
1033 | yaml_parser_set_parser_error(parser, | |
1034 | "found incompatible YAML document", token.start_mark) | |
1035 | return false | |
1036 | } | |
1037 | version_directive = &yaml_version_directive_t{ | |
1038 | major: token.major, | |
1039 | minor: token.minor, | |
1040 | } | |
1041 | } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { | |
1042 | value := yaml_tag_directive_t{ | |
1043 | handle: token.value, | |
1044 | prefix: token.prefix, | |
1045 | } | |
1046 | if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { | |
1047 | return false | |
1048 | } | |
1049 | tag_directives = append(tag_directives, value) | |
1050 | } | |
1051 | ||
1052 | skip_token(parser) | |
1053 | token = peek_token(parser) | |
1054 | if token == nil { | |
1055 | return false | |
1056 | } | |
1057 | } | |
1058 | ||
1059 | for i := range default_tag_directives { | |
1060 | if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { | |
1061 | return false | |
1062 | } | |
1063 | } | |
1064 | ||
1065 | if version_directive_ref != nil { | |
1066 | *version_directive_ref = version_directive | |
1067 | } | |
1068 | if tag_directives_ref != nil { | |
1069 | *tag_directives_ref = tag_directives | |
1070 | } | |
1071 | return true | |
1072 | } | |
1073 | ||
1074 | // Append a tag directive to the directives stack. | |
1075 | func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { | |
1076 | for i := range parser.tag_directives { | |
1077 | if bytes.Equal(value.handle, parser.tag_directives[i].handle) { | |
1078 | if allow_duplicates { | |
1079 | return true | |
1080 | } | |
1081 | return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) | |
1082 | } | |
1083 | } | |
1084 | ||
1085 | // [Go] I suspect the copy is unnecessary. This was likely done | |
1086 | // because there was no way to track ownership of the data. | |
1087 | value_copy := yaml_tag_directive_t{ | |
1088 | handle: make([]byte, len(value.handle)), | |
1089 | prefix: make([]byte, len(value.prefix)), | |
1090 | } | |
1091 | copy(value_copy.handle, value.handle) | |
1092 | copy(value_copy.prefix, value.prefix) | |
1093 | parser.tag_directives = append(parser.tag_directives, value_copy) | |
1094 | return true | |
1095 | } |