2 #include "yaml_private.h"
9 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
16 yaml_parser_set_composer_error(yaml_parser_t *parser,
17 const char *problem, yaml_mark_t problem_mark);
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);
30 yaml_parser_register_anchor(yaml_parser_t *parser,
31 int index, yaml_char_t *anchor);
38 yaml_parser_delete_aliases(yaml_parser_t *parser);
45 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
48 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
51 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
54 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
57 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
60 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
63 * Load the next document of the stream.
67 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
71 assert(parser); /* Non-NULL parser object is expected. */
72 assert(document); /* Non-NULL document object is expected. */
74 memset(document, 0, sizeof(yaml_document_t));
75 if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
78 if (!parser->stream_start_produced) {
79 if (!yaml_parser_parse(parser, &event)) goto error;
80 assert(event.type == YAML_STREAM_START_EVENT);
81 /* STREAM-START is expected. */
84 if (parser->stream_end_produced) {
88 if (!yaml_parser_parse(parser, &event)) goto error;
89 if (event.type == YAML_STREAM_END_EVENT) {
93 if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
96 parser->document = document;
98 if (!yaml_parser_load_document(parser, &event)) goto error;
100 yaml_parser_delete_aliases(parser);
101 parser->document = NULL;
107 yaml_parser_delete_aliases(parser);
108 yaml_document_delete(document);
109 parser->document = NULL;
115 * Set composer error.
119 yaml_parser_set_composer_error(yaml_parser_t *parser,
120 const char *problem, yaml_mark_t problem_mark)
122 parser->error = YAML_COMPOSER_ERROR;
123 parser->problem = problem;
124 parser->problem_mark = problem_mark;
130 * Set composer error with context.
134 yaml_parser_set_composer_error_context(yaml_parser_t *parser,
135 const char *context, yaml_mark_t context_mark,
136 const char *problem, yaml_mark_t problem_mark)
138 parser->error = YAML_COMPOSER_ERROR;
139 parser->context = context;
140 parser->context_mark = context_mark;
141 parser->problem = problem;
142 parser->problem_mark = problem_mark;
148 * Delete the stack of aliases.
152 yaml_parser_delete_aliases(yaml_parser_t *parser)
154 while (!STACK_EMPTY(parser, parser->aliases)) {
155 yaml_free(POP(parser, parser->aliases).anchor);
157 STACK_DEL(parser, parser->aliases);
161 * Compose a document object.
165 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
169 assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170 /* DOCUMENT-START is expected. */
172 parser->document->version_directive
173 = first_event->data.document_start.version_directive;
174 parser->document->tag_directives.start
175 = first_event->data.document_start.tag_directives.start;
176 parser->document->tag_directives.end
177 = first_event->data.document_start.tag_directives.end;
178 parser->document->start_implicit
179 = first_event->data.document_start.implicit;
180 parser->document->start_mark = first_event->start_mark;
182 if (!yaml_parser_parse(parser, &event)) return 0;
184 if (!yaml_parser_load_node(parser, &event)) return 0;
186 if (!yaml_parser_parse(parser, &event)) return 0;
187 assert(event.type == YAML_DOCUMENT_END_EVENT);
188 /* DOCUMENT-END is expected. */
190 parser->document->end_implicit = event.data.document_end.implicit;
191 parser->document->end_mark = event.end_mark;
201 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
203 switch (first_event->type) {
204 case YAML_ALIAS_EVENT:
205 return yaml_parser_load_alias(parser, first_event);
206 case YAML_SCALAR_EVENT:
207 return yaml_parser_load_scalar(parser, first_event);
208 case YAML_SEQUENCE_START_EVENT:
209 return yaml_parser_load_sequence(parser, first_event);
210 case YAML_MAPPING_START_EVENT:
211 return yaml_parser_load_mapping(parser, first_event);
213 assert(0); /* Could not happen. */
225 yaml_parser_register_anchor(yaml_parser_t *parser,
226 int index, yaml_char_t *anchor)
228 yaml_alias_data_t data = { anchor, index, { 0, 0, 0 } };
229 yaml_alias_data_t *alias_data;
231 if (!anchor) return 1;
233 data.mark = parser->document->nodes.start[index-1].start_mark;
235 for (alias_data = parser->aliases.start;
236 alias_data != parser->aliases.top; alias_data ++) {
237 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
239 return yaml_parser_set_composer_error_context(parser,
240 "found duplicate anchor; first occurence",
241 alias_data->mark, "second occurence", data.mark);
245 if (!PUSH(parser, parser->aliases, data)) {
254 * Compose a node corresponding to an alias.
258 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
260 yaml_char_t *anchor = first_event->data.alias.anchor;
261 yaml_alias_data_t *alias_data;
263 for (alias_data = parser->aliases.start;
264 alias_data != parser->aliases.top; alias_data ++) {
265 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
267 return alias_data->index;
272 return yaml_parser_set_composer_error(parser, "found undefined alias",
273 first_event->start_mark);
277 * Compose a scalar node.
281 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
285 yaml_char_t *tag = first_event->data.scalar.tag;
287 if (!tag || strcmp((char *)tag, "!") == 0) {
289 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
290 if (!tag) goto error;
293 SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
294 first_event->data.scalar.length, first_event->data.scalar.style,
295 first_event->start_mark, first_event->end_mark);
297 if (!PUSH(parser, parser->document->nodes, node)) goto error;
299 index = parser->document->nodes.top - parser->document->nodes.start;
301 if (!yaml_parser_register_anchor(parser, index,
302 first_event->data.scalar.anchor)) return 0;
308 yaml_free(first_event->data.scalar.anchor);
309 yaml_free(first_event->data.scalar.value);
314 * Compose a sequence node.
318 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
323 yaml_node_item_t *start;
324 yaml_node_item_t *end;
325 yaml_node_item_t *top;
326 } items = { NULL, NULL, NULL };
327 int index, item_index;
328 yaml_char_t *tag = first_event->data.sequence_start.tag;
330 if (!tag || strcmp((char *)tag, "!") == 0) {
332 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
333 if (!tag) goto error;
336 if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
338 SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
339 first_event->data.sequence_start.style,
340 first_event->start_mark, first_event->end_mark);
342 if (!PUSH(parser, parser->document->nodes, node)) goto error;
344 index = parser->document->nodes.top - parser->document->nodes.start;
346 if (!yaml_parser_register_anchor(parser, index,
347 first_event->data.sequence_start.anchor)) return 0;
349 if (!yaml_parser_parse(parser, &event)) return 0;
351 while (event.type != YAML_SEQUENCE_END_EVENT) {
352 item_index = yaml_parser_load_node(parser, &event);
353 if (!item_index) return 0;
355 parser->document->nodes.start[index-1].data.sequence.items,
356 item_index)) return 0;
357 if (!yaml_parser_parse(parser, &event)) return 0;
360 parser->document->nodes.start[index-1].end_mark = event.end_mark;
366 yaml_free(first_event->data.sequence_start.anchor);
371 * Compose a mapping node.
375 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
380 yaml_node_pair_t *start;
381 yaml_node_pair_t *end;
382 yaml_node_pair_t *top;
383 } pairs = { NULL, NULL, NULL };
385 yaml_node_pair_t pair;
386 yaml_char_t *tag = first_event->data.mapping_start.tag;
388 if (!tag || strcmp((char *)tag, "!") == 0) {
390 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
391 if (!tag) goto error;
394 if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
396 MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
397 first_event->data.mapping_start.style,
398 first_event->start_mark, first_event->end_mark);
400 if (!PUSH(parser, parser->document->nodes, node)) goto error;
402 index = parser->document->nodes.top - parser->document->nodes.start;
404 if (!yaml_parser_register_anchor(parser, index,
405 first_event->data.mapping_start.anchor)) return 0;
407 if (!yaml_parser_parse(parser, &event)) return 0;
409 while (event.type != YAML_MAPPING_END_EVENT) {
410 pair.key = yaml_parser_load_node(parser, &event);
411 if (!pair.key) return 0;
412 if (!yaml_parser_parse(parser, &event)) return 0;
413 pair.value = yaml_parser_load_node(parser, &event);
414 if (!pair.value) return 0;
416 parser->document->nodes.start[index-1].data.mapping.pairs,
418 if (!yaml_parser_parse(parser, &event)) return 0;
421 parser->document->nodes.start[index-1].end_mark = event.end_mark;
427 yaml_free(first_event->data.mapping_start.anchor);