00001
00002 #include "yaml_private.h"
00003
00004
00005
00006
00007
00008 YAML_DECLARE(int)
00009 yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
00010
00011
00012
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
00027
00028
00029 static int
00030 yaml_parser_register_anchor(yaml_parser_t *parser,
00031 int index, yaml_char_t *anchor);
00032
00033
00034
00035
00036
00037 static void
00038 yaml_parser_delete_aliases(yaml_parser_t *parser);
00039
00040
00041
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
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);
00072 assert(document);
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
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
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
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
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
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
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
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
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);
00214 return 0;
00215 }
00216
00217 return 0;
00218 }
00219
00220
00221
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
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
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 ptrdiff_t node_index;
00287 int index;
00288 yaml_char_t *tag = first_event->data.scalar.tag;
00289
00290 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
00291
00292 if (!tag || strcmp((char *)tag, "!") == 0) {
00293 yaml_free(tag);
00294 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
00295 if (!tag) goto error;
00296 }
00297
00298 SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
00299 first_event->data.scalar.length, first_event->data.scalar.style,
00300 first_event->start_mark, first_event->end_mark);
00301
00302 if (!PUSH(parser, parser->document->nodes, node)) goto error;
00303
00304 node_index = parser->document->nodes.top - parser->document->nodes.start;
00305 #if PTRDIFF_MAX > INT_MAX
00306 if (node_index > INT_MAX) goto error;
00307 #endif
00308 index = (int)node_index;
00309
00310 if (!yaml_parser_register_anchor(parser, index,
00311 first_event->data.scalar.anchor)) return 0;
00312
00313 return index;
00314
00315 error:
00316 yaml_free(tag);
00317 yaml_free(first_event->data.scalar.anchor);
00318 yaml_free(first_event->data.scalar.value);
00319 return 0;
00320 }
00321
00322
00323
00324
00325
00326 static int
00327 yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
00328 {
00329 yaml_event_t event;
00330 yaml_node_t node;
00331 struct {
00332 yaml_node_item_t *start;
00333 yaml_node_item_t *end;
00334 yaml_node_item_t *top;
00335 } items = { NULL, NULL, NULL };
00336 int index, item_index;
00337 ptrdiff_t node_index;
00338 yaml_char_t *tag = first_event->data.sequence_start.tag;
00339
00340 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
00341
00342 if (!tag || strcmp((char *)tag, "!") == 0) {
00343 yaml_free(tag);
00344 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
00345 if (!tag) goto error;
00346 }
00347
00348 if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
00349
00350 SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
00351 first_event->data.sequence_start.style,
00352 first_event->start_mark, first_event->end_mark);
00353
00354 if (!PUSH(parser, parser->document->nodes, node)) goto error;
00355
00356 node_index = parser->document->nodes.top - parser->document->nodes.start;
00357 #if PTRDIFF_MAX > INT_MAX
00358 if (node_index > INT_MAX) goto error;
00359 #endif
00360 index = (int)node_index;
00361
00362 if (!yaml_parser_register_anchor(parser, index,
00363 first_event->data.sequence_start.anchor)) return 0;
00364
00365 if (!yaml_parser_parse(parser, &event)) return 0;
00366
00367 while (event.type != YAML_SEQUENCE_END_EVENT) {
00368 if (!STACK_LIMIT(parser,
00369 parser->document->nodes.start[index-1].data.sequence.items,
00370 INT_MAX-1)) return 0;
00371 item_index = yaml_parser_load_node(parser, &event);
00372 if (!item_index) return 0;
00373 if (!PUSH(parser,
00374 parser->document->nodes.start[index-1].data.sequence.items,
00375 item_index)) return 0;
00376 if (!yaml_parser_parse(parser, &event)) return 0;
00377 }
00378
00379 parser->document->nodes.start[index-1].end_mark = event.end_mark;
00380
00381 return index;
00382
00383 error:
00384 yaml_free(tag);
00385 yaml_free(first_event->data.sequence_start.anchor);
00386 return 0;
00387 }
00388
00389
00390
00391
00392
00393 static int
00394 yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
00395 {
00396 yaml_event_t event;
00397 yaml_node_t node;
00398 struct {
00399 yaml_node_pair_t *start;
00400 yaml_node_pair_t *end;
00401 yaml_node_pair_t *top;
00402 } pairs = { NULL, NULL, NULL };
00403 int index;
00404 ptrdiff_t node_index;
00405 yaml_node_pair_t pair;
00406 yaml_char_t *tag = first_event->data.mapping_start.tag;
00407
00408 if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
00409
00410 if (!tag || strcmp((char *)tag, "!") == 0) {
00411 yaml_free(tag);
00412 tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
00413 if (!tag) goto error;
00414 }
00415
00416 if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
00417
00418 MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
00419 first_event->data.mapping_start.style,
00420 first_event->start_mark, first_event->end_mark);
00421
00422 if (!PUSH(parser, parser->document->nodes, node)) goto error;
00423
00424 node_index = parser->document->nodes.top - parser->document->nodes.start;
00425 #if PTRDIFF_MAX > INT_MAX
00426 if (node_index > INT_MAX) goto error;
00427 #endif
00428 index = (int)node_index;
00429
00430 if (!yaml_parser_register_anchor(parser, index,
00431 first_event->data.mapping_start.anchor)) return 0;
00432
00433 if (!yaml_parser_parse(parser, &event)) return 0;
00434
00435 while (event.type != YAML_MAPPING_END_EVENT) {
00436 if (!STACK_LIMIT(parser,
00437 parser->document->nodes.start[index-1].data.mapping.pairs,
00438 INT_MAX-1)) return 0;
00439 pair.key = yaml_parser_load_node(parser, &event);
00440 if (!pair.key) return 0;
00441 if (!yaml_parser_parse(parser, &event)) return 0;
00442 pair.value = yaml_parser_load_node(parser, &event);
00443 if (!pair.value) return 0;
00444 if (!PUSH(parser,
00445 parser->document->nodes.start[index-1].data.mapping.pairs,
00446 pair)) return 0;
00447 if (!yaml_parser_parse(parser, &event)) return 0;
00448 }
00449
00450 parser->document->nodes.start[index-1].end_mark = event.end_mark;
00451
00452 return index;
00453
00454 error:
00455 yaml_free(tag);
00456 yaml_free(first_event->data.mapping_start.anchor);
00457 return 0;
00458 }
00459
00460