File Coverage

loader.c
Criterion Covered Total %
statement 0 184 0.0
branch 0 156 0.0
condition n/a
subroutine n/a
pod n/a
total 0 340 0.0


line stmt bran cond sub pod time code
1              
2             #include "yaml_private.h"
3              
4             /*
5             * API functions: see yaml.h
6             */
7              
8             /*
9             * Error handling.
10             */
11              
12             static int
13             yaml_parser_set_composer_error(yaml_parser_t *parser,
14             const char *problem, yaml_mark_t problem_mark);
15              
16             static int
17             yaml_parser_set_composer_error_context(yaml_parser_t *parser,
18             const char *context, yaml_mark_t context_mark,
19             const char *problem, yaml_mark_t problem_mark);
20              
21              
22             /*
23             * Alias handling.
24             */
25              
26             static int
27             yaml_parser_register_anchor(yaml_parser_t *parser,
28             int index, yaml_char_t *anchor);
29              
30             /*
31             * Clean up functions.
32             */
33              
34             static void
35             yaml_parser_delete_aliases(yaml_parser_t *parser);
36              
37             /*
38             * Composer functions.
39             */
40              
41             static int
42             yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
43              
44             static int
45             yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
46              
47             static int
48             yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
49              
50             static int
51             yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
52              
53             static int
54             yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
55              
56             static int
57             yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
58              
59             /*
60             * Load the next document of the stream.
61             */
62              
63             YAML_DECLARE(int)
64 0           yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
65             {
66             yaml_event_t event;
67              
68 0 0         assert(parser); /* Non-NULL parser object is expected. */
69 0 0         assert(document); /* Non-NULL document object is expected. */
70              
71 0           memset(document, 0, sizeof(yaml_document_t));
72 0 0         if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
    0          
73 0           goto error;
74              
75 0 0         if (!parser->stream_start_produced) {
76 0 0         if (!yaml_parser_parse(parser, &event))
77 0           goto error;
78 0 0         assert(event.type == YAML_STREAM_START_EVENT);
79             /* STREAM-START is expected. */
80             }
81              
82 0 0         if (parser->stream_end_produced) {
83 0           return 1;
84             }
85              
86 0 0         if (!yaml_parser_parse(parser, &event))
87 0           goto error;
88 0 0         if (event.type == YAML_STREAM_END_EVENT) {
89 0           return 1;
90             }
91              
92 0 0         if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
    0          
93 0           goto error;
94              
95 0           parser->document = document;
96              
97 0 0         if (!yaml_parser_load_document(parser, &event))
98 0           goto error;
99              
100 0           yaml_parser_delete_aliases(parser);
101 0           parser->document = NULL;
102              
103 0           return 1;
104              
105             error:
106              
107 0           yaml_parser_delete_aliases(parser);
108 0           yaml_document_delete(document);
109 0           parser->document = NULL;
110              
111 0           return 0;
112             }
113              
114             /*
115             * Set composer error.
116             */
117              
118             static int
119 0           yaml_parser_set_composer_error(yaml_parser_t *parser,
120             const char *problem, yaml_mark_t problem_mark)
121             {
122 0           parser->error = YAML_COMPOSER_ERROR;
123 0           parser->problem = problem;
124 0           parser->problem_mark = problem_mark;
125              
126 0           return 0;
127             }
128              
129             /*
130             * Set composer error with context.
131             */
132              
133             static int
134 0           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 0           parser->error = YAML_COMPOSER_ERROR;
139 0           parser->context = context;
140 0           parser->context_mark = context_mark;
141 0           parser->problem = problem;
142 0           parser->problem_mark = problem_mark;
143              
144 0           return 0;
145             }
146              
147             /*
148             * Delete the stack of aliases.
149             */
150              
151             static void
152 0           yaml_parser_delete_aliases(yaml_parser_t *parser)
153             {
154 0 0         while (!STACK_EMPTY(parser, parser->aliases)) {
155 0           yaml_free(POP(parser, parser->aliases).anchor);
156             }
157 0           STACK_DEL(parser, parser->aliases);
158 0           }
159              
160             /*
161             * Compose a document object.
162             */
163              
164             static int
165 0           yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
166             {
167             yaml_event_t event;
168              
169 0 0         assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170             /* DOCUMENT-START is expected. */
171              
172 0           parser->document->version_directive
173 0           = first_event->data.document_start.version_directive;
174 0           parser->document->tag_directives.start
175 0           = first_event->data.document_start.tag_directives.start;
176 0           parser->document->tag_directives.end
177 0           = first_event->data.document_start.tag_directives.end;
178 0           parser->document->start_implicit
179 0           = first_event->data.document_start.implicit;
180 0           parser->document->start_mark = first_event->start_mark;
181              
182 0 0         if (!yaml_parser_parse(parser, &event)) return 0;
183              
184 0 0         if (!yaml_parser_load_node(parser, &event)) return 0;
185              
186 0 0         if (!yaml_parser_parse(parser, &event)) return 0;
187 0 0         assert(event.type == YAML_DOCUMENT_END_EVENT);
188             /* DOCUMENT-END is expected. */
189              
190 0           parser->document->end_implicit = event.data.document_end.implicit;
191 0           parser->document->end_mark = event.end_mark;
192              
193 0           return 1;
194             }
195              
196             /*
197             * Compose a node.
198             */
199              
200             static int
201 0           yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
202             {
203 0           switch (first_event->type) {
204             case YAML_ALIAS_EVENT:
205 0           return yaml_parser_load_alias(parser, first_event);
206             case YAML_SCALAR_EVENT:
207 0           return yaml_parser_load_scalar(parser, first_event);
208             case YAML_SEQUENCE_START_EVENT:
209 0           return yaml_parser_load_sequence(parser, first_event);
210             case YAML_MAPPING_START_EVENT:
211 0           return yaml_parser_load_mapping(parser, first_event);
212             default:
213 0           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 0           yaml_parser_register_anchor(yaml_parser_t *parser,
226             int index, yaml_char_t *anchor)
227             {
228             yaml_alias_data_t data;
229             yaml_alias_data_t *alias_data;
230              
231 0 0         if (!anchor) return 1;
232              
233 0           data.anchor = anchor;
234 0           data.index = index;
235 0           data.mark = parser->document->nodes.start[index-1].start_mark;
236              
237 0 0         for (alias_data = parser->aliases.start;
238 0           alias_data != parser->aliases.top; alias_data ++) {
239 0 0         if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
240 0           yaml_free(anchor);
241 0           return yaml_parser_set_composer_error_context(parser,
242             "found duplicate anchor; first occurrence",
243             alias_data->mark, "second occurrence", data.mark);
244             }
245             }
246              
247 0 0         if (!PUSH(parser, parser->aliases, data)) {
    0          
    0          
248 0           yaml_free(anchor);
249 0           return 0;
250             }
251              
252 0           return 1;
253             }
254              
255             /*
256             * Compose a node corresponding to an alias.
257             */
258              
259             static int
260 0           yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
261             {
262 0           yaml_char_t *anchor = first_event->data.alias.anchor;
263             yaml_alias_data_t *alias_data;
264              
265 0 0         for (alias_data = parser->aliases.start;
266 0           alias_data != parser->aliases.top; alias_data ++) {
267 0 0         if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
268 0           yaml_free(anchor);
269 0           return alias_data->index;
270             }
271             }
272              
273 0           yaml_free(anchor);
274 0           return yaml_parser_set_composer_error(parser, "found undefined alias",
275             first_event->start_mark);
276             }
277              
278             /*
279             * Compose a scalar node.
280             */
281              
282             static int
283 0           yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
284             {
285             yaml_node_t node;
286             int index;
287 0           yaml_char_t *tag = first_event->data.scalar.tag;
288              
289 0 0         if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1))
    0          
290 0           goto error;
291              
292 0 0         if (!tag || strcmp((char *)tag, "!") == 0) {
    0          
293 0           yaml_free(tag);
294 0           tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
295 0 0         if (!tag)
296 0           goto error;
297             }
298              
299 0           SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
300             first_event->data.scalar.length, first_event->data.scalar.style,
301             first_event->start_mark, first_event->end_mark);
302              
303 0 0         if (!PUSH(parser, parser->document->nodes, node))
    0          
    0          
304 0           goto error;
305              
306 0           index = parser->document->nodes.top - parser->document->nodes.start;
307              
308 0 0         if (!yaml_parser_register_anchor(parser, index,
309             first_event->data.scalar.anchor))
310 0           return 0;
311              
312 0           return index;
313              
314             error:
315 0           yaml_free(tag);
316 0           yaml_free(first_event->data.scalar.anchor);
317 0           yaml_free(first_event->data.scalar.value);
318 0           return 0;
319             }
320              
321             /*
322             * Compose a sequence node.
323             */
324              
325             static int
326 0           yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
327             {
328             yaml_event_t event;
329             yaml_node_t node;
330             struct {
331             yaml_node_item_t *start;
332             yaml_node_item_t *end;
333             yaml_node_item_t *top;
334 0           } items = { NULL, NULL, NULL };
335             int index, item_index;
336 0           yaml_char_t *tag = first_event->data.sequence_start.tag;
337              
338 0 0         if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1))
    0          
339 0           goto error;
340              
341 0 0         if (!tag || strcmp((char *)tag, "!") == 0) {
    0          
342 0           yaml_free(tag);
343 0           tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
344 0 0         if (!tag)
345 0           goto error;
346             }
347              
348 0 0         if (!STACK_INIT(parser, items, yaml_node_item_t*))
    0          
349 0           goto error;
350              
351 0           SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
352             first_event->data.sequence_start.style,
353             first_event->start_mark, first_event->end_mark);
354              
355 0 0         if (!PUSH(parser, parser->document->nodes, node))
    0          
    0          
356 0           goto error;
357              
358 0           index = parser->document->nodes.top - parser->document->nodes.start;
359              
360 0 0         if (!yaml_parser_register_anchor(parser, index,
361             first_event->data.sequence_start.anchor))
362 0           return 0;
363              
364 0 0         if (!yaml_parser_parse(parser, &event)) return 0;
365              
366 0 0         while (event.type != YAML_SEQUENCE_END_EVENT) {
367 0 0         if (!STACK_LIMIT(parser,
    0          
368             parser->document->nodes.start[index-1].data.sequence.items,
369 0           INT_MAX-1)) return 0;
370 0           item_index = yaml_parser_load_node(parser, &event);
371 0 0         if (!item_index) return 0;
372 0 0         if (!PUSH(parser,
    0          
    0          
373             parser->document->nodes.start[index-1].data.sequence.items,
374 0           item_index)) return 0;
375 0 0         if (!yaml_parser_parse(parser, &event)) return 0;
376             }
377              
378 0           parser->document->nodes.start[index-1].end_mark = event.end_mark;
379              
380 0           return index;
381              
382             error:
383 0           yaml_free(tag);
384 0           yaml_free(first_event->data.sequence_start.anchor);
385 0           return 0;
386             }
387              
388             /*
389             * Compose a mapping node.
390             */
391              
392             static int
393 0           yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
394             {
395             yaml_event_t event;
396             yaml_node_t node;
397             struct {
398             yaml_node_pair_t *start;
399             yaml_node_pair_t *end;
400             yaml_node_pair_t *top;
401 0           } pairs = { NULL, NULL, NULL };
402             int index;
403             yaml_node_pair_t pair;
404 0           yaml_char_t *tag = first_event->data.mapping_start.tag;
405              
406 0 0         if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1))
    0          
407 0           goto error;
408              
409 0 0         if (!tag || strcmp((char *)tag, "!") == 0) {
    0          
410 0           yaml_free(tag);
411 0           tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
412 0 0         if (!tag)
413 0           goto error;
414             }
415              
416 0 0         if (!STACK_INIT(parser, pairs, yaml_node_pair_t*))
    0          
417 0           goto error;
418              
419 0           MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
420             first_event->data.mapping_start.style,
421             first_event->start_mark, first_event->end_mark);
422              
423 0 0         if (!PUSH(parser, parser->document->nodes, node))
    0          
    0          
424 0           goto error;
425              
426 0           index = parser->document->nodes.top - parser->document->nodes.start;
427              
428 0 0         if (!yaml_parser_register_anchor(parser, index,
429             first_event->data.mapping_start.anchor))
430 0           return 0;
431              
432 0 0         if (!yaml_parser_parse(parser, &event))
433 0           return 0;
434              
435 0 0         while (event.type != YAML_MAPPING_END_EVENT) {
436 0 0         if (!STACK_LIMIT(parser,
    0          
437             parser->document->nodes.start[index-1].data.mapping.pairs,
438             INT_MAX-1))
439 0           return 0;
440 0           pair.key = yaml_parser_load_node(parser, &event);
441 0 0         if (!pair.key) return 0;
442 0 0         if (!yaml_parser_parse(parser, &event))
443 0           return 0;
444 0           pair.value = yaml_parser_load_node(parser, &event);
445 0 0         if (!pair.value)
446 0           return 0;
447 0 0         if (!PUSH(parser,
    0          
    0          
448             parser->document->nodes.start[index-1].data.mapping.pairs,
449 0           pair)) return 0;
450 0 0         if (!yaml_parser_parse(parser, &event))
451 0           return 0;
452             }
453              
454 0           parser->document->nodes.start[index-1].end_mark = event.end_mark;
455              
456 0           return index;
457              
458             error:
459 0           yaml_free(tag);
460 0           yaml_free(first_event->data.mapping_start.anchor);
461 0           return 0;
462             }
463