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) {
104: return 1;
105: }
107: if (!yaml_parser_parse(parser, &event)) goto error;
108: if (event.type == YAML_STREAM_END_EVENT) {
109: return 1;
110: }
112: if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
113: goto error;
115: parser->document = document;
117: if (!yaml_parser_load_document(parser, &event)) goto error;
119: yaml_parser_delete_aliases(parser);
120: parser->document = NULL;
122: return 1;
124: error:
126: yaml_parser_delete_aliases(parser);
127: yaml_document_delete(document);
128: parser->document = NULL;
130: return 0;
131: }
133: /*
134: * Set composer error.
135: */
137: static int
138: yaml_parser_set_composer_error(yaml_parser_t *parser,
139: const char *problem, yaml_mark_t problem_mark)
140: {
141: parser->error = YAML_COMPOSER_ERROR;
142: parser->problem = problem;
143: parser->problem_mark = problem_mark;
145: return 0;
146: }
148: /*
149: * Set composer error with context.
150: */
152: static int
153: yaml_parser_set_composer_error_context(yaml_parser_t *parser,
154: const char *context, yaml_mark_t context_mark,
155: const char *problem, yaml_mark_t problem_mark)
156: {
157: parser->error = YAML_COMPOSER_ERROR;
158: parser->context = context;
159: parser->context_mark = context_mark;
160: parser->problem = problem;
161: parser->problem_mark = problem_mark;
163: return 0;
164: }
166: /*
167: * Delete the stack of aliases.
168: */
170: static void
171: yaml_parser_delete_aliases(yaml_parser_t *parser)
172: {
173: while (!STACK_EMPTY(parser, parser->aliases)) {
174: yaml_free(POP(parser, parser->aliases).anchor);
175: }
176: STACK_DEL(parser, parser->aliases);
177: }
179: /*
180: * Compose a document object.
181: */
183: static int
184: yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *event)
185: {
186: struct loader_ctx ctx = { NULL, NULL, NULL };
188: assert(event->type == YAML_DOCUMENT_START_EVENT);
189: /* DOCUMENT-START is expected. */
191: parser->document->version_directive
192: = event->data.document_start.version_directive;
193: parser->document->tag_directives.start
194: = event->data.document_start.tag_directives.start;
195: parser->document->tag_directives.end
196: = event->data.document_start.tag_directives.end;
197: parser->document->start_implicit
198: = event->data.document_start.implicit;
199: parser->document->start_mark = event->start_mark;
201: if (!STACK_INIT(parser, ctx, int*)) return 0;
202: if (!yaml_parser_load_nodes(parser, &ctx)) {
203: STACK_DEL(parser, ctx);
204: return 0;
205: }
206: STACK_DEL(parser, ctx);
208: return 1;
209: }
211: /*
212: * Compose a node tree.
213: */
215: static int
216: yaml_parser_load_nodes(yaml_parser_t *parser, struct loader_ctx *ctx)
217: {
218: yaml_event_t event;
220: do {
221: if (!yaml_parser_parse(parser, &event)) return 0;
223: switch (event.type) {
224: case YAML_ALIAS_EVENT:
225: if (!yaml_parser_load_alias(parser, &event, ctx)) return 0;
226: break;
227: case YAML_SCALAR_EVENT:
228: if (!yaml_parser_load_scalar(parser, &event, ctx)) return 0;
229: break;
230: case YAML_SEQUENCE_START_EVENT:
231: if (!yaml_parser_load_sequence(parser, &event, ctx)) return 0;
232: break;
233: case YAML_SEQUENCE_END_EVENT:
234: if (!yaml_parser_load_sequence_end(parser, &event, ctx))
235: return 0;
236: break;
237: case YAML_MAPPING_START_EVENT:
238: if (!yaml_parser_load_mapping(parser, &event, ctx)) return 0;
239: break;
240: case YAML_MAPPING_END_EVENT:
241: if (!yaml_parser_load_mapping_end(parser, &event, ctx))
242: return 0;
243: break;
244: default:
245: assert(0); /* Could not happen. */
246: return 0;
247: case YAML_DOCUMENT_END_EVENT:
248: break;
249: }
250: } while (event.type != YAML_DOCUMENT_END_EVENT);
252: parser->document->end_implicit = event.data.document_end.implicit;
253: parser->document->end_mark = event.end_mark;
255: return 1;
256: }
258: /*
259: * Add an anchor.
260: */
262: static int
263: yaml_parser_register_anchor(yaml_parser_t *parser,
264: int index, yaml_char_t *anchor)
265: {
266: yaml_alias_data_t data;
267: yaml_alias_data_t *alias_data;
269: if (!anchor) return 1;
271: data.anchor = anchor;
272: data.index = index;
273: data.mark = parser->document->nodes.start[index-1].start_mark;
275: for (alias_data = parser->aliases.start;
276: alias_data != parser->aliases.top; alias_data ++) {
277: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
278: yaml_free(anchor);
279: return yaml_parser_set_composer_error_context(parser,
280: "found duplicate anchor; first occurrence",
281: alias_data->mark, "second occurrence", data.mark);
282: }
283: }
285: if (!PUSH(parser, parser->aliases, data)) {
286: yaml_free(anchor);
287: return 0;
288: }
290: return 1;
291: }
293: /*
294: * Compose node into its parent in the stree.
295: */
297: static int
298: yaml_parser_load_node_add(yaml_parser_t *parser, struct loader_ctx *ctx,
299: int index)
300: {
301: struct yaml_node_s *parent;
302: int parent_index;
304: if (STACK_EMPTY(parser, *ctx)) {
305: /* This is the root node, there's no tree to add it to. */
306: return 1;
307: }
309: parent_index = *((*ctx).top - 1);
310: parent = &parser->document->nodes.start[parent_index-1];
312: switch (parent->type) {
313: case YAML_SEQUENCE_NODE:
314: if (!STACK_LIMIT(parser, parent->data.sequence.items, INT_MAX-1))
315: return 0;
316: if (!PUSH(parser, parent->data.sequence.items, index))
317: return 0;
318: break;
319: case YAML_MAPPING_NODE: {
320: yaml_node_pair_t pair;
321: if (!STACK_EMPTY(parser, parent->data.mapping.pairs)) {
322: yaml_node_pair_t *p = parent->data.mapping.pairs.top - 1;
323: if (p->key != 0 && p->value == 0) {
324: p->value = index;
325: break;
326: }
327: }
329: pair.key = index;
330: pair.value = 0;
331: if (!STACK_LIMIT(parser, parent->data.mapping.pairs, INT_MAX-1))
332: return 0;
333: if (!PUSH(parser, parent->data.mapping.pairs, pair))
334: return 0;
336: break;
337: }
338: default:
339: assert(0); /* Could not happen. */
340: return 0;
341: }
342: return 1;
343: }
345: /*
346: * Compose a node corresponding to an alias.
347: */
349: static int
350: yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *event,
351: struct loader_ctx *ctx)
352: {
353: yaml_char_t *anchor = event->data.alias.anchor;
354: yaml_alias_data_t *alias_data;
356: for (alias_data = parser->aliases.start;
357: alias_data != parser->aliases.top; alias_data ++) {
358: if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
359: yaml_free(anchor);
360: return yaml_parser_load_node_add(parser, ctx, alias_data->index);
361: }
362: }
364: yaml_free(anchor);
365: return yaml_parser_set_composer_error(parser, "found undefined alias",
366: event->start_mark);
367: }
369: /*
370: * Compose a scalar node.
371: */
373: static int
374: yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *event,
375: struct loader_ctx *ctx)
376: {
377: yaml_node_t node;
378: int index;
379: yaml_char_t *tag = event->data.scalar.tag;
381: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
383: if (!tag || strcmp((char *)tag, "!") == 0) {
384: yaml_free(tag);
385: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
386: if (!tag) goto error;
387: }
389: SCALAR_NODE_INIT(node, tag, event->data.scalar.value,
390: event->data.scalar.length, event->data.scalar.style,
391: event->start_mark, event->end_mark);
393: if (!PUSH(parser, parser->document->nodes, node)) goto error;
395: index = parser->document->nodes.top - parser->document->nodes.start;
397: if (!yaml_parser_register_anchor(parser, index,
398: event->data.scalar.anchor)) return 0;
400: return yaml_parser_load_node_add(parser, ctx, index);
402: error:
403: yaml_free(tag);
404: yaml_free(event->data.scalar.anchor);
405: yaml_free(event->data.scalar.value);
406: return 0;
407: }
409: /*
410: * Compose a sequence node.
411: */
413: static int
414: yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *event,
415: struct loader_ctx *ctx)
416: {
417: yaml_node_t node;
418: struct {
419: yaml_node_item_t *start;
420: yaml_node_item_t *end;
421: yaml_node_item_t *top;
422: } items = { NULL, NULL, NULL };
423: int index;
424: yaml_char_t *tag = event->data.sequence_start.tag;
426: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
428: if (!tag || strcmp((char *)tag, "!") == 0) {
429: yaml_free(tag);
430: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
431: if (!tag) goto error;
432: }
434: if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
436: SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
437: event->data.sequence_start.style,
438: event->start_mark, event->end_mark);
440: if (!PUSH(parser, parser->document->nodes, node)) goto error;
442: index = parser->document->nodes.top - parser->document->nodes.start;
444: if (!yaml_parser_register_anchor(parser, index,
445: event->data.sequence_start.anchor)) return 0;
447: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
449: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
450: if (!PUSH(parser, *ctx, index)) return 0;
452: return 1;
454: error:
455: yaml_free(tag);
456: yaml_free(event->data.sequence_start.anchor);
457: return 0;
458: }
460: static int
461: yaml_parser_load_sequence_end(yaml_parser_t *parser, yaml_event_t *event,
462: struct loader_ctx *ctx)
463: {
464: int index;
466: assert(((*ctx).top - (*ctx).start) > 0);
468: index = *((*ctx).top - 1);
469: assert(parser->document->nodes.start[index-1].type == YAML_SEQUENCE_NODE);
470: parser->document->nodes.start[index-1].end_mark = event->end_mark;
472: (void)POP(parser, *ctx);
474: return 1;
475: }
477: /*
478: * Compose a mapping node.
479: */
481: static int
482: yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *event,
483: struct loader_ctx *ctx)
484: {
485: yaml_node_t node;
486: struct {
487: yaml_node_pair_t *start;
488: yaml_node_pair_t *end;
489: yaml_node_pair_t *top;
490: } pairs = { NULL, NULL, NULL };
491: int index;
492: yaml_char_t *tag = event->data.mapping_start.tag;
494: if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
496: if (!tag || strcmp((char *)tag, "!") == 0) {
497: yaml_free(tag);
498: tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
499: if (!tag) goto error;
500: }
502: if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
504: MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
505: event->data.mapping_start.style,
506: event->start_mark, event->end_mark);
508: if (!PUSH(parser, parser->document->nodes, node)) goto error;
510: index = parser->document->nodes.top - parser->document->nodes.start;
512: if (!yaml_parser_register_anchor(parser, index,
513: event->data.mapping_start.anchor)) return 0;
515: if (!yaml_parser_load_node_add(parser, ctx, index)) return 0;
517: if (!STACK_LIMIT(parser, *ctx, INT_MAX-1)) return 0;
518: if (!PUSH(parser, *ctx, index)) return 0;
520: return 1;
522: error:
523: yaml_free(tag);
524: yaml_free(event->data.mapping_start.anchor);
525: return 0;
526: }
528: static int
529: yaml_parser_load_mapping_end(yaml_parser_t *parser, yaml_event_t *event,
530: struct loader_ctx *ctx)
531: {
532: int index;
534: assert(((*ctx).top - (*ctx).start) > 0);
536: index = *((*ctx).top - 1);
537: assert(parser->document->nodes.start[index-1].type == YAML_MAPPING_NODE);
538: parser->document->nodes.start[index-1].end_mark = event->end_mark;
540: (void)POP(parser, *ctx);
542: return 1;
543: }