]> andersk Git - libyaml.git/blob - src/loader.c
Eliminate some warnings and add more doxygen definitions.
[libyaml.git] / src / loader.c
1
2 #include "yaml_private.h"
3
4 /*
5  * API functions.
6  */
7
8 YAML_DECLARE(int)
9 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
10
11 /*
12  * Error handling.
13  */
14
15 static int
16 yaml_parser_set_composer_error(yaml_parser_t *parser,
17         const char *problem, yaml_mark_t problem_mark);
18
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);
23
24
25 /*
26  * Alias handling.
27  */
28
29 static int
30 yaml_parser_register_anchor(yaml_parser_t *parser,
31         int index, yaml_char_t *anchor);
32
33 /*
34  * Clean up functions.
35  */
36
37 static void
38 yaml_parser_delete_aliases(yaml_parser_t *parser);
39
40 /*
41  * Composer functions.
42  */
43
44 static int
45 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
46
47 static int
48 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
49
50 static int
51 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
52
53 static int
54 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
55
56 static int
57 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
58
59 static int
60 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
61
62 /*
63  * Load the next document of the stream.
64  */
65
66 YAML_DECLARE(int)
67 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
68 {
69     yaml_event_t event;
70
71     assert(parser);     /* Non-NULL parser object is expected. */
72     assert(document);   /* Non-NULL document object is expected. */
73
74     memset(document, 0, sizeof(yaml_document_t));
75     if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
76         goto error;
77
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. */
82     }
83
84     if (parser->stream_end_produced) {
85         return 1;
86     }
87
88     if (!yaml_parser_parse(parser, &event)) goto error;
89     if (event.type == YAML_STREAM_END_EVENT) {
90         return 1;
91     }
92
93     if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
94         goto error;
95
96     parser->document = document;
97
98     if (!yaml_parser_load_document(parser, &event)) goto error;
99
100     yaml_parser_delete_aliases(parser);
101     parser->document = NULL;
102
103     return 1;
104
105 error:
106
107     yaml_parser_delete_aliases(parser);
108     yaml_document_delete(document);
109     parser->document = NULL;
110
111     return 0;
112 }
113
114 /*
115  * Set composer error.
116  */
117
118 static int
119 yaml_parser_set_composer_error(yaml_parser_t *parser,
120         const char *problem, yaml_mark_t problem_mark)
121 {
122     parser->error = YAML_COMPOSER_ERROR;
123     parser->problem = problem;
124     parser->problem_mark = problem_mark;
125
126     return 0;
127 }
128
129 /*
130  * Set composer error with context.
131  */
132
133 static int
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)
137 {
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;
143
144     return 0;
145 }
146
147 /*
148  * Delete the stack of aliases.
149  */
150
151 static void
152 yaml_parser_delete_aliases(yaml_parser_t *parser)
153 {
154     while (!STACK_EMPTY(parser, parser->aliases)) {
155         yaml_free(POP(parser, parser->aliases).anchor);
156     }
157     STACK_DEL(parser, parser->aliases);
158 }
159
160 /*
161  * Compose a document object.
162  */
163
164 static int
165 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
166 {
167     yaml_event_t event;
168
169     assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170                         /* DOCUMENT-START is expected. */
171
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;
181
182     if (!yaml_parser_parse(parser, &event)) return 0;
183
184     if (!yaml_parser_load_node(parser, &event)) return 0;
185
186     if (!yaml_parser_parse(parser, &event)) return 0;
187     assert(event.type == YAML_DOCUMENT_END_EVENT);
188                         /* DOCUMENT-END is expected. */
189
190     parser->document->end_implicit = event.data.document_end.implicit;
191     parser->document->end_mark = event.end_mark;
192
193     return 1;
194 }
195
196 /*
197  * Compose a node.
198  */
199
200 static int
201 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
202 {
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);
212         default:
213             assert(0);  /* Could not happen. */
214             return 0;
215     }
216
217     return 0;
218 }
219
220 /*
221  * Add an anchor.
222  */
223
224 static int
225 yaml_parser_register_anchor(yaml_parser_t *parser,
226         int index, yaml_char_t *anchor)
227 {
228     yaml_alias_data_t data = { anchor, index, { 0, 0, 0 } };
229     yaml_alias_data_t *alias_data;
230
231     if (!anchor) return 1;
232
233     data.mark = parser->document->nodes.start[index-1].start_mark;
234
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) {
238             yaml_free(anchor);
239             return yaml_parser_set_composer_error_context(parser,
240                     "found duplicate anchor; first occurence",
241                     alias_data->mark, "second occurence", data.mark);
242         }
243     }
244
245     if (!PUSH(parser, parser->aliases, data)) {
246         yaml_free(anchor);
247         return 0;
248     }
249
250     return 1;
251 }
252
253 /*
254  * Compose a node corresponding to an alias.
255  */
256
257 static int
258 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
259 {
260     yaml_char_t *anchor = first_event->data.alias.anchor;
261     yaml_alias_data_t *alias_data;
262
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) {
266             yaml_free(anchor);
267             return alias_data->index;
268         }
269     }
270
271     yaml_free(anchor);
272     return yaml_parser_set_composer_error(parser, "found undefined alias",
273             first_event->start_mark);
274 }
275
276 /*
277  * Compose a scalar node.
278  */
279
280 static int
281 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
282 {
283     yaml_node_t node;
284     int index;
285     yaml_char_t *tag = first_event->data.scalar.tag;
286
287     if (!tag || strcmp((char *)tag, "!") == 0) {
288         yaml_free(tag);
289         tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
290         if (!tag) goto error;
291     }
292
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);
296
297     if (!PUSH(parser, parser->document->nodes, node)) goto error;
298
299     index = parser->document->nodes.top - parser->document->nodes.start;
300
301     if (!yaml_parser_register_anchor(parser, index,
302                 first_event->data.scalar.anchor)) return 0;
303
304     return index;
305
306 error:
307     yaml_free(tag);
308     yaml_free(first_event->data.scalar.anchor);
309     yaml_free(first_event->data.scalar.value);
310     return 0;
311 }
312
313 /*
314  * Compose a sequence node.
315  */
316
317 static int
318 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
319 {
320     yaml_event_t event;
321     yaml_node_t node;
322     struct {
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;
329
330     if (!tag || strcmp((char *)tag, "!") == 0) {
331         yaml_free(tag);
332         tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
333         if (!tag) goto error;
334     }
335
336     if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
337
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);
341
342     if (!PUSH(parser, parser->document->nodes, node)) goto error;
343
344     index = parser->document->nodes.top - parser->document->nodes.start;
345
346     if (!yaml_parser_register_anchor(parser, index,
347                 first_event->data.sequence_start.anchor)) return 0;
348
349     if (!yaml_parser_parse(parser, &event)) return 0;
350
351     while (event.type != YAML_SEQUENCE_END_EVENT) {
352         item_index = yaml_parser_load_node(parser, &event);
353         if (!item_index) return 0;
354         if (!PUSH(parser,
355                     parser->document->nodes.start[index-1].data.sequence.items,
356                     item_index)) return 0;
357         if (!yaml_parser_parse(parser, &event)) return 0;
358     }
359
360     parser->document->nodes.start[index-1].end_mark = event.end_mark;
361
362     return index;
363
364 error:
365     yaml_free(tag);
366     yaml_free(first_event->data.sequence_start.anchor);
367     return 0;
368 }
369
370 /*
371  * Compose a mapping node.
372  */
373
374 static int
375 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
376 {
377     yaml_event_t event;
378     yaml_node_t node;
379     struct {
380         yaml_node_pair_t *start;
381         yaml_node_pair_t *end;
382         yaml_node_pair_t *top;
383     } pairs = { NULL, NULL, NULL };
384     int index;
385     yaml_node_pair_t pair;
386     yaml_char_t *tag = first_event->data.mapping_start.tag;
387
388     if (!tag || strcmp((char *)tag, "!") == 0) {
389         yaml_free(tag);
390         tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
391         if (!tag) goto error;
392     }
393
394     if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
395
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);
399
400     if (!PUSH(parser, parser->document->nodes, node)) goto error;
401
402     index = parser->document->nodes.top - parser->document->nodes.start;
403
404     if (!yaml_parser_register_anchor(parser, index,
405                 first_event->data.mapping_start.anchor)) return 0;
406
407     if (!yaml_parser_parse(parser, &event)) return 0;
408
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;
415         if (!PUSH(parser,
416                     parser->document->nodes.start[index-1].data.mapping.pairs,
417                     pair)) return 0;
418         if (!yaml_parser_parse(parser, &event)) return 0;
419     }
420
421     parser->document->nodes.start[index-1].end_mark = event.end_mark;
422
423     return index;
424
425 error:
426     yaml_free(tag);
427     yaml_free(first_event->data.mapping_start.anchor);
428     return 0;
429 }
430
This page took 0.157234 seconds and 5 git commands to generate.