]>
Commit | Line | Data |
---|---|---|
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 | ||
54 | YAML_DECLARE(yaml_event_t *) | |
55 | yaml_parser_get_event(yaml_parser_t *parser); | |
56 | ||
57 | YAML_DECLARE(yaml_event_t *) | |
58 | yaml_parser_peek_event(yaml_parser_t *parser); | |
59 | ||
52fba2c6 KS |
60 | /* |
61 | * Error handling. | |
62 | */ | |
63 | ||
64 | static int | |
65 | yaml_parser_set_parser_error(yaml_parser_t *parser, | |
66 | const char *problem, yaml_mark_t problem_mark); | |
67 | ||
68 | static int | |
69 | yaml_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 | ||
77 | static int | |
78 | yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size, | |
79 | size_t item_size); | |
80 | ||
ab01bac8 KS |
81 | static int |
82 | yaml_parser_append_tag_directive(yaml_parser_t *parser, | |
83 | yaml_tag_directive_t *tag_directive); | |
84 | ||
52fba2c6 KS |
85 | static int |
86 | yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state); | |
87 | ||
88 | static int | |
89 | yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark); | |
90 | ||
1eb01be7 KS |
91 | /* |
92 | * State functions. | |
93 | */ | |
94 | ||
95 | static yaml_event_t * | |
96 | yaml_parser_state_machine(yaml_parser_t *parser); | |
97 | ||
98 | static yaml_event_t * | |
99 | yaml_parser_parse_stream_start(yaml_parser_t *parser); | |
100 | ||
101 | static yaml_event_t * | |
102 | yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit); | |
103 | ||
104 | static yaml_event_t * | |
105 | yaml_parser_parse_document_content(yaml_parser_t *parser); | |
106 | ||
107 | static yaml_event_t * | |
108 | yaml_parser_parse_document_end(yaml_parser_t *parser); | |
109 | ||
110 | static yaml_event_t * | |
111 | yaml_parser_parse_node(yaml_parser_t *parser, | |
112 | int block, int indentless_sequence); | |
113 | ||
114 | static yaml_event_t * | |
115 | yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first); | |
116 | ||
117 | static yaml_event_t * | |
118 | yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser); | |
119 | ||
120 | static yaml_event_t * | |
121 | yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first); | |
122 | ||
123 | static yaml_event_t * | |
124 | yaml_parser_parse_block_mapping_value(yaml_parser_t *parser); | |
125 | ||
126 | static yaml_event_t * | |
127 | yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first); | |
128 | ||
129 | static yaml_event_t * | |
130 | yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser); | |
131 | ||
132 | static yaml_event_t * | |
133 | yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser); | |
134 | ||
135 | static yaml_event_t * | |
136 | yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser); | |
137 | ||
138 | static yaml_event_t * | |
139 | yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first); | |
140 | ||
141 | static yaml_event_t * | |
142 | yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty); | |
143 | ||
52fba2c6 KS |
144 | /* |
145 | * Utility functions. | |
146 | */ | |
147 | ||
148 | static yaml_event_t * | |
149 | yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark); | |
150 | ||
151 | static int | |
152 | yaml_parser_process_directives(yaml_parser_t *parser); | |
153 | ||
1eb01be7 KS |
154 | /* |
155 | * Get the next event and advance the parser. | |
156 | */ | |
157 | ||
158 | YAML_DECLARE(yaml_event_t *) | |
159 | yaml_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 | ||
180 | YAML_DECLARE(yaml_event_t *) | |
181 | yaml_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 | ||
200 | static int | |
201 | yaml_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 | ||
211 | static int | |
212 | yaml_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 | ||
229 | static int | |
230 | yaml_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 | ||
252 | static int | |
253 | yaml_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 | ||
271 | static int | |
272 | yaml_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 | ||
288 | static int | |
289 | yaml_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 | ||
305 | static yaml_event_t * | |
306 | yaml_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 | ||
390 | static yaml_event_t * | |
391 | yaml_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 | ||
422 | static yaml_event_t * | |
423 | yaml_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 | ||
504 | static yaml_event_t * | |
505 | yaml_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 | ||
533 | static yaml_event_t * | |
534 | yaml_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 | ||
606 | static yaml_event_t * | |
607 | yaml_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 | ||
821 | error: | |
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 | ||
836 | static yaml_event_t * | |
837 | yaml_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 | ||
902 | static yaml_event_t * | |
903 | yaml_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 | ||
953 | static yaml_event_t * | |
954 | yaml_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 | ||
1026 | static yaml_event_t * | |
1027 | yaml_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 | 1076 | static yaml_event_t * |
ab01bac8 KS |
1077 | yaml_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 | |
1142 | static yaml_event_t * | |
ab01bac8 KS |
1143 | yaml_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 | |
1172 | static yaml_event_t * | |
ab01bac8 KS |
1173 | yaml_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 | |
1202 | static yaml_event_t * | |
ab01bac8 KS |
1203 | yaml_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 | |
1229 | static yaml_event_t * | |
ab01bac8 KS |
1230 | yaml_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 | |
1302 | static yaml_event_t * | |
ab01bac8 KS |
1303 | yaml_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 | ||
1337 | static yaml_event_t * | |
1338 | yaml_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 | ||
1365 | static int | |
1366 | yaml_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 |