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