From f75fdf3b557dd71c4151db91814e2bdcf4568982 Mon Sep 17 00:00:00 2001 From: xi Date: Mon, 3 Jul 2006 13:34:57 +0000 Subject: Add event constructors and destructors. git-svn-id: http://svn.pyyaml.org/libyaml/trunk@199 18f92427-320e-0410-9341-c67f048884a3 --- include/yaml/yaml.h | 277 +++++++++++++++++++++++++++++++++++++++++++++++----- src/api.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++- src/reader.c | 2 +- 3 files changed, 511 insertions(+), 27 deletions(-) diff --git a/include/yaml/yaml.h b/include/yaml/yaml.h index 6acbb54..7ca4a9b 100644 --- a/include/yaml/yaml.h +++ b/include/yaml/yaml.h @@ -77,6 +77,22 @@ yaml_get_version(int *major, int *minor, int *patch); /** The character type (UTF-8 octet). */ typedef unsigned char yaml_char_t; +/** The version directive data. */ +typedef struct { + /** The major version number. */ + int major; + /** The minor version number. */ + int minor; +} yaml_version_directive_t; + +/** The tag directive data. */ +typedef struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag prefix. */ + yaml_char_t *prefix; +} yaml_tag_directive_t; + /** The stream encoding. */ typedef enum { YAML_ANY_ENCODING, @@ -194,11 +210,23 @@ typedef struct { /** The token data. */ union { - /** The stream encoding (for @c YAML_STREAM_START_TOKEN). */ - yaml_encoding_t encoding; + /** The stream start (for @c YAML_STREAM_START_TOKEN). */ + struct { + /** The stream encoding. */ + yaml_encoding_t encoding; + } stream_start; + + /** The alias (for @c YAML_ALIAS_TOKEN). */ + struct { + /** The alias value. */ + yaml_char_t *value; + } alias; - /** The anchor (for @c YAML_ALIAS_TOKEN and @c YAML_ANCHOR_TOKEN). */ - yaml_char_t *anchor; + /** The anchor (for @c YAML_ANCHOR_TOKEN). */ + struct { + /** The anchor value. */ + yaml_char_t *value; + } anchor; /** The tag (for @c YAML_TAG_TOKEN). */ struct { @@ -419,8 +447,12 @@ yaml_token_delete(yaml_token_t *token); /** @} */ -/* +/** + * @defgroup events Events + * @{ + */ +/** Event types. */ typedef enum { YAML_STREAM_START_EVENT, YAML_STREAM_END_EVENT, @@ -438,57 +470,258 @@ typedef enum { YAML_MAPPING_END_EVENT } yaml_event_type_t; +/** The event structure. */ typedef struct { + + /** The event type. */ yaml_event_type_t type; + + /** The event data. */ union { + + /** The stream parameters (for @c YAML_STREAM_START_EVENT). */ struct { + /** The document encoding. */ yaml_encoding_t encoding; } stream_start; + + /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */ struct { - struct { - int major; - int minor; - } version; - struct { - char *handle; - char *prefix; - } **tag_pairs; + /** The version directive. */ + yaml_version_directive_t *version_directive; + /** The list of tag directives. */ + yaml_tag_directive_t **tag_directives; + /** Is the document indicator implicit? */ int implicit; } document_start; + + /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */ struct { + /** Is the document end indicator implicit? */ int implicit; } document_end; + + /** The alias parameters (for @c YAML_ALIAS_EVENT). */ struct { - char *anchor; + /** The anchor. */ + yaml_char_t *anchor; } alias; + + /** The scalar parameters (for @c YAML_SCALAR_EVENT). */ struct { - char *anchor; - char *tag; - char *value; + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ size_t length; + /** Is the tag optional for the plain style? */ int plain_implicit; + /** Is the tag optional for any non-plain style? */ int quoted_implicit; + /** The scalar style. */ yaml_scalar_style_t style; } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */ struct { - char *anchor; - char *tag; + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ int implicit; + /** The sequence style. */ yaml_sequence_style_t style; } sequence_start; + + /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */ struct { - char *anchor; - char *tag; + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ int implicit; + /** The mapping style. */ yaml_mapping_style_t style; } mapping_start; + } data; + + /** The beginning of the token. */ yaml_mark_t start_mark; + + /** The end of the token. */ yaml_mark_t end_mark; } yaml_event_t; -*/ +/** + * Create a new @c YAML_STREAM_START_EVENT event. + * + * @param[in] encoding The stream encoding. + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_stream_start_event_new(yaml_encoding_t encoding, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_STREAM_END_TOKEN event. + * + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_DOCUMENT_START_EVENT event. + * + * @param[in] version_directive The version directive or @c NULL. + * @param[in] tag_directives A list of tag directives or @c NULL. + * @param[in] implicit Is the document indicator present? + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_document_start_event_new(yaml_version_directive_t *version_directive, + yaml_tag_directive_t **tag_directives, int implicit, + yaml_mark_t start_mark, yaml_mark_t end_mark); +/** + * Create a new @c YAML_DOCUMENT_END_EVENT event. + * + * @param[in] implicit Is the document end indicator present? + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_document_end_event_new(int implicit, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_ALIAS_EVENT event. + * + * @param[in] anchor The anchor value. + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_alias_event_new(yaml_char_t *anchor, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_SCALAR_EVENT event. + * + * @param[in] anchor The anchor value or @c NULL. + * @param[in] tag The tag value or @c NULL. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] plain_implicit Is the tag optional for the plain style? + * @param[in] quoted_implicit Is the tag optional for any non-plain style? + * @param[in] style The scalar style. + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, size_t length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_SEQUENCE_START_EVENT event. + * + * @param[in] anchor The anchor value or @c NULL. + * @param[in] tag The tag value or @c NULL. + * @param[in] implicit Is the tag optional? + * @param[in] style The sequence style. + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_sequence_start_new(yaml_char_t *anchor, yaml_char_t *tag, + int implicit, yaml_sequence_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_SEQUENCE_END_EVENT event. + * + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_sequence_end_new(yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_MAPPING_START_EVENT event. + * + * @param[in] anchor The anchor value or @c NULL. + * @param[in] tag The tag value or @c NULL. + * @param[in] implicit Is the tag optional? + * @param[in] style The mapping style. + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_mapping_start_new(yaml_char_t *anchor, yaml_char_t *tag, + int implicit, yaml_mapping_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Create a new @c YAML_MAPPING_END_EVENT event. + * + * @param[in] start_mark The beginning of the event. + * @param[in] end_mark The end of the event. + * + * @returns A new event object, or @c NULL on error. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_mapping_end_new(yaml_mark_t start_mark, yaml_mark_t end_mark); + +/** + * Destroy an event object. + * + * @param[in] event An event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event); + +/** @} */ /** * @defgroup parser Parser Definitions diff --git a/src/api.c b/src/api.c index 2af17c3..88e03e7 100644 --- a/src/api.c +++ b/src/api.c @@ -276,7 +276,7 @@ yaml_stream_start_token_new(yaml_encoding_t encoding, if (!token) return NULL; - token->data.encoding = encoding; + token->data.stream_start.encoding = encoding; return token; } @@ -347,7 +347,7 @@ yaml_alias_token_new(yaml_char_t *anchor, if (!token) return NULL; - token->data.anchor = anchor; + token->data.alias.value = anchor; return token; } @@ -365,7 +365,7 @@ yaml_anchor_token_new(yaml_char_t *anchor, if (!token) return NULL; - token->data.anchor = anchor; + token->data.anchor.value = anchor; return token; } @@ -427,8 +427,11 @@ yaml_token_delete(yaml_token_t *token) break; case YAML_ALIAS_TOKEN: + yaml_free(token->data.alias.value); + break; + case YAML_ANCHOR_TOKEN: - yaml_free(token->data.anchor); + yaml_free(token->data.anchor.value); break; case YAML_TAG_TOKEN: @@ -446,3 +449,251 @@ yaml_token_delete(yaml_token_t *token) yaml_free(token); } +/* + * Create an event. + */ + +static yaml_event_t * +yaml_event_new(yaml_event_type_t type, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_malloc(sizeof(yaml_event_t)); + + if (!event) return NULL; + + memset(event, 0, sizeof(yaml_event_t)); + + event->type = type; + event->start_mark = start_mark; + event->end_mark = end_mark; + + return event; +} + +/* + * Create a STREAM-START event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_stream_start_event_new(yaml_encoding_t encoding, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_STREAM_START_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.stream_start.encoding = encoding; + + return event; +} + +/* + * Create a STREAM-END event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + return yaml_event_new(YAML_STREAM_END_EVENT, start_mark, end_mark); +} + +/* + * Create a DOCUMENT-START event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_document_start_event_new(yaml_version_directive_t *version_directive, + yaml_tag_directive_t **tag_directives, int implicit, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_START_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.document_start.version_directive = version_directive; + event->data.document_start.tag_directives = tag_directives; + event->data.document_start.implicit = implicit; + + return event; +} + +/* + * Create a DOCUMENT-END event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_document_end_event_new(int implicit, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_END_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.document_end.implicit = implicit; + + return event; +} + +/* + * Create an ALIAS event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_alias_event_new(yaml_char_t *anchor, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_ALIAS_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.alias.anchor = anchor; + + return event; +} + +/* + * Create a SCALAR event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, size_t length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_SCALAR_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.scalar.anchor = anchor; + event->data.scalar.tag = tag; + event->data.scalar.value = value; + event->data.scalar.length = length; + event->data.scalar.plain_implicit = plain_implicit; + event->data.scalar.quoted_implicit = quoted_implicit; + event->data.scalar.style = style; + + return event; +} + +/* + * Create a SEQUENCE-START event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_sequence_start_new(yaml_char_t *anchor, yaml_char_t *tag, + int implicit, yaml_sequence_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_SEQUENCE_START_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.sequence_start.anchor = anchor; + event->data.sequence_start.tag = tag; + event->data.sequence_start.implicit = implicit; + event->data.sequence_start.style = style; + + return event; +} + +/* + * Create a SEQUENCE-END event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_sequence_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + return yaml_event_new(YAML_SEQUENCE_END_EVENT, start_mark, end_mark); +} + +/* + * Create a MAPPING-START event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_mapping_start_new(yaml_char_t *anchor, yaml_char_t *tag, + int implicit, yaml_mapping_style_t style, + yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + yaml_event_t *event = yaml_event_new(YAML_MAPPING_START_EVENT, + start_mark, end_mark); + + if (!event) return NULL; + + event->data.mapping_start.anchor = anchor; + event->data.mapping_start.tag = tag; + event->data.mapping_start.implicit = implicit; + event->data.mapping_start.style = style; + + return event; +} + +/* + * Create a MAPPING-END event. + */ + +YAML_DECLARE(yaml_event_t *) +yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark) +{ + return yaml_event_new(YAML_MAPPING_END_EVENT, start_mark, end_mark); +} + +/* + * Destroy an event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event) +{ + assert(event); /* Non-NULL event object expected. */ + + switch (event->type) + { + case YAML_DOCUMENT_START_EVENT: + yaml_free(event->data.document_start.version_directive); + if (event->data.document_start.tag_directives) { + yaml_tag_directive_t **tag_directive; + for (tag_directive = event->data.document_start.tag_directives; + *tag_directive; tag_directive++) { + yaml_free((*tag_directive)->handle); + yaml_free((*tag_directive)->prefix); + yaml_free(*tag_directive); + } + yaml_free(event->data.document_start.tag_directives); + } + break; + + case YAML_ALIAS_EVENT: + yaml_free(event->data.alias.anchor); + break; + + case YAML_SCALAR_EVENT: + yaml_free(event->data.scalar.anchor); + yaml_free(event->data.scalar.tag); + yaml_free(event->data.scalar.value); + break; + + case YAML_SEQUENCE_START_EVENT: + yaml_free(event->data.sequence_start.anchor); + yaml_free(event->data.sequence_start.tag); + break; + + case YAML_MAPPING_START_EVENT: + yaml_free(event->data.mapping_start.anchor); + yaml_free(event->data.mapping_start.tag); + break; + } + + memset(event, 0, sizeof(yaml_event_t)); + + yaml_free(event); +} + diff --git a/src/reader.c b/src/reader.c index e4e6f1a..946d298 100644 --- a/src/reader.c +++ b/src/reader.c @@ -148,7 +148,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length) size_t size = parser->buffer_end - parser->pointer; memmove(parser->buffer, parser->pointer, size); parser->pointer = parser->buffer; - parser->buffer_end -= size; + parser->buffer_end = parser->buffer + size; } else if (parser->pointer == parser->buffer_end) { parser->pointer = parser->buffer; -- cgit v1.2.1