X-Git-Url: http://andersk.mit.edu/gitweb/libyaml.git/blobdiff_plain/625fcfe9edfbe8576ec6ef8d2d6adaed4bb86403..1560fc82ad6f642553edacae9d99f192ed480221:/src/parser.c diff --git a/src/parser.c b/src/parser.c index fe9e171..1198c73 100644 --- a/src/parser.c +++ b/src/parser.c @@ -41,72 +41,6 @@ #include "yaml_private.h" -/* - * Event initializers. - */ - -#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \ - (memset(&(event), 0, sizeof(yaml_event_t)), \ - (event).type = (event_type), \ - (event).start_mark = (event_start_mark), \ - (event).end_mark = (event_end_mark)) - -#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \ - (event).data.stream_start.encoding = (event_encoding)) - -#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark))) - -#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \ - event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \ - (event).data.document_start.version_directive = (event_version_directive), \ - (event).data.document_start.tag_directives.start = (event_tag_directives_start), \ - (event).data.document_start.tag_directives.end = (event_tag_directives_end), \ - (event).data.document_start.implicit = (event_implicit)) - -#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \ - (event).data.document_end.implicit = (event_implicit)) - -#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \ - (event).data.alias.anchor = (event_anchor)) - -#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \ - event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \ - (event).data.scalar.anchor = (event_anchor), \ - (event).data.scalar.tag = (event_tag), \ - (event).data.scalar.value = (event_value), \ - (event).data.scalar.length = (event_length), \ - (event).data.scalar.plain_implicit = (event_plain_implicit), \ - (event).data.scalar.quoted_implicit = (event_quoted_implicit), \ - (event).data.scalar.style = (event_style)) - -#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \ - event_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \ - (event).data.sequence_start.anchor = (event_anchor), \ - (event).data.sequence_start.tag = (event_tag), \ - (event).data.sequence_start.implicit = (event_implicit), \ - (event).data.sequence_start.style = (event_style)) - -#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark))) - -#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \ - event_implicit,event_style,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \ - (event).data.mapping_start.anchor = (event_anchor), \ - (event).data.mapping_start.tag = (event_tag), \ - (event).data.mapping_start.implicit = (event_implicit), \ - (event).data.mapping_start.style = (event_style)) - -#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \ - (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark))) - /* * Peek the next token in the token queue. */ @@ -238,12 +172,14 @@ yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event) assert(parser); /* Non-NULL parser object is expected. */ assert(event); /* Non-NULL event object is expected. */ + /* Erase the event object. */ + + memset(event, 0, sizeof(yaml_event_t)); + /* No events after the end of the stream or error. */ if (parser->stream_end_produced || parser->error || parser->state == YAML_PARSE_END_STATE) { - memset(event, 0, sizeof(yaml_event_t)); - return 1; } @@ -363,6 +299,8 @@ yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event) default: assert(1); /* Invalid state. */ } + + return 0; } /* @@ -381,7 +319,7 @@ yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event) if (token->type != YAML_STREAM_START_TOKEN) { return yaml_parser_set_parser_error(parser, - "did not found expected ", token->start_mark); + "did not find expected ", token->start_mark); } parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; @@ -414,6 +352,17 @@ yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, token = PEEK_TOKEN(parser); if (!token) return 0; + /* Parse extra document end indicators. */ + + if (!implicit) + { + while (token->type == YAML_DOCUMENT_END_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + } + /* Parse an implicit document. */ if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN && @@ -444,7 +393,7 @@ yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, if (!token) goto error; if (token->type != YAML_DOCUMENT_START_TOKEN) { yaml_parser_set_parser_error(parser, - "did not found expected ", token->start_mark); + "did not find expected ", token->start_mark); goto error; } if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) @@ -529,11 +478,9 @@ yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event) start_mark = end_mark = token->start_mark; - while (token->type == YAML_DOCUMENT_END_TOKEN) { + if (token->type == YAML_DOCUMENT_END_TOKEN) { end_mark = token->end_mark; SKIP_TOKEN(parser); - token = PEEK_TOKEN(parser); - if (!token) return 0; implicit = 0; } @@ -658,7 +605,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) { size_t prefix_len = strlen((char *)tag_directive->prefix); size_t suffix_len = strlen((char *)tag_suffix); - tag = yaml_malloc(prefix_len+suffix_len+1); + tag = YAML_MALLOC(prefix_len+suffix_len+1); if (!tag) { parser->error = YAML_MEMORY_ERROR; goto error; @@ -738,7 +685,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, return 1; } else if (anchor || tag) { - yaml_char_t *value = yaml_malloc(1); + yaml_char_t *value = YAML_MALLOC(1); if (!value) { parser->error = YAML_MEMORY_ERROR; goto error; @@ -754,7 +701,7 @@ yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, yaml_parser_set_parser_error_context(parser, (block ? "while parsing a block node" : "while parsing a flow node"), start_mark, - "did not found expected node content", token->start_mark); + "did not find expected node content", token->start_mark); goto error; } } @@ -813,7 +760,7 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, else if (token->type == YAML_BLOCK_END_TOKEN) { parser->state = POP(parser, parser->states); - POP(parser, parser->marks); + (void)POP(parser, parser->marks); SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -823,7 +770,7 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, { return yaml_parser_set_parser_error_context(parser, "while parsing a block collection", POP(parser, parser->marks), - "did not found expected '-' indicator", token->start_mark); + "did not find expected '-' indicator", token->start_mark); } } @@ -922,7 +869,7 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, else if (token->type == YAML_BLOCK_END_TOKEN) { parser->state = POP(parser, parser->states); - POP(parser, parser->marks); + (void)POP(parser, parser->marks); MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -932,7 +879,7 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, { return yaml_parser_set_parser_error_context(parser, "while parsing a block mapping", POP(parser, parser->marks), - "did not found expected key", token->start_mark); + "did not find expected key", token->start_mark); } } @@ -1025,7 +972,7 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, else { return yaml_parser_set_parser_error_context(parser, "while parsing a flow sequence", POP(parser, parser->marks), - "did not found expected ',' or ']'", token->start_mark); + "did not find expected ',' or ']'", token->start_mark); } } @@ -1047,7 +994,7 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, } parser->state = POP(parser, parser->states); - POP(parser, parser->marks); + (void)POP(parser, parser->marks); SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -1176,7 +1123,7 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, else { return yaml_parser_set_parser_error_context(parser, "while parsing a flow mapping", POP(parser, parser->marks), - "did not found expected ',' or '}'", token->start_mark); + "did not find expected ',' or '}'", token->start_mark); } } @@ -1207,7 +1154,7 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, } parser->state = POP(parser, parser->states); - POP(parser, parser->marks); + (void)POP(parser, parser->marks); MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); SKIP_TOKEN(parser); return 1; @@ -1261,7 +1208,7 @@ yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, { yaml_char_t *value; - value = yaml_malloc(1); + value = YAML_MALLOC(1); if (!value) { parser->error = YAML_MEMORY_ERROR; return 0; @@ -1298,7 +1245,7 @@ yaml_parser_process_directives(yaml_parser_t *parser, } tag_directives = { NULL, NULL, NULL }; yaml_token_t *token; - if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE)) + if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*)) goto error; token = PEEK_TOKEN(parser); @@ -1314,12 +1261,12 @@ yaml_parser_process_directives(yaml_parser_t *parser, goto error; } if (token->data.version_directive.major != 1 - && token->data.version_directive.minor != 1) { + || token->data.version_directive.minor != 1) { yaml_parser_set_parser_error(parser, "found incompatible YAML document", token->start_mark); goto error; } - version_directive = yaml_malloc(sizeof(yaml_version_directive_t)); + version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t); if (!version_directive) { parser->error = YAML_MEMORY_ERROR; goto error; @@ -1329,10 +1276,10 @@ yaml_parser_process_directives(yaml_parser_t *parser, } else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { - yaml_tag_directive_t value = { - token->data.tag_directive.handle, - token->data.tag_directive.prefix - }; + yaml_tag_directive_t value; + value.handle = token->data.tag_directive.handle; + value.prefix = token->data.tag_directive.prefix; + if (!yaml_parser_append_tag_directive(parser, value, 0, token->start_mark)) goto error; @@ -1344,7 +1291,7 @@ yaml_parser_process_directives(yaml_parser_t *parser, token = PEEK_TOKEN(parser); if (!token) goto error; } - + for (default_tag_directive = default_tag_directives; default_tag_directive->handle; default_tag_directive++) { if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, @@ -1358,13 +1305,19 @@ yaml_parser_process_directives(yaml_parser_t *parser, if (tag_directives_start_ref) { if (STACK_EMPTY(parser, tag_directives)) { *tag_directives_start_ref = *tag_directives_end_ref = NULL; + STACK_DEL(parser, tag_directives); } else { *tag_directives_start_ref = tag_directives.start; - *tag_directives_end_ref = tag_directives.end; + *tag_directives_end_ref = tag_directives.top; } } + else { + STACK_DEL(parser, tag_directives); + } + if (!version_directive_ref) + yaml_free(version_directive); return 1; error: @@ -1378,13 +1331,16 @@ error: return 0; } +/* + * Append a tag directive to the directives stack. + */ + static int yaml_parser_append_tag_directive(yaml_parser_t *parser, yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) { yaml_tag_directive_t *tag_directive; yaml_tag_directive_t copy = { NULL, NULL }; - int length; for (tag_directive = parser->tag_directives.start; tag_directive != parser->tag_directives.top; tag_directive ++) { @@ -1396,8 +1352,8 @@ yaml_parser_append_tag_directive(yaml_parser_t *parser, } } - copy.handle = (yaml_char_t *)yaml_strdup((char *)value.handle); - copy.prefix = (yaml_char_t *)yaml_strdup((char *)value.prefix); + copy.handle = yaml_strdup(value.handle); + copy.prefix = yaml_strdup(value.prefix); if (!copy.handle || !copy.prefix) { parser->error = YAML_MEMORY_ERROR; goto error;