Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 00002 #include "yaml_private.h" 00003 00004 /* 00005 * API functions. 00006 */ 00007 00008 YAML_DECLARE(int) 00009 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); 00010 00011 /* 00012 * Error handling. 00013 */ 00014 00015 static int 00016 yaml_parser_set_composer_error(yaml_parser_t *parser, 00017 const char *problem, yaml_mark_t problem_mark); 00018 00019 static int 00020 yaml_parser_set_composer_error_context(yaml_parser_t *parser, 00021 const char *context, yaml_mark_t context_mark, 00022 const char *problem, yaml_mark_t problem_mark); 00023 00024 00025 /* 00026 * Alias handling. 00027 */ 00028 00029 static int 00030 yaml_parser_register_anchor(yaml_parser_t *parser, 00031 int index, yaml_char_t *anchor); 00032 00033 /* 00034 * Clean up functions. 00035 */ 00036 00037 static void 00038 yaml_parser_delete_aliases(yaml_parser_t *parser); 00039 00040 /* 00041 * Composer functions. 00042 */ 00043 00044 static int 00045 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event); 00046 00047 static int 00048 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event); 00049 00050 static int 00051 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event); 00052 00053 static int 00054 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event); 00055 00056 static int 00057 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event); 00058 00059 static int 00060 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event); 00061 00062 /* 00063 * Load the next document of the stream. 00064 */ 00065 00066 YAML_DECLARE(int) 00067 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document) 00068 { 00069 yaml_event_t event; 00070 00071 assert(parser); /* Non-NULL parser object is expected. */ 00072 assert(document); /* Non-NULL document object is expected. */ 00073 00074 memset(document, 0, sizeof(yaml_document_t)); 00075 if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE)) 00076 goto error; 00077 00078 if (!parser->stream_start_produced) { 00079 if (!yaml_parser_parse(parser, &event)) goto error; 00080 assert(event.type == YAML_STREAM_START_EVENT); 00081 /* STREAM-START is expected. */ 00082 } 00083 00084 if (parser->stream_end_produced) { 00085 return 1; 00086 } 00087 00088 if (!yaml_parser_parse(parser, &event)) goto error; 00089 if (event.type == YAML_STREAM_END_EVENT) { 00090 return 1; 00091 } 00092 00093 if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE)) 00094 goto error; 00095 00096 parser->document = document; 00097 00098 if (!yaml_parser_load_document(parser, &event)) goto error; 00099 00100 yaml_parser_delete_aliases(parser); 00101 parser->document = NULL; 00102 00103 return 1; 00104 00105 error: 00106 00107 yaml_parser_delete_aliases(parser); 00108 yaml_document_delete(document); 00109 parser->document = NULL; 00110 00111 return 0; 00112 } 00113 00114 /* 00115 * Set composer error. 00116 */ 00117 00118 static int 00119 yaml_parser_set_composer_error(yaml_parser_t *parser, 00120 const char *problem, yaml_mark_t problem_mark) 00121 { 00122 parser->error = YAML_COMPOSER_ERROR; 00123 parser->problem = problem; 00124 parser->problem_mark = problem_mark; 00125 00126 return 0; 00127 } 00128 00129 /* 00130 * Set composer error with context. 00131 */ 00132 00133 static int 00134 yaml_parser_set_composer_error_context(yaml_parser_t *parser, 00135 const char *context, yaml_mark_t context_mark, 00136 const char *problem, yaml_mark_t problem_mark) 00137 { 00138 parser->error = YAML_COMPOSER_ERROR; 00139 parser->context = context; 00140 parser->context_mark = context_mark; 00141 parser->problem = problem; 00142 parser->problem_mark = problem_mark; 00143 00144 return 0; 00145 } 00146 00147 /* 00148 * Delete the stack of aliases. 00149 */ 00150 00151 static void 00152 yaml_parser_delete_aliases(yaml_parser_t *parser) 00153 { 00154 while (!STACK_EMPTY(parser, parser->aliases)) { 00155 yaml_free(POP(parser, parser->aliases).anchor); 00156 } 00157 STACK_DEL(parser, parser->aliases); 00158 } 00159 00160 /* 00161 * Compose a document object. 00162 */ 00163 00164 static int 00165 yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event) 00166 { 00167 yaml_event_t event; 00168 00169 assert(first_event->type == YAML_DOCUMENT_START_EVENT); 00170 /* DOCUMENT-START is expected. */ 00171 00172 parser->document->version_directive 00173 = first_event->data.document_start.version_directive; 00174 parser->document->tag_directives.start 00175 = first_event->data.document_start.tag_directives.start; 00176 parser->document->tag_directives.end 00177 = first_event->data.document_start.tag_directives.end; 00178 parser->document->start_implicit 00179 = first_event->data.document_start.implicit; 00180 parser->document->start_mark = first_event->start_mark; 00181 00182 if (!yaml_parser_parse(parser, &event)) return 0; 00183 00184 if (!yaml_parser_load_node(parser, &event)) return 0; 00185 00186 if (!yaml_parser_parse(parser, &event)) return 0; 00187 assert(event.type == YAML_DOCUMENT_END_EVENT); 00188 /* DOCUMENT-END is expected. */ 00189 00190 parser->document->end_implicit = event.data.document_end.implicit; 00191 parser->document->end_mark = event.end_mark; 00192 00193 return 1; 00194 } 00195 00196 /* 00197 * Compose a node. 00198 */ 00199 00200 static int 00201 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event) 00202 { 00203 switch (first_event->type) { 00204 case YAML_ALIAS_EVENT: 00205 return yaml_parser_load_alias(parser, first_event); 00206 case YAML_SCALAR_EVENT: 00207 return yaml_parser_load_scalar(parser, first_event); 00208 case YAML_SEQUENCE_START_EVENT: 00209 return yaml_parser_load_sequence(parser, first_event); 00210 case YAML_MAPPING_START_EVENT: 00211 return yaml_parser_load_mapping(parser, first_event); 00212 default: 00213 assert(0); /* Could not happen. */ 00214 return 0; 00215 } 00216 00217 return 0; 00218 } 00219 00220 /* 00221 * Add an anchor. 00222 */ 00223 00224 static int 00225 yaml_parser_register_anchor(yaml_parser_t *parser, 00226 int index, yaml_char_t *anchor) 00227 { 00228 yaml_alias_data_t data; 00229 yaml_alias_data_t *alias_data; 00230 00231 if (!anchor) return 1; 00232 00233 data.anchor = anchor; 00234 data.index = index; 00235 data.mark = parser->document->nodes.start[index-1].start_mark; 00236 00237 for (alias_data = parser->aliases.start; 00238 alias_data != parser->aliases.top; alias_data ++) { 00239 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { 00240 yaml_free(anchor); 00241 return yaml_parser_set_composer_error_context(parser, 00242 "found duplicate anchor; first occurence", 00243 alias_data->mark, "second occurence", data.mark); 00244 } 00245 } 00246 00247 if (!PUSH(parser, parser->aliases, data)) { 00248 yaml_free(anchor); 00249 return 0; 00250 } 00251 00252 return 1; 00253 } 00254 00255 /* 00256 * Compose a node corresponding to an alias. 00257 */ 00258 00259 static int 00260 yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event) 00261 { 00262 yaml_char_t *anchor = first_event->data.alias.anchor; 00263 yaml_alias_data_t *alias_data; 00264 00265 for (alias_data = parser->aliases.start; 00266 alias_data != parser->aliases.top; alias_data ++) { 00267 if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { 00268 yaml_free(anchor); 00269 return alias_data->index; 00270 } 00271 } 00272 00273 yaml_free(anchor); 00274 return yaml_parser_set_composer_error(parser, "found undefined alias", 00275 first_event->start_mark); 00276 } 00277 00278 /* 00279 * Compose a scalar node. 00280 */ 00281 00282 static int 00283 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) 00284 { 00285 yaml_node_t node; 00286 int index; 00287 yaml_char_t *tag = first_event->data.scalar.tag; 00288 00289 if (!tag || strcmp((char *)tag, "!") == 0) { 00290 yaml_free(tag); 00291 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); 00292 if (!tag) goto error; 00293 } 00294 00295 SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value, 00296 first_event->data.scalar.length, first_event->data.scalar.style, 00297 first_event->start_mark, first_event->end_mark); 00298 00299 if (!PUSH(parser, parser->document->nodes, node)) goto error; 00300 00301 index = parser->document->nodes.top - parser->document->nodes.start; 00302 00303 if (!yaml_parser_register_anchor(parser, index, 00304 first_event->data.scalar.anchor)) return 0; 00305 00306 return index; 00307 00308 error: 00309 yaml_free(tag); 00310 yaml_free(first_event->data.scalar.anchor); 00311 yaml_free(first_event->data.scalar.value); 00312 return 0; 00313 } 00314 00315 /* 00316 * Compose a sequence node. 00317 */ 00318 00319 static int 00320 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) 00321 { 00322 yaml_event_t event; 00323 yaml_node_t node; 00324 struct { 00325 yaml_node_item_t *start; 00326 yaml_node_item_t *end; 00327 yaml_node_item_t *top; 00328 } items = { NULL, NULL, NULL }; 00329 int index, item_index; 00330 yaml_char_t *tag = first_event->data.sequence_start.tag; 00331 00332 if (!tag || strcmp((char *)tag, "!") == 0) { 00333 yaml_free(tag); 00334 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); 00335 if (!tag) goto error; 00336 } 00337 00338 if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error; 00339 00340 SEQUENCE_NODE_INIT(node, tag, items.start, items.end, 00341 first_event->data.sequence_start.style, 00342 first_event->start_mark, first_event->end_mark); 00343 00344 if (!PUSH(parser, parser->document->nodes, node)) goto error; 00345 00346 index = parser->document->nodes.top - parser->document->nodes.start; 00347 00348 if (!yaml_parser_register_anchor(parser, index, 00349 first_event->data.sequence_start.anchor)) return 0; 00350 00351 if (!yaml_parser_parse(parser, &event)) return 0; 00352 00353 while (event.type != YAML_SEQUENCE_END_EVENT) { 00354 item_index = yaml_parser_load_node(parser, &event); 00355 if (!item_index) return 0; 00356 if (!PUSH(parser, 00357 parser->document->nodes.start[index-1].data.sequence.items, 00358 item_index)) return 0; 00359 if (!yaml_parser_parse(parser, &event)) return 0; 00360 } 00361 00362 parser->document->nodes.start[index-1].end_mark = event.end_mark; 00363 00364 return index; 00365 00366 error: 00367 yaml_free(tag); 00368 yaml_free(first_event->data.sequence_start.anchor); 00369 return 0; 00370 } 00371 00372 /* 00373 * Compose a mapping node. 00374 */ 00375 00376 static int 00377 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) 00378 { 00379 yaml_event_t event; 00380 yaml_node_t node; 00381 struct { 00382 yaml_node_pair_t *start; 00383 yaml_node_pair_t *end; 00384 yaml_node_pair_t *top; 00385 } pairs = { NULL, NULL, NULL }; 00386 int index; 00387 yaml_node_pair_t pair; 00388 yaml_char_t *tag = first_event->data.mapping_start.tag; 00389 00390 if (!tag || strcmp((char *)tag, "!") == 0) { 00391 yaml_free(tag); 00392 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); 00393 if (!tag) goto error; 00394 } 00395 00396 if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error; 00397 00398 MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end, 00399 first_event->data.mapping_start.style, 00400 first_event->start_mark, first_event->end_mark); 00401 00402 if (!PUSH(parser, parser->document->nodes, node)) goto error; 00403 00404 index = parser->document->nodes.top - parser->document->nodes.start; 00405 00406 if (!yaml_parser_register_anchor(parser, index, 00407 first_event->data.mapping_start.anchor)) return 0; 00408 00409 if (!yaml_parser_parse(parser, &event)) return 0; 00410 00411 while (event.type != YAML_MAPPING_END_EVENT) { 00412 pair.key = yaml_parser_load_node(parser, &event); 00413 if (!pair.key) return 0; 00414 if (!yaml_parser_parse(parser, &event)) return 0; 00415 pair.value = yaml_parser_load_node(parser, &event); 00416 if (!pair.value) return 0; 00417 if (!PUSH(parser, 00418 parser->document->nodes.start[index-1].data.mapping.pairs, 00419 pair)) return 0; 00420 if (!yaml_parser_parse(parser, &event)) return 0; 00421 } 00422 00423 parser->document->nodes.start[index-1].end_mark = event.end_mark; 00424 00425 return index; 00426 00427 error: 00428 yaml_free(tag); 00429 yaml_free(first_event->data.mapping_start.anchor); 00430 return 0; 00431 } 00432 00433