]> andersk Git - libyaml.git/blame - src/parser.c
Complete the Parser (it requires refactoring though) and fix some bugs.
[libyaml.git] / src / parser.c
CommitLineData
1eb01be7
KS
1
2/*
3 * The parser implements the following grammar:
4 *
5 * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
6 * implicit_document ::= block_node DOCUMENT-END*
7 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8 * block_node_or_indentless_sequence ::=
9 * ALIAS
10 * | properties (block_content | indentless_block_sequence)?
11 * | block_content
12 * | indentless_block_sequence
13 * block_node ::= ALIAS
14 * | properties block_content?
15 * | block_content
16 * flow_node ::= ALIAS
17 * | properties flow_content?
18 * | flow_content
19 * properties ::= TAG ANCHOR? | ANCHOR TAG?
20 * block_content ::= block_collection | flow_collection | SCALAR
21 * flow_content ::= flow_collection | SCALAR
22 * block_collection ::= block_sequence | block_mapping
23 * flow_collection ::= flow_sequence | flow_mapping
24 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
26 * block_mapping ::= BLOCK-MAPPING_START
27 * ((KEY block_node_or_indentless_sequence?)?
28 * (VALUE block_node_or_indentless_sequence?)?)*
29 * BLOCK-END
30 * flow_sequence ::= FLOW-SEQUENCE-START
31 * (flow_sequence_entry FLOW-ENTRY)*
32 * flow_sequence_entry?
33 * FLOW-SEQUENCE-END
34 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35 * flow_mapping ::= FLOW-MAPPING-START
36 * (flow_mapping_entry FLOW-ENTRY)*
37 * flow_mapping_entry?
38 * FLOW-MAPPING-END
39 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40 */
41
42#if HAVE_CONFIG_H
43#include <config.h>
44#endif
45
46#include <yaml.h>
47
48#include <assert.h>
49
50/*
51 * Public API declarations.
52 */
53
54YAML_DECLARE(yaml_event_t *)
55yaml_parser_get_event(yaml_parser_t *parser);
56
57YAML_DECLARE(yaml_event_t *)
58yaml_parser_peek_event(yaml_parser_t *parser);
59
52fba2c6
KS
60/*
61 * Error handling.
62 */
63
64static int
65yaml_parser_set_parser_error(yaml_parser_t *parser,
66 const char *problem, yaml_mark_t problem_mark);
67
68static int
69yaml_parser_set_parser_error_context(yaml_parser_t *parser,
70 const char *context, yaml_mark_t context_mark,
71 const char *problem, yaml_mark_t problem_mark);
72
73/*
74 * Buffers and lists.
75 */
76
77static int
78yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
79 size_t item_size);
80
ab01bac8
KS
81static int
82yaml_parser_append_tag_directive(yaml_parser_t *parser,
83 yaml_tag_directive_t *tag_directive);
84
52fba2c6
KS
85static int
86yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state);
87
88static int
89yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark);
90
1eb01be7
KS
91/*
92 * State functions.
93 */
94
95static yaml_event_t *
96yaml_parser_state_machine(yaml_parser_t *parser);
97
98static yaml_event_t *
99yaml_parser_parse_stream_start(yaml_parser_t *parser);
100
101static yaml_event_t *
102yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit);
103
104static yaml_event_t *
105yaml_parser_parse_document_content(yaml_parser_t *parser);
106
107static yaml_event_t *
108yaml_parser_parse_document_end(yaml_parser_t *parser);
109
110static yaml_event_t *
111yaml_parser_parse_node(yaml_parser_t *parser,
112 int block, int indentless_sequence);
113
114static yaml_event_t *
115yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first);
116
117static yaml_event_t *
118yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser);
119
120static yaml_event_t *
121yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first);
122
123static yaml_event_t *
124yaml_parser_parse_block_mapping_value(yaml_parser_t *parser);
125
126static yaml_event_t *
127yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first);
128
129static yaml_event_t *
130yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser);
131
132static yaml_event_t *
133yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser);
134
135static yaml_event_t *
136yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser);
137
138static yaml_event_t *
139yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first);
140
141static yaml_event_t *
142yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty);
143
52fba2c6
KS
144/*
145 * Utility functions.
146 */
147
148static yaml_event_t *
149yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark);
150
151static int
152yaml_parser_process_directives(yaml_parser_t *parser);
153
1eb01be7
KS
154/*
155 * Get the next event and advance the parser.
156 */
157
158YAML_DECLARE(yaml_event_t *)
159yaml_parser_get_event(yaml_parser_t *parser)
160{
161 yaml_event_t *value;
162
163 /* Update the current event if needed. */
164
165 if (!parser->current_event) {
166 parser->current_event = yaml_parser_state_machine(parser);
167 }
168
169 /* Return and clear the current event. */
170
171 value = parser->current_event;
172 parser->current_event = NULL;
173 return value;
174}
175
176/*
177 * Peek the next event.
178 */
179
180YAML_DECLARE(yaml_event_t *)
181yaml_parser_peek_event(yaml_parser_t *parser)
182{
183 yaml_event_t *value;
184
185 /* Update the current event if needed. */
186
187 if (!parser->current_event) {
188 parser->current_event = yaml_parser_state_machine(parser);
189 }
190
191 /* Return the current event. */
192
193 return parser->current_event;
194}
195
52fba2c6
KS
196/*
197 * Set parser error.
198 */
199
200static int
201yaml_parser_set_parser_error(yaml_parser_t *parser,
202 const char *problem, yaml_mark_t problem_mark)
203{
204 parser->error = YAML_PARSER_ERROR;
205 parser->problem = problem;
206 parser->problem_mark = problem_mark;
207
208 return 0;
209}
210
211static int
212yaml_parser_set_parser_error_context(yaml_parser_t *parser,
213 const char *context, yaml_mark_t context_mark,
214 const char *problem, yaml_mark_t problem_mark)
215{
216 parser->error = YAML_PARSER_ERROR;
217 parser->context = context;
218 parser->context_mark = context_mark;
219 parser->problem = problem;
220 parser->problem_mark = problem_mark;
221
222 return 0;
223}
224
ab01bac8
KS
225/*
226 * Double a list.
227 */
228
229static int
230yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
231 size_t item_size)
232{
233 void *new_buffer = yaml_realloc(*buffer, item_size*(*size)*2);
234
235 if (!new_buffer) {
236 parser->error = YAML_MEMORY_ERROR;
237 return 0;
238 }
239
240 memset(new_buffer+item_size*(*size), 0, item_size*(*size));
241
242 *buffer = new_buffer;
243 *size *= 2;
244
245 return 1;
246}
247
248/*
249 * Push a tag directive to the directive list.
250 */
251
252static int
253yaml_parser_append_tag_directive(yaml_parser_t *parser,
254 yaml_tag_directive_t *tag_directive)
255{
256 if (parser->tag_directives_length == parser->tag_directives_size-1) {
257 if (!yaml_parser_resize_list(parser, (void **)&parser->tag_directives,
258 &parser->tag_directives_size, sizeof(yaml_tag_directive_t)))
259 return 0;
260 }
261
262 parser->tag_directives[parser->tag_directives_length++] = tag_directive;
263 parser->tag_directives[parser->tag_directives_length] = NULL;
264 return 1;
265}
266
52fba2c6
KS
267/*
268 * Push a state to the state stack.
269 */
270
271static int
272yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state)
273{
274 if (parser->states_length == parser->states_size-1) {
275 if (!yaml_parser_resize_list(parser, (void **)&parser->states,
276 &parser->states_size, sizeof(yaml_parser_state_t)))
277 return 0;
278 }
279
280 parser->states[parser->states_length++] = state;
281 return 1;
282}
283
284/*
285 * Push a mark to the mark stack.
286 */
287
288static int
289yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark)
290{
291 if (parser->marks_length == parser->marks_size-1) {
292 if (!yaml_parser_resize_list(parser, (void **)&parser->marks,
293 &parser->marks_size, sizeof(yaml_mark_t)))
294 return 0;
295 }
296
297 parser->marks[parser->marks_length++] = mark;
298 return 1;
299}
300
1eb01be7
KS
301/*
302 * State dispatcher.
303 */
304
305static yaml_event_t *
306yaml_parser_state_machine(yaml_parser_t *parser)
307{
308 assert (parser->state != YAML_PARSE_END_STATE);
309
310 switch (parser->state)
311 {
312 case YAML_PARSE_STREAM_START_STATE:
313 return yaml_parser_parse_stream_start(parser);
314
315 case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
316 return yaml_parser_parse_document_start(parser, 1);
317
318 case YAML_PARSE_DOCUMENT_START_STATE:
319 return yaml_parser_parse_document_start(parser, 0);
320
321 case YAML_PARSE_DOCUMENT_CONTENT_STATE:
322 return yaml_parser_parse_document_content(parser);
323
324 case YAML_PARSE_DOCUMENT_END_STATE:
325 return yaml_parser_parse_document_end(parser);
326
327 case YAML_PARSE_BLOCK_NODE_STATE:
328 return yaml_parser_parse_node(parser, 1, 0);
329
330 case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
331 return yaml_parser_parse_node(parser, 1, 1);
332
333 case YAML_PARSE_FLOW_NODE_STATE:
334 return yaml_parser_parse_node(parser, 0, 0);
335
336 case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
337 return yaml_parser_parse_block_sequence_entry(parser, 1);
338
339 case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
340 return yaml_parser_parse_block_sequence_entry(parser, 0);
341
342 case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
343 return yaml_parser_parse_indentless_sequence_entry(parser);
344
345 case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
346 return yaml_parser_parse_block_mapping_key(parser, 1);
347
348 case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
349 return yaml_parser_parse_block_mapping_key(parser, 0);
350
351 case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
352 return yaml_parser_parse_block_mapping_value(parser);
353
354 case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
355 return yaml_parser_parse_flow_sequence_entry(parser, 1);
356
357 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
358 return yaml_parser_parse_flow_sequence_entry(parser, 0);
359
360 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
361 return yaml_parser_parse_flow_sequence_entry_mapping_key(parser);
362
363 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
364 return yaml_parser_parse_flow_sequence_entry_mapping_value(parser);
365
366 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
367 return yaml_parser_parse_flow_sequence_entry_mapping_end(parser);
368
369 case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
370 return yaml_parser_parse_flow_mapping_key(parser, 1);
371
372 case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
373 return yaml_parser_parse_flow_mapping_key(parser, 0);
374
375 case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
376 return yaml_parser_parse_flow_mapping_value(parser, 0);
377
378 case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
379 return yaml_parser_parse_flow_mapping_value(parser, 1);
380 }
381 assert(1);
382}
383
52fba2c6
KS
384/*
385 * Parse the production:
386 * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
387 * ************
388 */
389
390static yaml_event_t *
391yaml_parser_parse_stream_start(yaml_parser_t *parser)
392{
393 yaml_token_t *token;
394 yaml_event_t *event;
395
396 token = yaml_parser_get_token(parser);
397 if (!token) return NULL;
398
399 assert(token->type == YAML_STREAM_START_TOKEN);
400
401 event = yaml_stream_start_event_new(token->data.stream_start.encoding,
402 token->start_mark, token->start_mark);
403 yaml_token_delete(token);
404 if (!event) {
405 parser->error = YAML_MEMORY_ERROR;
406 return NULL;
407 }
408
409 parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
410
411 return event;
412}
413
414/*
415 * Parse the productions:
416 * implicit_document ::= block_node DOCUMENT-END*
417 * *
418 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
419 * *************************
420 */
421
422static yaml_event_t *
423yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit)
424{
425 yaml_token_t *token;
426 yaml_event_t *event;
427
428 token = yaml_parser_peek_token(parser);
429 if (!token) return NULL;
430
431 /* Parse an implicit document. */
432
433 if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
434 token->type != YAML_TAG_DIRECTIVE_TOKEN &&
435 token->type != YAML_DOCUMENT_START_TOKEN &&
436 token->type != YAML_STREAM_END_TOKEN)
437 {
438 if (!yaml_parser_process_directives(parser)) return NULL;
439 if (!yaml_parser_append_state(parser, YAML_PARSE_DOCUMENT_END_STATE))
440 return NULL;
441 parser->state = YAML_PARSE_BLOCK_NODE_STATE;
442 event = yaml_document_start_event_new(
443 parser->version_directive, parser->tag_directives, 1,
444 token->start_mark, token->start_mark);
ab01bac8
KS
445 if (!event) {
446 parser->error = YAML_MEMORY_ERROR;
447 return NULL;
448 }
52fba2c6
KS
449 return event;
450 }
451
452 /* Parse an explicit document. */
453
454 else if (token->type != YAML_STREAM_END_TOKEN)
455 {
456 yaml_mark_t start_mark, end_mark;
457 start_mark = token->start_mark;
458 if (!yaml_parser_process_directives(parser)) return NULL;
459 token = yaml_parser_peek_token(parser);
460 if (!token) return NULL;
461 if (token->type != YAML_DOCUMENT_START_TOKEN) {
462 yaml_parser_set_parser_error(parser,
463 "did not found expected <document start>", token->start_mark);
464 return NULL;
465 }
466 token = yaml_parser_get_token(parser);
467 end_mark = token->end_mark;
468 yaml_token_delete(token);
469 if (!yaml_parser_append_state(parser, YAML_PARSE_DOCUMENT_END_STATE))
470 return NULL;
471 parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
472 event = yaml_document_start_event_new(
473 parser->version_directive, parser->tag_directives, 0,
474 start_mark, end_mark);
ab01bac8
KS
475 if (!event) {
476 parser->error = YAML_MEMORY_ERROR;
477 return NULL;
478 }
52fba2c6
KS
479 return event;
480 }
481
482 /* Parse the stream end. */
483
484 else
485 {
486 token = yaml_parser_get_token(parser);
487 parser->state = YAML_PARSE_END_STATE;
488 event = yaml_stream_end_event_new(token->start_mark, token->end_mark);
489 yaml_token_delete(token);
ab01bac8
KS
490 if (!event) {
491 parser->error = YAML_MEMORY_ERROR;
492 return NULL;
493 }
52fba2c6
KS
494 return event;
495 }
496}
497
498/*
499 * Parse the productions:
500 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
501 * ***********
502 */
503
504static yaml_event_t *
505yaml_parser_parse_document_content(yaml_parser_t *parser)
506{
507 yaml_token_t *token;
508
509 token = yaml_parser_peek_token(parser);
510 if (!token) return NULL;
511
512 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
513 token->type == YAML_TAG_DIRECTIVE_TOKEN ||
514 token->type == YAML_DOCUMENT_START_TOKEN ||
515 token->type == YAML_DOCUMENT_END_TOKEN ||
516 token->type == YAML_STREAM_END_TOKEN) {
517 parser->state = parser->states[--parser->states_length];
518 return yaml_parser_process_empty_scalar(parser, token->start_mark);
519 }
520 else {
521 return yaml_parser_parse_node(parser, 1, 0);
522 }
523}
524
525/*
526 * Parse the productions:
527 * implicit_document ::= block_node DOCUMENT-END*
528 * *************
529 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
530 * *************
531 */
532
533static yaml_event_t *
534yaml_parser_parse_document_end(yaml_parser_t *parser)
535{
536 yaml_token_t *token;
537 yaml_event_t *event;
538 yaml_mark_t start_mark, end_mark;
539 int implicit = 1;
540
541 token = yaml_parser_peek_token(parser);
542 if (!token) return NULL;
543
544 start_mark = end_mark = token->start_mark;
545
546 while (token->type == YAML_DOCUMENT_END_TOKEN) {
547 end_mark = token->end_mark;
548 yaml_token_delete(yaml_parser_get_token(parser));
549 token = yaml_parser_peek_token(parser);
550 if (!token) return NULL;
551 implicit = 0;
552 }
553
ab01bac8
KS
554 parser->version_directive = NULL;
555 parser->tag_directives = NULL;
556 parser->tag_directives = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
557 if (!parser->tag_directives) {
558 parser->error = YAML_MEMORY_ERROR;
559 return NULL;
560 }
561 memset(parser->tag_directives, 0, YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
562 parser->tag_directives_size = YAML_DEFAULT_SIZE;
563 parser->tag_directives_length = 0;
564
565
566
52fba2c6
KS
567 event = yaml_document_end_event_new(implicit, start_mark, end_mark);
568 if (!event) {
569 parser->error = YAML_MEMORY_ERROR;
570 return NULL;
571 }
ab01bac8
KS
572 parser->state = YAML_PARSE_DOCUMENT_START_STATE;
573
52fba2c6
KS
574 return event;
575}
576
577/*
578 * Parse the productions:
579 * block_node_or_indentless_sequence ::=
580 * ALIAS
581 * *****
582 * | properties (block_content | indentless_block_sequence)?
583 * ********** *
584 * | block_content | indentless_block_sequence
585 * *
586 * block_node ::= ALIAS
587 * *****
588 * | properties block_content?
589 * ********** *
590 * | block_content
591 * *
592 * flow_node ::= ALIAS
593 * *****
594 * | properties flow_content?
595 * ********** *
596 * | flow_content
597 * *
598 * properties ::= TAG ANCHOR? | ANCHOR TAG?
599 * *************************
600 * block_content ::= block_collection | flow_collection | SCALAR
601 * ******
602 * flow_content ::= flow_collection | SCALAR
603 * ******
604 */
605
606static yaml_event_t *
607yaml_parser_parse_node(yaml_parser_t *parser,
608 int block, int indentless_sequence)
609{
610 yaml_token_t *token;
611 yaml_event_t *event;
612 yaml_char_t *anchor = NULL;
613 yaml_char_t *tag_handle = NULL;
614 yaml_char_t *tag_suffix = NULL;
615 yaml_char_t *tag = NULL;
616 yaml_mark_t start_mark, end_mark, tag_mark;
617 int implicit;
618
619 token = yaml_parser_peek_token(parser);
620 if (!token) return NULL;
621
622 if (token->type == YAML_ALIAS_TOKEN)
623 {
ab01bac8 624 parser->state = parser->states[--parser->states_length];
52fba2c6
KS
625 token = yaml_parser_get_token(parser);
626 event = yaml_alias_event_new(token->data.alias.value,
627 token->start_mark, token->end_mark);
628 if (!event) {
629 yaml_token_delete(token);
630 parser->error = YAML_MEMORY_ERROR;
631 return NULL;
632 }
633 yaml_free(token);
634 return event;
635 }
636
637 else
638 {
639 start_mark = end_mark = token->start_mark;
640
641 if (token->type == YAML_ANCHOR_TOKEN)
642 {
643 token = yaml_parser_get_token(parser);
644 anchor = token->data.anchor.value;
645 start_mark = token->start_mark;
646 end_mark = token->end_mark;
647 yaml_free(token);
648 token = yaml_parser_peek_token(parser);
649 if (!token) goto error;
650 if (token->type == YAML_TAG_TOKEN)
651 {
652 token = yaml_parser_get_token(parser);
653 tag_handle = token->data.tag.handle;
654 tag_suffix = token->data.tag.suffix;
655 tag_mark = token->start_mark;
656 end_mark = token->end_mark;
657 yaml_free(token);
658 token = yaml_parser_peek_token(parser);
659 if (!token) goto error;
660 }
661 }
662 else if (token->type == YAML_TAG_TOKEN)
663 {
664 token = yaml_parser_get_token(parser);
665 tag_handle = token->data.tag.handle;
666 tag_suffix = token->data.tag.suffix;
667 start_mark = tag_mark = token->start_mark;
668 end_mark = token->end_mark;
669 yaml_free(token);
670 token = yaml_parser_peek_token(parser);
671 if (!token) goto error;
672 if (token->type == YAML_ANCHOR_TOKEN)
673 {
674 token = yaml_parser_get_token(parser);
675 anchor = token->data.anchor.value;
676 end_mark = token->end_mark;
677 yaml_free(token);
678 token = yaml_parser_peek_token(parser);
679 if (!token) goto error;
680 }
681 }
682
683 if (tag_handle) {
684 if (!*tag_handle) {
685 tag = tag_suffix;
686 yaml_free(tag_handle);
687 tag_handle = tag_suffix = NULL;
688 }
689 else {
690 yaml_tag_directive_t **tag_directive = parser->tag_directives;
691 for (tag_directive = parser->tag_directives;
692 *tag_directive; tag_directive++) {
693 if (strcmp((char *)(*tag_directive)->handle, (char *)tag_handle) == 0) {
694 size_t prefix_len = strlen((char *)(*tag_directive)->prefix);
695 size_t suffix_len = strlen((char *)tag_suffix);
696 tag = yaml_malloc(prefix_len+suffix_len+1);
697 if (!tag) {
698 parser->error = YAML_MEMORY_ERROR;
699 goto error;
700 }
ab01bac8 701 memcpy(tag, (*tag_directive)->prefix, prefix_len);
52fba2c6
KS
702 memcpy(tag+prefix_len, tag_suffix, suffix_len);
703 tag[prefix_len+suffix_len] = '\0';
704 yaml_free(tag_handle);
705 yaml_free(tag_suffix);
706 tag_handle = tag_suffix = NULL;
707 break;
708 }
709 }
ab01bac8 710 if (!*tag_directive) {
52fba2c6
KS
711 yaml_parser_set_parser_error_context(parser,
712 "while parsing a node", start_mark,
713 "found undefined tag handle", tag_mark);
714 goto error;
715 }
716 }
717 }
718
719 implicit = (!tag || !*tag);
720 if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
721 end_mark = token->end_mark;
722 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
723 event = yaml_sequence_start_event_new(anchor, tag, implicit,
724 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
725 if (!event) goto error;
ab01bac8 726 return event;
52fba2c6
KS
727 }
728 else {
729 if (token->type == YAML_SCALAR_TOKEN) {
730 int plain_implicit = 0;
731 int quoted_implicit = 0;
732 token = yaml_parser_get_token(parser);
733 end_mark = token->end_mark;
734 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
ab01bac8 735 || (tag && strcmp((char *)tag, "!") == 0)) {
52fba2c6
KS
736 plain_implicit = 1;
737 }
738 else if (!tag) {
739 quoted_implicit = 1;
740 }
741 parser->state = parser->states[--parser->states_length];
742 event = yaml_scalar_event_new(anchor, tag,
743 token->data.scalar.value, token->data.scalar.length,
744 plain_implicit, quoted_implicit,
745 token->data.scalar.style, start_mark, end_mark);
746 if (!event) {
747 parser->error = YAML_MEMORY_ERROR;
748 yaml_token_delete(token);
749 goto error;
750 }
751 yaml_free(token);
752 }
753 else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
754 end_mark = token->end_mark;
755 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
756 event = yaml_sequence_start_event_new(anchor, tag, implicit,
757 YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
758 if (!event) {
759 parser->error = YAML_MEMORY_ERROR;
760 goto error;
761 }
762 }
763 else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
764 end_mark = token->end_mark;
765 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
766 event = yaml_mapping_start_event_new(anchor, tag, implicit,
767 YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
768 if (!event) {
769 parser->error = YAML_MEMORY_ERROR;
770 goto error;
771 }
772 }
773 else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
774 end_mark = token->end_mark;
775 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
776 event = yaml_sequence_start_event_new(anchor, tag, implicit,
777 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
778 if (!event) {
779 parser->error = YAML_MEMORY_ERROR;
780 goto error;
781 }
782 }
783 else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
784 end_mark = token->end_mark;
785 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
786 event = yaml_mapping_start_event_new(anchor, tag, implicit,
787 YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
788 if (!event) {
789 parser->error = YAML_MEMORY_ERROR;
790 goto error;
791 }
792 }
793 else if (anchor || tag) {
794 yaml_char_t *value = yaml_malloc(1);
795 if (!value) {
796 parser->error = YAML_MEMORY_ERROR;
797 goto error;
798 }
799 value[0] = '\0';
ab01bac8 800 parser->state = parser->states[--parser->states_length];
52fba2c6
KS
801 event = yaml_scalar_event_new(anchor, tag, value, 0,
802 implicit, 0, YAML_PLAIN_SCALAR_STYLE,
803 start_mark, end_mark);
804 if (!event) {
805 yaml_free(value);
806 parser->error = YAML_MEMORY_ERROR;
807 goto error;
808 }
809 }
810 else {
811 yaml_parser_set_parser_error_context(parser,
812 (block ? "while parsing a block node"
813 : "while parsing a flow node"), start_mark,
814 "did not found expected node content", token->start_mark);
815 goto error;
816 }
817 return event;
818 }
819 }
820
821error:
822 yaml_free(anchor);
823 yaml_free(tag_handle);
824 yaml_free(tag_suffix);
825 yaml_free(tag);
826
827 return NULL;
828}
829
830/*
831 * Parse the productions:
832 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
833 * ******************** *********** * *********
834 */
835
836static yaml_event_t *
837yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first)
838{
839 yaml_token_t *token;
840 yaml_event_t *event;
841
842 if (first) {
843 token = yaml_parser_get_token(parser);
844 if (!yaml_parser_append_mark(parser, token->start_mark)) {
845 yaml_token_delete(token);
846 return NULL;
847 }
848 yaml_token_delete(token);
849 }
850
851 token = yaml_parser_get_token(parser);
852 if (!token) return NULL;
853
854 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
855 {
856 yaml_mark_t mark = token->end_mark;
857 yaml_token_delete(token);
858 token = yaml_parser_peek_token(parser);
859 if (!token) return NULL;
860 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
861 token->type != YAML_BLOCK_END_TOKEN) {
862 if (!yaml_parser_append_state(parser,
863 YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
864 return NULL;
865 return yaml_parser_parse_node(parser, 1, 0);
866 }
867 else {
868 parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
869 return yaml_parser_process_empty_scalar(parser, mark);
870 }
871 }
872
873 else if (token->type == YAML_BLOCK_END_TOKEN)
874 {
875 parser->state = parser->states[--parser->states_length];
ab01bac8 876 parser->marks_length --;
52fba2c6
KS
877 event = yaml_sequence_end_event_new(token->start_mark, token->end_mark);
878 yaml_token_delete(token);
879 if (!event) {
880 parser->error = YAML_MEMORY_ERROR;
881 return NULL;
882 }
883 return event;
884 }
885
886 else
887 {
888 yaml_parser_set_parser_error_context(parser,
889 "while parsing a block collection", parser->marks[parser->marks_length-1],
890 "did not found expected '-' indicator", token->start_mark);
891 yaml_token_delete(token);
892 return NULL;
893 }
894}
895
896/*
897 * Parse the productions:
898 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
899 * *********** *
900 */
901
902static yaml_event_t *
903yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser)
904{
905 yaml_token_t *token;
906 yaml_event_t *event;
907
908 token = yaml_parser_peek_token(parser);
909 if (!token) return NULL;
910
911 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
912 {
913 yaml_mark_t mark = token->end_mark;
914 yaml_token_delete(yaml_parser_get_token(parser));
915 token = yaml_parser_peek_token(parser);
916 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
917 token->type != YAML_BLOCK_END_TOKEN) {
918 if (!yaml_parser_append_state(parser,
919 YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
920 return NULL;
921 return yaml_parser_parse_node(parser, 1, 0);
922 }
923 else {
924 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
925 return yaml_parser_process_empty_scalar(parser, mark);
926 }
927 }
928
929 else
930 {
931 parser->state = parser->states[--parser->states_length];
932 event = yaml_sequence_end_event_new(token->start_mark, token->start_mark);
933 if (!event) {
934 parser->error = YAML_MEMORY_ERROR;
935 return NULL;
936 }
937 return event;
938 }
939}
940
941/*
942 * Parse the productions:
943 * block_mapping ::= BLOCK-MAPPING_START
944 * *******************
945 * ((KEY block_node_or_indentless_sequence?)?
946 * *** *
947 * (VALUE block_node_or_indentless_sequence?)?)*
948 *
949 * BLOCK-END
950 * *********
951 */
952
953static yaml_event_t *
954yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first)
955{
956 yaml_token_t *token;
957 yaml_event_t *event;
958
959 if (first) {
960 token = yaml_parser_get_token(parser);
961 if (!yaml_parser_append_mark(parser, token->start_mark)) {
962 yaml_token_delete(token);
963 return NULL;
964 }
965 yaml_token_delete(token);
966 }
967
968 token = yaml_parser_get_token(parser);
969 if (!token) return NULL;
970
971 if (token->type == YAML_KEY_TOKEN)
972 {
973 yaml_mark_t mark = token->end_mark;
974 yaml_token_delete(token);
975 token = yaml_parser_peek_token(parser);
976 if (!token) return NULL;
977 if (token->type != YAML_KEY_TOKEN &&
978 token->type != YAML_VALUE_TOKEN &&
979 token->type != YAML_BLOCK_END_TOKEN) {
980 if (!yaml_parser_append_state(parser,
981 YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
982 return NULL;
983 return yaml_parser_parse_node(parser, 1, 1);
984 }
985 else {
986 parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
987 return yaml_parser_process_empty_scalar(parser, mark);
988 }
989 }
990
991 else if (token->type == YAML_BLOCK_END_TOKEN)
992 {
993 parser->state = parser->states[--parser->states_length];
ab01bac8
KS
994 parser->marks_length --;
995 event = yaml_mapping_end_event_new(token->start_mark, token->end_mark);
52fba2c6
KS
996 yaml_token_delete(token);
997 if (!event) {
998 parser->error = YAML_MEMORY_ERROR;
999 return NULL;
1000 }
1001 return event;
1002 }
1003
1004 else
1005 {
1006 yaml_parser_set_parser_error_context(parser,
1007 "while parsing a block mapping", parser->marks[parser->marks_length-1],
1008 "did not found expected key", token->start_mark);
1009 yaml_token_delete(token);
1010 return NULL;
1011 }
1012}
1013
1014/*
1015 * Parse the productions:
1016 * block_mapping ::= BLOCK-MAPPING_START
1017 *
1018 * ((KEY block_node_or_indentless_sequence?)?
1019 *
1020 * (VALUE block_node_or_indentless_sequence?)?)*
1021 * ***** *
1022 * BLOCK-END
1023 *
1024 */
1025
1026static yaml_event_t *
1027yaml_parser_parse_block_mapping_value(yaml_parser_t *parser)
1028{
1029 yaml_token_t *token;
1030 yaml_event_t *event;
1031
1032 token = yaml_parser_peek_token(parser);
1033 if (!token) return NULL;
1034
1035 if (token->type == YAML_VALUE_TOKEN)
1036 {
1037 yaml_mark_t mark = token->end_mark;
1038 yaml_token_delete(yaml_parser_get_token(parser));
1039 token = yaml_parser_peek_token(parser);
1040 if (!token) return NULL;
1041 if (token->type != YAML_KEY_TOKEN &&
1042 token->type != YAML_VALUE_TOKEN &&
1043 token->type != YAML_BLOCK_END_TOKEN) {
1044 if (!yaml_parser_append_state(parser,
1045 YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
1046 return NULL;
1047 return yaml_parser_parse_node(parser, 1, 1);
1048 }
1049 else {
1050 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
1051 return yaml_parser_process_empty_scalar(parser, mark);
1052 }
1053 }
1054
1055 else
1056 {
1057 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
1058 return yaml_parser_process_empty_scalar(parser, token->start_mark);
1059 }
1060}
1061
ab01bac8
KS
1062/*
1063 * Parse the productions:
1064 * flow_sequence ::= FLOW-SEQUENCE-START
1065 * *******************
1066 * (flow_sequence_entry FLOW-ENTRY)*
1067 * * **********
1068 * flow_sequence_entry?
1069 * *
1070 * FLOW-SEQUENCE-END
1071 * *****************
1072 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1073 * *
1074 */
1075
52fba2c6 1076static yaml_event_t *
ab01bac8
KS
1077yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first)
1078{
1079 yaml_token_t *token;
1080 yaml_event_t *event;
1081
1082 if (first) {
1083 token = yaml_parser_get_token(parser);
1084 if (!yaml_parser_append_mark(parser, token->start_mark)) {
1085 yaml_token_delete(token);
1086 return NULL;
1087 }
1088 yaml_token_delete(token);
1089 }
1090
1091 token = yaml_parser_peek_token(parser);
1092 if (!token) return NULL;
1093
1094 if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
1095 {
1096 if (!first) {
1097 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1098 yaml_token_delete(yaml_parser_get_token(parser));
1099 token = yaml_parser_peek_token(parser);
1100 if (!token) return NULL;
1101 }
1102 else {
1103 yaml_parser_set_parser_error_context(parser,
1104 "while parsing a flow sequence", parser->marks[parser->marks_length-1],
1105 "did not found expected ',' or ']'", token->start_mark);
1106 return NULL;
1107 }
1108 }
1109
1110 if (token->type == YAML_KEY_TOKEN) {
1111 token = yaml_parser_get_token(parser);
1112 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
1113 event = yaml_mapping_start_event_new(NULL, NULL,
1114 1, YAML_FLOW_MAPPING_STYLE,
1115 token->start_mark, token->end_mark);
1116 yaml_token_delete(token);
1117 return event;
1118 }
1119
1120 else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1121 if (!yaml_parser_append_state(parser,
1122 YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
1123 return NULL;
1124 return yaml_parser_parse_node(parser, 0, 0);
1125 }
1126 }
1127
1128 parser->state = parser->states[--parser->states_length];
1129 parser->marks_length --;
1130 token = yaml_parser_get_token(parser);
1131 event = yaml_sequence_end_event_new(token->start_mark, token->end_mark);
1132 yaml_token_delete(token);
1133 return event;
1134}
1135
1136/*
1137 * Parse the productions:
1138 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1139 * *** *
1140 */
52fba2c6
KS
1141
1142static yaml_event_t *
ab01bac8
KS
1143yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser)
1144{
1145 yaml_token_t *token;
1146 yaml_event_t *event;
1147
1148 token = yaml_parser_peek_token(parser);
1149 if (!token) return NULL;
1150
1151 if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1152 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1153 if (!yaml_parser_append_state(parser,
1154 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1155 return NULL;
1156 return yaml_parser_parse_node(parser, 0, 0);
1157 }
1158 else {
1159 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1160 event = yaml_parser_process_empty_scalar(parser, token->end_mark);
1161 yaml_token_delete(token);
1162 return event;
1163 }
1164}
1165
1166/*
1167 * Parse the productions:
1168 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1169 * ***** *
1170 */
52fba2c6
KS
1171
1172static yaml_event_t *
ab01bac8
KS
1173yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser)
1174{
1175 yaml_token_t *token;
1176
1177 token = yaml_parser_peek_token(parser);
1178 if (!token) return NULL;
1179
1180 if (token->type == YAML_VALUE_TOKEN) {
1181 yaml_token_delete(yaml_parser_get_token(parser));
1182 token = yaml_parser_peek_token(parser);
1183 if (!token) return NULL;
1184 if (token->type != YAML_FLOW_ENTRY_TOKEN
1185 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1186 if (!yaml_parser_append_state(parser,
1187 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1188 return NULL;
1189 return yaml_parser_parse_node(parser, 0, 0);
1190 }
1191 }
1192 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1193 return yaml_parser_process_empty_scalar(parser, token->start_mark);
1194}
1195
1196/*
1197 * Parse the productions:
1198 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1199 * *
1200 */
52fba2c6
KS
1201
1202static yaml_event_t *
ab01bac8
KS
1203yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser)
1204{
1205 yaml_token_t *token;
1206
1207 token = yaml_parser_peek_token(parser);
1208 if (!token) return NULL;
1209
1210 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1211
1212 return yaml_mapping_end_event_new(token->start_mark, token->start_mark);
1213}
1214
1215/*
1216 * Parse the productions:
1217 * flow_mapping ::= FLOW-MAPPING-START
1218 * ******************
1219 * (flow_mapping_entry FLOW-ENTRY)*
1220 * * **********
1221 * flow_mapping_entry?
1222 * ******************
1223 * FLOW-MAPPING-END
1224 * ****************
1225 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1226 * * *** *
1227 */
52fba2c6
KS
1228
1229static yaml_event_t *
ab01bac8
KS
1230yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first)
1231{
1232 yaml_token_t *token;
1233 yaml_event_t *event;
1234
1235 if (first) {
1236 token = yaml_parser_get_token(parser);
1237 if (!yaml_parser_append_mark(parser, token->start_mark)) {
1238 yaml_token_delete(token);
1239 return NULL;
1240 }
1241 yaml_token_delete(token);
1242 }
1243
1244 token = yaml_parser_peek_token(parser);
1245 if (!token) return;
1246
1247 if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1248 {
1249 if (!first) {
1250 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1251 yaml_token_delete(yaml_parser_get_token(parser));
1252 token = yaml_parser_peek_token(parser);
1253 if (!token) return;
1254 }
1255 else {
1256 yaml_parser_set_parser_error_context(parser,
1257 "while parsing a flow mapping", parser->marks[parser->marks_length-1],
1258 "did not found expected ',' or '}'", token->start_mark);
1259 return NULL;
1260 }
1261 }
1262
1263 if (token->type == YAML_KEY_TOKEN) {
1264 yaml_token_delete(yaml_parser_get_token(parser));
1265 token = yaml_parser_peek_token(parser);
1266 if (!token) return NULL;
1267 if (token->type != YAML_VALUE_TOKEN
1268 && token->type != YAML_FLOW_ENTRY_TOKEN
1269 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1270 if (!yaml_parser_append_state(parser,
1271 YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1272 return NULL;
1273 return yaml_parser_parse_node(parser, 0, 0);
1274 }
1275 else {
1276 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1277 return yaml_parser_process_empty_scalar(parser, token->start_mark);
1278 }
1279 }
1280 else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1281 if (!yaml_parser_append_state(parser,
1282 YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1283 return NULL;
1284 return yaml_parser_parse_node(parser, 0, 0);
1285 }
1286 }
1287
1288 parser->state = parser->states[--parser->states_length];
1289 parser->marks_length --;
1290 token = yaml_parser_get_token(parser);
1291 event = yaml_mapping_end_event_new(token->start_mark, token->end_mark);
1292 yaml_token_delete(token);
1293 return event;
1294}
1295
1296/*
1297 * Parse the productions:
1298 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1299 * * ***** *
1300 */
52fba2c6
KS
1301
1302static yaml_event_t *
ab01bac8
KS
1303yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty)
1304{
1305 yaml_token_t *token;
1306 yaml_event_t *event;
1307
1308 token = yaml_parser_peek_token(parser);
1309 if (!token) return;
1310
1311 if (empty) {
1312 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1313 return yaml_parser_process_empty_scalar(parser, token->start_mark);
1314 }
1315
1316 if (token->type == YAML_VALUE_TOKEN) {
1317 yaml_token_delete(yaml_parser_get_token(parser));
1318 token = yaml_parser_peek_token(parser);
1319 if (!token) return NULL;
1320 if (token->type != YAML_FLOW_ENTRY_TOKEN
1321 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1322 if (!yaml_parser_append_state(parser,
1323 YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1324 return NULL;
1325 return yaml_parser_parse_node(parser, 0, 0);
1326 }
1327 }
1328
1329 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1330 return yaml_parser_process_empty_scalar(parser, token->start_mark);
1331}
1332
1333/*
1334 * Generate an empty scalar event.
1335 */
1336
1337static yaml_event_t *
1338yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark)
1339{
1340 yaml_event_t *event;
1341 yaml_char_t *value;
1342
1343 value = yaml_malloc(1);
1344 if (!value) {
1345 parser->error = YAML_MEMORY_ERROR;
1346 return NULL;
1347 }
1348 value[0] = '\0';
1349
1350 event = yaml_scalar_event_new(NULL, NULL, value, 0,
1351 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1352 if (!event) {
1353 yaml_free(value);
1354 parser->error = YAML_MEMORY_ERROR;
1355 return NULL;
1356 }
1357
1358 return event;
1359}
1360
1361/*
1362 * Parse directives.
1363 */
1364
1365static int
1366yaml_parser_process_directives(yaml_parser_t *parser)
1367{
1368 yaml_tag_directive_t default_tag_directives[] = {
1369 {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1370 {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1371 {NULL, NULL}
1372 };
1373 yaml_tag_directive_t *ref;
1374 yaml_tag_directive_t *default_tag_directive;
1375 yaml_tag_directive_t **tag_directive;
1376 yaml_token_t *token;
1377
1378 token = yaml_parser_peek_token(parser);
1379 if (!token) return 0;
1380
1381 while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1382 token->type == YAML_TAG_DIRECTIVE_TOKEN)
1383 {
1384 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1385 if (parser->version_directive) {
1386 return yaml_parser_set_parser_error(parser,
1387 "found duplicate %YAML directive", token->start_mark);
1388 }
1389 if (token->data.version_directive.major != 1
1390 && token->data.version_directive.minor != 1) {
1391 return yaml_parser_set_parser_error(parser,
1392 "found incompatible YAML document", token->start_mark);
1393 }
1394 parser->version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1395 if (!parser->version_directive) {
1396 parser->error = YAML_MEMORY_ERROR;
1397 return 0;
1398 }
1399 parser->version_directive->major = token->data.version_directive.major;
1400 parser->version_directive->minor = token->data.version_directive.minor;
1401 }
1402
1403 else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1404 yaml_tag_directive_t value = {
1405 token->data.tag_directive.handle,
1406 token->data.tag_directive.prefix
1407 };
1408 for (tag_directive = parser->tag_directives;
1409 *tag_directive; tag_directive++) {
1410 if (strcmp((char *)value.handle,
1411 (char *)(*tag_directive)->handle) == 0) {
1412 return yaml_parser_set_parser_error(parser,
1413 "found duplicate %TAG directive", token->start_mark);
1414 }
1415 }
1416 ref = yaml_malloc(sizeof(yaml_tag_directive_t));
1417 if (!ref) {
1418 parser->error = YAML_MEMORY_ERROR;
1419 return 0;
1420 }
1421 *ref = value;
1422 if (!yaml_parser_append_tag_directive(parser, ref)) {
1423 yaml_free(ref);
1424 return 0;
1425 }
1426 }
1427 yaml_free(yaml_parser_get_token(parser));
1428 token = yaml_parser_peek_token(parser);
1429 if (!token) return 0;
1430 }
1431
1432 for (default_tag_directive = default_tag_directives;
1433 default_tag_directive->handle; default_tag_directive++) {
1434 int found = 0;
1435 for (tag_directive = parser->tag_directives;
1436 *tag_directive; tag_directive++) {
1437 if (strcmp((char *)default_tag_directive->handle,
1438 (char *)(*tag_directive)->handle) == 0) {
1439 found = 1;
1440 break;
1441 }
1442 }
1443 if (!found) {
1444 ref = yaml_malloc(sizeof(yaml_tag_directive_t));
1445 if (!ref) {
1446 parser->error = YAML_MEMORY_ERROR;
1447 return 0;
1448 }
1449 ref->handle = yaml_malloc(strlen((char *)default_tag_directive->handle)+1);
1450 if (!ref->handle) {
1451 yaml_free(ref);
1452 parser->error = YAML_MEMORY_ERROR;
1453 return 0;
1454 }
1455 ref->prefix = yaml_malloc(strlen((char *)default_tag_directive->prefix)+1);
1456 if (!ref->prefix) {
1457 yaml_free(ref->handle);
1458 yaml_free(ref);
1459 parser->error = YAML_MEMORY_ERROR;
1460 return 0;
1461 }
1462 memcpy(ref->handle, default_tag_directive->handle,
1463 strlen((char *)default_tag_directive->handle)+1);
1464 memcpy(ref->prefix, default_tag_directive->prefix,
1465 strlen((char *)default_tag_directive->prefix)+1);
1466 if (!yaml_parser_append_tag_directive(parser, ref)) {
1467 yaml_free(ref);
1468 return 0;
1469 }
1470 }
1471 }
1472 return 1;
1473}
52fba2c6 1474
This page took 0.66401 seconds and 5 git commands to generate.