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