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);