Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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