Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

loader.c
Go to the documentation of this file.
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;
229 yaml_alias_data_t *alias_data;
230
231 if (!anchor) return 1;
232
233 data.anchor = anchor;
234 data.index = index;
235 data.mark = parser->document->nodes.start[index-1].start_mark;
236
237 for (alias_data = parser->aliases.start;
238 alias_data != parser->aliases.top; alias_data ++) {
239 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
240 yaml_free(anchor);
241 return yaml_parser_set_composer_error_context(parser,
242 "found duplicate anchor; first occurence",
243 alias_data->mark, "second occurence", data.mark);
244 }
245 }
246
247 if (!PUSH(parser, parser->aliases, data)) {
248 yaml_free(anchor);
249 return 0;
250 }
251
252 return 1;
253 }
254
255 /*
256 * Compose a node corresponding to an alias.
257 */
258
259 static int
260 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
261 {
262 yaml_char_t *anchor = first_event->data.alias.anchor;
263 yaml_alias_data_t *alias_data;
264
265 for (alias_data = parser->aliases.start;
266 alias_data != parser->aliases.top; alias_data ++) {
267 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
268 yaml_free(anchor);
269 return alias_data->index;
270 }
271 }
272
273 yaml_free(anchor);
274 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 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
284 {
285 yaml_node_t node;
286 int index;
287 yaml_char_t *tag = first_event->data.scalar.tag;
288
289 if (!tag || strcmp((char *)tag, "!") == 0) {
290 yaml_free(tag);
291 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
292 if (!tag) goto error;
293 }
294
295 SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
296 first_event->data.scalar.length, first_event->data.scalar.style,
297 first_event->start_mark, first_event->end_mark);
298
299 if (!PUSH(parser, parser->document->nodes, node)) goto error;
300
301 index = parser->document->nodes.top - parser->document->nodes.start;
302
303 if (!yaml_parser_register_anchor(parser, index,
304 first_event->data.scalar.anchor)) return 0;
305
306 return index;
307
308 error:
309 yaml_free(tag);
310 yaml_free(first_event->data.scalar.anchor);
311 yaml_free(first_event->data.scalar.value);
312 return 0;
313 }
314
315 /*
316 * Compose a sequence node.
317 */
318
319 static int
320 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
321 {
322 yaml_event_t event;
323 yaml_node_t node;
324 struct {
325 yaml_node_item_t *start;
326 yaml_node_item_t *end;
327 yaml_node_item_t *top;
328 } items = { NULL, NULL, NULL };
329 int index, item_index;
330 yaml_char_t *tag = first_event->data.sequence_start.tag;
331
332 if (!tag || strcmp((char *)tag, "!") == 0) {
333 yaml_free(tag);
334 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
335 if (!tag) goto error;
336 }
337
338 if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
339
340 SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
341 first_event->data.sequence_start.style,
342 first_event->start_mark, first_event->end_mark);
343
344 if (!PUSH(parser, parser->document->nodes, node)) goto error;
345
346 index = parser->document->nodes.top - parser->document->nodes.start;
347
348 if (!yaml_parser_register_anchor(parser, index,
349 first_event->data.sequence_start.anchor)) return 0;
350
351 if (!yaml_parser_parse(parser, &event)) return 0;
352
353 while (event.type != YAML_SEQUENCE_END_EVENT) {
354 item_index = yaml_parser_load_node(parser, &event);
355 if (!item_index) return 0;
356 if (!PUSH(parser,
357 parser->document->nodes.start[index-1].data.sequence.items,
358 item_index)) return 0;
359 if (!yaml_parser_parse(parser, &event)) return 0;
360 }
361
362 parser->document->nodes.start[index-1].end_mark = event.end_mark;
363
364 return index;
365
366 error:
367 yaml_free(tag);
368 yaml_free(first_event->data.sequence_start.anchor);
369 return 0;
370 }
371
372 /*
373 * Compose a mapping node.
374 */
375
376 static int
377 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
378 {
379 yaml_event_t event;
380 yaml_node_t node;
381 struct {
382 yaml_node_pair_t *start;
383 yaml_node_pair_t *end;
384 yaml_node_pair_t *top;
385 } pairs = { NULL, NULL, NULL };
386 int index;
387 yaml_node_pair_t pair;
388 yaml_char_t *tag = first_event->data.mapping_start.tag;
389
390 if (!tag || strcmp((char *)tag, "!") == 0) {
391 yaml_free(tag);
392 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
393 if (!tag) goto error;
394 }
395
396 if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
397
398 MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
399 first_event->data.mapping_start.style,
400 first_event->start_mark, first_event->end_mark);
401
402 if (!PUSH(parser, parser->document->nodes, node)) goto error;
403
404 index = parser->document->nodes.top - parser->document->nodes.start;
405
406 if (!yaml_parser_register_anchor(parser, index,
407 first_event->data.mapping_start.anchor)) return 0;
408
409 if (!yaml_parser_parse(parser, &event)) return 0;
410
411 while (event.type != YAML_MAPPING_END_EVENT) {
412 pair.key = yaml_parser_load_node(parser, &event);
413 if (!pair.key) return 0;
414 if (!yaml_parser_parse(parser, &event)) return 0;
415 pair.value = yaml_parser_load_node(parser, &event);
416 if (!pair.value) return 0;
417 if (!PUSH(parser,
418 parser->document->nodes.start[index-1].data.mapping.pairs,
419 pair)) return 0;
420 if (!yaml_parser_parse(parser, &event)) return 0;
421 }
422
423 parser->document->nodes.start[index-1].end_mark = event.end_mark;
424
425 return index;
426
427 error:
428 yaml_free(tag);
429 yaml_free(first_event->data.mapping_start.anchor);
430 return 0;
431 }
432
data
VALUE data
Definition: tcltklib.c:3368
yaml_node_s::data
union yaml_node_s::@29 data
The node data.
yaml_strdup
yaml_strdup(const yaml_char_t *str)
Definition: api.c:61
yaml_parser_load_sequence
static int yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:320
yaml_alias_data_s::mark
yaml_mark_t mark
The anchor mark.
Definition: yaml.h:1071
PUSH
#define PUSH(x)
Definition: bigdecimal.c:64
yaml_parser_parse
yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
Parse the input stream and produce the next parsing event.
Definition: parser.c:170
yaml_mark_s
The pointer position.
Definition: yaml.h:145
yaml_event_s
The event structure.
Definition: yaml.h:384
yaml_document_s::version_directive
yaml_version_directive_t * version_directive
The version directive.
Definition: yaml.h:791
yaml_document_s::end_implicit
int end_implicit
Is the document end indicator implicit?
Definition: yaml.h:804
pair
volatile VALUE pair
Definition: tkutil.c:554
yaml_node_s::start_mark
yaml_mark_t start_mark
The beginning of the node.
Definition: yaml.h:771
YAML_SEQUENCE_START_EVENT
A SEQUENCE-START event.
Definition: yaml.h:373
YAML_COMPOSER_ERROR
Cannot compose a YAML document.
Definition: yaml.h:136
yaml_event_s::document_start
struct yaml_event_s::@20::@22 document_start
The document parameters (for YAML_DOCUMENT_START_EVENT).
yaml_parser_register_anchor
static int yaml_parser_register_anchor(yaml_parser_t *parser, int index, yaml_char_t *anchor)
Definition: loader.c:225
SCALAR_NODE_INIT
#define SCALAR_NODE_INIT(node, node_tag, node_value, node_length,node_style, start_mark, end_mark)
Definition: yaml_private.h:621
YAML_MAPPING_START_EVENT
A MAPPING-START event.
Definition: yaml.h:378
yaml_parser_s
The parser structure.
Definition: yaml.h:1081
yaml_document_s::end
yaml_node_t * end
The end of the stack.
Definition: yaml.h:785
MAPPING_NODE_INIT
#define MAPPING_NODE_INIT(node, node_tag, node_pairs_start, node_pairs_end,node_style, start_mark, end_mark)
Definition: yaml_private.h:636
yaml_event_s::end_mark
yaml_mark_t end_mark
The end of the event.
Definition: yaml.h:474
yaml_node_s::mapping
struct yaml_node_s::@29::@32 mapping
The mapping parameters (for YAML_MAPPING_NODE).
INITIAL_STACK_SIZE
#define INITIAL_STACK_SIZE
Definition: yaml_private.h:76
yaml_char_t
unsigned char yaml_char_t
The character type (UTF-8 octet).
Definition: yaml.h:78
yaml_parser_s::start
const unsigned char * start
The string start pointer.
Definition: yaml.h:1123
index
int index
Definition: tcltklib.c:4478
yaml_parser_s::context
const char * context
The error context.
Definition: yaml.h:1099
yaml_parser_load_document
static int yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:165
yaml_node_pair_s
An element of a mapping node.
Definition: yaml.h:709
yaml_document_delete
yaml_document_delete(yaml_document_t *document)
Delete a YAML document and all its nodes.
Definition: api.c:1117
yaml_node_item_t
int yaml_node_item_t
An element of a sequence node.
Definition: yaml.h:706
yaml_node_s
The node structure.
Definition: yaml.h:717
yaml_alias_data_s::anchor
yaml_char_t * anchor
The anchor.
Definition: yaml.h:1067
STACK_EMPTY
#define STACK_EMPTY(context, stack)
Definition: yaml_private.h:424
yaml_node_pair_s::key
int key
The key of the element.
Definition: yaml.h:711
yaml_free
yaml_free(void *ptr)
Definition: api.c:51
YAML_DEFAULT_SEQUENCE_TAG
#define YAML_DEFAULT_SEQUENCE_TAG
The default sequence tag is !!seq.
Definition: yaml.h:685
memset
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
yaml_parser_load_alias
static int yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:260
yaml_parser_set_composer_error
static int yaml_parser_set_composer_error(yaml_parser_t *parser, const char *problem, yaml_mark_t problem_mark)
Definition: loader.c:119
yaml_parser_s::top
int * top
The top of the stack.
Definition: yaml.h:1216
yaml_parser_s::aliases
struct yaml_parser_s::@46 aliases
The alias data.
yaml_alias_data_s::index
int index
The node id.
Definition: yaml.h:1069
yaml_parser_load_mapping
static int yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:377
yaml_node_s::end_mark
yaml_mark_t end_mark
The end of the node.
Definition: yaml.h:773
YAML_DOCUMENT_START_EVENT
A DOCUMENT-START event.
Definition: yaml.h:363
YAML_DECLARE
#define YAML_DECLARE(type)
The public API declaration.
Definition: yaml.h:38
yaml_parser_delete_aliases
static void yaml_parser_delete_aliases(yaml_parser_t *parser)
Definition: loader.c:152
YAML_MAPPING_END_EVENT
A MAPPING-END event.
Definition: yaml.h:380
STACK_DEL
#define STACK_DEL(context, stack)
Definition: yaml_private.h:420
yaml_document_s::top
yaml_node_t * top
The top of the stack.
Definition: yaml.h:787
yaml_parser_load
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
Parse the input stream and produce the next YAML document.
Definition: loader.c:67
yaml_alias_data_s
This structure holds aliases data.
Definition: yaml.h:1065
yaml_parser_s::error
yaml_error_type_t error
Error type.
Definition: yaml.h:1089
yaml_document_s::start_implicit
int start_implicit
Is the document start indicator implicit?
Definition: yaml.h:802
const
#define const
Definition: strftime.c:102
YAML_SEQUENCE_END_EVENT
A SEQUENCE-END event.
Definition: yaml.h:375
yaml_node_pair_s::value
int value
The value of the element.
Definition: yaml.h:713
yaml_node_s::start
yaml_node_item_t * start
The beginning of the stack.
Definition: yaml.h:743
yaml_event_s::mapping_start
struct yaml_event_s::@20::@27 mapping_start
The mapping parameters (for YAML_MAPPING_START_EVENT).
yaml_node_s::sequence
struct yaml_node_s::@29::@31 sequence
The sequence parameters (for YAML_SEQUENCE_NODE).
yaml_document_s::start_mark
yaml_mark_t start_mark
The beginning of the document.
Definition: yaml.h:807
yaml_parser_load_scalar
static int yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:283
yaml_parser_s::context_mark
yaml_mark_t context_mark
The context position.
Definition: yaml.h:1101
yaml_parser_s::problem_mark
yaml_mark_t problem_mark
The problem position.
Definition: yaml.h:1097
end
gz end
Definition: zlib.c:2272
yaml_parser_load_node
static int yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:201
yaml_event_s::alias
struct yaml_event_s::@20::@24 alias
The alias parameters (for YAML_ALIAS_EVENT).
top
unsigned int top
Definition: nkf.c:4309
YAML_DOCUMENT_END_EVENT
A DOCUMENT-END event.
Definition: yaml.h:365
YAML_DEFAULT_SCALAR_TAG
#define YAML_DEFAULT_SCALAR_TAG
The default scalar tag is !!str.
Definition: yaml.h:683
YAML_SCALAR_EVENT
A SCALAR event.
Definition: yaml.h:370
YAML_STREAM_END_EVENT
A STREAM-END event.
Definition: yaml.h:360
yaml_event_s::data
union yaml_event_s::@20 data
The event data.
POP
#define POP(context, stack)
Definition: yaml_private.h:436
yaml_document_s::nodes
struct yaml_document_s::@35 nodes
The document nodes.
yaml_document_s::start
yaml_node_t * start
The beginning of the stack.
Definition: yaml.h:783
yaml_parser_set_composer_error_context
static int yaml_parser_set_composer_error_context(yaml_parser_t *parser, const char *context, yaml_mark_t context_mark, const char *problem, yaml_mark_t problem_mark)
Definition: loader.c:134
yaml_parser_s::document
yaml_document_t * document
The currently parsed document.
Definition: yaml.h:1297
parser
struct parser_params * parser
Definition: ripper.c:4507
YAML_STREAM_START_EVENT
A STREAM-START event.
Definition: yaml.h:358
assert
#define assert(condition)
Definition: ossl.h:45
SEQUENCE_NODE_INIT
#define SEQUENCE_NODE_INIT(node, node_tag, node_items_start, node_items_end,node_style, start_mark, end_mark)
Definition: yaml_private.h:628
yaml_parser_s::problem
const char * problem
Error description.
Definition: yaml.h:1091
STACK_INIT
#define STACK_INIT(context, stack, size)
Definition: yaml_private.h:412
YAML_DEFAULT_MAPPING_TAG
#define YAML_DEFAULT_MAPPING_TAG
The default mapping tag is !!map.
Definition: yaml.h:687
yaml_document_s::tag_directives
struct yaml_document_s::@36 tag_directives
The list of tag directives.
yaml_private.h
yaml_event_s::sequence_start
struct yaml_event_s::@20::@26 sequence_start
The sequence parameters (for YAML_SEQUENCE_START_EVENT).
NULL
#define NULL
Definition: _sdbm.c:103
yaml_document_s
The document structure.
Definition: yaml.h:778
yaml_event_s::type
yaml_event_type_t type
The event type.
Definition: yaml.h:387
yaml_event_s::scalar
struct yaml_event_s::@20::@25 scalar
The scalar parameters (for YAML_SCALAR_EVENT).
yaml_document_s::end_mark
yaml_mark_t end_mark
The end of the document.
Definition: yaml.h:809
YAML_ALIAS_EVENT
An ALIAS event.
Definition: yaml.h:368
yaml_event_s::start_mark
yaml_mark_t start_mark
The beginning of the event.
Definition: yaml.h:472