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