Changeset 267

Show
Ignore:
Timestamp:
01/19/08 08:54:22 (4 years ago)
Author:
xi
Message:

Minor API updates.

Location:
libyaml/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • libyaml/trunk/include/yaml.h

    r266 r267  
    88 *****************************************************************************/ 
    99 
    10 /* 
     10/***************************************************************************** 
    1111 * General guidelines. 
    12  * 
    13  * Naming conventions: all functions exported by LibYAML starts with the `yaml_` prefix; 
    14  * types starts with `yaml_` and ends with `_t`; macros and enumerations starts 
    15  * with `YAML_`. 
     12 *****************************************************************************/ 
     13 
     14/* 
     15 * Basic conventions. 
     16 * 
     17 * All functions exported by exported by LibYAML starts with the the prefix 
     18 * `yaml_`; types starts with `yaml_` and ends with `_t`; macros and 
     19 * enumeration values start with `YAML_`. 
     20 * 
     21 * A function may serve as method for an object or a particular type; such 
     22 * functions start with `yaml_<type>`.  A type constructor is named 
     23 * `yaml_<type>_new()`, a type destructor is named `yaml_<type>_delete()`. 
     24 * 
     25 * A function signifies whether it succeeded or failed with its return value; 
     26 * typically it is `1` for success, `0` for failure.  Functions that return a 
     27 * pointer may indicate an error condition by returning `NULL`.  Functions that 
     28 * never fail commonly do not return any value.  For most of the functions, an 
     29 * error value means that the function is unable to allocate some memory 
     30 * buffer.  For parsing and emitting functions, detailed information on the 
     31 * nature of the error could be obtained. 
     32 * 
     33 * LibYAML provides two active objects: parsers and emitters and three passive 
     34 * objects: tokens, events and documents. 
     35 * 
     36 *  
     37 * 
    1638 * 
    1739 * FIXME: Calling conventions. 
     
    1941 * FIXME: Errors and exceptions. 
    2042 * FIXME: And so on, and so forth. 
     43 * 
     44 * 
     45 * 
     46 * 
    2147 */ 
    2248 
     
    270296yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity); 
    271297 
    272 /****************************************************************************** 
     298/***************************************************************************** 
    273299 * Basic Types 
    274  ******************************************************************************/ 
     300 *****************************************************************************/ 
    275301 
    276302/* 
     
    348374} yaml_break_t; 
    349375 
    350 /****************************************************************************** 
     376/***************************************************************************** 
    351377 * Node Styles 
    352  ******************************************************************************/ 
     378 *****************************************************************************/ 
    353379 
    354380/* 
     
    403429 
    404430    /* The flow sequence style. */ 
    405     YAML_FLOW_SEQUENCE_STYLE 
     431    YAML_FLOW_SEQUENCE_STYLE, 
    406432    /* The block sequence style. */ 
    407     YAML_BLOCK_SEQUENCE_STYLE, 
     433    YAML_BLOCK_SEQUENCE_STYLE 
    408434} yaml_sequence_style_t; 
    409435 
     
    431457} yaml_mapping_style_t; 
    432458 
    433 /****************************************************************************** 
     459/***************************************************************************** 
    434460 * Tokens 
    435  ******************************************************************************/ 
     461 *****************************************************************************/ 
    436462 
    437463/* 
     
    681707yaml_token_clear(yaml_token_t *token); 
    682708 
    683 /****************************************************************************** 
     709/***************************************************************************** 
    684710 * Events 
    685  ******************************************************************************/ 
     711 *****************************************************************************/ 
    686712 
    687713/* 
     
    12211247yaml_event_create_mapping_end(yaml_event_t *event); 
    12221248 
    1223 /****************************************************************************** 
     1249/***************************************************************************** 
    12241250 * Documents and Nodes 
    1225  ******************************************************************************/ 
     1251 *****************************************************************************/ 
    12261252 
    12271253/* 
     
    12611287typedef enum yaml_document_type_e { 
    12621288    /* An empty uninitialized document. */ 
    1263     YAML_NO_DOCUMENT. 
     1289    YAML_NO_DOCUMENT, 
    12641290 
    12651291    /* A YAML document. */ 
     
    13831409 */ 
    13841410 
    1385 struct yaml_node_s { 
     1411typedef struct yaml_node_s { 
    13861412 
    13871413    /* The node type. */ 
     
    14431469    yaml_mark_t end_mark; 
    14441470 
    1445 }; 
     1471} yaml_node_t; 
    14461472 
    14471473/* 
     
    18191845 
    18201846/* 
    1821  * Get the value of a `!!null` SCALAR node. 
    1822  * 
    1823  * Use this function to ensure that the given node is a scalar, the node tag is 
    1824  * equal to `tag:yaml.org,2002:null` and the node value is a valid null value. 
    1825  * Given that the `!!null` tag admits only one valid value, the value is not 
    1826  * returned. 
    1827  * 
    1828  * Arguments: 
    1829  * 
    1830  * - `document`: a document object. 
    1831  * 
    1832  * - `node_id`: the node id; could be negative. 
    1833  * 
    1834  * Returns: `1` if the node is a valid `!!null` scalar, `0` otherwise. 
    1835  */ 
    1836  
    1837 YAML_DECLARE(int) 
    1838 yaml_document_get_null_node(yaml_document_t *document, int node_id); 
    1839  
    1840 /* 
    1841  * Get the value of a `!!bool` SCALAR node. 
    1842  * 
    1843  * Use this function to ensure that the given node is a scalar, the node tag is 
    1844  * `tag:yaml.org,2002:bool` and the node value is a valid boolean value.  The 
    1845  * function returns the true value as `1` and the false value as `0`. 
    1846  * 
    1847  * Arguments: 
    1848  * 
    1849  * - `document`: a document object. 
    1850  * 
    1851  * - `node_id`: the node id; could be negative. 
    1852  * 
    1853  * - `value`: a pointer to save the node value or `NULL`. 
    1854  * 
    1855  * Returns: `1` if the node is a valid `!!bool` scalar, `0` otherwise.  If the 
    1856  * function succeeds and `value` is not `NULL`, the node value is saved to 
    1857  * `value`. 
    1858  */ 
    1859  
    1860 YAML_DECLARE(int) 
    1861 yaml_document_get_bool_node(yaml_document_t *document, int node_id, 
    1862         int *value); 
    1863  
    1864 /* 
    1865  * Get the value of a `!!str` SCALAR node. 
    1866  * 
    1867  * Use this function to ensure that the given node is a scalar, the node tag is 
    1868  * `tag:yaml.org,2002:str` and the node value is a string that does not contain 
    1869  * the NUL character.  In this case, the function returns the node value.  The 
    1870  * produced value is valid until the document object is cleared or deleted. 
    1871  * 
    1872  * Arguments: 
    1873  * 
    1874  * - `document`: a document object. 
    1875  * 
    1876  * - `node_id`: the node id; could be negative. 
    1877  * 
    1878  * - `value`: a pointer to save the node value or `NULL`. 
    1879  * 
    1880  * Returns: `1` if the node is a valid `!!str` scalar, `0` otherwise.  If the 
    1881  * function succeeds and `value` is not `NULL`, the node value is saved to 
    1882  * `value`. 
    1883  */ 
    1884  
    1885 YAML_DECLARE(int) 
    1886 yaml_document_get_str_node(yaml_document_t *document, int node_id, 
    1887         char **value); 
    1888  
    1889 /* 
    1890  * Get the value of an `!!int` SCALAR node. 
    1891  * 
    1892  * Use this function to ensure that the given node is a scalar, the node tag is 
    1893  * `tag:yaml.org,2002:int` and the node value is a valid integer.  In this 
    1894  * case, the function parses the node value and returns an integer number.  The 
    1895  * function recognizes decimal, hexdecimal and octal numbers including negative 
    1896  * numbers. 
    1897  * 
    1898  * Arguments: 
    1899  * 
    1900  * - `document`: a document object. 
    1901  * 
    1902  * - `node_id`: the node id; could be negative. 
    1903  * 
    1904  * - `value`: a pointer to save the node value or `NULL`. 
    1905  * 
    1906  * Returns: `1` if the node is a valid `!!int` scalar, `0` otherwise.  If the 
    1907  * function succeeds and `value` is not `NULL`, the node value is saved to 
    1908  * `value`. 
    1909  */ 
    1910  
    1911 YAML_DECLARE(int) 
    1912 yaml_document_get_int_node(yaml_document_t *document, int node_id, 
    1913         int *value); 
    1914  
    1915 /* 
    1916  * Get the value of a `!!float` SCALAR node. 
    1917  * 
    1918  * Use this function to ensure that the given node is a scalar, the node tag is 
    1919  * `tag:yaml.org,2002:float` and the node value is a valid float value.  In 
    1920  * this case, the function parses the node value and returns a float number. 
    1921  * The function recognizes float values in exponential and fixed notation as 
    1922  * well as special values `.nan`, `.inf` and `-.inf`. 
    1923  * 
    1924  * Arguments: 
    1925  * 
    1926  * - `document`: a document object. 
    1927  * 
    1928  * - `node_id`: the node id; could be negative. 
    1929  * 
    1930  * - `value`: a pointer to save the node value or `NULL`. 
    1931  * 
    1932  * Returns: `1` if the node is a valid `!!float` scalar, `0` otherwise.  If the 
    1933  * function succeeds and `value` is not `NULL`, the node value is saved to 
    1934  * `value`. 
    1935  */ 
    1936  
    1937 YAML_DECLARE(int) 
    1938 yaml_document_get_float_node(yaml_document_t *document, int node_id, 
    1939         double *value); 
    1940  
    1941 /* 
    1942  * Get the value of a `!!seq` SEQUENCE node. 
    1943  * 
    1944  * Use this function to ensure that the given node is a sequence and the node 
    1945  * tag is `tag:yaml.org,2002:seq`.  In this case, the function returns the list 
    1946  * of nodes that belong to the sequence.  The produced list is valid until the 
    1947  * document object is modified. 
    1948  * 
    1949  * Arguments: 
    1950  * 
    1951  * - `document`: a document object. 
    1952  * 
    1953  * - `node_id`: the node id; could be negative. 
    1954  * 
    1955  * - `items`: a pointer to save the list of sequence items or `NULL`. 
    1956  * 
    1957  * - `length`: a pointer to save the length of the sequence or `NULL`. 
    1958  *   `length` must be equal to `NULL` if and only if `items` is also `NULL`. 
    1959  * 
    1960  * Returns: `1` if the node is a valid `!!seq` sequence, `0` otherwise.  If the 
    1961  * function succeeds and `items` is not `NULL`, the list of sequence items is 
    1962  * saved to `items` and the sequence length is saved to `length`. 
    1963  */ 
    1964  
    1965 YAML_DECLARE(int) 
    1966 yaml_document_get_seq_node(yaml_document_t *document, int node_id, 
    1967         yaml_node_item_t **items, size_t *length); 
    1968  
    1969 /* 
    1970  * Get the value of a `!!map` MAPPING node. 
    1971  * 
    1972  * Use this function to ensure that the given node is a mapping and the node 
    1973  * tag is `tag:yaml.org,2002:map`.  In this case, the function returns the list 
    1974  * of node pairs (key, value) that belong to the sequence.  The produced list 
    1975  * is valid until the document is modified. 
    1976  * 
    1977  * Arguments: 
    1978  * 
    1979  * - `document`: a document object. 
    1980  * 
    1981  * - `node_id`: the node id; could be negative. 
    1982  * 
    1983  * - `pairs`: a pointer to save the list of mapping pairs or `NULL`. 
    1984  * 
    1985  * - `length`: a pointer to save the length of the mapping or `NULL`. 
    1986  *   `length` must be equal to `NULL` if and only if `pairs` is also `NULL`. 
    1987  * 
    1988  * Returns: `1` if the node is a valid `!!map` mapping, `0` otherwise.  If the 
    1989  * function succeeds and `pairs` is not `NULL`, the list of mapping pairs is 
    1990  * saved to `pairs` and the mapping length is saved to `length`. 
    1991  */ 
    1992  
    1993 YAML_DECLARE(int) 
    1994 yaml_document_get_map_node(yaml_document_t *document, int node_id, 
    1995         yaml_node_pair_t **pairs, size_t *length); 
    1996  
    1997 /* 
    1998  * Add a `!!null` SCALAR node to the document. 
    1999  * 
    2000  * This function is a shorthand for the call: 
    2001  * 
    2002  *      yaml_document_add_scalar(document, node_id, NULL, 
    2003  *              YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE) 
    2004  * 
    2005  * Arguments: 
    2006  * 
    2007  * - `document`: a document object. 
    2008  * 
    2009  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2010  * 
    2011  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2012  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2013  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2014  */ 
    2015  
    2016 YAML_DECLARE(int) 
    2017 yaml_document_add_null_node(yaml_document_t *document, int *node_id); 
    2018  
    2019 /* 
    2020  * Add a `!!bool` SCALAR node to the document. 
    2021  * 
    2022  * This function is a shorthand for the call: 
    2023  * 
    2024  *      yaml_document_add_scalar(document, node_id, NULL, 
    2025  *              YAML_BOOL_TAG, (value ? "true" : "false"), -1, 
    2026  *              YAML_ANY_SCALAR_STYLE) 
    2027  * 
    2028  * Arguments: 
    2029  * 
    2030  * - `document`: a document object. 
    2031  * 
    2032  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2033  * 
    2034  * - `value`: a boolean value; any non-zero value is true, `0` is false. 
    2035  * 
    2036  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2037  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2038  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2039  */ 
    2040  
    2041 YAML_DECLARE(int) 
    2042 yaml_document_add_bool_node(yaml_document_t *document, int *node_id, 
    2043         int value); 
    2044  
    2045 /* 
    2046  * Add a `!!str` SCALAR node to the document. 
    2047  * 
    2048  * This function is a shorthand for the call: 
    2049  * 
    2050  *      yaml_document_add_scalar(document, node_id, NULL, 
    2051  *              YAML_STR_TAG, (const yaml_char_t *) value, -1, 
    2052  *              YAML_ANY_SCALAR_STYLE) 
    2053  * 
    2054  * Arguments: 
    2055  * 
    2056  * - `document`: a document object. 
    2057  * 
    2058  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2059  * 
    2060  * - `value`: a NUL-terminated UTF-8 string.  The function does not check if 
    2061  *   `value` is a valid UTF-8 string, but if it is not so, the emitter will 
    2062  *   fail to emit the node. 
    2063  * 
    2064  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2065  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2066  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2067  */ 
    2068  
    2069 YAML_DECLARE(int) 
    2070 yaml_document_add_str_node(yaml_document_t *document, int *node_id, 
    2071         const char *value); 
    2072  
    2073 /* 
    2074  * Add an `!!int` SCALAR node to the document. 
    2075  * 
    2076  * This function is a shorthand for the call: 
    2077  * 
    2078  *      yaml_document_add_scalar(document, node_id, NULL, 
    2079  *              YAML_INT_TAG, <string representation of the value>, -1, 
    2080  *              YAML_ANY_SCALAR_STYLE) 
    2081  * 
    2082  * Arguments: 
    2083  * 
    2084  * - `document`: a document object. 
    2085  * 
    2086  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2087  * 
    2088  * - `value`: an integer value. 
    2089  * 
    2090  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2091  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2092  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2093  */ 
    2094  
    2095 YAML_DECLARE(int) 
    2096 yaml_document_add_int_node(yaml_document_t *document, int *node_id, 
    2097         int value); 
    2098  
    2099 /* 
    2100  * Add a `!!float` SCALAR node to the document. 
    2101  * 
    2102  * This function is a shorthand for the call: 
    2103  * 
    2104  *      yaml_document_add_scalar(document, node_id, NULL, 
    2105  *              YAML_FLOAT_TAG, <string representation of the value>, -1, 
    2106  *              YAML_ANY_SCALAR_STYLE) 
    2107  * 
    2108  * Arguments: 
    2109  * 
    2110  * - `document`: a document object. 
    2111  * 
    2112  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2113  * 
    2114  * - `value`: a float value. 
    2115  * 
    2116  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2117  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2118  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2119  */ 
    2120  
    2121 YAML_DECLARE(int) 
    2122 yaml_document_add_float_node(yaml_document_t *document, int *node_id, 
    2123         double value); 
    2124  
    2125 /* 
    2126  * Add a `!!seq` SEQUENCE node to the document. 
    2127  * 
    2128  * This function is a shorthand for the call: 
    2129  * 
    2130  *      yaml_document_add_sequence(document, node_id, NULL, 
    2131  *              YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE) 
    2132  * 
    2133  * Arguments: 
    2134  * 
    2135  * - `document`: a document object. 
    2136  * 
    2137  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2138  * 
    2139  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2140  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2141  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2142  */ 
    2143  
    2144 YAML_DECLARE(int) 
    2145 yaml_document_add_seq_node(yaml_document_t *document, int *node_id); 
    2146  
    2147 /* 
    2148  * Add a `!!map` MAPPING node to the document. 
    2149  * 
    2150  * This function is a shorthand for the call: 
    2151  * 
    2152  *      yaml_document_add_mapping(document, node_id, NULL, 
    2153  *              YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE) 
    2154  * 
    2155  * Arguments: 
    2156  * 
    2157  * - `document`: a document object. 
    2158  * 
    2159  * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
    2160  * 
    2161  * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
    2162  * allocate memory for new buffers.  If the function succeeds, the id of the 
    2163  * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
    2164  */ 
    2165  
    2166 YAML_DECLARE(int) 
    2167 yaml_document_add_map_node(yaml_document_t *document, int *node_id); 
    2168  
    2169 /* 
    21701847 * Add an item to a SEQUENCE node. 
    21711848 * 
     
    22231900        int mapping_id, int key_id, int value_id); 
    22241901 
    2225 /****************************************************************************** 
     1902/* 
     1903 * Get the value of a `!!null` SCALAR node. 
     1904 * 
     1905 * Use this function to ensure that the given node is a scalar, the node tag is 
     1906 * equal to `tag:yaml.org,2002:null` and the node value is a valid null value. 
     1907 * Given that the `!!null` tag admits only one valid value, the value is not 
     1908 * returned. 
     1909 * 
     1910 * Arguments: 
     1911 * 
     1912 * - `document`: a document object. 
     1913 * 
     1914 * - `node_id`: the node id; could be negative. 
     1915 * 
     1916 * Returns: `1` if the node is a valid `!!null` scalar, `0` otherwise. 
     1917 */ 
     1918 
     1919YAML_DECLARE(int) 
     1920yaml_document_get_null_node(yaml_document_t *document, int node_id); 
     1921 
     1922/* 
     1923 * Get the value of a `!!bool` SCALAR node. 
     1924 * 
     1925 * Use this function to ensure that the given node is a scalar, the node tag is 
     1926 * `tag:yaml.org,2002:bool` and the node value is a valid boolean value.  The 
     1927 * function returns the true value as `1` and the false value as `0`. 
     1928 * 
     1929 * Arguments: 
     1930 * 
     1931 * - `document`: a document object. 
     1932 * 
     1933 * - `node_id`: the node id; could be negative. 
     1934 * 
     1935 * - `value`: a pointer to save the node value or `NULL`. 
     1936 * 
     1937 * Returns: `1` if the node is a valid `!!bool` scalar, `0` otherwise.  If the 
     1938 * function succeeds and `value` is not `NULL`, the node value is saved to 
     1939 * `value`. 
     1940 */ 
     1941 
     1942YAML_DECLARE(int) 
     1943yaml_document_get_bool_node(yaml_document_t *document, int node_id, 
     1944        int *value); 
     1945 
     1946/* 
     1947 * Get the value of a `!!str` SCALAR node. 
     1948 * 
     1949 * Use this function to ensure that the given node is a scalar, the node tag is 
     1950 * `tag:yaml.org,2002:str` and the node value is a string that does not contain 
     1951 * the NUL character.  In this case, the function returns the node value.  The 
     1952 * produced value is valid until the document object is cleared or deleted. 
     1953 * 
     1954 * Arguments: 
     1955 * 
     1956 * - `document`: a document object. 
     1957 * 
     1958 * - `node_id`: the node id; could be negative. 
     1959 * 
     1960 * - `value`: a pointer to save the node value or `NULL`. 
     1961 * 
     1962 * Returns: `1` if the node is a valid `!!str` scalar, `0` otherwise.  If the 
     1963 * function succeeds and `value` is not `NULL`, the node value is saved to 
     1964 * `value`. 
     1965 */ 
     1966 
     1967YAML_DECLARE(int) 
     1968yaml_document_get_str_node(yaml_document_t *document, int node_id, 
     1969        char **value); 
     1970 
     1971/* 
     1972 * Get the value of an `!!int` SCALAR node. 
     1973 * 
     1974 * Use this function to ensure that the given node is a scalar, the node tag is 
     1975 * `tag:yaml.org,2002:int` and the node value is a valid integer.  In this 
     1976 * case, the function parses the node value and returns an integer number.  The 
     1977 * function recognizes decimal, hexdecimal and octal numbers including negative 
     1978 * numbers.  The function uses `strtol()` for string-to-integer conversion. 
     1979 * 
     1980 * Arguments: 
     1981 * 
     1982 * - `document`: a document object. 
     1983 * 
     1984 * - `node_id`: the node id; could be negative. 
     1985 * 
     1986 * - `value`: a pointer to save the node value or `NULL`. 
     1987 * 
     1988 * Returns: `1` if the node is a valid `!!int` scalar, `0` otherwise.  If the 
     1989 * function succeeds and `value` is not `NULL`, the node value is saved to 
     1990 * `value`. 
     1991 */ 
     1992 
     1993YAML_DECLARE(int) 
     1994yaml_document_get_int_node(yaml_document_t *document, int node_id, 
     1995        long *value); 
     1996 
     1997/* 
     1998 * Get the value of a `!!float` SCALAR node. 
     1999 * 
     2000 * Use this function to ensure that the given node is a scalar, the node tag is 
     2001 * `tag:yaml.org,2002:float` and the node value is a valid float value.  In 
     2002 * this case, the function parses the node value and returns a float number. 
     2003 * The function recognizes float values in exponential and fixed notation as 
     2004 * well as special values `.nan`, `.inf` and `-.inf`.  The function uses 
     2005 * `strtod()` for string-to-float conversion.  The `.nan`, `.inf` and `-.inf` 
     2006 * values are generated as `0.0/0.0`, `1.0/0.0` and `-1.0/0.0` respectively. 
     2007 * 
     2008 * Arguments: 
     2009 * 
     2010 * - `document`: a document object. 
     2011 * 
     2012 * - `node_id`: the node id; could be negative. 
     2013 * 
     2014 * - `value`: a pointer to save the node value or `NULL`. 
     2015 * 
     2016 * Returns: `1` if the node is a valid `!!float` scalar, `0` otherwise.  If the 
     2017 * function succeeds and `value` is not `NULL`, the node value is saved to 
     2018 * `value`. 
     2019 */ 
     2020 
     2021YAML_DECLARE(int) 
     2022yaml_document_get_float_node(yaml_document_t *document, int node_id, 
     2023        double *value); 
     2024 
     2025/* 
     2026 * Get the value of a `!!seq` SEQUENCE node. 
     2027 * 
     2028 * Use this function to ensure that the given node is a sequence and the node 
     2029 * tag is `tag:yaml.org,2002:seq`.  In this case, the function returns the list 
     2030 * of nodes that belong to the sequence.  The produced list is valid until the 
     2031 * document object is modified. 
     2032 * 
     2033 * Arguments: 
     2034 * 
     2035 * - `document`: a document object. 
     2036 * 
     2037 * - `node_id`: the node id; could be negative. 
     2038 * 
     2039 * - `items`: a pointer to save the list of sequence items or `NULL`. 
     2040 * 
     2041 * - `length`: a pointer to save the length of the sequence or `NULL`. 
     2042 *   `length` must be equal to `NULL` if and only if `items` is also `NULL`. 
     2043 * 
     2044 * Returns: `1` if the node is a valid `!!seq` sequence, `0` otherwise.  If the 
     2045 * function succeeds and `items` is not `NULL`, the list of sequence items is 
     2046 * saved to `items` and the sequence length is saved to `length`. 
     2047 */ 
     2048 
     2049YAML_DECLARE(int) 
     2050yaml_document_get_seq_node(yaml_document_t *document, int node_id, 
     2051        yaml_node_item_t **items, size_t *length); 
     2052 
     2053/* 
     2054 * Get the value of a `!!map` MAPPING node. 
     2055 * 
     2056 * Use this function to ensure that the given node is a mapping and the node 
     2057 * tag is `tag:yaml.org,2002:map`.  In this case, the function returns the list 
     2058 * of node pairs (key, value) that belong to the sequence.  The produced list 
     2059 * is valid until the document is modified. 
     2060 * 
     2061 * Arguments: 
     2062 * 
     2063 * - `document`: a document object. 
     2064 * 
     2065 * - `node_id`: the node id; could be negative. 
     2066 * 
     2067 * - `pairs`: a pointer to save the list of mapping pairs or `NULL`. 
     2068 * 
     2069 * - `length`: a pointer to save the length of the mapping or `NULL`. 
     2070 *   `length` must be equal to `NULL` if and only if `pairs` is also `NULL`. 
     2071 * 
     2072 * Returns: `1` if the node is a valid `!!map` mapping, `0` otherwise.  If the 
     2073 * function succeeds and `pairs` is not `NULL`, the list of mapping pairs is 
     2074 * saved to `pairs` and the mapping length is saved to `length`. 
     2075 */ 
     2076 
     2077YAML_DECLARE(int) 
     2078yaml_document_get_map_node(yaml_document_t *document, int node_id, 
     2079        yaml_node_pair_t **pairs, size_t *length); 
     2080 
     2081/* 
     2082 * Add a `!!null` SCALAR node to the document. 
     2083 * 
     2084 * This function is a shorthand for the call: 
     2085 * 
     2086 *      yaml_document_add_scalar(document, node_id, NULL, 
     2087 *              YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE) 
     2088 * 
     2089 * Arguments: 
     2090 * 
     2091 * - `document`: a document object. 
     2092 * 
     2093 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2094 * 
     2095 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2096 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2097 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2098 */ 
     2099 
     2100YAML_DECLARE(int) 
     2101yaml_document_add_null_node(yaml_document_t *document, int *node_id); 
     2102 
     2103/* 
     2104 * Add a `!!bool` SCALAR node to the document. 
     2105 * 
     2106 * This function is a shorthand for the call: 
     2107 * 
     2108 *      yaml_document_add_scalar(document, node_id, NULL, 
     2109 *              YAML_BOOL_TAG, (value ? "true" : "false"), -1, 
     2110 *              YAML_ANY_SCALAR_STYLE) 
     2111 * 
     2112 * Arguments: 
     2113 * 
     2114 * - `document`: a document object. 
     2115 * 
     2116 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2117 * 
     2118 * - `value`: a boolean value; any non-zero value is true, `0` is false. 
     2119 * 
     2120 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2121 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2122 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2123 */ 
     2124 
     2125YAML_DECLARE(int) 
     2126yaml_document_add_bool_node(yaml_document_t *document, int *node_id, 
     2127        int value); 
     2128 
     2129/* 
     2130 * Add a `!!str` SCALAR node to the document. 
     2131 * 
     2132 * This function is a shorthand for the call: 
     2133 * 
     2134 *      yaml_document_add_scalar(document, node_id, NULL, 
     2135 *              YAML_STR_TAG, (const yaml_char_t *) value, -1, 
     2136 *              YAML_ANY_SCALAR_STYLE) 
     2137 * 
     2138 * Arguments: 
     2139 * 
     2140 * - `document`: a document object. 
     2141 * 
     2142 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2143 * 
     2144 * - `value`: a NUL-terminated UTF-8 string.  The function does not check if 
     2145 *   `value` is a valid UTF-8 string, but if it is not so, the emitter will 
     2146 *   fail to emit the node. 
     2147 * 
     2148 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2149 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2150 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2151 */ 
     2152 
     2153YAML_DECLARE(int) 
     2154yaml_document_add_str_node(yaml_document_t *document, int *node_id, 
     2155        const char *value); 
     2156 
     2157/* 
     2158 * Add an `!!int` SCALAR node to the document. 
     2159 * 
     2160 * This function is a shorthand for the call: 
     2161 * 
     2162 *      yaml_document_add_scalar(document, node_id, NULL, 
     2163 *              YAML_INT_TAG, <string representation of the value>, -1, 
     2164 *              YAML_ANY_SCALAR_STYLE) 
     2165 * 
     2166 * Arguments: 
     2167 * 
     2168 * - `document`: a document object. 
     2169 * 
     2170 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2171 * 
     2172 * - `value`: an integer value. 
     2173 * 
     2174 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2175 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2176 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2177 */ 
     2178 
     2179YAML_DECLARE(int) 
     2180yaml_document_add_int_node(yaml_document_t *document, int *node_id, 
     2181        long value); 
     2182 
     2183/* 
     2184 * Add a `!!float` SCALAR node to the document. 
     2185 * 
     2186 * This function is a shorthand for the call: 
     2187 * 
     2188 *      yaml_document_add_scalar(document, node_id, NULL, 
     2189 *              YAML_FLOAT_TAG, <string representation of the value>, -1, 
     2190 *              YAML_ANY_SCALAR_STYLE) 
     2191 * 
     2192 * Arguments: 
     2193 * 
     2194 * - `document`: a document object. 
     2195 * 
     2196 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2197 * 
     2198 * - `value`: a float value. 
     2199 * 
     2200 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2201 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2202 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2203 */ 
     2204 
     2205YAML_DECLARE(int) 
     2206yaml_document_add_float_node(yaml_document_t *document, int *node_id, 
     2207        double value); 
     2208 
     2209/* 
     2210 * Add a `!!seq` SEQUENCE node to the document. 
     2211 * 
     2212 * This function is a shorthand for the call: 
     2213 * 
     2214 *      yaml_document_add_sequence(document, node_id, NULL, 
     2215 *              YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE) 
     2216 * 
     2217 * Arguments: 
     2218 * 
     2219 * - `document`: a document object. 
     2220 * 
     2221 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2222 * 
     2223 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2224 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2225 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2226 */ 
     2227 
     2228YAML_DECLARE(int) 
     2229yaml_document_add_seq_node(yaml_document_t *document, int *node_id); 
     2230 
     2231/* 
     2232 * Add a `!!map` MAPPING node to the document. 
     2233 * 
     2234 * This function is a shorthand for the call: 
     2235 * 
     2236 *      yaml_document_add_mapping(document, node_id, NULL, 
     2237 *              YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE) 
     2238 * 
     2239 * Arguments: 
     2240 * 
     2241 * - `document`: a document object. 
     2242 * 
     2243 * - `node_id`: a pointer to save the id of the generated node or `NULL`. 
     2244 * 
     2245 * Returns: `1` on success, `0` on error.  The function may fail if it cannot 
     2246 * allocate memory for new buffers.  If the function succeeds, the id of the 
     2247 * added node is returned via the pointer `node_id` if it is not set to `NULL`. 
     2248 */ 
     2249 
     2250YAML_DECLARE(int) 
     2251yaml_document_add_map_node(yaml_document_t *document, int *node_id); 
     2252 
     2253/***************************************************************************** 
    22262254 * Callback Definitions 
    2227  ******************************************************************************/ 
     2255 *****************************************************************************/ 
    22282256 
    22292257/* 
     
    23062334 
    23072335typedef int yaml_resolver_t(void *data, yaml_incomplete_node_t *node, 
    2308         yaml_char_t **tag); 
    2309  
    2310 /****************************************************************************** 
     2336        const yaml_char_t **tag); 
     2337 
     2338/***************************************************************************** 
    23112339 * Parser Definitions 
    2312  ******************************************************************************/ 
     2340 *****************************************************************************/ 
    23132341 
    23142342/* 
     
    23602388 
    23612389YAML_DECLARE(void) 
    2362 yaml_parser_clear(yaml_parser_t *parser); 
     2390yaml_parser_reset(yaml_parser_t *parser); 
    23632391 
    23642392/* 
     
    26182646        yaml_document_t *document); 
    26192647 
    2620 /****************************************************************************** 
     2648/***************************************************************************** 
    26212649 * Emitter Definitions 
    2622  ******************************************************************************/ 
     2650 *****************************************************************************/ 
    26232651 
    26242652/* 
     
    26702698 
    26712699YAML_DECLARE(void) 
    2672 yaml_emitter_clear(yaml_emitter_t *emitter); 
     2700yaml_emitter_reset(yaml_emitter_t *emitter); 
    26732701 
    26742702/* 
  • libyaml/trunk/src/api.c

    r265 r267  
     1/***************************************************************************** 
     2 * LibYAML API Implementation 
     3 * 
     4 * Copyright (c) 2006 Kirill Simonov 
     5 * 
     6 * LibYAML is free software; you can use, modify and/or redistribute it under 
     7 * the terms of the MIT license; see the file LICENCE for more details. 
     8 *****************************************************************************/ 
    19 
    210#include "yaml_private.h" 
    311 
    4 /* 
    5  * Get the library version. 
     12/***************************************************************************** 
     13 * Version Information 
     14 *****************************************************************************/ 
     15 
     16/* 
     17 * Get the library version as a static string. 
    618 */ 
    719 
     
    2436} 
    2537 
     38/***************************************************************************** 
     39 * Memory Management 
     40 *****************************************************************************/ 
     41 
    2642/* 
    2743 * Allocate a dynamic memory block. 
     
    6682    return (yaml_char_t *)strdup((char *)str); 
    6783} 
     84 
     85/***************************************************************************** 
     86 * Error Handling 
     87 *****************************************************************************/ 
    6888 
    6989/* 
     
    171191} 
    172192 
     193/***************************************************************************** 
     194 * String, Stack and Queue Management 
     195 *****************************************************************************/ 
    173196 
    174197/* 
     
    264287} 
    265288 
    266  
    267 /* 
    268  * Create a new parser object. 
    269  */ 
    270  
    271 YAML_DECLARE(yaml_parser_t *) 
    272 yaml_parser_new(void) 
    273 { 
    274     yaml_parser_t *parser = yaml_malloc(sizeof(yaml_parser_t)); 
    275  
    276     if (!parser) 
    277         return NULL; 
    278  
    279     memset(parser, 0, sizeof(yaml_parser_t)); 
    280     if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY)) 
    281         goto error; 
    282     if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY)) 
    283         goto error; 
    284     if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY)) 
    285         goto error; 
    286     if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_CAPACITY)) 
    287         goto error; 
    288     if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_CAPACITY)) 
    289         goto error; 
    290     if (!STACK_INIT(parser, parser->states, INITIAL_STACK_CAPACITY)) 
    291         goto error; 
    292     if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_CAPACITY)) 
    293         goto error; 
    294     if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_CAPACITY)) 
    295         goto error; 
    296  
    297     return parser; 
    298  
    299 error: 
    300     yaml_parser_delete(parser); 
    301  
    302     return NULL; 
    303 } 
    304  
    305 /* 
    306  * Destroy a parser object. 
    307  */ 
    308  
    309 YAML_DECLARE(void) 
    310 yaml_parser_delete(yaml_parser_t *parser) 
    311 { 
    312     assert(parser); /* Non-NULL parser object expected. */ 
    313  
    314     IOSTRING_DEL(parser, parser->raw_input); 
    315     IOSTRING_DEL(parser, parser->input); 
    316     while (!QUEUE_EMPTY(parser, parser->tokens)) { 
    317         yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
    318     } 
    319     QUEUE_DEL(parser, parser->tokens); 
    320     STACK_DEL(parser, parser->indents); 
    321     STACK_DEL(parser, parser->simple_keys); 
    322     STACK_DEL(parser, parser->states); 
    323     STACK_DEL(parser, parser->marks); 
    324     while (!STACK_EMPTY(parser, parser->tag_directives)) { 
    325         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
    326         yaml_free(tag_directive.handle); 
    327         yaml_free(tag_directive.prefix); 
    328     } 
    329     STACK_DEL(parser, parser->tag_directives); 
    330  
    331     memset(parser, 0, sizeof(yaml_parser_t)); 
    332     yaml_free(parser); 
    333 } 
    334  
    335 /* 
    336  * Get the current parser error. 
    337  */ 
    338  
    339 YAML_DECLARE(void) 
    340 yaml_parser_get_error(yaml_parser_t *parser, yaml_error_t *error) 
    341 { 
    342     assert(parser); /* Non-NULL parser object expected. */ 
    343  
    344     *error = parser->error; 
    345 } 
    346  
    347 /* 
    348  * Standard string read handler. 
    349  */ 
    350  
    351 static int 
    352 yaml_string_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
    353         size_t *length) 
    354 { 
    355     yaml_standard_reader_data_t *data = untyped_data; 
    356  
    357     if (data->string.pointer == data->string.length) { 
    358         *length = 0; 
    359         return 1; 
    360     } 
    361  
    362     if (capacity > (size_t)(data->string.length - data->string.pointer)) { 
    363         capacity = data->string.length - data->string.pointer; 
    364     } 
    365  
    366     memcpy(buffer, data->string.buffer + data->string.pointer, capacity); 
    367     data->string.pointer += capacity; 
    368     *length = capacity; 
    369     return 1; 
    370 } 
    371  
    372 /* 
    373  * Standard file read handler. 
    374  */ 
    375  
    376 static int 
    377 yaml_file_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
    378         size_t *length) 
    379 { 
    380     yaml_standard_reader_data_t *data = untyped_data; 
    381  
    382     *length = fread(buffer, 1, capacity, data->file); 
    383     return !ferror(data->file); 
    384 } 
    385  
    386 /* 
    387  * Set a string input. 
    388  */ 
    389  
    390 YAML_DECLARE(void) 
    391 yaml_parser_set_string_reader(yaml_parser_t *parser, 
    392         const unsigned char *buffer, size_t length) 
    393 { 
    394     assert(parser); /* Non-NULL parser object expected. */ 
    395     assert(!parser->reader);    /* You can set the input handler only once. */ 
    396     assert(buffer); /* Non-NULL input string expected. */ 
    397  
    398     parser->reader = yaml_string_reader; 
    399     parser->reader_data = &(parser->standard_reader_data); 
    400  
    401     parser->standard_reader_data.string.buffer = buffer; 
    402     parser->standard_reader_data.string.pointer = 0; 
    403     parser->standard_reader_data.string.length = length; 
    404 } 
    405  
    406 /* 
    407  * Set a file input. 
    408  */ 
    409  
    410 YAML_DECLARE(void) 
    411 yaml_parser_set_file_reader(yaml_parser_t *parser, FILE *file) 
    412 { 
    413     assert(parser); /* Non-NULL parser object expected. */ 
    414     assert(!parser->reader);    /* You can set the input handler only once. */ 
    415     assert(file);   /* Non-NULL file object expected. */ 
    416  
    417     parser->reader = yaml_file_reader; 
    418     parser->reader_data = &(parser->standard_reader_data); 
    419  
    420     parser->standard_reader_data.file = file; 
    421 } 
    422  
    423 /* 
    424  * Set a generic input. 
    425  */ 
    426  
    427 YAML_DECLARE(void) 
    428 yaml_parser_set_reader(yaml_parser_t *parser, 
    429         yaml_reader_t *reader, void *data) 
    430 { 
    431     assert(parser); /* Non-NULL parser object expected. */ 
    432     assert(!parser->reader);    /* You can set the input handler only once. */ 
    433     assert(reader); /* Non-NULL read handler expected. */ 
    434  
    435     parser->reader = reader; 
    436     parser->reader_data = data; 
    437 } 
    438  
    439 /* 
    440  * Set the source encoding. 
    441  */ 
    442  
    443 YAML_DECLARE(void) 
    444 yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) 
    445 { 
    446     assert(parser); /* Non-NULL parser object expected. */ 
    447     assert(!parser->encoding);  /* Encoding is already set or detected. */ 
    448  
    449     parser->encoding = encoding; 
    450 } 
    451  
    452 /* 
    453  * Create a new emitter object. 
    454  */ 
    455  
    456 YAML_DECLARE(yaml_emitter_t *) 
    457 yaml_emitter_new(void) 
    458 { 
    459     yaml_emitter_t *emitter = yaml_malloc(sizeof(yaml_emitter_t)); 
    460  
    461     if (!emitter) 
    462         return NULL; 
    463  
    464     memset(emitter, 0, sizeof(yaml_emitter_t)); 
    465     if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY)) 
    466         goto error; 
    467     if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY)) 
    468         goto error; 
    469     if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY)) 
    470         goto error; 
    471     if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_CAPACITY)) 
    472         goto error; 
    473     if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_CAPACITY)) 
    474         goto error; 
    475     if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_CAPACITY)) 
    476         goto error; 
    477  
    478     return emitter; 
    479  
    480 error: 
    481     yaml_emitter_delete(emitter); 
    482  
    483     return NULL; 
    484 } 
    485  
    486 /* 
    487  * Destroy an emitter object. 
    488  */ 
    489  
    490 YAML_DECLARE(void) 
    491 yaml_emitter_delete(yaml_emitter_t *emitter) 
    492 { 
    493     assert(emitter);    /* Non-NULL emitter object expected. */ 
    494  
    495     IOSTRING_DEL(emitter, emitter->output); 
    496     IOSTRING_DEL(emitter, emitter->raw_output); 
    497     STACK_DEL(emitter, emitter->states); 
    498     while (!QUEUE_EMPTY(emitter, emitter->events)) { 
    499         yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
    500     } 
    501     QUEUE_DEL(emitter, emitter->events); 
    502     STACK_DEL(emitter, emitter->indents); 
    503     while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
    504         yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
    505         yaml_free(tag_directive.handle); 
    506         yaml_free(tag_directive.prefix); 
    507     } 
    508     STACK_DEL(emitter, emitter->tag_directives); 
    509     yaml_free(emitter->anchors); 
    510  
    511     memset(emitter, 0, sizeof(yaml_emitter_t)); 
    512     yaml_free(emitter); 
    513 } 
    514  
    515 /* 
    516  * Get the current emitter error. 
    517  */ 
    518  
    519 YAML_DECLARE(void) 
    520 yaml_emitter_get_error(yaml_emitter_t *emitter, yaml_error_t *error) 
    521 { 
    522     assert(emitter);    /* Non-NULL emitter object expected. */ 
    523  
    524     *error = emitter->error; 
    525 } 
    526  
    527 /* 
    528  * String write handler. 
    529  */ 
    530  
    531 static int 
    532 yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
    533 { 
    534     yaml_standard_writer_data_t *data = untyped_data; 
    535     int result = 1; 
    536  
    537     if (data->string.capacity - data->string.pointer < length) { 
    538         length = data->string.capacity - data->string.pointer; 
    539         result = 0; 
    540     } 
    541  
    542     memcpy(data->string.buffer + data->string.pointer, buffer, length); 
    543     data->string.pointer += length; 
    544     *data->length += length; 
    545  
    546     return result; 
    547 } 
    548  
    549 /* 
    550  * File write handler. 
    551  */ 
    552  
    553 static int 
    554 yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
    555 { 
    556     yaml_standard_writer_data_t *data = untyped_data; 
    557  
    558     return (fwrite(buffer, 1, length, data->file) == length); 
    559 } 
    560 /* 
    561  * Set a string output. 
    562  */ 
    563  
    564 YAML_DECLARE(void) 
    565 yaml_emitter_set_string_writer(yaml_emitter_t *emitter, 
    566         unsigned char *buffer, size_t capacity, size_t *length) 
    567 { 
    568     assert(emitter);    /* Non-NULL emitter object expected. */ 
    569     assert(!emitter->writer);   /* You can set the output only once. */ 
    570     assert(buffer);     /* Non-NULL output string expected. */ 
    571  
    572     emitter->writer = yaml_string_writer; 
    573     emitter->writer_data = &(emitter->standard_writer_data); 
    574  
    575     emitter->standard_writer_data.string.buffer = buffer; 
    576     emitter->standard_writer_data.string.pointer = 0; 
    577     emitter->standard_writer_data.string.capacity = capacity; 
    578     emitter->standard_writer_data.length = length; 
    579  
    580     *length = 0; 
    581 } 
    582  
    583 /* 
    584  * Set a file output. 
    585  */ 
    586  
    587 YAML_DECLARE(void) 
    588 yaml_emitter_set_file_writer(yaml_emitter_t *emitter, FILE *file) 
    589 { 
    590     assert(emitter);    /* Non-NULL emitter object expected. */ 
    591     assert(!emitter->writer);   /* You can set the output only once. */ 
    592     assert(file);       /* Non-NULL file object expected. */ 
    593  
    594     emitter->writer = yaml_string_writer; 
    595     emitter->writer_data = &(emitter->standard_writer_data); 
    596  
    597     emitter->standard_writer_data.file = file; 
    598 } 
    599  
    600 /* 
    601  * Set a generic output handler. 
    602  */ 
    603  
    604 YAML_DECLARE(void) 
    605 yaml_emitter_set_writer(yaml_emitter_t *emitter, 
    606         yaml_writer_t *writer, void *data) 
    607 { 
    608     assert(emitter);    /* Non-NULL emitter object expected. */ 
    609     assert(!emitter->writer);   /* You can set the output only once. */ 
    610     assert(writer); /* Non-NULL handler object expected. */ 
    611  
    612     emitter->writer = writer; 
    613     emitter->writer_data = data; 
    614 } 
    615  
    616 /* 
    617  * Set the output encoding. 
    618  */ 
    619  
    620 YAML_DECLARE(void) 
    621 yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) 
    622 { 
    623     assert(emitter);    /* Non-NULL emitter object expected. */ 
    624     assert(!emitter->encoding);     /* You can set encoding only once. */ 
    625  
    626     emitter->encoding = encoding; 
    627 } 
    628  
    629 /* 
    630  * Set the canonical output style. 
    631  */ 
    632  
    633 YAML_DECLARE(void) 
    634 yaml_emitter_set_canonical(yaml_emitter_t *emitter, int is_canonical) 
    635 { 
    636     assert(emitter);    /* Non-NULL emitter object expected. */ 
    637  
    638     emitter->is_canonical = (is_canonical != 0); 
    639 } 
    640  
    641 /* 
    642  * Set the indentation increment. 
    643  */ 
    644  
    645 YAML_DECLARE(void) 
    646 yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) 
    647 { 
    648     assert(emitter);    /* Non-NULL emitter object expected. */ 
    649  
    650     emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; 
    651 } 
    652  
    653 /* 
    654  * Set the preferred line width. 
    655  */ 
    656  
    657 YAML_DECLARE(void) 
    658 yaml_emitter_set_width(yaml_emitter_t *emitter, int width) 
    659 { 
    660     assert(emitter);    /* Non-NULL emitter object expected. */ 
    661  
    662     emitter->best_width = (width >= 0) ? width : -1; 
    663 } 
    664  
    665 /* 
    666  * Set if unescaped non-ASCII characters are allowed. 
    667  */ 
    668  
    669 YAML_DECLARE(void) 
    670 yaml_emitter_set_unicode(yaml_emitter_t *emitter, int is_unicode) 
    671 { 
    672     assert(emitter);    /* Non-NULL emitter object expected. */ 
    673  
    674     emitter->is_unicode = (is_unicode != 0); 
    675 } 
    676  
    677 /* 
    678  * Set the preferred line break character. 
    679  */ 
    680  
    681 YAML_DECLARE(void) 
    682 yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) 
    683 { 
    684     assert(emitter);    /* Non-NULL emitter object expected. */ 
    685  
    686     emitter->line_break = line_break; 
    687 } 
     289/***************************************************************************** 
     290 * Token API 
     291 *****************************************************************************/ 
    688292 
    689293/* 
     
    713317    assert(token);  /* Non-NULL token object expected. */ 
    714318 
    715     yaml_token_destroy(token); 
     319    yaml_token_clear(token); 
    716320    yaml_free(token); 
    717321} 
     
    726330    assert(token);  /* Non-NULL token object is expected. */ 
    727331    assert(model);  /* Non-NULL model token object is expected. */ 
     332    assert(!token->type);   /* The token must be empty. */ 
    728333 
    729334    memset(token, 0, sizeof(yaml_token_t)); 
    730335 
    731336    token->type = model->type; 
     337    token->start_mark = model->start_mark; 
     338    token->end_mark = model->end_mark; 
    732339 
    733340    switch (token->type) 
     
    790397 
    791398error: 
    792     yaml_token_destroy(token); 
     399    yaml_token_clear(token); 
    793400 
    794401    return 0; 
     
    796403 
    797404/* 
    798  * Destroy a token object. 
    799  */ 
    800  
    801 YAML_DECLARE(void) 
    802 yaml_token_destroy(yaml_token_t *token) 
     405 * Clear a token object. 
     406 */ 
     407 
     408YAML_DECLARE(void) 
     409yaml_token_clear(yaml_token_t *token) 
    803410{ 
    804411    assert(token);  /* Non-NULL token object expected. */ 
     
    835442} 
    836443 
    837 /* 
    838  * Check if a string is a valid UTF-8 sequence. 
    839  * 
    840  * Check 'reader.c' for more details on UTF-8 encoding. 
    841  */ 
    842  
    843 static int 
    844 yaml_valid_utf8(const yaml_char_t *buffer, size_t length) 
    845 { 
    846     size_t pointer = 0; 
    847  
    848     while (pointer < length) { 
    849         unsigned char octet; 
    850         unsigned int width; 
    851         unsigned int value; 
    852         size_t k; 
    853  
    854         octet = buffer[pointer]; 
    855         width = (octet & 0x80) == 0x00 ? 1 : 
    856                 (octet & 0xE0) == 0xC0 ? 2 : 
    857                 (octet & 0xF0) == 0xE0 ? 3 : 
    858                 (octet & 0xF8) == 0xF0 ? 4 : 0; 
    859         value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
    860                 (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
    861                 (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
    862                 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
    863         if (!width) return 0; 
    864         if (pointer+width > length) return 0; 
    865         for (k = 1; k < width; k ++) { 
    866             octet = buffer[pointer+k]; 
    867             if ((octet & 0xC0) != 0x80) return 0; 
    868             value = (value << 6) + (octet & 0x3F); 
    869         } 
    870         if (!((width == 1) || 
    871             (width == 2 && value >= 0x80) || 
    872             (width == 3 && value >= 0x800) || 
    873             (width == 4 && value >= 0x10000))) return 0; 
    874  
    875         pointer += width; 
    876     } 
    877  
    878     return 1; 
    879 } 
     444/***************************************************************************** 
     445 * Event API 
     446 *****************************************************************************/ 
    880447 
    881448/* 
     
    905472    assert(event);  /* Non-NULL event object expected. */ 
    906473 
    907     yaml_event_destroy(event); 
     474    yaml_event_clear(event); 
    908475    yaml_free(event); 
    909476} 
     
    922489    assert(event);  /* Non-NULL event object is expected. */ 
    923490    assert(model);  /* Non-NULL model event object is expected. */ 
     491    assert(!event->type);   /* The event must be empty. */ 
    924492 
    925493    memset(event, 0, sizeof(yaml_event_t)); 
    926494 
    927495    event->type = model->type; 
     496    event->start_mark = model->start_mark; 
     497    event->end_mark = model->end_mark; 
    928498 
    929499    switch (event->type) 
     
    989559                    model->data.scalar.length+1); 
    990560            event->data.scalar.length = model->data.scalar.length; 
    991             event->data.scalar.is_plain_implicit = 
    992                 model->data.scalar.is_plain_implicit; 
    993             event->data.scalar.is_quoted_implicit = 
    994                 model->data.scalar.is_quoted_implicit; 
     561            event->data.scalar.is_plain_nonspecific = 
     562                model->data.scalar.is_plain_nonspecific; 
     563            event->data.scalar.is_quoted_nonspecific = 
     564                model->data.scalar.is_quoted_nonspecific; 
    995565            event->data.scalar.style = model->data.scalar.style; 
    996566            break; 
     
    1005575                        yaml_strdup(model->data.sequence_start.tag))) 
    1006576                goto error; 
    1007             event->data.sequence_start.is_implicit = 
    1008                 model->data.sequence_start.is_implicit; 
     577            event->data.sequence_start.is_nonspecific = 
     578                model->data.sequence_start.is_nonspecific; 
    1009579            event->data.sequence_start.style = 
    1010580                model->data.sequence_start.style; 
     
    1020590                        yaml_strdup(model->data.mapping_start.tag))) 
    1021591                goto error; 
    1022             event->data.mapping_start.is_implicit = 
    1023                 model->data.mapping_start.is_implicit; 
     592            event->data.mapping_start.is_nonspecific = 
     593                model->data.mapping_start.is_nonspecific; 
    1024594            event->data.mapping_start.style = 
    1025595                model->data.mapping_start.style; 
     
    1033603 
    1034604error: 
    1035     yaml_event_destroy(event); 
     605    yaml_event_clear(event); 
    1036606 
    1037607    return 0; 
     
    1039609 
    1040610/* 
    1041  * Create STREAM-START. 
    1042  */ 
    1043  
    1044 YAML_DECLARE(int) 
    1045 yaml_event_create_stream_start(yaml_event_t *event, 
    1046         yaml_encoding_t encoding) 
    1047 { 
    1048     yaml_mark_t mark = { 0, 0, 0 }; 
    1049  
    1050     assert(event);  /* Non-NULL event object is expected. */ 
    1051  
    1052     STREAM_START_EVENT_INIT(*event, encoding, mark, mark); 
    1053  
    1054     return 1; 
    1055 } 
    1056  
    1057 /* 
    1058  * Create STREAM-END. 
    1059  */ 
    1060  
    1061 YAML_DECLARE(int) 
    1062 yaml_event_create_stream_end(yaml_event_t *event) 
    1063 { 
    1064     yaml_mark_t mark = { 0, 0, 0 }; 
    1065  
    1066     assert(event);  /* Non-NULL event object is expected. */ 
    1067  
    1068     STREAM_END_EVENT_INIT(*event, mark, mark); 
    1069  
    1070     return 1; 
    1071 } 
    1072  
    1073 /* 
    1074  * Create DOCUMENT-START. 
    1075  */ 
    1076  
    1077 YAML_DECLARE(int) 
    1078 yaml_event_create_document_start(yaml_event_t *event, 
    1079         const yaml_version_directive_t *version_directive, 
    1080         const yaml_tag_directive_t *tag_directives, 
    1081         int is_implicit) 
    1082 { 
    1083     struct { 
    1084         yaml_error_t error; 
    1085     } self; 
    1086     yaml_mark_t mark = { 0, 0, 0 }; 
    1087     yaml_version_directive_t *version_directive_copy = NULL; 
    1088     struct { 
    1089         yaml_tag_directive_t *list; 
    1090         size_t length; 
    1091         size_t capacity; 
    1092     } tag_directives_copy = { NULL, 0, 0 }; 
    1093  
    1094     assert(event);          /* Non-NULL event object is expected. */ 
    1095  
    1096     if (version_directive) { 
    1097         version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
    1098         if (!version_directive_copy) goto error; 
    1099         *version_directive_copy = *version_directive; 
    1100     } 
    1101  
    1102     if (tag_directives && (tag_directives->handle || tag_directives->prefix)) { 
    1103         if (!STACK_INIT(&self, tag_directives_copy, INITIAL_STACK_CAPACITY)) 
    1104             goto error; 
    1105         while (tag_directives->handle || tag_directives->prefix) { 
    1106             yaml_tag_directive_t value = *tag_directives; 
    1107             assert(value.handle); 
    1108             assert(value.prefix); 
    1109             if (!yaml_valid_utf8(value.handle, strlen((char *)value.handle))) 
    1110                 goto error; 
    1111             if (!yaml_valid_utf8(value.prefix, strlen((char *)value.prefix))) 
    1112                 goto error; 
    1113             if (!PUSH(&self, tag_directives_copy, value)) 
    1114                 goto error; 
    1115             value.handle = yaml_strdup(value.handle); 
    1116             value.prefix = yaml_strdup(value.prefix); 
    1117             tag_directives_copy.list[tag_directives_copy.length-1] = value; 
    1118             if (!value.handle || !value.prefix) 
    1119                 goto error; 
    1120         } 
    1121     } 
    1122  
    1123     DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, 
    1124             tag_directives_copy.list, tag_directives_copy.length, 
    1125             tag_directives_copy.capacity, is_implicit, mark, mark); 
    1126  
    1127     return 1; 
    1128  
    1129 error: 
    1130     yaml_free(version_directive_copy); 
    1131     while (!STACK_EMPTY(&self, tag_directives_copy)) { 
    1132         yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
    1133         yaml_free(value.handle); 
    1134         yaml_free(value.prefix); 
    1135     } 
    1136     STACK_DEL(&self, tag_directives_copy); 
    1137  
    1138     return 0; 
    1139 } 
    1140  
    1141 /* 
    1142  * Create DOCUMENT-END. 
    1143  */ 
    1144  
    1145 YAML_DECLARE(int) 
    1146 yaml_event_create_document_end(yaml_event_t *event, int is_implicit) 
    1147 { 
    1148     yaml_mark_t mark = { 0, 0, 0 }; 
    1149  
    1150     assert(event);      /* Non-NULL emitter object is expected. */ 
    1151  
    1152     DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark); 
    1153  
    1154     return 1; 
    1155 } 
    1156  
    1157 /* 
    1158  * Create ALIAS. 
    1159  */ 
    1160  
    1161 YAML_DECLARE(int) 
    1162 yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor) 
    1163 { 
    1164     yaml_mark_t mark = { 0, 0, 0 }; 
    1165     yaml_char_t *anchor_copy = NULL; 
    1166  
    1167     assert(event);      /* Non-NULL event object is expected. */ 
    1168     assert(anchor);     /* Non-NULL anchor is expected. */ 
    1169  
    1170     if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) return 0; 
    1171  
    1172     anchor_copy = yaml_strdup(anchor); 
    1173     if (!anchor_copy) 
    1174         return 0; 
    1175  
    1176     ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); 
    1177  
    1178     return 1; 
    1179 } 
    1180  
    1181 /* 
    1182  * Create SCALAR. 
    1183  */ 
    1184  
    1185 YAML_DECLARE(int) 
    1186 yaml_event_create_scalar(yaml_event_t *event, 
    1187         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1188         const yaml_char_t *value, size_t length, 
    1189         int is_plain_implicit, int is_quoted_implicit, 
    1190         yaml_scalar_style_t style) 
    1191 { 
    1192     yaml_mark_t mark = { 0, 0, 0 }; 
    1193     yaml_char_t *anchor_copy = NULL; 
    1194     yaml_char_t *tag_copy = NULL; 
    1195     yaml_char_t *value_copy = NULL; 
    1196  
    1197     assert(event);      /* Non-NULL event object is expected. */ 
    1198     assert(value);      /* Non-NULL anchor is expected. */ 
    1199  
    1200     if (anchor) { 
    1201         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1202             goto error; 
    1203         anchor_copy = yaml_strdup(anchor); 
    1204         if (!anchor_copy) 
    1205             goto error; 
    1206     } 
    1207  
    1208     if (tag) { 
    1209         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1210             goto error; 
    1211         tag_copy = yaml_strdup(tag); 
    1212         if (!tag_copy) 
    1213             goto error; 
    1214     } 
    1215  
    1216     if (length < 0) { 
    1217         length = strlen((char *)value); 
    1218     } 
    1219  
    1220     if (!yaml_valid_utf8(value, length)) 
    1221         goto error; 
    1222     value_copy = yaml_malloc(length+1); 
    1223     if (!value_copy) 
    1224         goto error; 
    1225     memcpy(value_copy, value, length); 
    1226     value_copy[length] = '\0'; 
    1227  
    1228     SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, 
    1229             is_plain_implicit, is_quoted_implicit, style, mark, mark); 
    1230  
    1231     return 1; 
    1232  
    1233 error: 
    1234     yaml_free(anchor_copy); 
    1235     yaml_free(tag_copy); 
    1236     yaml_free(value_copy); 
    1237  
    1238     return 0; 
    1239 } 
    1240  
    1241 /* 
    1242  * Create SEQUENCE-START. 
    1243  */ 
    1244  
    1245 YAML_DECLARE(int) 
    1246 yaml_event_create_sequence_start(yaml_event_t *event, 
    1247         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1248         int is_implicit, yaml_sequence_style_t style) 
    1249 { 
    1250     yaml_mark_t mark = { 0, 0, 0 }; 
    1251     yaml_char_t *anchor_copy = NULL; 
    1252     yaml_char_t *tag_copy = NULL; 
    1253  
    1254     assert(event);      /* Non-NULL event object is expected. */ 
    1255  
    1256     if (anchor) { 
    1257         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1258             goto error; 
    1259         anchor_copy = yaml_strdup(anchor); 
    1260         if (!anchor_copy) 
    1261             goto error; 
    1262     } 
    1263  
    1264     if (tag) { 
    1265         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1266             goto error; 
    1267         tag_copy = yaml_strdup(tag); 
    1268         if (!tag_copy) 
    1269             goto error; 
    1270     } 
    1271  
    1272     SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
    1273             is_implicit, style, mark, mark); 
    1274  
    1275     return 1; 
    1276  
    1277 error: 
    1278     yaml_free(anchor_copy); 
    1279     yaml_free(tag_copy); 
    1280  
    1281     return 0; 
    1282 } 
    1283  
    1284 /* 
    1285  * Create SEQUENCE-END. 
    1286  */ 
    1287  
    1288 YAML_DECLARE(int) 
    1289 yaml_event_create_sequence_end(yaml_event_t *event) 
    1290 { 
    1291     yaml_mark_t mark = { 0, 0, 0 }; 
    1292  
    1293     assert(event);      /* Non-NULL event object is expected. */ 
    1294  
    1295     SEQUENCE_END_EVENT_INIT(*event, mark, mark); 
    1296  
    1297     return 1; 
    1298 } 
    1299  
    1300 /* 
    1301  * Create MAPPING-START. 
    1302  */ 
    1303  
    1304 YAML_DECLARE(int) 
    1305 yaml_event_create_mapping_start(yaml_event_t *event, 
    1306         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1307         int is_implicit, yaml_mapping_style_t style) 
    1308 { 
    1309     yaml_mark_t mark = { 0, 0, 0 }; 
    1310     yaml_char_t *anchor_copy = NULL; 
    1311     yaml_char_t *tag_copy = NULL; 
    1312  
    1313     assert(event);      /* Non-NULL event object is expected. */ 
    1314  
    1315     if (anchor) { 
    1316         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1317             goto error; 
    1318         anchor_copy = yaml_strdup(anchor); 
    1319         if (!anchor_copy) 
    1320             goto error; 
    1321     } 
    1322  
    1323     if (tag) { 
    1324         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1325             goto error; 
    1326         tag_copy = yaml_strdup(tag); 
    1327         if (!tag_copy) 
    1328             goto error; 
    1329     } 
    1330  
    1331     MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
    1332             is_implicit, style, mark, mark); 
    1333  
    1334     return 1; 
    1335  
    1336 error: 
    1337     yaml_free(anchor_copy); 
    1338     yaml_free(tag_copy); 
    1339  
    1340     return 0; 
    1341 } 
    1342  
    1343 /* 
    1344  * Create MAPPING-END. 
    1345  */ 
    1346  
    1347 YAML_DECLARE(int) 
    1348 yaml_event_create_mapping_end(yaml_event_t *event) 
    1349 { 
    1350     yaml_mark_t mark = { 0, 0, 0 }; 
    1351  
    1352     assert(event);      /* Non-NULL event object is expected. */ 
    1353  
    1354     MAPPING_END_EVENT_INIT(*event, mark, mark); 
    1355  
    1356     return 1; 
    1357 } 
    1358  
    1359 /* 
    1360  * Destroy an event object. 
    1361  */ 
    1362  
    1363 YAML_DECLARE(void) 
    1364 yaml_event_destroy(yaml_event_t *event) 
     611 * Clear an event object. 
     612 */ 
     613 
     614YAML_DECLARE(void) 
     615yaml_event_clear(yaml_event_t *event) 
    1365616{ 
    1366617    struct { 
     
    1410661} 
    1411662 
    1412 #if 0 
    1413  
    1414 /* 
    1415  * Create a document object. 
    1416  */ 
    1417  
    1418 YAML_DECLARE(int) 
    1419 yaml_document_initialize(yaml_document_t *document, 
    1420         yaml_version_directive_t *version_directive, 
    1421         yaml_tag_directive_t *tag_directives_start, 
    1422         yaml_tag_directive_t *tag_directives_end, 
    1423         int start_implicit, int end_implicit) 
     663/* 
     664 * Create STREAM-START. 
     665 */ 
     666 
     667YAML_DECLARE(int) 
     668yaml_event_create_stream_start(yaml_event_t *event, 
     669        yaml_encoding_t encoding) 
     670{ 
     671    yaml_mark_t mark = { 0, 0, 0 }; 
     672 
     673    assert(event);  /* Non-NULL event object is expected. */ 
     674    assert(!event->type);   /* The event must be empty. */ 
     675 
     676    STREAM_START_EVENT_INIT(*event, encoding, mark, mark); 
     677 
     678    return 1; 
     679} 
     680 
     681/* 
     682 * Create STREAM-END. 
     683 */ 
     684 
     685YAML_DECLARE(int) 
     686yaml_event_create_stream_end(yaml_event_t *event) 
     687{ 
     688    yaml_mark_t mark = { 0, 0, 0 }; 
     689 
     690    assert(event);  /* Non-NULL event object is expected. */ 
     691    assert(!event->type);   /* The event must be empty. */ 
     692 
     693    STREAM_END_EVENT_INIT(*event, mark, mark); 
     694 
     695    return 1; 
     696} 
     697 
     698/* 
     699 * Create DOCUMENT-START. 
     700 */ 
     701 
     702YAML_DECLARE(int) 
     703yaml_event_create_document_start(yaml_event_t *event, 
     704        const yaml_version_directive_t *version_directive, 
     705        const yaml_tag_directive_t *tag_directives_list, 
     706        size_t tag_directives_length, int is_implicit) 
    1424707{ 
    1425708    struct { 
    1426         yaml_error_type_t error; 
    1427     } context; 
    1428     struct { 
    1429         yaml_node_t *start; 
    1430         yaml_node_t *end; 
    1431         yaml_node_t *top; 
    1432     } nodes = { NULL, NULL, NULL }; 
     709        yaml_error_t error; 
     710    } self; 
     711    yaml_mark_t mark = { 0, 0, 0 }; 
    1433712    yaml_version_directive_t *version_directive_copy = NULL; 
    1434713    struct { 
    1435         yaml_tag_directive_t *start; 
    1436         yaml_tag_directive_t *end; 
    1437         yaml_tag_directive_t *top; 
    1438     } tag_directives_copy = { NULL, NULL, NULL }; 
    1439     yaml_tag_directive_t value = { NULL, NULL }; 
    1440     yaml_mark_t mark = { 0, 0, 0 }; 
    1441  
    1442     assert(document);       /* Non-NULL document object is expected. */ 
    1443     assert((tag_directives_start && tag_directives_end) || 
    1444             (tag_directives_start == tag_directives_end)); 
    1445                             /* Valid tag directives are expected. */ 
    1446  
    1447     if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error; 
     714        yaml_tag_directive_t *list; 
     715        size_t length; 
     716        size_t capacity; 
     717    } tag_directives_copy = { NULL, 0, 0 }; 
     718    int idx; 
     719 
     720    assert(event);          /* Non-NULL event object is expected. */ 
     721    assert(!event->type);   /* The event must be empty. */ 
    1448722 
    1449723    if (version_directive) { 
    1450724        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
    1451725        if (!version_directive_copy) goto error; 
    1452         version_directive_copy->major = version_directive->major; 
    1453         version_directive_copy->minor = version_directive->minor; 
    1454     } 
    1455  
    1456     if (tag_directives_start != tag_directives_end) { 
    1457         yaml_tag_directive_t *tag_directive; 
    1458         if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) 
     726        *version_directive_copy = *version_directive; 
     727    } 
     728 
     729    if (tag_directives_list && tag_directives_length) { 
     730        if (!STACK_INIT(&self, tag_directives_copy, tag_directives_length)) 
    1459731            goto error; 
    1460         for (tag_directive = tag_directives_start; 
    1461                 tag_directive != tag_directives_end; tag_directive ++) { 
    1462             assert(tag_directive->handle); 
    1463             assert(tag_directive->prefix); 
    1464             if (!yaml_valid_utf8(tag_directive->handle, 
    1465                         strlen((char *)tag_directive->handle))) 
     732        for (idx = 0; idx < tag_directives_length; idx++) { 
     733            yaml_tag_directive_t value = tag_directives_list[idx]; 
     734            assert(value.handle); 
     735            assert(value.prefix); 
     736            value.handle = yaml_strdup(value.handle); 
     737            value.prefix = yaml_strdup(value.prefix); 
     738            PUSH(&self, tag_directives_copy, value); 
     739            if (!value.handle || !value.prefix) 
    1466740                goto error; 
    1467             if (!yaml_valid_utf8(tag_directive->prefix, 
    1468                         strlen((char *)tag_directive->prefix))) 
    1469                 goto error; 
    1470             value.handle = yaml_strdup(tag_directive->handle); 
    1471             value.prefix = yaml_strdup(tag_directive->prefix); 
    1472             if (!value.handle || !value.prefix) goto error; 
    1473             if (!PUSH(&context, tag_directives_copy, value)) 
    1474                 goto error; 
    1475             value.handle = NULL; 
    1476             value.prefix = NULL; 
    1477741        } 
    1478742    } 
    1479743 
    1480     DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, 
    1481             tag_directives_copy.start, tag_directives_copy.top, 
    1482             start_implicit, end_implicit, mark, mark); 
     744    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, 
     745            tag_directives_copy.list, tag_directives_copy.length, 
     746            tag_directives_copy.capacity, is_implicit, mark, mark); 
    1483747 
    1484748    return 1; 
    1485749 
    1486750error: 
    1487     STACK_DEL(&context, nodes); 
    1488751    yaml_free(version_directive_copy); 
    1489     while (!STACK_EMPTY(&context, tag_directives_copy)) { 
    1490         yaml_tag_directive_t value = POP(&context, tag_directives_copy); 
     752    while (!STACK_EMPTY(&self, tag_directives_copy)) { 
     753        yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
    1491754        yaml_free(value.handle); 
    1492755        yaml_free(value.prefix); 
    1493756    } 
    1494     STACK_DEL(&context, tag_directives_copy); 
    1495     yaml_free(value.handle); 
    1496     yaml_free(value.prefix); 
     757    STACK_DEL(&self, tag_directives_copy); 
    1497758 
    1498759    return 0; 
     
    1500761 
    1501762/* 
    1502  * Destroy a document object. 
     763 * Create DOCUMENT-END. 
     764 */ 
     765 
     766YAML_DECLARE(int) 
     767yaml_event_create_document_end(yaml_event_t *event, int is_implicit) 
     768{ 
     769    yaml_mark_t mark = { 0, 0, 0 }; 
     770 
     771    assert(event);      /* Non-NULL emitter object is expected. */ 
     772    assert(!event->type);   /* The event must be empty. */ 
     773 
     774    DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark); 
     775 
     776    return 1; 
     777} 
     778 
     779/* 
     780 * Create ALIAS. 
     781 */ 
     782 
     783YAML_DECLARE(int) 
     784yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor) 
     785{ 
     786    yaml_mark_t mark = { 0, 0, 0 }; 
     787    yaml_char_t *anchor_copy = NULL; 
     788 
     789    assert(event);      /* Non-NULL event object is expected. */ 
     790    assert(!event->type);   /* The event must be empty. */ 
     791    assert(anchor);     /* Non-NULL anchor is expected. */ 
     792 
     793    anchor_copy = yaml_strdup(anchor); 
     794    if (!anchor_copy) 
     795        return 0; 
     796 
     797    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); 
     798 
     799    return 1; 
     800} 
     801 
     802/* 
     803 * Create SCALAR. 
     804 */ 
     805 
     806YAML_DECLARE(int) 
     807yaml_event_create_scalar(yaml_event_t *event, 
     808        const yaml_char_t *anchor, const yaml_char_t *tag, 
     809        const yaml_char_t *value, int length, 
     810        int is_plain_nonspecific, int is_quoted_nonspecific, 
     811        yaml_scalar_style_t style) 
     812{ 
     813    yaml_mark_t mark = { 0, 0, 0 }; 
     814    yaml_char_t *anchor_copy = NULL; 
     815    yaml_char_t *tag_copy = NULL; 
     816    yaml_char_t *value_copy = NULL; 
     817 
     818    assert(event);      /* Non-NULL event object is expected. */ 
     819    assert(!event->type);   /* The event must be empty. */ 
     820    assert(value);      /* Non-NULL anchor is expected. */ 
     821 
     822    if (anchor) { 
     823        anchor_copy = yaml_strdup(anchor); 
     824        if (!anchor_copy) 
     825            goto error; 
     826    } 
     827 
     828    if (tag) { 
     829        tag_copy = yaml_strdup(tag); 
     830        if (!tag_copy) 
     831            goto error; 
     832    } 
     833 
     834    if (length < 0) { 
     835        length = strlen((char *)value); 
     836    } 
     837 
     838    value_copy = yaml_malloc(length+1); 
     839    if (!value_copy) 
     840        goto error; 
     841    memcpy(value_copy, value, length); 
     842    value_copy[length] = '\0'; 
     843 
     844    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, 
     845            is_plain_nonspecific, is_quoted_nonspecific, style, mark, mark); 
     846 
     847    return 1; 
     848 
     849error: 
     850    yaml_free(anchor_copy); 
     851    yaml_free(tag_copy); 
     852    yaml_free(value_copy); 
     853 
     854    return 0; 
     855} 
     856 
     857/* 
     858 * Create SEQUENCE-START. 
     859 */ 
     860 
     861YAML_DECLARE(int) 
     862yaml_event_create_sequence_start(yaml_event_t *event, 
     863        const yaml_char_t *anchor, const yaml_char_t *tag, 
     864        int is_nonspecific, yaml_sequence_style_t style) 
     865{ 
     866    yaml_mark_t mark = { 0, 0, 0 }; 
     867    yaml_char_t *anchor_copy = NULL; 
     868    yaml_char_t *tag_copy = NULL; 
     869 
     870    assert(event);      /* Non-NULL event object is expected. */ 
     871    assert(!event->type);   /* The event must be empty. */ 
     872 
     873    if (anchor) { 
     874        anchor_copy = yaml_strdup(anchor); 
     875        if (!anchor_copy) 
     876            goto error; 
     877    } 
     878 
     879    if (tag) { 
     880        tag_copy = yaml_strdup(tag); 
     881        if (!tag_copy) 
     882            goto error; 
     883    } 
     884 
     885    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     886            is_nonspecific, style, mark, mark); 
     887 
     888    return 1; 
     889 
     890error: 
     891    yaml_free(anchor_copy); 
     892    yaml_free(tag_copy); 
     893 
     894    return 0; 
     895} 
     896 
     897/* 
     898 * Create SEQUENCE-END. 
     899 */ 
     900 
     901YAML_DECLARE(int) 
     902yaml_event_create_sequence_end(yaml_event_t *event) 
     903{ 
     904    yaml_mark_t mark = { 0, 0, 0 }; 
     905 
     906    assert(event);      /* Non-NULL event object is expected. */ 
     907    assert(!event->type);   /* The event must be empty. */ 
     908 
     909    SEQUENCE_END_EVENT_INIT(*event, mark, mark); 
     910 
     911    return 1; 
     912} 
     913 
     914/* 
     915 * Create MAPPING-START. 
     916 */ 
     917 
     918YAML_DECLARE(int) 
     919yaml_event_create_mapping_start(yaml_event_t *event, 
     920        const yaml_char_t *anchor, const yaml_char_t *tag, 
     921        int is_nonspecific, yaml_mapping_style_t style) 
     922{ 
     923    yaml_mark_t mark = { 0, 0, 0 }; 
     924    yaml_char_t *anchor_copy = NULL; 
     925    yaml_char_t *tag_copy = NULL; 
     926 
     927    assert(event);      /* Non-NULL event object is expected. */ 
     928    assert(!event->type);   /* The event must be empty. */ 
     929 
     930    if (anchor) { 
     931        anchor_copy = yaml_strdup(anchor); 
     932        if (!anchor_copy) 
     933            goto error; 
     934    } 
     935 
     936    if (tag) { 
     937        tag_copy = yaml_strdup(tag); 
     938        if (!tag_copy) 
     939            goto error; 
     940    } 
     941 
     942    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     943            is_nonspecific, style, mark, mark); 
     944 
     945    return 1; 
     946 
     947error: 
     948    yaml_free(anchor_copy); 
     949    yaml_free(tag_copy); 
     950 
     951    return 0; 
     952} 
     953 
     954/* 
     955 * Create MAPPING-END. 
     956 */ 
     957 
     958YAML_DECLARE(int) 
     959yaml_event_create_mapping_end(yaml_event_t *event) 
     960{ 
     961    yaml_mark_t mark = { 0, 0, 0 }; 
     962 
     963    assert(event);      /* Non-NULL event object is expected. */ 
     964    assert(!event->type);   /* The event must be empty. */ 
     965 
     966    MAPPING_END_EVENT_INIT(*event, mark, mark); 
     967 
     968    return 1; 
     969} 
     970 
     971/***************************************************************************** 
     972 * Document API 
     973 *****************************************************************************/ 
     974 
     975/* 
     976 * Allocate a document object. 
     977 */ 
     978 
     979YAML_DECLARE(yaml_document_t *) 
     980yaml_document_new(void) 
     981{ 
     982    yaml_document_t *document = yaml_malloc(sizeof(yaml_document_t)); 
     983 
     984    if (!document) 
     985        return NULL; 
     986 
     987    memset(document, 0, sizeof(yaml_document_t)); 
     988 
     989    return document; 
     990} 
     991 
     992/* 
     993 * Deallocate a document object. 
    1503994 */ 
    1504995 
    1505996YAML_DECLARE(void) 
    1506997yaml_document_delete(yaml_document_t *document) 
     998{ 
     999    assert(document);   /* Non-NULL document object is expected. */ 
     1000 
     1001    yaml_document_clear(document); 
     1002    yaml_free(document); 
     1003} 
     1004 
     1005/* 
     1006 * Duplicate a document object. 
     1007 */ 
     1008 
     1009YAML_DECLARE(int) 
     1010yaml_document_duplicate(yaml_document_t *document, yaml_document_t *model) 
     1011{ 
     1012    struct { 
     1013        yaml_error_t error; 
     1014    } self; 
     1015    yaml_char_t *anchor = NULL; 
     1016    yaml_char_t *tag = NULL; 
     1017    yaml_char_t *value = NULL; 
     1018    yaml_node_item_t *item_list = NULL; 
     1019    yaml_node_pair_t *pair_list = NULL; 
     1020    int idx; 
     1021 
     1022    assert(document);   /* Non-NULL document object is expected. */ 
     1023    assert(!document->type);    /* The document must be empty. */ 
     1024    assert(model);      /* Non-NULL model object is expected. */ 
     1025 
     1026    if (model->type != YAML_DOCUMENT) 
     1027        return 1; 
     1028 
     1029    if (!yaml_document_create(document, model->version_directive, 
     1030                model->tag_directives.list, model->tag_directives.length, 
     1031                model->is_start_implicit, model->is_end_implicit)) 
     1032        return 0; 
     1033 
     1034    document->start_mark = model->start_mark; 
     1035    document->end_mark = model->end_mark; 
     1036 
     1037    for (idx = 0; idx < model->nodes.length; idx++) 
     1038    { 
     1039        yaml_node_t *node = STACK_ITER(&self, model->nodes, idx); 
     1040        yaml_node_t copy; 
     1041        if (node->anchor) { 
     1042            anchor = yaml_strdup(node->anchor); 
     1043            if (!anchor) goto error; 
     1044        } 
     1045        tag = yaml_strdup(node->tag); 
     1046        if (!tag) goto error; 
     1047        switch (node->type) 
     1048        { 
     1049            case YAML_SCALAR_NODE: 
     1050                value = yaml_malloc(node->data.scalar.length+1); 
     1051                if (!value) 
     1052                    goto error; 
     1053                memcpy(value, node->data.scalar.value, 
     1054                        node->data.scalar.length); 
     1055                value[node->data.scalar.length] = '\0'; 
     1056                SCALAR_NODE_INIT(copy, anchor, tag, value, 
     1057                        node->data.scalar.length, node->data.scalar.style, 
     1058                        node->start_mark, node->end_mark); 
     1059                break; 
     1060 
     1061            case YAML_SEQUENCE_NODE: 
     1062                item_list = yaml_malloc(node->data.sequence.items.capacity 
     1063                        * sizeof(yaml_node_item_t)); 
     1064                if (!item_list) goto error; 
     1065                memcpy(item_list, node->data.sequence.items.list, 
     1066                        node->data.sequence.items.capacity 
     1067                        * sizeof(yaml_node_item_t)); 
     1068                SEQUENCE_NODE_INIT(copy, anchor, tag, item_list, 
     1069                        node->data.sequence.items.length, 
     1070                        node->data.sequence.items.capacity, 
     1071                        node->data.sequence.style, 
     1072                        node->start_mark, node->end_mark); 
     1073                break; 
     1074 
     1075            case YAML_MAPPING_NODE: 
     1076                pair_list = yaml_malloc(node->data.mapping.pairs.capacity 
     1077                        * sizeof(yaml_node_pair_t)); 
     1078                if (!pair_list) goto error; 
     1079                memcpy(pair_list, node->data.mapping.pairs.list, 
     1080                        node->data.mapping.pairs.capacity 
     1081                        * sizeof(yaml_node_pair_t)); 
     1082                MAPPING_NODE_INIT(copy, anchor, tag, pair_list, 
     1083                        node->data.mapping.pairs.length, 
     1084                        node->data.mapping.pairs.capacity, 
     1085                        node->data.mapping.style, 
     1086                        node->start_mark, node->end_mark); 
     1087                break; 
     1088 
     1089            default: 
     1090                assert(0);  /* Should never happen. */ 
     1091        } 
     1092 
     1093        if (!PUSH(&self, document->nodes, copy)) 
     1094            goto error; 
     1095 
     1096        anchor = NULL; 
     1097        tag = NULL; 
     1098        value = NULL; 
     1099        item_list = NULL; 
     1100        pair_list = NULL; 
     1101    } 
     1102 
     1103error: 
     1104    yaml_free(anchor); 
     1105    yaml_free(tag); 
     1106    yaml_free(value); 
     1107    yaml_free(item_list); 
     1108    yaml_free(pair_list); 
     1109 
     1110    yaml_document_clear(document); 
     1111 
     1112    return 0; 
     1113} 
     1114 
     1115/* 
     1116 * Clear a document object. 
     1117 */ 
     1118 
     1119YAML_DECLARE(void) 
     1120yaml_document_clear(yaml_document_t *document) 
    15071121{ 
    15081122    struct { 
    15091123        yaml_error_type_t error; 
    1510     } context; 
     1124    } self; 
    15111125    yaml_tag_directive_t *tag_directive; 
    15121126 
    1513     context.error = YAML_NO_ERROR;  /* Eliminate a compliler warning. */ 
     1127    self.error = YAML_NO_ERROR;  /* Eliminate a compliler warning. */ 
    15141128 
    15151129    assert(document);   /* Non-NULL document object is expected. */ 
     1130 
     1131    if (!document->type) 
     1132        return; 
    15161133 
    15171134    while (!STACK_EMPTY(&context, document->nodes)) { 
     
    15321149        } 
    15331150    } 
    1534     STACK_DEL(&context, document->nodes); 
     1151    STACK_DEL(&self, document->nodes); 
    15351152 
    15361153    yaml_free(document->version_directive); 
    1537     for (tag_directive = document->tag_directives.start; 
    1538             tag_directive != document->tag_directives.end; 
    1539             tag_directive++) { 
    1540         yaml_free(tag_directive->handle); 
    1541         yaml_free(tag_directive->prefix); 
    1542     } 
    1543     yaml_free(document->tag_directives.start); 
     1154    while (!STACK_EMPTY(&self, document->tag_directives)) { 
     1155        yaml_tag_directive_t tag_directive = POP(&self, document->tag_directives); 
     1156        yaml_free(tag_directive.handle); 
     1157        yaml_free(tag_directive.prefix); 
     1158    } 
     1159    STACK_DEL(&self, document->tag_directives); 
    15441160 
    15451161    memset(document, 0, sizeof(yaml_document_t)); 
    15461162} 
    15471163 
    1548 /** 
     1164/* 
     1165 * Create a document. 
     1166 */ 
     1167 
     1168YAML_DECLARE(int) 
     1169yaml_document_create(yaml_document_t *document, 
     1170        const yaml_version_directive_t *version_directive, 
     1171        const yaml_tag_directive_t *tag_directives_list, 
     1172        size_t tag_directives_length, 
     1173        int is_start_implicit, int is_end_implicit) 
     1174{ 
     1175    struct { 
     1176        yaml_error_t error; 
     1177    } self; 
     1178    yaml_mark_t mark = { 0, 0, 0 }; 
     1179    struct { 
     1180        yaml_node_t *list; 
     1181        size_t length; 
     1182        size_t capacity; 
     1183    } nodes; 
     1184    yaml_version_directive_t *version_directive_copy = NULL; 
     1185    struct { 
     1186        yaml_tag_directive_t *list; 
     1187        size_t length; 
     1188        size_t capacity; 
     1189    } tag_directives_copy = { NULL, 0, 0 }; 
     1190    int idx; 
     1191 
     1192    assert(document);           /* Non-NULL event object is expected. */ 
     1193    assert(!document->type);    /* The document must be empty. */ 
     1194     
     1195    if (!STACK_INIT(&self, nodes, INITIAL_STACK_CAPACITY)) 
     1196        goto error; 
     1197 
     1198    if (version_directive) { 
     1199        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
     1200        if (!version_directive_copy) goto error; 
     1201        *version_directive_copy = *version_directive; 
     1202    } 
     1203 
     1204    if (tag_directives_list && tag_directives_length) { 
     1205        if (!STACK_INIT(&self, tag_directives_copy, tag_directives_length)) 
     1206            goto error; 
     1207        for (idx = 0; idx < tag_directives_length; idx++) { 
     1208            yaml_tag_directive_t value = tag_directives_list[idx]; 
     1209            assert(value.handle); 
     1210            assert(value.prefix); 
     1211            value.handle = yaml_strdup(value.handle); 
     1212            value.prefix = yaml_strdup(value.prefix); 
     1213            PUSH(&self, tag_directives_copy, value); 
     1214            if (!value.handle || !value.prefix) 
     1215                goto error; 
     1216        } 
     1217    } 
     1218 
     1219    DOCUMENT_INIT(*document, nodes.list, nodes.length, nodes.capacity, 
     1220            version_directive_copy, tag_directives_copy.list, 
     1221            tag_directives_copy.length, tag_directives_copy.capacity, 
     1222            is_start_implicit, is_end_implicit, mark, mark); 
     1223 
     1224    return 1; 
     1225 
     1226error: 
     1227    STACK_DEL(&self, nodes); 
     1228 
     1229    yaml_free(version_directive_copy); 
     1230 
     1231    while (!STACK_EMPTY(&self, tag_directives_copy)) { 
     1232        yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
     1233        yaml_free(value.handle); 
     1234        yaml_free(value.prefix); 
     1235    } 
     1236    STACK_DEL(&self, tag_directives_copy); 
     1237 
     1238    return 0; 
     1239} 
     1240 
     1241/* 
    15491242 * Get a document node. 
    15501243 */ 
    15511244 
    15521245YAML_DECLARE(yaml_node_t *) 
    1553 yaml_document_get_node(yaml_document_t *document, int index) 
     1246yaml_document_get_node(yaml_document_t *document, int node_id) 
    15541247{ 
    15551248    assert(document);   /* Non-NULL document object is expected. */ 
    1556  
    1557     if (index > 0 && document->nodes.start + index <= document->nodes.top) { 
    1558         return document->nodes.start + index - 1; 
     1249    assert(document->type); /* Initialized document is expected. */ 
     1250 
     1251    if (node_id < 0) { 
     1252        node_id += document->nodes.length; 
     1253    } 
     1254 
     1255    if (node_id >= 0 && node_id < document->nodes.length) { 
     1256        return document->nodes.list + node_id; 
    15591257    } 
    15601258    return NULL; 
    15611259} 
    15621260 
    1563 /** 
    1564  * Get the root object. 
    1565  */ 
    1566  
    1567 YAML_DECLARE(yaml_node_t *) 
    1568 yaml_document_get_root_node(yaml_document_t *document) 
    1569 { 
    1570     assert(document);   /* Non-NULL document object is expected. */ 
    1571  
    1572     if (document->nodes.top != document->nodes.start) { 
    1573         return document->nodes.start; 
    1574     } 
    1575     return NULL; 
    1576 } 
    1577  
    15781261/* 
    15791262 * Add a scalar node to a document. 
     
    15811264 
    15821265YAML_DECLARE(int) 
    1583 yaml_document_add_scalar(yaml_document_t *document, 
    1584         yaml_char_t *tag, yaml_char_t *value, int length, 
     1266yaml_document_add_scalar(yaml_document_t *document, int *node_id, 
     1267        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1268        const yaml_char_t *value, int length, 
    15851269        yaml_scalar_style_t style) 
    15861270{ 
    15871271    struct { 
    1588         yaml_error_type_t error; 
    1589     } context; 
     1272        yaml_error_t error; 
     1273    } self; 
    15901274    yaml_mark_t mark = { 0, 0, 0 }; 
     1275    yaml_char_t *anchor_copy = NULL; 
    15911276    yaml_char_t *tag_copy = NULL; 
    15921277    yaml_char_t *value_copy = NULL; 
     
    15941279 
    15951280    assert(document);   /* Non-NULL document object is expected. */ 
     1281    assert(document->type); /* Initialized document is required. */ 
     1282    assert(tag);        /* Non-NULL tag is expected. */ 
    15961283    assert(value);      /* Non-NULL value is expected. */ 
    15971284 
    1598     if (!tag) { 
    1599         tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; 
    1600     } 
    1601  
    1602     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1285    if (anchor) { 
     1286        anchor_copy = yaml_strdup(anchor); 
     1287        if (!anchor_copy) goto error; 
     1288    } 
     1289 
    16031290    tag_copy = yaml_strdup(tag); 
    16041291    if (!tag_copy) goto error; 
     
    16081295    } 
    16091296 
    1610     if (!yaml_valid_utf8(value, length)) goto error; 
    16111297    value_copy = yaml_malloc(length+1); 
    16121298    if (!value_copy) goto error; 
     
    16141300    value_copy[length] = '\0'; 
    16151301 
    1616     SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); 
    1617     if (!PUSH(&context, document->nodes, node)) goto error; 
    1618  
    1619     return document->nodes.top - document->nodes.start; 
     1302    SCALAR_NODE_INIT(node, anchor_copy, tag_copy, value_copy, length, 
     1303            style, mark, mark); 
     1304    if (!PUSH(&self, document->nodes, node)) goto error; 
     1305 
     1306    if (node_id) { 
     1307        *node_id = document->nodes.length-1; 
     1308    } 
     1309 
     1310    return 1; 
    16201311 
    16211312error: 
     1313    yaml_free(anchor_copy); 
    16221314    yaml_free(tag_copy); 
    16231315    yaml_free(value_copy); 
     
    16311323 
    16321324YAML_DECLARE(int) 
    1633 yaml_document_add_sequence(yaml_document_t *document, 
    1634         yaml_char_t *tag, yaml_sequence_style_t style) 
     1325yaml_document_add_sequence(yaml_document_t *document, int *node_id, 
     1326        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1327        yaml_sequence_style_t style) 
    16351328{ 
    16361329    struct { 
    1637         yaml_error_type_t error; 
    1638     } context; 
     1330        yaml_error_t error; 
     1331    } self; 
    16391332    yaml_mark_t mark = { 0, 0, 0 }; 
     1333    yaml_char_t *anchor_copy = NULL; 
    16401334    yaml_char_t *tag_copy = NULL; 
    16411335    struct { 
    1642         yaml_node_item_t *start; 
    1643         yaml_node_item_t *end; 
    1644         yaml_node_item_t *top; 
    1645     } items = { NULL, NULL, NULL }; 
     1336        yaml_node_item_t *list; 
     1337        size_t length; 
     1338        size_t capacity; 
     1339    } items = { NULL, 0, 0 }; 
    16461340    yaml_node_t node; 
    16471341 
    16481342    assert(document);   /* Non-NULL document object is expected. */ 
    1649  
    1650     if (!tag) { 
    1651         tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; 
    1652     } 
    1653  
    1654     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1343    assert(document->type); /* Initialized document is required. */ 
     1344    assert(tag);        /* Non-NULL tag is expected. */ 
     1345 
     1346    if (anchor) { 
     1347        anchor_copy = yaml_strdup(anchor); 
     1348        if (!anchor_copy) goto error; 
     1349    } 
     1350 
    16551351    tag_copy = yaml_strdup(tag); 
    16561352    if (!tag_copy) goto error; 
    16571353 
    1658     if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error; 
    1659  
    1660     SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, 
    1661             style, mark, mark); 
    1662     if (!PUSH(&context, document->nodes, node)) goto error; 
    1663  
    1664     return document->nodes.top - document->nodes.start; 
     1354    if (!STACK_INIT(&self, items, INITIAL_STACK_CAPACITY)) goto error; 
     1355 
     1356    SEQUENCE_NODE_INIT(node, anchor_copy, tag_copy, 
     1357            items.list, items.length, items.capacity, style, mark, mark); 
     1358    if (!PUSH(&self, document->nodes, node)) goto error; 
     1359 
     1360    if (node_id) { 
     1361        *node_id = document->nodes.length-1; 
     1362    } 
     1363 
     1364    return 1; 
    16651365 
    16661366error: 
    1667     STACK_DEL(&context, items); 
     1367    STACK_DEL(&self, items); 
     1368    yaml_free(anchor_copy); 
    16681369    yaml_free(tag_copy); 
    16691370 
     
    16761377 
    16771378YAML_DECLARE(int) 
    1678 yaml_document_add_mapping(yaml_document_t *document, 
    1679         yaml_char_t *tag, yaml_mapping_style_t style) 
     1379yaml_document_add_mapping(yaml_document_t *document, int *node_id, 
     1380        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1381        yaml_mapping_style_t style) 
    16801382{ 
    16811383    struct { 
    1682         yaml_error_type_t error; 
    1683     } context; 
     1384        yaml_error_t error; 
     1385    } self; 
    16841386    yaml_mark_t mark = { 0, 0, 0 }; 
     1387    yaml_char_t *anchor_copy = NULL; 
    16851388    yaml_char_t *tag_copy = NULL; 
    16861389    struct { 
    1687         yaml_node_pair_t *start; 
    1688         yaml_node_pair_t *end; 
    1689         yaml_node_pair_t *top; 
    1690     } pairs = { NULL, NULL, NULL }; 
     1390        yaml_node_pair_t *list; 
     1391        size_t length; 
     1392        size_t capacity; 
     1393    } pairs = { NULL, 0, 0 }; 
    16911394    yaml_node_t node; 
    16921395 
    16931396    assert(document);   /* Non-NULL document object is expected. */ 
    1694  
    1695     if (!tag) { 
    1696         tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; 
    1697     } 
    1698  
    1699     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1397    assert(document->type); /* Initialized document is required. */ 
     1398    assert(tag);        /* Non-NULL tag is expected. */ 
     1399 
     1400    if (anchor) { 
     1401        anchor_copy = yaml_strdup(anchor); 
     1402        if (!anchor_copy) goto error; 
     1403    } 
     1404 
    17001405    tag_copy = yaml_strdup(tag); 
    17011406    if (!tag_copy) goto error; 
    17021407 
    1703     if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error; 
    1704  
    1705     MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, 
    1706             style, mark, mark); 
    1707     if (!PUSH(&context, document->nodes, node)) goto error; 
    1708  
    1709     return document->nodes.top - document->nodes.start; 
     1408    if (!STACK_INIT(&self, pairs, INITIAL_STACK_CAPACITY)) goto error; 
     1409 
     1410    MAPPING_NODE_INIT(node, anchor_copy, tag_copy, 
     1411            pairs.list, pairs.length, pairs.capacity, style, mark, mark); 
     1412    if (!PUSH(&self, document->nodes, node)) goto error; 
     1413 
     1414    if (node_id) { 
     1415        *node_id = document->nodes.length-1; 
     1416    } 
     1417 
     1418    return 1; 
    17101419 
    17111420error: 
    1712     STACK_DEL(&context, pairs); 
     1421    STACK_DEL(&self, pairs); 
     1422    yaml_free(anchor_copy); 
    17131423    yaml_free(tag_copy); 
    17141424 
     
    17221432YAML_DECLARE(int) 
    17231433yaml_document_append_sequence_item(yaml_document_t *document, 
    1724         int sequence, int item) 
     1434        int sequence_id, int item_id) 
    17251435{ 
    17261436    struct { 
    1727         yaml_error_type_t error; 
    1728     } context; 
     1437        yaml_error_t error; 
     1438    } self; 
    17291439 
    17301440    assert(document);       /* Non-NULL document is required. */ 
    1731     assert(sequence > 0 
    1732             && document->nodes.start + sequence <= document->nodes.top); 
     1441    assert(document->type); /* Initialized document is expected. */ 
     1442 
     1443    if (sequence_id) { 
     1444        sequence_id += document->nodes.length; 
     1445    } 
     1446    if (item_id) { 
     1447        item_id += document->nodes.length; 
     1448    } 
     1449 
     1450    assert(sequence_id >= 0 && sequence_id < document->nodes.length); 
    17331451                            /* Valid sequence id is required. */ 
    1734     assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); 
    1735                             /* A sequence node is required. */ 
    1736     assert(item > 0 && document->nodes.start + item <= document->nodes.top); 
     1452    assert(item_id >= 0 && item_id < document->nodes.length); 
    17371453                            /* Valid item id is required. */ 
    1738  
    1739     if (!PUSH(&context, 
    1740                 document->nodes.start[sequence-1].data.sequence.items, item)) 
     1454    assert(document->nodes.list[sequence_id].type == YAML_SEQUENCE_NODE); 
     1455                            /* A sequence node is expected. */ 
     1456 
     1457    if (!PUSH(&self, 
     1458                document->nodes.list[sequence_id].data.sequence.items, item_id)) 
    17411459        return 0; 
    17421460 
     
    17501468YAML_DECLARE(int) 
    17511469yaml_document_append_mapping_pair(yaml_document_t *document, 
    1752         int mapping, int key, int value) 
     1470        int mapping_id, int key_id, int value_id) 
    17531471{ 
    17541472    struct { 
    1755         yaml_error_type_t error; 
    1756     } context; 
    1757     yaml_node_pair_t pair = { key, value }; 
     1473        yaml_error_t error; 
     1474    } self; 
     1475    yaml_node_pair_t pair = { key_id, value_id }; 
    17581476 
    17591477    assert(document);       /* Non-NULL document is required. */ 
    1760     assert(mapping > 0 
    1761             && document->nodes.start + mapping <= document->nodes.top); 
     1478    assert(document->type); /* Initialized document is expected. */ 
     1479 
     1480    if (mapping_id < 0) { 
     1481        mapping_id += document->nodes.length; 
     1482    } 
     1483    if (key_id < 0) { 
     1484        key_id += document->nodes.length; 
     1485    } 
     1486    if (value_id < 0) { 
     1487        value_id += document->nodes.length; 
     1488    } 
     1489 
     1490    assert(mapping_id >= 0 && mapping_id < document->nodes.length); 
    17621491                            /* Valid mapping id is required. */ 
    1763     assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); 
    1764                             /* A mapping node is required. */ 
    1765     assert(key > 0 && document->nodes.start + key <= document->nodes.top); 
     1492    assert(key_id >= 0 && key_id < document->nodes.length); 
    17661493                            /* Valid key id is required. */ 
    1767     assert(value > 0 && document->nodes.start + value <= document->nodes.top); 
     1494    assert(value_id >= 0 && value_id < document->nodes.length); 
    17681495                            /* Valid value id is required. */ 
    1769  
    1770     if (!PUSH(&context, 
    1771                 document->nodes.start[mapping-1].data.mapping.pairs, pair)) 
    1772         return 0; 
    1773  
    1774     return 1; 
    1775 } 
    1776  
    1777 #endif 
    1778  
     1496    assert(document->nodes.list[mapping_id].type == YAML_MAPPING_NODE); 
     1497                            /* A mapping node is expected. */ 
     1498 
     1499    if (!PUSH(&self, 
     1500                document->nodes.list[mapping_id].data.mapping.pairs, pair)) 
     1501        return 0; 
     1502 
     1503    return 1; 
     1504} 
     1505 
     1506/* 
     1507 * Ensure that the node is a `!!null` SCALAR node. 
     1508 */ 
     1509 
     1510YAML_DECLARE(int) 
     1511yaml_document_get_null_node(yaml_document_t *document, int node_id) 
     1512{ 
     1513    yaml_node_t *node; 
     1514    yaml_char_t *scalar; 
     1515 
     1516    assert(document);       /* Non-NULL document is required. */ 
     1517    assert(document->type); /* Initialized document is expected. */ 
     1518 
     1519    if (node_id < 0) { 
     1520        node_id += document->nodes.length; 
     1521    } 
     1522 
     1523    assert(node_id >= 0 && node_id < document->nodes.length); 
     1524                            /* Valid node id is required. */ 
     1525 
     1526    node = document->nodes.list + node_id; 
     1527 
     1528    if (node->type != YAML_SCALAR_NODE) 
     1529        return 0; 
     1530 
     1531    if (strcmp(node->tag, YAML_NULL_TAG)) 
     1532        return 0; 
     1533 
     1534    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1535        return 0; 
     1536 
     1537    scalar = node->data.scalar.value; 
     1538 
     1539    if (!strcmp(scalar, "") || !strcmp(scalar, "~") || !strcmp(scalar, "null") 
     1540            || !strcmp(scalar, "Null") || !strcmp(scalar, "NULL")) 
     1541        return 1; 
     1542 
     1543    return 0; 
     1544} 
     1545 
     1546/* 
     1547 * Ensure that the node is a `!!bool` SCALAR node. 
     1548 */ 
     1549 
     1550YAML_DECLARE(int) 
     1551yaml_document_get_bool_node(yaml_document_t *document, int node_id, int *value) 
     1552{ 
     1553    yaml_node_t *node; 
     1554    yaml_char_t *scalar; 
     1555 
     1556    assert(document);       /* Non-NULL document is required. */ 
     1557    assert(document->type); /* Initialized document is expected. */ 
     1558 
     1559    if (node_id < 0) { 
     1560        node_id += document->nodes.length; 
     1561    } 
     1562 
     1563    assert(node_id >= 0 && node_id < document->nodes.length); 
     1564                            /* Valid node id is required. */ 
     1565 
     1566    node = document->nodes.list + node_id; 
     1567 
     1568    if (node->type != YAML_SCALAR_NODE) 
     1569        return 0; 
     1570 
     1571    if (strcmp(node->tag, YAML_BOOL_TAG)) 
     1572        return 0; 
     1573 
     1574    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1575        return 0; 
     1576 
     1577    scalar = node->data.scalar.value; 
     1578 
     1579    if (!strcmp(scalar, "yes") || !strcmp(scalar, "Yes") || !strcmp(scalar, "YES") || 
     1580            !strcmp(scalar, "true") || !strcmp(scalar, "True") || !strcmp(scalar, "TRUE") || 
     1581            !strcmp(scalar, "on") || !strcmp(scalar, "On") || !strcmp(scalar, "ON")) { 
     1582        if (value) { 
     1583            *value = 1; 
     1584        } 
     1585        return 1; 
     1586    } 
     1587 
     1588    if (!strcmp(scalar, "no") || !strcmp(scalar, "No") || !strcmp(scalar, "NO") || 
     1589            !strcmp(scalar, "false") || !strcmp(scalar, "False") || !strcmp(scalar, "FALSE") || 
     1590            !strcmp(scalar, "off") || !strcmp(scalar, "Off") || !strcmp(scalar, "OFF")) { 
     1591        if (value) { 
     1592            *value = 0; 
     1593        } 
     1594        return 1; 
     1595    } 
     1596 
     1597    return 0; 
     1598} 
     1599 
     1600/* 
     1601 * Ensure that the node is a `!!str` SCALAR node. 
     1602 */ 
     1603 
     1604YAML_DECLARE(int) 
     1605yaml_document_get_str_node(yaml_document_t *document, int node_id, 
     1606        char **value) 
     1607{ 
     1608    yaml_node_t *node; 
     1609 
     1610    assert(document);       /* Non-NULL document is required. */ 
     1611    assert(document->type); /* Initialized document is expected. */ 
     1612 
     1613    if (node_id < 0) { 
     1614        node_id += document->nodes.length; 
     1615    } 
     1616 
     1617    assert(node_id >= 0 && node_id < document->nodes.length); 
     1618                            /* Valid node id is required. */ 
     1619 
     1620    node = document->nodes.list + node_id; 
     1621 
     1622    if (node->type != YAML_SCALAR_NODE) 
     1623        return 0; 
     1624 
     1625    if (strcmp(node->tag, YAML_STR_TAG)) 
     1626        return 0; 
     1627 
     1628    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1629        return 0; 
     1630 
     1631    if (value) { 
     1632        *value = node->data.scalar.value; 
     1633    } 
     1634 
     1635    return 1; 
     1636} 
     1637 
     1638/* 
     1639 * Ensure that the node is an `!!int` SCALAR node. 
     1640 */ 
     1641 
     1642YAML_DECLARE(int) 
     1643yaml_document_get_int_node(yaml_document_t *document, int node_id, 
     1644        long *value) 
     1645{ 
     1646    yaml_node_t *node; 
     1647    yaml_char_t *scalar; 
     1648    char *tail; 
     1649    long integer; 
     1650    int old_errno = errno, new_errno; 
     1651 
     1652    assert(document);       /* Non-NULL document is required. */ 
     1653    assert(document->type); /* Initialized document is expected. */ 
     1654 
     1655    if (node_id < 0) { 
     1656        node_id += document->nodes.length; 
     1657    } 
     1658 
     1659    assert(node_id >= 0 && node_id < document->nodes.length); 
     1660                            /* Valid node id is required. */ 
     1661 
     1662    node = document->nodes.list + node_id; 
     1663 
     1664    if (node->type != YAML_SCALAR_NODE) 
     1665        return 0; 
     1666 
     1667    if (strcmp(node->tag, YAML_INT_TAG)) 
     1668        return 0; 
     1669 
     1670    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1671        return 0; 
     1672 
     1673    if (!node->data.scalar.length) 
     1674        return 0; 
     1675 
     1676    scalar = node->data.scalar.value; 
     1677 
     1678    errno = 0; 
     1679 
     1680    integer = strtol((char *)scalar, &tail, 0); 
     1681 
     1682    new_errno = errno; 
     1683    errno = old_errno; 
     1684 
     1685    if (new_errno || *tail) { 
     1686        return 0; 
     1687    } 
     1688 
     1689    if (value) { 
     1690        *value = integer; 
     1691    } 
     1692 
     1693    return 1; 
     1694} 
     1695 
     1696/* 
     1697 * Ensure that the node is a `!!float` SCALAR node. 
     1698 */ 
     1699 
     1700YAML_DECLARE(int) 
     1701yaml_document_get_float_node(yaml_document_t *document, int node_id, 
     1702        double *value) 
     1703{ 
     1704    yaml_node_t *node; 
     1705    yaml_char_t *scalar; 
     1706    char buffer[128]; 
     1707    char *pointer; 
     1708    char *tail; 
     1709    double real; 
     1710    int old_errno = errno, new_errno; 
     1711    char decimal_point = localeconv()->decimal_point[0]; 
     1712 
     1713    assert(document);       /* Non-NULL document is required. */ 
     1714    assert(document->type); /* Initialized document is expected. */ 
     1715 
     1716    if (node_id < 0) { 
     1717        node_id += document->nodes.length; 
     1718    } 
     1719 
     1720    assert(node_id >= 0 && node_id < document->nodes.length); 
     1721                            /* Valid node id is required. */ 
     1722 
     1723    node = document->nodes.list + node_id; 
     1724 
     1725    if (node->type != YAML_SCALAR_NODE) 
     1726        return 0; 
     1727 
     1728    if (strcmp(node->tag, YAML_FLOAT_TAG) && strcmp(node->tag, YAML_INT_TAG)) 
     1729        return 0; 
     1730 
     1731    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1732        return 0; 
     1733 
     1734    if (!node->data.scalar.length) 
     1735        return 0; 
     1736 
     1737    scalar = node->data.scalar.value; 
     1738 
     1739    if (!strcmp(scalar, ".nan") || !strcmp(scalar, ".NaN") || !strcmp(scalar, ".NAN")) { 
     1740        if (value) { 
     1741            *value = 0.0/0.0; 
     1742        } 
     1743        return 1; 
     1744    } 
     1745 
     1746    if (!strcmp(scalar, ".inf") || !strcmp(scalar, ".Inf") || !strcmp(scalar, ".INF") || 
     1747            !strcmp(scalar, "+.inf") || !strcmp(scalar, "+.Inf") || !strcmp(scalar, "+.INF")) { 
     1748        if (value) { 
     1749            *value = 1.0/0.0; 
     1750        } 
     1751        return 1; 
     1752    } 
     1753 
     1754    if (!strcmp(scalar, "-.inf") || !strcmp(scalar, "-.Inf") || !strcmp(scalar, "-.INF")) { 
     1755        if (value) { 
     1756            *value = -1.0/0.0; 
     1757        } 
     1758        return 1; 
     1759    } 
     1760 
     1761    if (strlen(scalar) >= sizeof(buffer)) 
     1762        return 0; 
     1763 
     1764    strcpy(buffer, (const char *)scalar); 
     1765 
     1766    /* Replace a locale-dependent decimal point with a dot. */ 
     1767 
     1768    for (pointer = buffer; *pointer; pointer++) { 
     1769        if (*pointer == decimal_point) { 
     1770            *pointer = '.'; 
     1771            break; 
     1772        } 
     1773    } 
     1774 
     1775    errno = 0; 
     1776 
     1777    real = strtod(buffer, &tail); 
     1778 
     1779    new_errno = errno; 
     1780    errno = old_errno; 
     1781 
     1782    if (new_errno || *tail) { 
     1783        return 0; 
     1784    } 
     1785 
     1786    if (value) { 
     1787        *value = real; 
     1788    } 
     1789 
     1790    return 1; 
     1791} 
     1792 
     1793/* 
     1794 * Ensure that the node is a `!!seq` SEQUENCE node. 
     1795 */ 
     1796 
     1797YAML_DECLARE(int) 
     1798yaml_document_get_seq_node(yaml_document_t *document, int node_id, 
     1799        yaml_node_item_t **items, size_t *length) 
     1800{ 
     1801    yaml_node_t *node; 
     1802 
     1803    assert(document);       /* Non-NULL document is required. */ 
     1804    assert(document->type); /* Initialized document is expected. */ 
     1805 
     1806    assert((items && length) || (!items && !length)); 
     1807                /* items and length must be equal to NULL simultaneously. */ 
     1808 
     1809    if (node_id < 0) { 
     1810        node_id += document->nodes.length; 
     1811    } 
     1812 
     1813    assert(node_id >= 0 && node_id < document->nodes.length); 
     1814                            /* Valid node id is required. */ 
     1815 
     1816    node = document->nodes.list + node_id; 
     1817 
     1818    if (node->type != YAML_SEQUENCE_NODE) 
     1819        return 0; 
     1820 
     1821    if (strcmp(node->tag, YAML_SEQ_TAG)) 
     1822        return 0; 
     1823 
     1824    if (items && length) { 
     1825        *items = node->data.sequence.items.list; 
     1826        *length = node->data.sequence.items.length; 
     1827    } 
     1828 
     1829    return 1; 
     1830} 
     1831 
     1832/* 
     1833 * Ensure that the node is a `!!map` MAPPING node. 
     1834 */ 
     1835 
     1836YAML_DECLARE(int) 
     1837yaml_document_get_map_node(yaml_document_t *document, int node_id, 
     1838        yaml_node_pair_t **pairs, size_t *length) 
     1839{ 
     1840    yaml_node_t *node; 
     1841 
     1842    assert(document);       /* Non-NULL document is required. */ 
     1843    assert(document->type); /* Initialized document is expected. */ 
     1844 
     1845    assert((pairs && length) || (!pairs && !length)); 
     1846                /* pairs and length must be equal to NULL simultaneously. */ 
     1847 
     1848    if (node_id < 0) { 
     1849        node_id += document->nodes.length; 
     1850    } 
     1851 
     1852    assert(node_id >= 0 && node_id < document->nodes.length); 
     1853                            /* Valid node id is required. */ 
     1854 
     1855    node = document->nodes.list + node_id; 
     1856 
     1857    if (node->type != YAML_MAPPING_NODE) 
     1858        return 0; 
     1859 
     1860    if (strcmp(node->tag, YAML_MAP_TAG)) 
     1861        return 0; 
     1862 
     1863    if (pairs && length) { 
     1864        *pairs = node->data.mapping.pairs.list; 
     1865        *length = node->data.mapping.pairs.length; 
     1866    } 
     1867 
     1868    return 1; 
     1869} 
     1870 
     1871/* 
     1872 * Add a `!!null` SCALAR node. 
     1873 */ 
     1874 
     1875YAML_DECLARE(int) 
     1876yaml_document_add_null_node(yaml_document_t *document, int *node_id) 
     1877{ 
     1878    return yaml_document_add_scalar(document, node_id, NULL, 
     1879