Actual source code: loader.c
1: #include "yaml_private.h"
3: /*
4: * API functions.
5: */
7: YAML_DECLARE(int)
8: yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
10: /*
11: * Error handling.
12: */
14: static int
15: yaml_parser_set_composer_error(yaml_parser_t *parser,
16: const char *problem, yaml_mark_t problem_mark);
18: static int
19: yaml_parser_set_composer_error_context(yaml_parser_t *parser,
20: const char *context, yaml_mark_t context_mark,
21: const char *problem, yaml_mark_t problem_mark);
24: /*
25: * Alias handling.
26: */
28: static int
29: yaml_parser_register_anchor(yaml_parser_t *parser,
30: int index, yaml_char_t *anchor);
32: /*
33: * Clean up functions.
34: */
36: static void
37: yaml_parser_delete_aliases(yaml_parser_t *parser);
39: /*
40: * Document loading context.
41: */
42: struct loader_ctx {
43: int *start;
44: int *end;
45: int *top;
46: };
48: /*
49: * Composer functions.
50: */
51: static int
52: yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx);
54: static int
55: yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event);
57: static int
58: yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
59: struct loader_ctx *ctx);
61: static int
62: yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
63: struct loader_ctx *ctx);
65: static int
66: yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
67: struct loader_ctx *ctx);
69: static int
70: yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
71: struct loader_ctx *ctx);
73: static int
74: yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
75: struct loader_ctx *ctx);
77: static int
78: yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
79: struct loader_ctx *ctx);
81: /*
82: * Load the next document of the stream.
83: */
85: YAML_DECLARE(int)
86: yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
87: {
88: yaml_event_t event;
90: assert(parser); /* Non-NULL parser object is expected. */
91: assert(document); /* Non-NULL document object is expected. */
93: memset(document, 0, sizeof(yaml_document_t));
94: if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
95: goto error;
97: if (!parser->stream_start_produced) {
98: if (!yaml_parser_parse(parser, &event)) goto error;
99: assert(event.type == YAML_STREAM_START_EVENT);
100: /* STREAM-START is expected. */
101: }
103: if (parser->stream_end_produced) return 1;
105: if (!yaml_parser_parse(parser, &event)) goto error;
106: if (event.type == YAML_STREAM_END_EVENT) return 1;
108: if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
109: goto error;
111: parser->document = document;
113: if (!yaml_parser_load_document(parser, &event)) goto error;
115: yaml_parser_delete_aliases(parser);
116: parser->document = NULL;
118: return 1;
120: error:
122: yaml_parser_delete_aliases(parser);
123: yaml_document_delete(document);
124: parser->document = NULL;
126: return 0;
127: }
129: /*
130: * Set composer error.
131: */
133: static int
134: yaml_parser_set_composer_error(yaml_parser_t *parser,
135: const char *problem, yaml_mark_t problem_mark)
136: {
137: parser->error = YAML_COMPOSER_ERROR;
138: parser->problem = problem;
139: parser->problem_mark = problem_mark;
141: return 0;
142: }
144: /*
145: * Set composer error with context.
146: */
148: static int
149: yaml_parser_set_composer_error_context(yaml_parser_t *parser,
150: const char *context, yaml_mark_t context_mark,
151: const char *problem, yaml_mark_t problem_mark)
152: {
153: parser->error = YAML_COMPOSER_ERROR;
154: parser->context = context;
155: parser->context_mark = context_mark;
156: parser->problem = problem;
157: parser->problem_mark = problem_mark;
159: return 0;
160: }
162: /*
163: * Delete the stack of aliases.
164: */
166: static void
167: yaml_parser_delete_aliases(yaml_parser_t *parser)
168: {
169: while (!STACK_EMPTY(parser, parser->aliases)) yaml_free(POP(parser, parser->aliases).anchor);
170: STACK_DEL(parser, parser->aliases);
171: }
173: /*
174: * Compose a document object.
175: */
177: static int
178: yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
179: {
180: struct loader_ctx ctx = { NULL, NULL, NULL };
182: assert(event->type == YAML_DOCUMENT_START_EVENT);
183: /* DOCUMENT-START is expected. */
185: parser->document->version_directive
186: = event->data.document_start.version_directive;
187: parser->document->tag_directives.start
188: = event->data.document_start.tag_directives.start;
189: parser->document->tag_directives.end
190: = event->data.document_start.tag_directives.end;
191: parser->document->start_implicit
192: = event->data.document_start.implicit;
193: parser->document->start_mark = event->start_mark;
195: if (!STACK_INIT(parser, ctx, int*)) return 0;
196: if (!yaml_parser_load_nodes(parser, &ctx)) {
197: STACK_DEL(parser, ctx);
198: return 0;
199: }
200: STACK_DEL(parser, ctx);
202: return 1;
203: }
205: /*
206: * Compose a node tree.
207: */
209: static int
210: yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
211: {
212: yaml_event_t event;
214: do {
215: if (!yaml_parser_parse(parser, &event)) return 0;
217: switch (event.type) {
218: case YAML_ALIAS_EVENT:
219: if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
220: break;
221: case YAML_SCALAR_EVENT:
222: if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
223: break;
224: case YAML_SEQUENCE_START_EVENT:
225: if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
226: break;
227: case YAML_SEQUENCE_END_EVENT:
228: if (!yaml_parser_load_sequence_end(parser, &event, ctx))
229: return 0;
230: break;
231: case YAML_MAPPING_START_EVENT:
232: if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
233: break;
234: case YAML_MAPPING_END_EVENT:
235: if (!yaml_parser_load_mapping_end(parser, &event, ctx))
236: return 0;
237: break;
238: default:
239: assert(0); /* Could not happen. */
240: return 0;
241: case YAML_DOCUMENT_END_EVENT:
242: break;
243: }
244: } while (event.type != YAML_DOCUMENT_END_EVENT);
246: parser->document->end_implicit = event.data.document_end.implicit;
247: parser->document->end_mark = event.end_mark;
249: return 1;
250: }
252: /*
253: * Add an anchor.
254: */
256: static int
257: yaml_parser_register_anchor(yaml_parser_t *parser,
258: int index, yaml_char_t *anchor)
259: {
260: yaml_alias_data_t data;
261: yaml_alias_data_t *alias_data;
263: if (!anchor) return 1;
265: data.anchor = anchor;
266: data.index = index;
267: data.mark = parser->document->nodes.start[index-1].start_mark;
269: for (alias_data = parser->aliases.start;
270: alias_data != parser->aliases.top; alias_data ++) {
271: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
272: yaml_free(anchor);
273: return yaml_parser_set_composer_error_context(parser,
274: "found duplicate anchor; first occurrence",
275: alias_data->mark, "second occurrence", data.mark);
276: }
277: }
279: if (!PUSH(parser, parser->aliases, data)) {
280: yaml_free(anchor);
281: return 0;
282: }
284: return 1;
285: }
287: /*
288: * Compose node into its parent in the stree.
289: */
291: static int
292: yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
293: int index)
294: {
295: struct yaml_node_s *parent;
296: int parent_index;
298: if (STACK_EMPTY(parser, *ctx)) {
299: /* This is the root node, there's no tree to add it to. */
300: return 1;
301: }
303: parent_index = *((*ctx).top - 1);
304: parent = &parser->document->nodes.start[parent_index-1];
306: switch (parent->type) {
307: case YAML_SEQUENCE_NODE:
308: if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
309: return 0;
310: if (!PUSH(parser, parent->data.sequence.items, index))
311: return 0;
312: break;
313: case YAML_MAPPING_NODE: {
314: yaml_node_pair_t pair;
315: if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
316: yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
317: if (p->key != 0 && p->value == 0) {
318: p->value = index;
319: break;
320: }
321: }
323: pair.key = index;
324: pair.value = 0;
325: if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
326: return 0;
327: if (!PUSH(parser, parent->data.mapping.pairs, pair))
328: return 0;
330: break;
331: }
332: default:
333: assert(0); /* Could not happen. */
334: return 0;
335: }
336: return 1;
337: }
339: /*
340: * Compose a node corresponding to an alias.
341: */
343: static int
344: yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
345: struct loader_ctx *ctx)
346: {
347: yaml_char_t *anchor = event->data.alias.anchor;
348: yaml_alias_data_t *alias_data;
350: for (alias_data = parser->aliases.start;
351: alias_data != parser->aliases.top; alias_data ++) {
352: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
353: yaml_free(anchor);
354: return yaml_parser_load_node_add(parser, ctx, alias_data->index);
355: }
356: }
358: yaml_free(anchor);
359: return yaml_parser_set_composer_error(parser, "found undefined alias",
360: event->start_mark);
361: }
363: /*
364: * Compose a scalar node.
365: */
367: static int
368: yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
369: struct loader_ctx *ctx)
370: {
371: yaml_node_t node;
372: int index;
373: yaml_char_t *tag = event->data.scalar.tag;
375: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
377: if (!tag || strcmp((char *)tag, "!") == 0) {
378: yaml_free(tag);
379: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
380: if (!tag) goto error;
381: }
383: SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
384: event->data.scalar.length, event->data.scalar.style,
385: event->start_mark, event->end_mark);
387: if (!PUSH(parser, parser->document->nodes, node)) goto error;
389: index = parser->document->nodes.top - parser->document->nodes.start;
391: if (!yaml_parser_register_anchor(parser, index,
392: event->data.scalar.anchor)) return 0;
394: return yaml_parser_load_node_add(parser, ctx, index);
396: error:
397: yaml_free(tag);
398: yaml_free(event->data.scalar.anchor);
399: yaml_free(event->data.scalar.value);
400: return 0;
401: }
403: /*
404: * Compose a sequence node.
405: */
407: static int
408: yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
409: struct loader_ctx *ctx)
410: {
411: yaml_node_t node;
412: struct {
413: yaml_node_item_t *start;
414: yaml_node_item_t *end;
415: yaml_node_item_t *top;
416: } items = { NULL, NULL, NULL };
417: int index;
418: yaml_char_t *tag = event->data.sequence_start.tag;
420: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
422: if (!tag || strcmp((char *)tag, "!") == 0) {
423: yaml_free(tag);
424: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
425: if (!tag) goto error;
426: }
428: if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
430: SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
431: event->data.sequence_start.style,
432: event->start_mark, event->end_mark);
434: if (!PUSH(parser, parser->document->nodes, node)) goto error;
436: index = parser->document->nodes.top - parser->document->nodes.start;
438: if (!yaml_parser_register_anchor(parser, index,
439: event->data.sequence_start.anchor)) return 0;
441: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
443: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
444: if (!PUSH(parser, *ctx, index)) return 0;
446: return 1;
448: error:
449: yaml_free(tag);
450: yaml_free(event->data.sequence_start.anchor);
451: return 0;
452: }
454: static int
455: yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
456: struct loader_ctx *ctx)
457: {
458: int index;
460: assert(((*ctx).top - (*ctx).start) > 0);
462: index = *((*ctx).top - 1);
463: assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
464: parser->document->nodes.start[index-1].end_mark = event->end_mark;
466: (void)POP(parser, *ctx);
468: return 1;
469: }
471: /*
472: * Compose a mapping node.
473: */
475: static int
476: yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
477: struct loader_ctx *ctx)
478: {
479: yaml_node_t node;
480: struct {
481: yaml_node_pair_t *start;
482: yaml_node_pair_t *end;
483: yaml_node_pair_t *top;
484: } pairs = { NULL, NULL, NULL };
485: int index;
486: yaml_char_t *tag = event->data.mapping_start.tag;
488: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
490: if (!tag || strcmp((char *)tag, "!") == 0) {
491: yaml_free(tag);
492: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
493: if (!tag) goto error;
494: }
496: if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
498: MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
499: event->data.mapping_start.style,
500: event->start_mark, event->end_mark);
502: if (!PUSH(parser, parser->document->nodes, node)) goto error;
504: index = parser->document->nodes.top - parser->document->nodes.start;
506: if (!yaml_parser_register_anchor(parser, index,
507: event->data.mapping_start.anchor)) return 0;
509: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
511: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
512: if (!PUSH(parser, *ctx, index)) return 0;
514: return 1;
516: error:
517: yaml_free(tag);
518: yaml_free(event->data.mapping_start.anchor);
519: return 0;
520: }
522: static int
523: yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
524: struct loader_ctx *ctx)
525: {
526: int index;
528: assert(((*ctx).top - (*ctx).start) > 0);
530: index = *((*ctx).top - 1);
531: assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
532: parser->document->nodes.start[index-1].end_mark = event->end_mark;
534: (void)POP(parser, *ctx);
536: return 1;
537: }