Commits

Kirill Simonov committed 90c7f94

Minor API updates.

  • Participants
  • Parent commits b3f4201

Comments (0)

Files changed (4)

File include/yaml.h

  * the terms of the MIT license; see the file LICENCE for more details.
  *****************************************************************************/
 
+/*****************************************************************************
+ * General guidelines.
+ *****************************************************************************/
+
 /*
- * General guidelines.
- *
- * Naming conventions: all functions exported by LibYAML starts with the `yaml_` prefix;
- * types starts with `yaml_` and ends with `_t`; macros and enumerations starts
- * with `YAML_`.
+ * Basic conventions.
+ *
+ * All functions exported by exported by LibYAML starts with the the prefix
+ * `yaml_`; types starts with `yaml_` and ends with `_t`; macros and
+ * enumeration values start with `YAML_`.
+ *
+ * A function may serve as method for an object or a particular type; such
+ * functions start with `yaml_<type>`.  A type constructor is named
+ * `yaml_<type>_new()`, a type destructor is named `yaml_<type>_delete()`.
+ *
+ * A function signifies whether it succeeded or failed with its return value;
+ * typically it is `1` for success, `0` for failure.  Functions that return a
+ * pointer may indicate an error condition by returning `NULL`.  Functions that
+ * never fail commonly do not return any value.  For most of the functions, an
+ * error value means that the function is unable to allocate some memory
+ * buffer.  For parsing and emitting functions, detailed information on the
+ * nature of the error could be obtained.
+ *
+ * LibYAML provides two active objects: parsers and emitters and three passive
+ * objects: tokens, events and documents.
+ *
+ * 
+ *
  *
  * FIXME: Calling conventions.
  * FIXME: Memory allocation.
  * FIXME: Errors and exceptions.
  * FIXME: And so on, and so forth.
+ *
+ *
+ *
+ *
  */
 
 
 YAML_DECLARE(int)
 yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity);
 
-/******************************************************************************
+/*****************************************************************************
  * Basic Types
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * The character type (UTF-8 octet).
     YAML_CRLN_BREAK
 } yaml_break_t;
 
-/******************************************************************************
+/*****************************************************************************
  * Node Styles
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * Scalar styles.
     YAML_ANY_SEQUENCE_STYLE,
 
     /* The flow sequence style. */
-    YAML_FLOW_SEQUENCE_STYLE
+    YAML_FLOW_SEQUENCE_STYLE,
     /* The block sequence style. */
-    YAML_BLOCK_SEQUENCE_STYLE,
+    YAML_BLOCK_SEQUENCE_STYLE
 } yaml_sequence_style_t;
 
 /*
     YAML_FLOW_MAPPING_STYLE
 } yaml_mapping_style_t;
 
-/******************************************************************************
+/*****************************************************************************
  * Tokens
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * Token types.
 YAML_DECLARE(void)
 yaml_token_clear(yaml_token_t *token);
 
-/******************************************************************************
+/*****************************************************************************
  * Events
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * Event types.
 YAML_DECLARE(int)
 yaml_event_create_mapping_end(yaml_event_t *event);
 
-/******************************************************************************
+/*****************************************************************************
  * Documents and Nodes
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * Well-known scalar tags.
 
 typedef enum yaml_document_type_e {
     /* An empty uninitialized document. */
-    YAML_NO_DOCUMENT.
+    YAML_NO_DOCUMENT,
 
     /* A YAML document. */
     YAML_DOCUMENT
  * node object is destroyed when the document containing it is destroyed.
  */
 
-struct yaml_node_s {
+typedef struct yaml_node_s {
 
     /* The node type. */
     yaml_node_type_t type;
     /* The end of the node. */
     yaml_mark_t end_mark;
 
-};
+} yaml_node_t;
 
 /*
  * The incomplete node object.
         yaml_mapping_style_t style);
 
 /*
- * Get the value of a `!!null` SCALAR node.
- *
- * Use this function to ensure that the given node is a scalar, the node tag is
- * equal to `tag:yaml.org,2002:null` and the node value is a valid null value.
- * Given that the `!!null` tag admits only one valid value, the value is not
- * returned.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * Returns: `1` if the node is a valid `!!null` scalar, `0` otherwise.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_null_node(yaml_document_t *document, int node_id);
-
-/*
- * Get the value of a `!!bool` SCALAR node.
- *
- * Use this function to ensure that the given node is a scalar, the node tag is
- * `tag:yaml.org,2002:bool` and the node value is a valid boolean value.  The
- * function returns the true value as `1` and the false value as `0`.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `value`: a pointer to save the node value or `NULL`.
- *
- * Returns: `1` if the node is a valid `!!bool` scalar, `0` otherwise.  If the
- * function succeeds and `value` is not `NULL`, the node value is saved to
- * `value`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_bool_node(yaml_document_t *document, int node_id,
-        int *value);
-
-/*
- * Get the value of a `!!str` SCALAR node.
- *
- * Use this function to ensure that the given node is a scalar, the node tag is
- * `tag:yaml.org,2002:str` and the node value is a string that does not contain
- * the NUL character.  In this case, the function returns the node value.  The
- * produced value is valid until the document object is cleared or deleted.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `value`: a pointer to save the node value or `NULL`.
- *
- * Returns: `1` if the node is a valid `!!str` scalar, `0` otherwise.  If the
- * function succeeds and `value` is not `NULL`, the node value is saved to
- * `value`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_str_node(yaml_document_t *document, int node_id,
-        char **value);
-
-/*
- * Get the value of an `!!int` SCALAR node.
- *
- * Use this function to ensure that the given node is a scalar, the node tag is
- * `tag:yaml.org,2002:int` and the node value is a valid integer.  In this
- * case, the function parses the node value and returns an integer number.  The
- * function recognizes decimal, hexdecimal and octal numbers including negative
- * numbers.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `value`: a pointer to save the node value or `NULL`.
- *
- * Returns: `1` if the node is a valid `!!int` scalar, `0` otherwise.  If the
- * function succeeds and `value` is not `NULL`, the node value is saved to
- * `value`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_int_node(yaml_document_t *document, int node_id,
-        int *value);
-
-/*
- * Get the value of a `!!float` SCALAR node.
- *
- * Use this function to ensure that the given node is a scalar, the node tag is
- * `tag:yaml.org,2002:float` and the node value is a valid float value.  In
- * this case, the function parses the node value and returns a float number.
- * The function recognizes float values in exponential and fixed notation as
- * well as special values `.nan`, `.inf` and `-.inf`.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `value`: a pointer to save the node value or `NULL`.
- *
- * Returns: `1` if the node is a valid `!!float` scalar, `0` otherwise.  If the
- * function succeeds and `value` is not `NULL`, the node value is saved to
- * `value`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_float_node(yaml_document_t *document, int node_id,
-        double *value);
-
-/*
- * Get the value of a `!!seq` SEQUENCE node.
- *
- * Use this function to ensure that the given node is a sequence and the node
- * tag is `tag:yaml.org,2002:seq`.  In this case, the function returns the list
- * of nodes that belong to the sequence.  The produced list is valid until the
- * document object is modified.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `items`: a pointer to save the list of sequence items or `NULL`.
- *
- * - `length`: a pointer to save the length of the sequence or `NULL`.
- *   `length` must be equal to `NULL` if and only if `items` is also `NULL`.
- *
- * Returns: `1` if the node is a valid `!!seq` sequence, `0` otherwise.  If the
- * function succeeds and `items` is not `NULL`, the list of sequence items is
- * saved to `items` and the sequence length is saved to `length`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_seq_node(yaml_document_t *document, int node_id,
-        yaml_node_item_t **items, size_t *length);
-
-/*
- * Get the value of a `!!map` MAPPING node.
- *
- * Use this function to ensure that the given node is a mapping and the node
- * tag is `tag:yaml.org,2002:map`.  In this case, the function returns the list
- * of node pairs (key, value) that belong to the sequence.  The produced list
- * is valid until the document is modified.
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: the node id; could be negative.
- *
- * - `pairs`: a pointer to save the list of mapping pairs or `NULL`.
- *
- * - `length`: a pointer to save the length of the mapping or `NULL`.
- *   `length` must be equal to `NULL` if and only if `pairs` is also `NULL`.
- *
- * Returns: `1` if the node is a valid `!!map` mapping, `0` otherwise.  If the
- * function succeeds and `pairs` is not `NULL`, the list of mapping pairs is
- * saved to `pairs` and the mapping length is saved to `length`.
- */
-
-YAML_DECLARE(int)
-yaml_document_get_map_node(yaml_document_t *document, int node_id,
-        yaml_node_pair_t **pairs, size_t *length);
-
-/*
- * Add a `!!null` SCALAR node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_scalar(document, node_id, NULL,
- *              YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_null_node(yaml_document_t *document, int *node_id);
-
-/*
- * Add a `!!bool` SCALAR node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_scalar(document, node_id, NULL,
- *              YAML_BOOL_TAG, (value ? "true" : "false"), -1,
- *              YAML_ANY_SCALAR_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * - `value`: a boolean value; any non-zero value is true, `0` is false.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_bool_node(yaml_document_t *document, int *node_id,
-        int value);
-
-/*
- * Add a `!!str` SCALAR node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_scalar(document, node_id, NULL,
- *              YAML_STR_TAG, (const yaml_char_t *) value, -1,
- *              YAML_ANY_SCALAR_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * - `value`: a NUL-terminated UTF-8 string.  The function does not check if
- *   `value` is a valid UTF-8 string, but if it is not so, the emitter will
- *   fail to emit the node.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_str_node(yaml_document_t *document, int *node_id,
-        const char *value);
-
-/*
- * Add an `!!int` SCALAR node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_scalar(document, node_id, NULL,
- *              YAML_INT_TAG, <string representation of the value>, -1,
- *              YAML_ANY_SCALAR_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * - `value`: an integer value.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_int_node(yaml_document_t *document, int *node_id,
-        int value);
-
-/*
- * Add a `!!float` SCALAR node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_scalar(document, node_id, NULL,
- *              YAML_FLOAT_TAG, <string representation of the value>, -1,
- *              YAML_ANY_SCALAR_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * - `value`: a float value.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_float_node(yaml_document_t *document, int *node_id,
-        double value);
-
-/*
- * Add a `!!seq` SEQUENCE node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_sequence(document, node_id, NULL,
- *              YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_seq_node(yaml_document_t *document, int *node_id);
-
-/*
- * Add a `!!map` MAPPING node to the document.
- *
- * This function is a shorthand for the call:
- *
- *      yaml_document_add_mapping(document, node_id, NULL,
- *              YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE)
- *
- * Arguments:
- *
- * - `document`: a document object.
- *
- * - `node_id`: a pointer to save the id of the generated node or `NULL`.
- *
- * Returns: `1` on success, `0` on error.  The function may fail if it cannot
- * allocate memory for new buffers.  If the function succeeds, the id of the
- * added node is returned via the pointer `node_id` if it is not set to `NULL`.
- */
-
-YAML_DECLARE(int)
-yaml_document_add_map_node(yaml_document_t *document, int *node_id);
-
-/*
  * Add an item to a SEQUENCE node.
  *
  * The order in which items are added to a sequence coincides with the order
 yaml_document_append_mapping_pair(yaml_document_t *document,
         int mapping_id, int key_id, int value_id);
 
-/******************************************************************************
+/*
+ * Get the value of a `!!null` SCALAR node.
+ *
+ * Use this function to ensure that the given node is a scalar, the node tag is
+ * equal to `tag:yaml.org,2002:null` and the node value is a valid null value.
+ * Given that the `!!null` tag admits only one valid value, the value is not
+ * returned.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * Returns: `1` if the node is a valid `!!null` scalar, `0` otherwise.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_null_node(yaml_document_t *document, int node_id);
+
+/*
+ * Get the value of a `!!bool` SCALAR node.
+ *
+ * Use this function to ensure that the given node is a scalar, the node tag is
+ * `tag:yaml.org,2002:bool` and the node value is a valid boolean value.  The
+ * function returns the true value as `1` and the false value as `0`.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `value`: a pointer to save the node value or `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!bool` scalar, `0` otherwise.  If the
+ * function succeeds and `value` is not `NULL`, the node value is saved to
+ * `value`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_bool_node(yaml_document_t *document, int node_id,
+        int *value);
+
+/*
+ * Get the value of a `!!str` SCALAR node.
+ *
+ * Use this function to ensure that the given node is a scalar, the node tag is
+ * `tag:yaml.org,2002:str` and the node value is a string that does not contain
+ * the NUL character.  In this case, the function returns the node value.  The
+ * produced value is valid until the document object is cleared or deleted.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `value`: a pointer to save the node value or `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!str` scalar, `0` otherwise.  If the
+ * function succeeds and `value` is not `NULL`, the node value is saved to
+ * `value`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_str_node(yaml_document_t *document, int node_id,
+        char **value);
+
+/*
+ * Get the value of an `!!int` SCALAR node.
+ *
+ * Use this function to ensure that the given node is a scalar, the node tag is
+ * `tag:yaml.org,2002:int` and the node value is a valid integer.  In this
+ * case, the function parses the node value and returns an integer number.  The
+ * function recognizes decimal, hexdecimal and octal numbers including negative
+ * numbers.  The function uses `strtol()` for string-to-integer conversion.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `value`: a pointer to save the node value or `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!int` scalar, `0` otherwise.  If the
+ * function succeeds and `value` is not `NULL`, the node value is saved to
+ * `value`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_int_node(yaml_document_t *document, int node_id,
+        long *value);
+
+/*
+ * Get the value of a `!!float` SCALAR node.
+ *
+ * Use this function to ensure that the given node is a scalar, the node tag is
+ * `tag:yaml.org,2002:float` and the node value is a valid float value.  In
+ * this case, the function parses the node value and returns a float number.
+ * The function recognizes float values in exponential and fixed notation as
+ * well as special values `.nan`, `.inf` and `-.inf`.  The function uses
+ * `strtod()` for string-to-float conversion.  The `.nan`, `.inf` and `-.inf`
+ * values are generated as `0.0/0.0`, `1.0/0.0` and `-1.0/0.0` respectively.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `value`: a pointer to save the node value or `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!float` scalar, `0` otherwise.  If the
+ * function succeeds and `value` is not `NULL`, the node value is saved to
+ * `value`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_float_node(yaml_document_t *document, int node_id,
+        double *value);
+
+/*
+ * Get the value of a `!!seq` SEQUENCE node.
+ *
+ * Use this function to ensure that the given node is a sequence and the node
+ * tag is `tag:yaml.org,2002:seq`.  In this case, the function returns the list
+ * of nodes that belong to the sequence.  The produced list is valid until the
+ * document object is modified.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `items`: a pointer to save the list of sequence items or `NULL`.
+ *
+ * - `length`: a pointer to save the length of the sequence or `NULL`.
+ *   `length` must be equal to `NULL` if and only if `items` is also `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!seq` sequence, `0` otherwise.  If the
+ * function succeeds and `items` is not `NULL`, the list of sequence items is
+ * saved to `items` and the sequence length is saved to `length`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_seq_node(yaml_document_t *document, int node_id,
+        yaml_node_item_t **items, size_t *length);
+
+/*
+ * Get the value of a `!!map` MAPPING node.
+ *
+ * Use this function to ensure that the given node is a mapping and the node
+ * tag is `tag:yaml.org,2002:map`.  In this case, the function returns the list
+ * of node pairs (key, value) that belong to the sequence.  The produced list
+ * is valid until the document is modified.
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: the node id; could be negative.
+ *
+ * - `pairs`: a pointer to save the list of mapping pairs or `NULL`.
+ *
+ * - `length`: a pointer to save the length of the mapping or `NULL`.
+ *   `length` must be equal to `NULL` if and only if `pairs` is also `NULL`.
+ *
+ * Returns: `1` if the node is a valid `!!map` mapping, `0` otherwise.  If the
+ * function succeeds and `pairs` is not `NULL`, the list of mapping pairs is
+ * saved to `pairs` and the mapping length is saved to `length`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_get_map_node(yaml_document_t *document, int node_id,
+        yaml_node_pair_t **pairs, size_t *length);
+
+/*
+ * Add a `!!null` SCALAR node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_scalar(document, node_id, NULL,
+ *              YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_null_node(yaml_document_t *document, int *node_id);
+
+/*
+ * Add a `!!bool` SCALAR node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_scalar(document, node_id, NULL,
+ *              YAML_BOOL_TAG, (value ? "true" : "false"), -1,
+ *              YAML_ANY_SCALAR_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * - `value`: a boolean value; any non-zero value is true, `0` is false.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_bool_node(yaml_document_t *document, int *node_id,
+        int value);
+
+/*
+ * Add a `!!str` SCALAR node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_scalar(document, node_id, NULL,
+ *              YAML_STR_TAG, (const yaml_char_t *) value, -1,
+ *              YAML_ANY_SCALAR_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * - `value`: a NUL-terminated UTF-8 string.  The function does not check if
+ *   `value` is a valid UTF-8 string, but if it is not so, the emitter will
+ *   fail to emit the node.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_str_node(yaml_document_t *document, int *node_id,
+        const char *value);
+
+/*
+ * Add an `!!int` SCALAR node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_scalar(document, node_id, NULL,
+ *              YAML_INT_TAG, <string representation of the value>, -1,
+ *              YAML_ANY_SCALAR_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * - `value`: an integer value.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_int_node(yaml_document_t *document, int *node_id,
+        long value);
+
+/*
+ * Add a `!!float` SCALAR node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_scalar(document, node_id, NULL,
+ *              YAML_FLOAT_TAG, <string representation of the value>, -1,
+ *              YAML_ANY_SCALAR_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * - `value`: a float value.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_float_node(yaml_document_t *document, int *node_id,
+        double value);
+
+/*
+ * Add a `!!seq` SEQUENCE node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_sequence(document, node_id, NULL,
+ *              YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_seq_node(yaml_document_t *document, int *node_id);
+
+/*
+ * Add a `!!map` MAPPING node to the document.
+ *
+ * This function is a shorthand for the call:
+ *
+ *      yaml_document_add_mapping(document, node_id, NULL,
+ *              YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE)
+ *
+ * Arguments:
+ *
+ * - `document`: a document object.
+ *
+ * - `node_id`: a pointer to save the id of the generated node or `NULL`.
+ *
+ * Returns: `1` on success, `0` on error.  The function may fail if it cannot
+ * allocate memory for new buffers.  If the function succeeds, the id of the
+ * added node is returned via the pointer `node_id` if it is not set to `NULL`.
+ */
+
+YAML_DECLARE(int)
+yaml_document_add_map_node(yaml_document_t *document, int *node_id);
+
+/*****************************************************************************
  * Callback Definitions
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * The prototype of a read handler.
  */
 
 typedef int yaml_resolver_t(void *data, yaml_incomplete_node_t *node,
-        yaml_char_t **tag);
-
-/******************************************************************************
+        const yaml_char_t **tag);
+
+/*****************************************************************************
  * Parser Definitions
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * An opaque definition of the parser object.
  */
 
 YAML_DECLARE(void)
-yaml_parser_clear(yaml_parser_t *parser);
+yaml_parser_reset(yaml_parser_t *parser);
 
 /*
  * Get the parser error.
 yaml_parser_parse_single_document(yaml_parser_t *parser,
         yaml_document_t *document);
 
-/******************************************************************************
+/*****************************************************************************
  * Emitter Definitions
- ******************************************************************************/
+ *****************************************************************************/
 
 /*
  * An opaque definition of the emitter object.
  */
 
 YAML_DECLARE(void)
-yaml_emitter_clear(yaml_emitter_t *emitter);
+yaml_emitter_reset(yaml_emitter_t *emitter);
 
 /*
  * Get the emitter error.
+/*****************************************************************************
+ * LibYAML API Implementation
+ *
+ * Copyright (c) 2006 Kirill Simonov
+ *
+ * LibYAML is free software; you can use, modify and/or redistribute it under
+ * the terms of the MIT license; see the file LICENCE for more details.
+ *****************************************************************************/
 
 #include "yaml_private.h"
 
+/*****************************************************************************
+ * Version Information
+ *****************************************************************************/
+
 /*
- * Get the library version.
+ * Get the library version as a static string.
  */
 
 YAML_DECLARE(const char *)
     *patch = YAML_VERSION_PATCH;
 }
 
+/*****************************************************************************
+ * Memory Management
+ *****************************************************************************/
+
 /*
  * Allocate a dynamic memory block.
  */
     return (yaml_char_t *)strdup((char *)str);
 }
 
+/*****************************************************************************
+ * Error Handling
+ *****************************************************************************/
+
 /*
  * Format an error message.
  */
     return (length >= 0 && length < capacity);
 }
 
+/*****************************************************************************
+ * String, Stack and Queue Management
+ *****************************************************************************/
 
 /*
  * Extend a string.
     return 1;
 }
 
-
-/*
- * Create a new parser object.
- */
-
-YAML_DECLARE(yaml_parser_t *)
-yaml_parser_new(void)
-{
-    yaml_parser_t *parser = yaml_malloc(sizeof(yaml_parser_t));
-
-    if (!parser)
-        return NULL;
-
-    memset(parser, 0, sizeof(yaml_parser_t));
-    if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY))
-        goto error;
-    if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY))
-        goto error;
-    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY))
-        goto error;
-    if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!STACK_INIT(parser, parser->states, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_CAPACITY))
-        goto error;
-
-    return parser;
-
-error:
-    yaml_parser_delete(parser);
-
-    return NULL;
-}
-
-/*
- * Destroy a parser object.
- */
-
-YAML_DECLARE(void)
-yaml_parser_delete(yaml_parser_t *parser)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-
-    IOSTRING_DEL(parser, parser->raw_input);
-    IOSTRING_DEL(parser, parser->input);
-    while (!QUEUE_EMPTY(parser, parser->tokens)) {
-        yaml_token_destroy(&DEQUEUE(parser, parser->tokens));
-    }
-    QUEUE_DEL(parser, parser->tokens);
-    STACK_DEL(parser, parser->indents);
-    STACK_DEL(parser, parser->simple_keys);
-    STACK_DEL(parser, parser->states);
-    STACK_DEL(parser, parser->marks);
-    while (!STACK_EMPTY(parser, parser->tag_directives)) {
-        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
-        yaml_free(tag_directive.handle);
-        yaml_free(tag_directive.prefix);
-    }
-    STACK_DEL(parser, parser->tag_directives);
-
-    memset(parser, 0, sizeof(yaml_parser_t));
-    yaml_free(parser);
-}
-
-/*
- * Get the current parser error.
- */
-
-YAML_DECLARE(void)
-yaml_parser_get_error(yaml_parser_t *parser, yaml_error_t *error)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-
-    *error = parser->error;
-}
-
-/*
- * Standard string read handler.
- */
-
-static int
-yaml_string_reader(void *untyped_data, unsigned char *buffer, size_t capacity,
-        size_t *length)
-{
-    yaml_standard_reader_data_t *data = untyped_data;
-
-    if (data->string.pointer == data->string.length) {
-        *length = 0;
-        return 1;
-    }
-
-    if (capacity > (size_t)(data->string.length - data->string.pointer)) {
-        capacity = data->string.length - data->string.pointer;
-    }
-
-    memcpy(buffer, data->string.buffer + data->string.pointer, capacity);
-    data->string.pointer += capacity;
-    *length = capacity;
-    return 1;
-}
-
-/*
- * Standard file read handler.
- */
-
-static int
-yaml_file_reader(void *untyped_data, unsigned char *buffer, size_t capacity,
-        size_t *length)
-{
-    yaml_standard_reader_data_t *data = untyped_data;
-
-    *length = fread(buffer, 1, capacity, data->file);
-    return !ferror(data->file);
-}
-
-/*
- * Set a string input.
- */
-
-YAML_DECLARE(void)
-yaml_parser_set_string_reader(yaml_parser_t *parser,
-        const unsigned char *buffer, size_t length)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-    assert(!parser->reader);    /* You can set the input handler only once. */
-    assert(buffer); /* Non-NULL input string expected. */
-
-    parser->reader = yaml_string_reader;
-    parser->reader_data = &(parser->standard_reader_data);
-
-    parser->standard_reader_data.string.buffer = buffer;
-    parser->standard_reader_data.string.pointer = 0;
-    parser->standard_reader_data.string.length = length;
-}
-
-/*
- * Set a file input.
- */
-
-YAML_DECLARE(void)
-yaml_parser_set_file_reader(yaml_parser_t *parser, FILE *file)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-    assert(!parser->reader);    /* You can set the input handler only once. */
-    assert(file);   /* Non-NULL file object expected. */
-
-    parser->reader = yaml_file_reader;
-    parser->reader_data = &(parser->standard_reader_data);
-
-    parser->standard_reader_data.file = file;
-}
-
-/*
- * Set a generic input.
- */
-
-YAML_DECLARE(void)
-yaml_parser_set_reader(yaml_parser_t *parser,
-        yaml_reader_t *reader, void *data)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-    assert(!parser->reader);    /* You can set the input handler only once. */
-    assert(reader); /* Non-NULL read handler expected. */
-
-    parser->reader = reader;
-    parser->reader_data = data;
-}
-
-/*
- * Set the source encoding.
- */
-
-YAML_DECLARE(void)
-yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
-{
-    assert(parser); /* Non-NULL parser object expected. */
-    assert(!parser->encoding);  /* Encoding is already set or detected. */
-
-    parser->encoding = encoding;
-}
-
-/*
- * Create a new emitter object.
- */
-
-YAML_DECLARE(yaml_emitter_t *)
-yaml_emitter_new(void)
-{
-    yaml_emitter_t *emitter = yaml_malloc(sizeof(yaml_emitter_t));
-
-    if (!emitter)
-        return NULL;
-
-    memset(emitter, 0, sizeof(yaml_emitter_t));
-    if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY))
-        goto error;
-    if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY))
-        goto error;
-    if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_CAPACITY))
-        goto error;
-    if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_CAPACITY))
-        goto error;
-    if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_CAPACITY))
-        goto error;
-
-    return emitter;
-
-error:
-    yaml_emitter_delete(emitter);
-
-    return NULL;
-}
-
-/*
- * Destroy an emitter object.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_delete(yaml_emitter_t *emitter)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    IOSTRING_DEL(emitter, emitter->output);
-    IOSTRING_DEL(emitter, emitter->raw_output);
-    STACK_DEL(emitter, emitter->states);
-    while (!QUEUE_EMPTY(emitter, emitter->events)) {
-        yaml_event_destroy(&DEQUEUE(emitter, emitter->events));
-    }
-    QUEUE_DEL(emitter, emitter->events);
-    STACK_DEL(emitter, emitter->indents);
-    while (!STACK_EMPTY(empty, emitter->tag_directives)) {
-        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
-        yaml_free(tag_directive.handle);
-        yaml_free(tag_directive.prefix);
-    }
-    STACK_DEL(emitter, emitter->tag_directives);
-    yaml_free(emitter->anchors);
-
-    memset(emitter, 0, sizeof(yaml_emitter_t));
-    yaml_free(emitter);
-}
-
-/*
- * Get the current emitter error.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_get_error(yaml_emitter_t *emitter, yaml_error_t *error)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    *error = emitter->error;
-}
-
-/*
- * String write handler.
- */
-
-static int
-yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length)
-{
-    yaml_standard_writer_data_t *data = untyped_data;
-    int result = 1;
-
-    if (data->string.capacity - data->string.pointer < length) {
-        length = data->string.capacity - data->string.pointer;
-        result = 0;
-    }
-
-    memcpy(data->string.buffer + data->string.pointer, buffer, length);
-    data->string.pointer += length;
-    *data->length += length;
-
-    return result;
-}
-
-/*
- * File write handler.
- */
-
-static int
-yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length)
-{
-    yaml_standard_writer_data_t *data = untyped_data;
-
-    return (fwrite(buffer, 1, length, data->file) == length);
-}
-/*
- * Set a string output.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_string_writer(yaml_emitter_t *emitter,
-        unsigned char *buffer, size_t capacity, size_t *length)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-    assert(!emitter->writer);   /* You can set the output only once. */
-    assert(buffer);     /* Non-NULL output string expected. */
-
-    emitter->writer = yaml_string_writer;
-    emitter->writer_data = &(emitter->standard_writer_data);
-
-    emitter->standard_writer_data.string.buffer = buffer;
-    emitter->standard_writer_data.string.pointer = 0;
-    emitter->standard_writer_data.string.capacity = capacity;
-    emitter->standard_writer_data.length = length;
-
-    *length = 0;
-}
-
-/*
- * Set a file output.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_file_writer(yaml_emitter_t *emitter, FILE *file)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-    assert(!emitter->writer);   /* You can set the output only once. */
-    assert(file);       /* Non-NULL file object expected. */
-
-    emitter->writer = yaml_string_writer;
-    emitter->writer_data = &(emitter->standard_writer_data);
-
-    emitter->standard_writer_data.file = file;
-}
-
-/*
- * Set a generic output handler.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_writer(yaml_emitter_t *emitter,
-        yaml_writer_t *writer, void *data)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-    assert(!emitter->writer);   /* You can set the output only once. */
-    assert(writer); /* Non-NULL handler object expected. */
-
-    emitter->writer = writer;
-    emitter->writer_data = data;
-}
-
-/*
- * Set the output encoding.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-    assert(!emitter->encoding);     /* You can set encoding only once. */
-
-    emitter->encoding = encoding;
-}
-
-/*
- * Set the canonical output style.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_canonical(yaml_emitter_t *emitter, int is_canonical)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    emitter->is_canonical = (is_canonical != 0);
-}
-
-/*
- * Set the indentation increment.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
-}
-
-/*
- * Set the preferred line width.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    emitter->best_width = (width >= 0) ? width : -1;
-}
-
-/*
- * Set if unescaped non-ASCII characters are allowed.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_unicode(yaml_emitter_t *emitter, int is_unicode)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    emitter->is_unicode = (is_unicode != 0);
-}
-
-/*
- * Set the preferred line break character.
- */
-
-YAML_DECLARE(void)
-yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
-{
-    assert(emitter);    /* Non-NULL emitter object expected. */
-
-    emitter->line_break = line_break;
-}
+/*****************************************************************************
+ * Token API
+ *****************************************************************************/
 
 /*
  * Allocate a token object.
 {
     assert(token);  /* Non-NULL token object expected. */
 
-    yaml_token_destroy(token);
+    yaml_token_clear(token);
     yaml_free(token);
 }
 
 {
     assert(token);  /* Non-NULL token object is expected. */
     assert(model);  /* Non-NULL model token object is expected. */
+    assert(!token->type);   /* The token must be empty. */
 
     memset(token, 0, sizeof(yaml_token_t));
 
     token->type = model->type;
+    token->start_mark = model->start_mark;
+    token->end_mark = model->end_mark;
 
     switch (token->type)
     {
     return 1;
 
 error:
-    yaml_token_destroy(token);
+    yaml_token_clear(token);
 
     return 0;
 }
 
 /*
- * Destroy a token object.
+ * Clear a token object.
  */
 
 YAML_DECLARE(void)
-yaml_token_destroy(yaml_token_t *token)
+yaml_token_clear(yaml_token_t *token)
 {
     assert(token);  /* Non-NULL token object expected. */
 
     memset(token, 0, sizeof(yaml_token_t));
 }
 
-/*
- * Check if a string is a valid UTF-8 sequence.
- *
- * Check 'reader.c' for more details on UTF-8 encoding.
- */
-
-static int
-yaml_valid_utf8(const yaml_char_t *buffer, size_t length)
-{
-    size_t pointer = 0;
-
-    while (pointer < length) {
-        unsigned char octet;
-        unsigned int width;
-        unsigned int value;
-        size_t k;
-
-        octet = buffer[pointer];
-        width = (octet & 0x80) == 0x00 ? 1 :
-                (octet & 0xE0) == 0xC0 ? 2 :
-                (octet & 0xF0) == 0xE0 ? 3 :
-                (octet & 0xF8) == 0xF0 ? 4 : 0;
-        value = (octet & 0x80) == 0x00 ? octet & 0x7F :
-                (octet & 0xE0) == 0xC0 ? octet & 0x1F :
-                (octet & 0xF0) == 0xE0 ? octet & 0x0F :
-                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
-        if (!width) return 0;
-        if (pointer+width > length) return 0;
-        for (k = 1; k < width; k ++) {
-            octet = buffer[pointer+k];
-            if ((octet & 0xC0) != 0x80) return 0;
-            value = (value << 6) + (octet & 0x3F);
-        }
-        if (!((width == 1) ||
-            (width == 2 && value >= 0x80) ||
-            (width == 3 && value >= 0x800) ||
-            (width == 4 && value >= 0x10000))) return 0;
-
-        pointer += width;
-    }
-
-    return 1;
-}
+/*****************************************************************************
+ * Event API
+ *****************************************************************************/
 
 /*
  * Allocate an event object.
 {
     assert(event);  /* Non-NULL event object expected. */
 
-    yaml_event_destroy(event);
+    yaml_event_clear(event);
     yaml_free(event);
 }
 
 
     assert(event);  /* Non-NULL event object is expected. */
     assert(model);  /* Non-NULL model event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
 
     memset(event, 0, sizeof(yaml_event_t));
 
     event->type = model->type;
+    event->start_mark = model->start_mark;
+    event->end_mark = model->end_mark;
 
     switch (event->type)
     {
             memcpy(event->data.scalar.value, model->data.scalar.value,
                     model->data.scalar.length+1);
             event->data.scalar.length = model->data.scalar.length;
-            event->data.scalar.is_plain_implicit =
-                model->data.scalar.is_plain_implicit;
-            event->data.scalar.is_quoted_implicit =
-                model->data.scalar.is_quoted_implicit;
+            event->data.scalar.is_plain_nonspecific =
+                model->data.scalar.is_plain_nonspecific;
+            event->data.scalar.is_quoted_nonspecific =
+                model->data.scalar.is_quoted_nonspecific;
             event->data.scalar.style = model->data.scalar.style;
             break;
 
                     !(event->data.sequence_start.tag =
                         yaml_strdup(model->data.sequence_start.tag)))
                 goto error;
-            event->data.sequence_start.is_implicit =
-                model->data.sequence_start.is_implicit;
+            event->data.sequence_start.is_nonspecific =
+                model->data.sequence_start.is_nonspecific;
             event->data.sequence_start.style =
                 model->data.sequence_start.style;
             break;
                     !(event->data.mapping_start.tag =
                         yaml_strdup(model->data.mapping_start.tag)))
                 goto error;
-            event->data.mapping_start.is_implicit =
-                model->data.mapping_start.is_implicit;
+            event->data.mapping_start.is_nonspecific =
+                model->data.mapping_start.is_nonspecific;
             event->data.mapping_start.style =
                 model->data.mapping_start.style;
             break;
     return 1;
 
 error:
-    yaml_event_destroy(event);
+    yaml_event_clear(event);
 
     return 0;
 }
 
 /*
- * Create STREAM-START.
+ * Clear an event object.
  */
 
-YAML_DECLARE(int)
-yaml_event_create_stream_start(yaml_event_t *event,
-        yaml_encoding_t encoding)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-
-    assert(event);  /* Non-NULL event object is expected. */
-
-    STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
-
-    return 1;
-}
-
-/*
- * Create STREAM-END.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_stream_end(yaml_event_t *event)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-
-    assert(event);  /* Non-NULL event object is expected. */
-
-    STREAM_END_EVENT_INIT(*event, mark, mark);
-
-    return 1;
-}
-
-/*
- * Create DOCUMENT-START.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_document_start(yaml_event_t *event,
-        const yaml_version_directive_t *version_directive,
-        const yaml_tag_directive_t *tag_directives,
-        int is_implicit)
-{
-    struct {
-        yaml_error_t error;
-    } self;
-    yaml_mark_t mark = { 0, 0, 0 };
-    yaml_version_directive_t *version_directive_copy = NULL;
-    struct {
-        yaml_tag_directive_t *list;
-        size_t length;
-        size_t capacity;
-    } tag_directives_copy = { NULL, 0, 0 };
-
-    assert(event);          /* Non-NULL event object is expected. */
-
-    if (version_directive) {
-        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
-        if (!version_directive_copy) goto error;
-        *version_directive_copy = *version_directive;
-    }
-
-    if (tag_directives && (tag_directives->handle || tag_directives->prefix)) {
-        if (!STACK_INIT(&self, tag_directives_copy, INITIAL_STACK_CAPACITY))
-            goto error;
-        while (tag_directives->handle || tag_directives->prefix) {
-            yaml_tag_directive_t value = *tag_directives;
-            assert(value.handle);
-            assert(value.prefix);
-            if (!yaml_valid_utf8(value.handle, strlen((char *)value.handle)))
-                goto error;
-            if (!yaml_valid_utf8(value.prefix, strlen((char *)value.prefix)))
-                goto error;
-            if (!PUSH(&self, tag_directives_copy, value))
-                goto error;
-            value.handle = yaml_strdup(value.handle);
-            value.prefix = yaml_strdup(value.prefix);
-            tag_directives_copy.list[tag_directives_copy.length-1] = value;
-            if (!value.handle || !value.prefix)
-                goto error;
-        }
-    }
-
-    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
-            tag_directives_copy.list, tag_directives_copy.length,
-            tag_directives_copy.capacity, is_implicit, mark, mark);
-
-    return 1;
-
-error:
-    yaml_free(version_directive_copy);
-    while (!STACK_EMPTY(&self, tag_directives_copy)) {
-        yaml_tag_directive_t value = POP(&self, tag_directives_copy);
-        yaml_free(value.handle);
-        yaml_free(value.prefix);
-    }
-    STACK_DEL(&self, tag_directives_copy);
-
-    return 0;
-}
-
-/*
- * Create DOCUMENT-END.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_document_end(yaml_event_t *event, int is_implicit)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-
-    assert(event);      /* Non-NULL emitter object is expected. */
-
-    DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark);
-
-    return 1;
-}
-
-/*
- * Create ALIAS.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-    yaml_char_t *anchor_copy = NULL;
-
-    assert(event);      /* Non-NULL event object is expected. */
-    assert(anchor);     /* Non-NULL anchor is expected. */
-
-    if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) return 0;
-
-    anchor_copy = yaml_strdup(anchor);
-    if (!anchor_copy)
-        return 0;
-
-    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
-
-    return 1;
-}
-
-/*
- * Create SCALAR.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_scalar(yaml_event_t *event,
-        const yaml_char_t *anchor, const yaml_char_t *tag,
-        const yaml_char_t *value, size_t length,
-        int is_plain_implicit, int is_quoted_implicit,
-        yaml_scalar_style_t style)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-    yaml_char_t *anchor_copy = NULL;
-    yaml_char_t *tag_copy = NULL;
-    yaml_char_t *value_copy = NULL;
-
-    assert(event);      /* Non-NULL event object is expected. */
-    assert(value);      /* Non-NULL anchor is expected. */
-
-    if (anchor) {
-        if (!yaml_valid_utf8(anchor, strlen((char *)anchor)))
-            goto error;
-        anchor_copy = yaml_strdup(anchor);
-        if (!anchor_copy)
-            goto error;
-    }
-
-    if (tag) {
-        if (!yaml_valid_utf8(tag, strlen((char *)tag)))
-            goto error;
-        tag_copy = yaml_strdup(tag);
-        if (!tag_copy)
-            goto error;
-    }
-
-    if (length < 0) {
-        length = strlen((char *)value);
-    }
-
-    if (!yaml_valid_utf8(value, length))
-        goto error;
-    value_copy = yaml_malloc(length+1);
-    if (!value_copy)
-        goto error;
-    memcpy(value_copy, value, length);
-    value_copy[length] = '\0';
-
-    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
-            is_plain_implicit, is_quoted_implicit, style, mark, mark);
-
-    return 1;
-
-error:
-    yaml_free(anchor_copy);
-    yaml_free(tag_copy);
-    yaml_free(value_copy);
-
-    return 0;
-}
-
-/*
- * Create SEQUENCE-START.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_sequence_start(yaml_event_t *event,
-        const yaml_char_t *anchor, const yaml_char_t *tag,
-        int is_implicit, yaml_sequence_style_t style)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-    yaml_char_t *anchor_copy = NULL;
-    yaml_char_t *tag_copy = NULL;
-
-    assert(event);      /* Non-NULL event object is expected. */
-
-    if (anchor) {
-        if (!yaml_valid_utf8(anchor, strlen((char *)anchor)))
-            goto error;
-        anchor_copy = yaml_strdup(anchor);
-        if (!anchor_copy)
-            goto error;
-    }
-
-    if (tag) {
-        if (!yaml_valid_utf8(tag, strlen((char *)tag)))
-            goto error;
-        tag_copy = yaml_strdup(tag);
-        if (!tag_copy)
-            goto error;
-    }
-
-    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-            is_implicit, style, mark, mark);
-
-    return 1;
-
-error:
-    yaml_free(anchor_copy);
-    yaml_free(tag_copy);
-
-    return 0;
-}
-
-/*
- * Create SEQUENCE-END.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_sequence_end(yaml_event_t *event)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-
-    assert(event);      /* Non-NULL event object is expected. */
-
-    SEQUENCE_END_EVENT_INIT(*event, mark, mark);
-
-    return 1;
-}
-
-/*
- * Create MAPPING-START.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_mapping_start(yaml_event_t *event,
-        const yaml_char_t *anchor, const yaml_char_t *tag,
-        int is_implicit, yaml_mapping_style_t style)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-    yaml_char_t *anchor_copy = NULL;
-    yaml_char_t *tag_copy = NULL;
-
-    assert(event);      /* Non-NULL event object is expected. */
-
-    if (anchor) {
-        if (!yaml_valid_utf8(anchor, strlen((char *)anchor)))
-            goto error;
-        anchor_copy = yaml_strdup(anchor);
-        if (!anchor_copy)
-            goto error;
-    }
-
-    if (tag) {
-        if (!yaml_valid_utf8(tag, strlen((char *)tag)))
-            goto error;
-        tag_copy = yaml_strdup(tag);
-        if (!tag_copy)
-            goto error;
-    }
-
-    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
-            is_implicit, style, mark, mark);
-
-    return 1;
-
-error:
-    yaml_free(anchor_copy);
-    yaml_free(tag_copy);
-
-    return 0;
-}
-
-/*
- * Create MAPPING-END.
- */
-
-YAML_DECLARE(int)
-yaml_event_create_mapping_end(yaml_event_t *event)
-{
-    yaml_mark_t mark = { 0, 0, 0 };
-
-    assert(event);      /* Non-NULL event object is expected. */
-
-    MAPPING_END_EVENT_INIT(*event, mark, mark);
-
-    return 1;
-}
-
-/*
- * Destroy an event object.
- */
-
 YAML_DECLARE(void)
-yaml_event_destroy(yaml_event_t *event)
+yaml_event_clear(yaml_event_t *event)
 {
     struct {
         yaml_error_t error;
     memset(event, 0, sizeof(yaml_event_t));
 }
 
-#if 0
-
 /*
- * Create a document object.
+ * Create STREAM-START.
  */
 
 YAML_DECLARE(int)
-yaml_document_initialize(yaml_document_t *document,
-        yaml_version_directive_t *version_directive,
-        yaml_tag_directive_t *tag_directives_start,
-        yaml_tag_directive_t *tag_directives_end,
-        int start_implicit, int end_implicit)
+yaml_event_create_stream_start(yaml_event_t *event,
+        yaml_encoding_t encoding)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+
+    assert(event);  /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
+
+    return 1;
+}
+
+/*
+ * Create STREAM-END.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_stream_end(yaml_event_t *event)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+
+    assert(event);  /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    STREAM_END_EVENT_INIT(*event, mark, mark);
+
+    return 1;
+}
+
+/*
+ * Create DOCUMENT-START.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_document_start(yaml_event_t *event,
+        const yaml_version_directive_t *version_directive,
+        const yaml_tag_directive_t *tag_directives_list,
+        size_t tag_directives_length, int is_implicit)
+{
+    struct {
+        yaml_error_t error;
+    } self;
+    yaml_mark_t mark = { 0, 0, 0 };
+    yaml_version_directive_t *version_directive_copy = NULL;
+    struct {
+        yaml_tag_directive_t *list;
+        size_t length;
+        size_t capacity;
+    } tag_directives_copy = { NULL, 0, 0 };
+    int idx;
+
+    assert(event);          /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    if (version_directive) {
+        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
+        if (!version_directive_copy) goto error;
+        *version_directive_copy = *version_directive;
+    }
+
+    if (tag_directives_list && tag_directives_length) {
+        if (!STACK_INIT(&self, tag_directives_copy, tag_directives_length))
+            goto error;
+        for (idx = 0; idx < tag_directives_length; idx++) {
+            yaml_tag_directive_t value = tag_directives_list[idx];
+            assert(value.handle);
+            assert(value.prefix);
+            value.handle = yaml_strdup(value.handle);
+            value.prefix = yaml_strdup(value.prefix);
+            PUSH(&self, tag_directives_copy, value);
+            if (!value.handle || !value.prefix)
+                goto error;
+        }
+    }
+
+    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
+            tag_directives_copy.list, tag_directives_copy.length,
+            tag_directives_copy.capacity, is_implicit, mark, mark);
+
+    return 1;
+
+error:
+    yaml_free(version_directive_copy);
+    while (!STACK_EMPTY(&self, tag_directives_copy)) {
+        yaml_tag_directive_t value = POP(&self, tag_directives_copy);
+        yaml_free(value.handle);
+        yaml_free(value.prefix);
+    }
+    STACK_DEL(&self, tag_directives_copy);
+
+    return 0;
+}
+
+/*
+ * Create DOCUMENT-END.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_document_end(yaml_event_t *event, int is_implicit)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+
+    assert(event);      /* Non-NULL emitter object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark);
+
+    return 1;
+}
+
+/*
+ * Create ALIAS.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+    yaml_char_t *anchor_copy = NULL;
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+    assert(anchor);     /* Non-NULL anchor is expected. */
+
+    anchor_copy = yaml_strdup(anchor);
+    if (!anchor_copy)
+        return 0;
+
+    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
+
+    return 1;
+}
+
+/*
+ * Create SCALAR.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_scalar(yaml_event_t *event,
+        const yaml_char_t *anchor, const yaml_char_t *tag,
+        const yaml_char_t *value, int length,
+        int is_plain_nonspecific, int is_quoted_nonspecific,
+        yaml_scalar_style_t style)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+    yaml_char_t *anchor_copy = NULL;
+    yaml_char_t *tag_copy = NULL;
+    yaml_char_t *value_copy = NULL;
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+    assert(value);      /* Non-NULL anchor is expected. */
+
+    if (anchor) {
+        anchor_copy = yaml_strdup(anchor);
+        if (!anchor_copy)
+            goto error;
+    }
+
+    if (tag) {
+        tag_copy = yaml_strdup(tag);
+        if (!tag_copy)
+            goto error;
+    }
+
+    if (length < 0) {
+        length = strlen((char *)value);
+    }
+
+    value_copy = yaml_malloc(length+1);
+    if (!value_copy)
+        goto error;
+    memcpy(value_copy, value, length);
+    value_copy[length] = '\0';
+
+    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
+            is_plain_nonspecific, is_quoted_nonspecific, style, mark, mark);
+
+    return 1;
+
+error:
+    yaml_free(anchor_copy);
+    yaml_free(tag_copy);
+    yaml_free(value_copy);
+
+    return 0;
+}
+
+/*
+ * Create SEQUENCE-START.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_sequence_start(yaml_event_t *event,
+        const yaml_char_t *anchor, const yaml_char_t *tag,
+        int is_nonspecific, yaml_sequence_style_t style)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+    yaml_char_t *anchor_copy = NULL;
+    yaml_char_t *tag_copy = NULL;
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    if (anchor) {
+        anchor_copy = yaml_strdup(anchor);
+        if (!anchor_copy)
+            goto error;
+    }
+
+    if (tag) {
+        tag_copy = yaml_strdup(tag);
+        if (!tag_copy)
+            goto error;
+    }
+
+    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+            is_nonspecific, style, mark, mark);
+
+    return 1;
+
+error:
+    yaml_free(anchor_copy);
+    yaml_free(tag_copy);
+
+    return 0;
+}
+
+/*
+ * Create SEQUENCE-END.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_sequence_end(yaml_event_t *event)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    SEQUENCE_END_EVENT_INIT(*event, mark, mark);
+
+    return 1;
+}
+
+/*
+ * Create MAPPING-START.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_mapping_start(yaml_event_t *event,
+        const yaml_char_t *anchor, const yaml_char_t *tag,
+        int is_nonspecific, yaml_mapping_style_t style)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+    yaml_char_t *anchor_copy = NULL;
+    yaml_char_t *tag_copy = NULL;
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    if (anchor) {
+        anchor_copy = yaml_strdup(anchor);
+        if (!anchor_copy)
+            goto error;
+    }
+
+    if (tag) {
+        tag_copy = yaml_strdup(tag);
+        if (!tag_copy)
+            goto error;
+    }
+
+    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
+            is_nonspecific, style, mark, mark);
+
+    return 1;
+
+error:
+    yaml_free(anchor_copy);
+    yaml_free(tag_copy);
+
+    return 0;
+}
+
+/*
+ * Create MAPPING-END.
+ */
+
+YAML_DECLARE(int)
+yaml_event_create_mapping_end(yaml_event_t *event)
+{
+    yaml_mark_t mark = { 0, 0, 0 };
+
+    assert(event);      /* Non-NULL event object is expected. */
+    assert(!event->type);   /* The event must be empty. */
+
+    MAPPING_END_EVENT_INIT(*event, mark, mark);
+
+    return 1;
+}
+
+/*****************************************************************************
+ * Document API
+ *****************************************************************************/
+
+/*
+ * Allocate a document object.
+ */
+
+YAML_DECLARE(yaml_document_t *)
+yaml_document_new(void)
+{
+    yaml_document_t *document = yaml_malloc(sizeof(yaml_document_t));
+
+    if (!document)
+        return NULL;
+
+    memset(document, 0, sizeof(yaml_document_t));
+
+    return document;
+}
+
+/*
+ * Deallocate a document object.
+ */
+
+YAML_DECLARE(void)
+yaml_document_delete(yaml_document_t *document)
+{
+    assert(document);   /* Non-NULL document object is expected. */
+
+    yaml_document_clear(document);
+    yaml_free(document);
+}
+
+/*
+ * Duplicate a document object.
+ */
+
+YAML_DECLARE(int)
+yaml_document_duplicate(yaml_document_t *document, yaml_document_t *model)
+{
+    struct {
+        yaml_error_t error;
+    } self;
+    yaml_char_t *anchor = NULL;
+    yaml_char_t *tag = NULL;
+    yaml_char_t *value = NULL;
+    yaml_node_item_t *item_list = NULL;
+    yaml_node_pair_t *pair_list = NULL;
+    int idx;
+
+    assert(document);   /* Non-NULL document object is expected. */
+    assert(!document->type);    /* The document must be empty. */
+    assert(model);      /* Non-NULL model object is expected. */
+
+    if (model->type != YAML_DOCUMENT)
+        return 1;
+