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: }