Actual source code: loader.c
2: #include "yaml_private.h"
4: /*
5: * API functions.
6: */
8: YAML_DECLARE(int)
9: yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
11: /*
12: * Error handling.
13: */
15: static int
16: yaml_parser_set_composer_error(yaml_parser_t *parser,
17: const char *problem, yaml_mark_t problem_mark);
19: static int
20: yaml_parser_set_composer_error_context(yaml_parser_t *parser,
21: const char *context, yaml_mark_t context_mark,
22: const char *problem, yaml_mark_t problem_mark);
25: /*
26: * Alias handling.
27: */
29: static int
30: yaml_parser_register_anchor(yaml_parser_t *parser,
31: int index, yaml_char_t *anchor);
33: /*
34: * Clean up functions.
35: */
37: static void
38: yaml_parser_delete_aliases(yaml_parser_t *parser);
40: /*
41: * Document loading context.
42: */
43: struct loader_ctx {
44: int *start;
45: int *end;
46: int *top;
47: };
49: /*
50: * Composer functions.
51: */
52: static int
53: yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
55: static int
56: yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
58: static int
59: yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
60: struct loader_ctx *ctx);
62: static int
63: yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
64: struct loader_ctx *ctx);
66: static int
67: yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
68: struct loader_ctx *ctx);
70: static int
71: yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
72: struct loader_ctx *ctx);
74: static int
75: yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
76: struct loader_ctx *ctx);
78: static int
79: yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
80: struct loader_ctx *ctx);
82: /*
83: * Load the next document of the stream.
84: */
86: YAML_DECLARE(int)
87: yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
88: {
89: yaml_event_t event;
91: assert(parser); /* Non-NULL parser object is expected. */
92: assert(document); /* Non-NULL document object is expected. */
94: memset(document, 0, sizeof(yaml_document_t));
95: if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
96: goto error;
98: if (!parser->stream_start_produced) {
99: if (!yaml_parser_parse(parser, &event)) goto error;
100: assert(event.type == YAML_STREAM_START_EVENT);
101: /* STREAM-START is expected. */
102: }
104: if (parser->stream_end_produced) {
105: return 1;
106: }
108: if (!yaml_parser_parse(parser, &event)) goto error;
109: if (event.type == YAML_STREAM_END_EVENT) {
110: return 1;
111: }
113: if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
114: goto error;
116: parser->document = document;
118: if (!yaml_parser_load_document(parser, &event)) goto error;
120: yaml_parser_delete_aliases(parser);
121: parser->document = NULL;
123: return 1;
125: error:
127: yaml_parser_delete_aliases(parser);
128: yaml_document_delete(document);
129: parser->document = NULL;
131: return 0;
132: }
134: /*
135: * Set composer error.
136: */
138: static int
139: yaml_parser_set_composer_error(yaml_parser_t *parser,
140: const char *problem, yaml_mark_t problem_mark)
141: {
142: parser->error = YAML_COMPOSER_ERROR;
143: parser->problem = problem;
144: parser->problem_mark = problem_mark;
146: return 0;
147: }
149: /*
150: * Set composer error with context.
151: */
153: static int
154: yaml_parser_set_composer_error_context(yaml_parser_t *parser,
155: const char *context, yaml_mark_t context_mark,
156: const char *problem, yaml_mark_t problem_mark)
157: {
158: parser->error = YAML_COMPOSER_ERROR;
159: parser->context = context;
160: parser->context_mark = context_mark;
161: parser->problem = problem;
162: parser->problem_mark = problem_mark;
164: return 0;
165: }
167: /*
168: * Delete the stack of aliases.
169: */
171: static void
172: yaml_parser_delete_aliases(yaml_parser_t *parser)
173: {
174: while (!STACK_EMPTY(parser, parser->aliases)) {
175: yaml_free(POP(parser, parser->aliases).anchor);
176: }
177: STACK_DEL(parser, parser->aliases);
178: }
180: /*
181: * Compose a document object.
182: */
184: static int
185: yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
186: {
187: struct loader_ctx ctx = { NULL, NULL, NULL };
189: assert(event->type == YAML_DOCUMENT_START_EVENT);
190: /* DOCUMENT-START is expected. */
192: parser->document->version_directive
193: = event->data.document_start.version_directive;
194: parser->document->tag_directives.start
195: = event->data.document_start.tag_directives.start;
196: parser->document->tag_directives.end
197: = event->data.document_start.tag_directives.end;
198: parser->document->start_implicit
199: = event->data.document_start.implicit;
200: parser->document->start_mark = event->start_mark;
202: if (!STACK_INIT(parser, ctx, int*)) return 0;
203: if (!yaml_parser_load_nodes(parser, &ctx)) {
204: STACK_DEL(parser, ctx);
205: return 0;
206: }
207: STACK_DEL(parser, ctx);
209: return 1;
210: }
212: /*
213: * Compose a node tree.
214: */
216: static int
217: yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
218: {
219: yaml_event_t event;
221: do {
222: if (!yaml_parser_parse(parser, &event)) return 0;
224: switch (event.type) {
225: case YAML_ALIAS_EVENT:
226: if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
227: break;
228: case YAML_SCALAR_EVENT:
229: if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
230: break;
231: case YAML_SEQUENCE_START_EVENT:
232: if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
233: break;
234: case YAML_SEQUENCE_END_EVENT:
235: if (!yaml_parser_load_sequence_end(parser, &event, ctx))
236: return 0;
237: break;
238: case YAML_MAPPING_START_EVENT:
239: if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
240: break;
241: case YAML_MAPPING_END_EVENT:
242: if (!yaml_parser_load_mapping_end(parser, &event, ctx))
243: return 0;
244: break;
245: default:
246: assert(0); /* Could not happen. */
247: return 0;
248: case YAML_DOCUMENT_END_EVENT:
249: break;
250: }
251: } while (event.type != YAML_DOCUMENT_END_EVENT);
253: parser->document->end_implicit = event.data.document_end.implicit;
254: parser->document->end_mark = event.end_mark;
256: return 1;
257: }
259: /*
260: * Add an anchor.
261: */
263: static int
264: yaml_parser_register_anchor(yaml_parser_t *parser,
265: int index, yaml_char_t *anchor)
266: {
267: yaml_alias_data_t data;
268: yaml_alias_data_t *alias_data;
270: if (!anchor) return 1;
272: data.anchor = anchor;
273: data.index = index;
274: data.mark = parser->document->nodes.start[index-1].start_mark;
276: for (alias_data = parser->aliases.start;
277: alias_data != parser->aliases.top; alias_data ++) {
278: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
279: yaml_free(anchor);
280: return yaml_parser_set_composer_error_context(parser,
281: "found duplicate anchor; first occurrence",
282: alias_data->mark, "second occurrence", data.mark);
283: }
284: }
286: if (!PUSH(parser, parser->aliases, data)) {
287: yaml_free(anchor);
288: return 0;
289: }
291: return 1;
292: }
294: /*
295: * Compose node into its parent in the stree.
296: */
298: static int
299: yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
300: int index)
301: {
302: struct yaml_node_s *parent;
303: int parent_index;
305: if (STACK_EMPTY(parser, *ctx)) {
306: /* This is the root node, there's no tree to add it to. */
307: return 1;
308: }
310: parent_index = *((*ctx).top - 1);
311: parent = &parser->document->nodes.start[parent_index-1];
313: switch (parent->type) {
314: case YAML_SEQUENCE_NODE:
315: if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
316: return 0;
317: if (!PUSH(parser, parent->data.sequence.items, index))
318: return 0;
319: break;
320: case YAML_MAPPING_NODE: {
321: yaml_node_pair_t pair;
322: if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
323: yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
324: if (p->key != 0 && p->value == 0) {
325: p->value = index;
326: break;
327: }
328: }
330: pair.key = index;
331: pair.value = 0;
332: if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
333: return 0;
334: if (!PUSH(parser, parent->data.mapping.pairs, pair))
335: return 0;
337: break;
338: }
339: default:
340: assert(0); /* Could not happen. */
341: return 0;
342: }
343: return 1;
344: }
346: /*
347: * Compose a node corresponding to an alias.
348: */
350: static int
351: yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
352: struct loader_ctx *ctx)
353: {
354: yaml_char_t *anchor = event->data.alias.anchor;
355: yaml_alias_data_t *alias_data;
357: for (alias_data = parser->aliases.start;
358: alias_data != parser->aliases.top; alias_data ++) {
359: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
360: yaml_free(anchor);
361: return yaml_parser_load_node_add(parser, ctx, alias_data->index);
362: }
363: }
365: yaml_free(anchor);
366: return yaml_parser_set_composer_error(parser, "found undefined alias",
367: event->start_mark);
368: }
370: /*
371: * Compose a scalar node.
372: */
374: static int
375: yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
376: struct loader_ctx *ctx)
377: {
378: yaml_node_t node;
379: int index;
380: yaml_char_t *tag = event->data.scalar.tag;
382: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
384: if (!tag || strcmp((char *)tag, "!") == 0) {
385: yaml_free(tag);
386: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
387: if (!tag) goto error;
388: }
390: SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
391: event->data.scalar.length, event->data.scalar.style,
392: event->start_mark, event->end_mark);
394: if (!PUSH(parser, parser->document->nodes, node)) goto error;
396: index = parser->document->nodes.top - parser->document->nodes.start;
398: if (!yaml_parser_register_anchor(parser, index,
399: event->data.scalar.anchor)) return 0;
401: return yaml_parser_load_node_add(parser, ctx, index);
403: error:
404: yaml_free(tag);
405: yaml_free(event->data.scalar.anchor);
406: yaml_free(event->data.scalar.value);
407: return 0;
408: }
410: /*
411: * Compose a sequence node.
412: */
414: static int
415: yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
416: struct loader_ctx *ctx)
417: {
418: yaml_node_t node;
419: struct {
420: yaml_node_item_t *start;
421: yaml_node_item_t *end;
422: yaml_node_item_t *top;
423: } items = { NULL, NULL, NULL };
424: int index;
425: yaml_char_t *tag = event->data.sequence_start.tag;
427: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
429: if (!tag || strcmp((char *)tag, "!") == 0) {
430: yaml_free(tag);
431: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
432: if (!tag) goto error;
433: }
435: if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
437: SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
438: event->data.sequence_start.style,
439: event->start_mark, event->end_mark);
441: if (!PUSH(parser, parser->document->nodes, node)) goto error;
443: index = parser->document->nodes.top - parser->document->nodes.start;
445: if (!yaml_parser_register_anchor(parser, index,
446: event->data.sequence_start.anchor)) return 0;
448: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
450: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
451: if (!PUSH(parser, *ctx, index)) return 0;
453: return 1;
455: error:
456: yaml_free(tag);
457: yaml_free(event->data.sequence_start.anchor);
458: return 0;
459: }
461: static int
462: yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
463: struct loader_ctx *ctx)
464: {
465: int index;
467: assert(((*ctx).top - (*ctx).start) > 0);
469: index = *((*ctx).top - 1);
470: assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
471: parser->document->nodes.start[index-1].end_mark = event->end_mark;
473: (void)POP(parser, *ctx);
475: return 1;
476: }
478: /*
479: * Compose a mapping node.
480: */
482: static int
483: yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
484: struct loader_ctx *ctx)
485: {
486: yaml_node_t node;
487: struct {
488: yaml_node_pair_t *start;
489: yaml_node_pair_t *end;
490: yaml_node_pair_t *top;
491: } pairs = { NULL, NULL, NULL };
492: int index;
493: yaml_char_t *tag = event->data.mapping_start.tag;
495: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
497: if (!tag || strcmp((char *)tag, "!") == 0) {
498: yaml_free(tag);
499: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
500: if (!tag) goto error;
501: }
503: if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
505: MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
506: event->data.mapping_start.style,
507: event->start_mark, event->end_mark);
509: if (!PUSH(parser, parser->document->nodes, node)) goto error;
511: index = parser->document->nodes.top - parser->document->nodes.start;
513: if (!yaml_parser_register_anchor(parser, index,
514: event->data.mapping_start.anchor)) return 0;
516: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
518: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
519: if (!PUSH(parser, *ctx, index)) return 0;
521: return 1;
523: error:
524: yaml_free(tag);
525: yaml_free(event->data.mapping_start.anchor);
526: return 0;
527: }
529: static int
530: yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
531: struct loader_ctx *ctx)
532: {
533: int index;
535: assert(((*ctx).top - (*ctx).start) > 0);
537: index = *((*ctx).top - 1);
538: assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
539: parser->document->nodes.start[index-1].end_mark = event->end_mark;
541: (void)POP(parser, *ctx);
543: return 1;
544: }