Commits

Kirill Simonov committed 20a0934

Add event constructors and destructors.

Comments (0)

Files changed (3)

include/yaml/yaml.h

 /** 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,
     /** 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 anchor (for @c YAML_ALIAS_TOKEN and @c YAML_ANCHOR_TOKEN). */
-        yaml_char_t *anchor;
+        /** The alias (for @c YAML_ALIAS_TOKEN). */
+        struct {
+            /** The alias value. */
+            yaml_char_t *value;
+        } alias;
+
+        /** The anchor (for @c YAML_ANCHOR_TOKEN). */
+        struct {
+            /** The anchor value. */
+            yaml_char_t *value;
+        } anchor;
 
         /** The tag (for @c YAML_TAG_TOKEN). */
         struct {
 
 /** @} */
 
-/*
+/**
+ * @defgroup events Events
+ * @{
+ */
 
+/** Event types. */
 typedef enum {
     YAML_STREAM_START_EVENT,
     YAML_STREAM_END_EVENT,
     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
 
     if (!token) return NULL;
 
-    token->data.encoding = encoding;
+    token->data.stream_start.encoding = encoding;
 
     return token;
 }
 
     if (!token) return NULL;
 
-    token->data.anchor = anchor;
+    token->data.alias.value = anchor;
 
     return token;
 }
 
     if (!token) return NULL;
 
-    token->data.anchor = anchor;
+    token->data.anchor.value = anchor;
 
     return 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:
     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);
+}
+
         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;