Changeset 267


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

Minor API updates.

Location:
libyaml/trunk
Files:
4 edited

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            YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE); 
     1880} 
     1881 
     1882/* 
     1883 * Add a `!!bool` SCALAR node. 
     1884 */ 
     1885 
     1886YAML_DECLARE(int) 
     1887yaml_document_add_bool_node(yaml_document_t *document, int *node_id, 
     1888        int value) 
     1889{ 
     1890    return yaml_document_add_scalar(document, node_id, NULL, YAML_BOOL_TAG, 
     1891            (value ? "true" : "false"), -1, YAML_ANY_SCALAR_STYLE); 
     1892} 
     1893 
     1894/* 
     1895 * Add a `!!str` SCALAR node. 
     1896 */ 
     1897 
     1898YAML_DECLARE(int) 
     1899yaml_document_add_str_node(yaml_document_t *document, int *node_id, 
     1900        const char *value) 
     1901{ 
     1902    return yaml_document_add_scalar(document, node_id, NULL, YAML_STR_TAG, 
     1903            (const yaml_char_t *) value, -1, YAML_ANY_SCALAR_STYLE); 
     1904} 
     1905 
     1906/* 
     1907 * Add an `!!int` SCALAR node. 
     1908 */ 
     1909 
     1910YAML_DECLARE(int) 
     1911yaml_document_add_int_node(yaml_document_t *document, int *node_id, 
     1912        long value) 
     1913{ 
     1914    char buffer[128];   /* 128 bytes should be enough for everybody. */ 
     1915    int length; 
     1916 
     1917    length = snprintf(buffer, sizeof(buffer), "%ld", value); 
     1918    if (length < 0 || length >= sizeof(buffer)) return 0; 
     1919 
     1920    return yaml_document_add_scalar(document, node_id, NULL, YAML_INT_TAG, 
     1921            (const yaml_char_t *) buffer, -1, YAML_ANY_SCALAR_STYLE); 
     1922} 
     1923 
     1924/* 
     1925 * Add a `!!float` SCALAR node. 
     1926 */ 
     1927 
     1928YAML_DECLARE(int) 
     1929yaml_document_add_float_node(yaml_document_t *document, int *node_id, 
     1930        double value) 
     1931{ 
     1932    char buffer[128];   /* 128 bytes should be enough for everybody. */ 
     1933    char *pointer; 
     1934    int length; 
     1935    char decimal_point = *localeconv()->decimal_point; 
     1936 
     1937    length = snprintf(buffer, sizeof(buffer), "%.12g", value); 
     1938        /* .12 is a reasonable precision; it is used by str(float) in Python. */ 
     1939    if (length < 0 || length >= sizeof(buffer)-3) return 0; 
     1940 
     1941    /* Replace a locale-dependent decimal point with a dot. */ 
     1942 
     1943    for (pointer = buffer; *pointer; pointer++) { 
     1944        if (*pointer == decimal_point) { 
     1945            *pointer = '.'; 
     1946            break; 
     1947        } 
     1948    } 
     1949 
     1950    /* Check if the formatted number contains a decimal dot. */ 
     1951 
     1952    for (pointer = buffer; *pointer; pointer++) { 
     1953        if (*pointer != '+' && *pointer != '-' && !isdigit(*pointer)) { 
     1954            break; 
     1955        } 
     1956    } 
     1957 
     1958    /* Add .0 at the end of the buffer if needed. */ 
     1959 
     1960    if (!*pointer) { 
     1961        *(pointer++) = '.'; 
     1962        *(pointer++) = '0'; 
     1963        *(pointer++) = '\0'; 
     1964    } 
     1965 
     1966    return yaml_document_add_scalar(document, node_id, NULL, YAML_FLOAT_TAG, 
     1967            (const yaml_char_t *) buffer, -1, YAML_ANY_SCALAR_STYLE); 
     1968} 
     1969 
     1970/* 
     1971 * Add a `!!seq` SEQUENCE node. 
     1972 */ 
     1973 
     1974YAML_DECLARE(int) 
     1975yaml_document_add_seq_node(yaml_document_t *document, int *node_id) 
     1976{ 
     1977    return yaml_document_add_sequence(document, node_id, NULL, 
     1978            YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE); 
     1979} 
     1980 
     1981/* 
     1982 * Add a `!!map` MAPPING node. 
     1983 */ 
     1984 
     1985YAML_DECLARE(int) 
     1986yaml_document_add_map_node(yaml_document_t *document, int *node_id) 
     1987{ 
     1988    return yaml_document_add_mapping(document, node_id, NULL, 
     1989            YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE); 
     1990} 
     1991 
     1992/***************************************************************************** 
     1993 * Standard Handlers 
     1994 *****************************************************************************/ 
     1995 
     1996/* 
     1997 * Standard string read handler. 
     1998 */ 
     1999 
     2000static int 
     2001yaml_string_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
     2002        size_t *length) 
     2003{ 
     2004    yaml_standard_reader_data_t *data = untyped_data; 
     2005 
     2006    if (data->string.pointer == data->string.length) { 
     2007        *length = 0; 
     2008        return 1; 
     2009    } 
     2010 
     2011    if (capacity > (size_t)(data->string.length - data->string.pointer)) { 
     2012        capacity = data->string.length - data->string.pointer; 
     2013    } 
     2014 
     2015    memcpy(buffer, data->string.buffer + data->string.pointer, capacity); 
     2016    data->string.pointer += capacity; 
     2017    *length = capacity; 
     2018    return 1; 
     2019} 
     2020 
     2021/* 
     2022 * Standard file read handler. 
     2023 */ 
     2024 
     2025static int 
     2026yaml_file_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
     2027        size_t *length) 
     2028{ 
     2029    yaml_standard_reader_data_t *data = untyped_data; 
     2030 
     2031    *length = fread(buffer, 1, capacity, data->file); 
     2032    return !ferror(data->file); 
     2033} 
     2034 
     2035/* 
     2036 * String write handler. 
     2037 */ 
     2038 
     2039static int 
     2040yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
     2041{ 
     2042    yaml_standard_writer_data_t *data = untyped_data; 
     2043    int result = 1; 
     2044 
     2045    if (data->string.capacity - data->string.pointer < length) { 
     2046        length = data->string.capacity - data->string.pointer; 
     2047        result = 0; 
     2048    } 
     2049 
     2050    memcpy(data->string.buffer + data->string.pointer, buffer, length); 
     2051    data->string.pointer += length; 
     2052    *data->length += length; 
     2053 
     2054    return result; 
     2055} 
     2056 
     2057/* 
     2058 * File write handler. 
     2059 */ 
     2060 
     2061static int 
     2062yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
     2063{ 
     2064    yaml_standard_writer_data_t *data = untyped_data; 
     2065 
     2066    return (fwrite(buffer, 1, length, data->file) == length); 
     2067} 
     2068 
     2069/* 
     2070 * Standard resolve handler. 
     2071 * 
     2072 * The standard resolve handler recognizes the following scalars: 
     2073 * 
     2074 * - `!!null`: `~|null|Null|NULL|<empty string>`. 
     2075 * 
     2076 * - `!!bool`: `yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE| 
     2077 *              on|On|ON|off|Off|OFF` 
     2078 * 
     2079 * - `!!int`: any string that is successfully converted using `strtol()`. 
     2080 * 
     2081 * - `!!float`: `[+-]?(.inf|.Inf|.INF)|.nan|.NaN|.NAN` or any string 
     2082 *   successfully converted using `strtod()`. 
     2083 */ 
     2084 
     2085static int 
     2086yaml_standard_resolver(void *untyped_data, yaml_incomplete_node_t *node, 
     2087        const yaml_char_t **tag) 
     2088{ 
     2089    if (node->type == YAML_SCALAR_NODE && node->data.scalar.is_plain) 
     2090    { 
     2091        yaml_char_t *value = node->data.scalar.value; 
     2092        char buffer[128]; 
     2093        char *pointer; 
     2094        char *tail; 
     2095        int old_errno, new_errno; 
     2096        char decimal_point = *(localeconv()->decimal_point); 
     2097 
     2098        if (strlen(value) != node->data.scalar.length) { 
     2099            *tag = YAML_STR_TAG; 
     2100            return 1; 
     2101        } 
     2102 
     2103        if (!strcmp(value, "") || !strcmp(value, "~") || 
     2104                !strcmp(value, "null") || !strcmp(value, "Null") || !strcmp(value, "NULL")) { 
     2105            *tag = YAML_NULL_TAG; 
     2106            return 1; 
     2107        } 
     2108 
     2109        if (!strcmp(value, "yes") || !strcmp(value, "Yes") || !strcmp(value, "YES") || 
     2110                !strcmp(value, "no") || !strcmp(value, "No") || !strcmp(value, "NO") || 
     2111                !strcmp(value, "true") || !strcmp(value, "True") || !strcmp(value, "TRUE") || 
     2112                !strcmp(value, "false") || !strcmp(value, "False") || !strcmp(value, "FALSE") || 
     2113                !strcmp(value, "on") || !strcmp(value, "On") || !strcmp(value, "ON") || 
     2114                !strcmp(value, "off") || !strcmp(value, "Off") || !strcmp(value, "OFF")) { 
     2115            *tag = YAML_BOOL_TAG; 
     2116            return 1; 
     2117        } 
     2118 
     2119        if (!strcmp(value, ".inf") || !strcmp(value, ".Inf") || !strcmp(value, ".INF") || 
     2120                !strcmp(value, "+.inf") || !strcmp(value, "+.Inf") || !strcmp(value, "+.INF") || 
     2121                !strcmp(value, "-.inf") || !strcmp(value, "-.Inf") || !strcmp(value, "-.INF") || 
     2122                !strcmp(value, ".nan") || !strcmp(value, ".NaN") || !strcmp(value, ".NAN")) { 
     2123            *tag = YAML_FLOAT_TAG; 
     2124            return 1; 
     2125        } 
     2126 
     2127        old_errno = errno; 
     2128        errno = 0; 
     2129 
     2130        strtol((const char *)value, &tail, 0); 
     2131 
     2132        new_errno = errno; 
     2133        errno = old_errno; 
     2134 
     2135        if (!new_errno && !*tail) { 
     2136            *tag = YAML_INT_TAG; 
     2137            return 1; 
     2138        } 
     2139 
     2140        if (strlen(value) < sizeof(buffer)) 
     2141        { 
     2142            strcpy(buffer, (const char *)value); 
     2143 
     2144            /* Replace a locale-dependent decimal point with a dot. */ 
     2145 
     2146            for (pointer = buffer; *pointer; pointer++) { 
     2147                if (*pointer == decimal_point) { 
     2148                    *pointer = '.'; 
     2149                    break; 
     2150                } 
     2151            } 
     2152 
     2153            old_errno = errno; 
     2154            errno = 0; 
     2155 
     2156            strtod(buffer, &tail); 
     2157 
     2158            new_errno = errno; 
     2159            errno = old_errno; 
     2160 
     2161            if (!new_errno && !*tail) { 
     2162                *tag = YAML_FLOAT_TAG; 
     2163                return 1; 
     2164            } 
     2165        } 
     2166    } 
     2167 
     2168    switch (node->type) 
     2169    { 
     2170        case YAML_SCALAR_NODE: 
     2171            *tag = YAML_STR_TAG; 
     2172            break; 
     2173        case YAML_SEQUENCE_NODE: 
     2174            *tag = YAML_SEQ_TAG; 
     2175            break; 
     2176        case YAML_MAPPING_NODE: 
     2177            *tag = YAML_MAP_TAG; 
     2178            break; 
     2179        default: 
     2180            assert(0);      /* Should never happen. */ 
     2181    } 
     2182 
     2183    return 1; 
     2184} 
     2185 
     2186 
     2187/***************************************************************************** 
     2188 * Parser API 
     2189 *****************************************************************************/ 
     2190 
     2191/* 
     2192 * Allocate a new parser object. 
     2193 */ 
     2194 
     2195YAML_DECLARE(yaml_parser_t *) 
     2196yaml_parser_new(void) 
     2197{ 
     2198    yaml_parser_t *parser = yaml_malloc(sizeof(yaml_parser_t)); 
     2199 
     2200    if (!parser) 
     2201        return NULL; 
     2202 
     2203    memset(parser, 0, sizeof(yaml_parser_t)); 
     2204 
     2205    if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY)) 
     2206        goto error; 
     2207    if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY)) 
     2208        goto error; 
     2209    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY)) 
     2210        goto error; 
     2211    if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_CAPACITY)) 
     2212        goto error; 
     2213    if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_CAPACITY)) 
     2214        goto error; 
     2215    if (!STACK_INIT(parser, parser->states, INITIAL_STACK_CAPACITY)) 
     2216        goto error; 
     2217    if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_CAPACITY)) 
     2218        goto error; 
     2219    if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_CAPACITY)) 
     2220        goto error; 
     2221 
     2222    return parser; 
     2223 
     2224error: 
     2225    yaml_parser_delete(parser); 
     2226 
     2227    return NULL; 
     2228} 
     2229 
     2230/* 
     2231 * Deallocate a parser object. 
     2232 */ 
     2233 
     2234YAML_DECLARE(void) 
     2235yaml_parser_delete(yaml_parser_t *parser) 
     2236{ 
     2237    assert(parser); /* Non-NULL parser object expected. */ 
     2238 
     2239    IOSTRING_DEL(parser, parser->raw_input); 
     2240    IOSTRING_DEL(parser, parser->input); 
     2241    while (!QUEUE_EMPTY(parser, parser->tokens)) { 
     2242        yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
     2243    } 
     2244    QUEUE_DEL(parser, parser->tokens); 
     2245    STACK_DEL(parser, parser->indents); 
     2246    STACK_DEL(parser, parser->simple_keys); 
     2247    STACK_DEL(parser, parser->states); 
     2248    STACK_DEL(parser, parser->marks); 
     2249    while (!STACK_EMPTY(parser, parser->tag_directives)) { 
     2250        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
     2251        yaml_free(tag_directive.handle); 
     2252        yaml_free(tag_directive.prefix); 
     2253    } 
     2254    STACK_DEL(parser, parser->tag_directives); 
     2255 
     2256    memset(parser, 0, sizeof(yaml_parser_t)); 
     2257 
     2258    yaml_free(parser); 
     2259} 
     2260 
     2261/* 
     2262 * Reset a parser object. 
     2263 */ 
     2264 
     2265YAML_DECLARE(void) 
     2266yaml_parser_reset(yaml_parser_t *parser) 
     2267{ 
     2268    yaml_parser_t copy = *parser; 
     2269 
     2270    assert(parser); /* Non-NULL parser object expected. */ 
     2271 
     2272    while (!QUEUE_EMPTY(parser, parser->tokens)) { 
     2273        yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
     2274    } 
     2275    while (!STACK_EMPTY(parser, parser->tag_directives)) { 
     2276        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
     2277        yaml_free(tag_directive.handle); 
     2278        yaml_free(tag_directive.prefix); 
     2279    } 
     2280 
     2281    memset(parser, 0, sizeof(yaml_parser_t)); 
     2282 
     2283    IOSTRING_SET(parser, parser->raw_input, 
     2284            copy.raw_input.buffer, copy.raw_input.capacity); 
     2285    IOSTRING_SET(parser, parser->input, 
     2286            copy.input.buffer, copy.input.capacity); 
     2287    QUEUE_SET(parser, parser->tokens, 
     2288            copy.tokens.list, copy.tokens.capacity); 
     2289    STACK_SET(parser, parser->indents, 
     2290            copy.indents.list, copy.indents.capacity); 
     2291    STACK_SET(parser, parser->simple_keys, 
     2292            copy.simple_keys.list, copy.simple_keys.capacity); 
     2293    STACK_SET(parser, parser->states, 
     2294            copy.states.list, copy.states.capacity); 
     2295    STACK_SET(parser, parser->marks, 
     2296            copy.marks.list, copy.marks.capacity); 
     2297    STACK_SET(parse, parser->tag_directives, 
     2298            copy.tag_directives.list, copy.tag_directives.capacity); 
     2299} 
     2300 
     2301/* 
     2302 * Get the current parser error. 
     2303 */ 
     2304 
     2305YAML_DECLARE(yaml_error_t *) 
     2306yaml_parser_get_error(yaml_parser_t *parser) 
     2307{ 
     2308    assert(parser); /* Non-NULL parser object expected. */ 
     2309 
     2310    return &(parser->error); 
     2311} 
     2312 
     2313/* 
     2314 * Set a string input. 
     2315 */ 
     2316 
     2317YAML_DECLARE(void) 
     2318yaml_parser_set_string_reader(yaml_parser_t *parser, 
     2319        const unsigned char *buffer, size_t length) 
     2320{ 
     2321    assert(parser); /* Non-NULL parser object expected. */ 
     2322    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2323    assert(buffer); /* Non-NULL input string expected. */ 
     2324 
     2325    parser->reader = yaml_string_reader; 
     2326    parser->reader_data = &(parser->standard_reader_data); 
     2327 
     2328    parser->standard_reader_data.string.buffer = buffer; 
     2329    parser->standard_reader_data.string.pointer = 0; 
     2330    parser->standard_reader_data.string.length = length; 
     2331} 
     2332 
     2333/* 
     2334 * Set a file input. 
     2335 */ 
     2336 
     2337YAML_DECLARE(void) 
     2338yaml_parser_set_file_reader(yaml_parser_t *parser, FILE *file) 
     2339{ 
     2340    assert(parser); /* Non-NULL parser object expected. */ 
     2341    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2342    assert(file);   /* Non-NULL file object expected. */ 
     2343 
     2344    parser->reader = yaml_file_reader; 
     2345    parser->reader_data = &(parser->standard_reader_data); 
     2346 
     2347    parser->standard_reader_data.file = file; 
     2348} 
     2349 
     2350/* 
     2351 * Set a generic input. 
     2352 */ 
     2353 
     2354YAML_DECLARE(void) 
     2355yaml_parser_set_reader(yaml_parser_t *parser, 
     2356        yaml_reader_t *reader, void *data) 
     2357{ 
     2358    assert(parser); /* Non-NULL parser object expected. */ 
     2359    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2360    assert(reader); /* Non-NULL read handler expected. */ 
     2361 
     2362    parser->reader = reader; 
     2363    parser->reader_data = data; 
     2364} 
     2365 
     2366/* 
     2367 * Set a standard tag resolver. 
     2368 */ 
     2369 
     2370YAML_DECLARE(void) 
     2371yaml_parser_set_standard_resolver(yaml_parser_t *parser) 
     2372{ 
     2373    assert(parser); /* Non-NULL parser object expected. */ 
     2374    assert(!parser->resolver);  /* You can set the tag resolver only once. */ 
     2375 
     2376    parser->resolver = yaml_standard_resolver; 
     2377    parser->resolver_data = NULL; 
     2378} 
     2379 
     2380/* 
     2381 * Set a generic tag resolver. 
     2382 */ 
     2383 
     2384YAML_DECLARE(void) 
     2385yaml_parser_set_resolver(yaml_parser_t *parser, 
     2386        yaml_resolver_t *resolver, void *data) 
     2387{ 
     2388    assert(parser);     /* Non-NULL parser object expected. */ 
     2389    assert(!parser->resolver);  /* You can set the tag resolver only once. */ 
     2390    assert(resolver);   /* Non-NULL resolver is expected. */ 
     2391 
     2392    parser->resolver = resolver; 
     2393    parser->resolver_data = data; 
     2394} 
     2395 
     2396/* 
     2397 * Set the source encoding. 
     2398 */ 
     2399 
     2400YAML_DECLARE(void) 
     2401yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) 
     2402{ 
     2403    assert(parser); /* Non-NULL parser object expected. */ 
     2404    assert(!parser->encoding);  /* Encoding is already set or detected. */ 
     2405 
     2406    parser->encoding = encoding; 
     2407} 
     2408 
     2409/***************************************************************************** 
     2410 * Parser API 
     2411 *****************************************************************************/ 
     2412 
     2413/* 
     2414 * Create a new emitter object. 
     2415 */ 
     2416 
     2417YAML_DECLARE(yaml_emitter_t *) 
     2418yaml_emitter_new(void) 
     2419{ 
     2420    yaml_emitter_t *emitter = yaml_malloc(sizeof(yaml_emitter_t)); 
     2421 
     2422    if (!emitter) 
     2423        return NULL; 
     2424 
     2425    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2426    if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY)) 
     2427        goto error; 
     2428    if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY)) 
     2429        goto error; 
     2430    if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY)) 
     2431        goto error; 
     2432    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_CAPACITY)) 
     2433        goto error; 
     2434    if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_CAPACITY)) 
     2435        goto error; 
     2436    if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_CAPACITY)) 
     2437        goto error; 
     2438 
     2439    return emitter; 
     2440 
     2441error: 
     2442    yaml_emitter_delete(emitter); 
     2443 
     2444    return NULL; 
     2445} 
     2446 
     2447/* 
     2448 * Destroy an emitter object. 
     2449 */ 
     2450 
     2451YAML_DECLARE(void) 
     2452yaml_emitter_delete(yaml_emitter_t *emitter) 
     2453{ 
     2454    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2455 
     2456    IOSTRING_DEL(emitter, emitter->output); 
     2457    IOSTRING_DEL(emitter, emitter->raw_output); 
     2458    STACK_DEL(emitter, emitter->states); 
     2459    while (!QUEUE_EMPTY(emitter, emitter->events)) { 
     2460        yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
     2461    } 
     2462    QUEUE_DEL(emitter, emitter->events); 
     2463    STACK_DEL(emitter, emitter->indents); 
     2464    while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
     2465        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
     2466        yaml_free(tag_directive.handle); 
     2467        yaml_free(tag_directive.prefix); 
     2468    } 
     2469    STACK_DEL(emitter, emitter->tag_directives); 
     2470    yaml_free(emitter->anchors); 
     2471 
     2472    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2473    yaml_free(emitter); 
     2474} 
     2475 
     2476/* 
     2477 * Reset an emitter object. 
     2478 */ 
     2479 
     2480YAML_DECLARE(void) 
     2481yaml_emitter_reset(yaml_emitter_t *emitter) 
     2482{ 
     2483    yaml_emitter_t copy = *emitter; 
     2484 
     2485    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2486 
     2487    while (!QUEUE_EMPTY(emitter, emitter->events)) { 
     2488        yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
     2489    } 
     2490    while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
     2491        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
     2492        yaml_free(tag_directive.handle); 
     2493        yaml_free(tag_directive.prefix); 
     2494    } 
     2495 
     2496    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2497 
     2498    IOSTRING_SET(emitter, emitter->output, 
     2499            copy.output.buffer, copy.output.capacity); 
     2500    IOSTRING_SET(emitter, emitter->raw_output, 
     2501            copy.raw_output.buffer, copy.raw_output.capacity); 
     2502    STACK_SET(emitter, emitter->states, 
     2503            copy.states.list, copy.states.capacity); 
     2504    QUEUE_SET(emitter, emitter->events, 
     2505            copy.events.list, copy.events.capacity); 
     2506    STACK_SET(emitter, emitter->indents, 
     2507            copy.indents.list, copy.indents.capacity); 
     2508    STACK_SET(emitter, emitter->tag_directives, 
     2509            copy.tag_directives.list, copy.tag_directives.capacity); 
     2510} 
     2511 
     2512/* 
     2513 * Get the current emitter error. 
     2514 */ 
     2515 
     2516YAML_DECLARE(yaml_error_t *) 
     2517yaml_emitter_get_error(yaml_emitter_t *emitter) 
     2518{ 
     2519    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2520 
     2521    return &(emitter->error); 
     2522} 
     2523 
     2524/* 
     2525 * Set a string output. 
     2526 */ 
     2527 
     2528YAML_DECLARE(void) 
     2529yaml_emitter_set_string_writer(yaml_emitter_t *emitter, 
     2530        unsigned char *buffer, size_t capacity, size_t *length) 
     2531{ 
     2532    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2533    assert(!emitter->writer);   /* You can set the output only once. */ 
     2534    assert(buffer);     /* Non-NULL output string expected. */ 
     2535 
     2536    emitter->writer = yaml_string_writer; 
     2537    emitter->writer_data = &(emitter->standard_writer_data); 
     2538 
     2539    emitter->standard_writer_data.string.buffer = buffer; 
     2540    emitter->standard_writer_data.string.pointer = 0; 
     2541    emitter->standard_writer_data.string.capacity = capacity; 
     2542    emitter->standard_writer_data.length = length; 
     2543 
     2544    *length = 0; 
     2545} 
     2546 
     2547/* 
     2548 * Set a file output. 
     2549 */ 
     2550 
     2551YAML_DECLARE(void) 
     2552yaml_emitter_set_file_writer(yaml_emitter_t *emitter, FILE *file) 
     2553{ 
     2554    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2555    assert(!emitter->writer);   /* You can set the output only once. */ 
     2556    assert(file);       /* Non-NULL file object expected. */ 
     2557 
     2558    emitter->writer = yaml_string_writer; 
     2559    emitter->writer_data = &(emitter->standard_writer_data); 
     2560 
     2561    emitter->standard_writer_data.file = file; 
     2562} 
     2563 
     2564/* 
     2565 * Set a generic output handler. 
     2566 */ 
     2567 
     2568YAML_DECLARE(void) 
     2569yaml_emitter_set_writer(yaml_emitter_t *emitter, 
     2570        yaml_writer_t *writer, void *data) 
     2571{ 
     2572    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2573    assert(!emitter->writer);   /* You can set the output only once. */ 
     2574    assert(writer); /* Non-NULL handler object expected. */ 
     2575 
     2576    emitter->writer = writer; 
     2577    emitter->writer_data = data; 
     2578} 
     2579 
     2580/* 
     2581 * Set a standard tag resolver. 
     2582 */ 
     2583 
     2584YAML_DECLARE(void) 
     2585yaml_emitter_set_standard_resolver(yaml_emitter_t *emitter) 
     2586{ 
     2587    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2588    assert(!emitter->resolver); /* You can set the tag resolver only once. */ 
     2589 
     2590    emitter->resolver = yaml_standard_resolver; 
     2591    emitter->resolver_data = NULL; 
     2592} 
     2593 
     2594/* 
     2595 * Set a generic tag resolver. 
     2596 */ 
     2597 
     2598YAML_DECLARE(void) 
     2599yaml_emitter_set_resolver(yaml_emitter_t *emitter, 
     2600        yaml_resolver_t *resolver, void *data) 
     2601{ 
     2602    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2603    assert(!emitter->resolver); /* You can set the tag resolver only once. */ 
     2604    assert(resolver);   /* Non-NULL resolver is expected. */ 
     2605 
     2606    emitter->resolver = resolver; 
     2607    emitter->resolver_data = data; 
     2608} 
     2609 
     2610/* 
     2611 * Set the output encoding. 
     2612 */ 
     2613 
     2614YAML_DECLARE(void) 
     2615yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) 
     2616{ 
     2617    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2618    assert(!emitter->encoding);     /* You can set encoding only once. */ 
     2619 
     2620    emitter->encoding = encoding; 
     2621} 
     2622 
     2623/* 
     2624 * Set the canonical output style. 
     2625 */ 
     2626 
     2627YAML_DECLARE(void) 
     2628yaml_emitter_set_canonical(yaml_emitter_t *emitter, int is_canonical) 
     2629{ 
     2630    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2631 
     2632    emitter->is_canonical = (is_canonical != 0); 
     2633} 
     2634 
     2635/* 
     2636 * Set the indentation increment. 
     2637 */ 
     2638 
     2639YAML_DECLARE(void) 
     2640yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) 
     2641{ 
     2642    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2643 
     2644    emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; 
     2645} 
     2646 
     2647/* 
     2648 * Set the preferred line width. 
     2649 */ 
     2650 
     2651YAML_DECLARE(void) 
     2652yaml_emitter_set_width(yaml_emitter_t *emitter, int width) 
     2653{ 
     2654    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2655 
     2656    emitter->best_width = (width >= 0) ? width : -1; 
     2657} 
     2658 
     2659/* 
     2660 * Set if unescaped non-ASCII characters are allowed. 
     2661 */ 
     2662 
     2663YAML_DECLARE(void) 
     2664yaml_emitter_set_unicode(yaml_emitter_t *emitter, int is_unicode) 
     2665{ 
     2666    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2667 
     2668    emitter->is_unicode = (is_unicode != 0); 
     2669} 
     2670 
     2671/* 
     2672 * Set the preferred line break character. 
     2673 */ 
     2674 
     2675YAML_DECLARE(void) 
     2676yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) 
     2677{ 
     2678    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2679 
     2680    emitter->line_break = line_break; 
     2681} 
     2682 
  • libyaml/trunk/src/emitter.c

    r265 r267  
    182182 * Analyzers. 
    183183 */ 
     184 
     185static int 
     186yaml_emitter_valid_utf8(yaml_emitter_t *emitter, yaml_istring_t string); 
    184187 
    185188static int 
     
    11491152    int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); 
    11501153 
    1151     if (no_tag && !event->data.scalar.is_plain_implicit 
    1152             && !event->data.scalar.is_quoted_implicit) { 
     1154    if (no_tag && !event->data.scalar.is_plain_nonspecific 
     1155            && !event->data.scalar.is_quoted_nonspecific) { 
    11531156        return EMITTER_ERROR_INIT(emitter, 
    1154                 "neither tag nor implicit flags are specified"); 
     1157                "neither tag nor nonspecific flags are specified"); 
    11551158    } 
    11561159 
     
    11721175                && (emitter->flow_level || emitter->is_simple_key_context)) 
    11731176            style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 
    1174         if (no_tag && !event->data.scalar.is_plain_implicit) 
     1177        if (no_tag && !event->data.scalar.is_plain_nonspecific) 
    11751178            style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 
    11761179    } 
     
    11891192    } 
    11901193 
    1191     if (no_tag && !event->data.scalar.is_quoted_implicit 
     1194    if (no_tag && !event->data.scalar.is_quoted_nonspecific 
    11921195            && style != YAML_PLAIN_SCALAR_STYLE) 
    11931196    { 
     
    13091312 
    13101313/* 
     1314 * Verify that a string is a valid UTF-8 sequence. 
     1315 * 
     1316 * Check 'reader.c' for more details on UTF-8 encoding. 
     1317 */ 
     1318 
     1319static int 
     1320yaml_emitter_valid_utf8(yaml_emitter_t *emitter, yaml_istring_t string) 
     1321{ 
     1322    while (string.pointer < string.length) 
     1323    { 
     1324        unsigned char octet; 
     1325        unsigned int width; 
     1326        unsigned int value; 
     1327        size_t idx; 
     1328 
     1329        octet = OCTET(string); 
     1330        width = (octet & 0x80) == 0x00 ? 1 : 
     1331                (octet & 0xE0) == 0xC0 ? 2 : 
     1332                (octet & 0xF0) == 0xE0 ? 3 : 
     1333                (octet & 0xF8) == 0xF0 ? 4 : 0; 
     1334        value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
     1335                (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
     1336                (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
     1337                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
     1338        if (!width) return 0; 
     1339        if (string.pointer+width > string.length) return 0; 
     1340        for (idx = 1; idx < width; idx ++) { 
     1341            octet = OCTET_AT(string, idx); 
     1342            if ((octet & 0xC0) != 0x80) return 0; 
     1343            value = (value << 6) + (octet & 0x3F); 
     1344        } 
     1345        if (!((width == 1) || 
     1346            (width == 2 && value >= 0x80) || 
     1347            (width == 3 && value >= 0x800) || 
     1348            (width == 4 && value >= 0x10000))) return 0; 
     1349 
     1350        string.pointer += width; 
     1351    } 
     1352 
     1353    return 1; 
     1354} 
     1355 
     1356 
     1357/* 
    13111358 * Check if a %TAG directive is valid. 
    13121359 */ 
     
    13211368            strlen((char *)tag_directive.prefix)); 
    13221369 
     1370    if (!yaml_emitter_valid_utf8(emitter, handle)) { 
     1371        return EMITTER_ERROR_INIT(emitter, 
     1372                "tag handle is not a valid UTF-8 string"); 
     1373    } 
     1374 
     1375    if (!yaml_emitter_valid_utf8(emitter, prefix)) { 
     1376        return EMITTER_ERROR_INIT(emitter, 
     1377                "tag prefix is not a valid UTF-8 string"); 
     1378    } 
     1379 
    13231380    if (!handle.length) { 
    13241381        return EMITTER_ERROR_INIT(emitter, "tag handle must not be empty"); 
     
    13591416{ 
    13601417    yaml_istring_t string = ISTRING(anchor, strlen((char *)anchor)); 
     1418 
     1419    if (!yaml_emitter_valid_utf8(emitter, string)) { 
     1420        return EMITTER_ERROR_INIT(emitter, is_alias ? 
     1421                "alias value is not a valid UTF-8 string" : 
     1422                "anchor value is not a valid UTF-8 string"); 
     1423    } 
    13611424 
    13621425    if (!string.length) { 
     
    13921455    yaml_istring_t string = ISTRING(tag, strlen((char *)tag)); 
    13931456    size_t idx; 
     1457 
     1458    if (!yaml_emitter_valid_utf8(emitter, string)) { 
     1459        return EMITTER_ERROR_INIT(emitter, 
     1460                "tag value is not a valid UTF-8 string"); 
     1461    } 
    13941462 
    13951463    if (!string.length) { 
     
    14511519    int leading = 0; 
    14521520 
     1521    if (!yaml_emitter_valid_utf8(emitter, string)) { 
     1522        return EMITTER_ERROR_INIT(emitter, 
     1523                "scalar value is not a valid UTF-8 string"); 
     1524    } 
     1525 
    14531526    emitter->scalar_data.value = value; 
    14541527    emitter->scalar_data.length = length; 
     
    16901763            } 
    16911764            if (event->data.scalar.tag && (emitter->is_canonical || 
    1692                         (!event->data.scalar.is_plain_implicit 
    1693                          && !event->data.scalar.is_quoted_implicit))) { 
     1765                        (!event->data.scalar.is_plain_nonspecific 
     1766                         && !event->data.scalar.is_quoted_nonspecific))) { 
    16941767                if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) 
    16951768                    return 0; 
     
    17071780            } 
    17081781            if (event->data.sequence_start.tag && (emitter->is_canonical || 
    1709                         !event->data.sequence_start.is_implicit)) { 
     1782                        !event->data.sequence_start.is_nonspecific)) { 
    17101783                if (!yaml_emitter_analyze_tag(emitter, 
    17111784                            event->data.sequence_start.tag)) 
     
    17211794            } 
    17221795            if (event->data.mapping_start.tag && (emitter->is_canonical || 
    1723                         !event->data.mapping_start.is_implicit)) { 
     1796                        !event->data.mapping_start.is_nonspecific)) { 
    17241797                if (!yaml_emitter_analyze_tag(emitter, 
    17251798                            event->data.mapping_start.tag)) 
  • libyaml/trunk/src/yaml_private.h

    r265 r267  
     1/***************************************************************************** 
     2 * Private Definitions for LibYAML 
     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#if HAVE_CONFIG_H 
     
    816#include <assert.h> 
    917#include <limits.h> 
    10  
    11 /* 
    12  * Memory management. 
    13  */ 
     18#include <errno.h> 
     19#include <ctype.h> 
     20#include <locale.h> 
     21 
     22/***************************************************************************** 
     23 * Memory Management 
     24 *****************************************************************************/ 
    1425 
    1526YAML_DECLARE(void *) 
     
    2536yaml_strdup(const yaml_char_t *); 
    2637 
    27 /* 
    28  * Error management. 
    29  */ 
     38/***************************************************************************** 
     39 * Error Management 
     40 *****************************************************************************/ 
    3041 
    3142/* 
     
    129140    RESOLVER_ERROR_INIT((self)->error, YAML_RESOLVER_ERROR, _problem) 
    130141 
     142/***************************************************************************** 
     143 * Buffer Sizes 
     144 *****************************************************************************/ 
     145 
    131146/* 
    132147 * The size of the input raw buffer. 
     
    139154 * 
    140155 * The input buffer should be large enough to hold the content of the raw 
    141  * buffer after it is decoded. 
     156 * buffer after it is decoded.  The raw input buffer could be encoded in UTF-8 
     157 * or UTF-16 while the input buffer is always encoded in UTF-8.  A UTF-16 
     158 * character may take 2 or 4 bytes, and a UTF-8 character takes up to 4 bytes. 
     159 * We use the *3 multiplier just to be safe. 
    142160 */ 
    143161 
     
    167185#define INITIAL_STRING_CAPACITY 16 
    168186 
    169 /* 
    170  * String management. 
    171  */ 
     187/***************************************************************************** 
     188 * String Management 
     189 *****************************************************************************/ 
    172190 
    173191/* 
     
    203221 
    204222/* 
    205  * Separate type for non-UTF-8 i/o strings. 
     223 * A separate type for non-UTF-8 i/o strings. 
    206224 */ 
    207225 
     
    213231} yaml_raw_iostring_t; 
    214232 
     233/* 
     234 * Double the string capacity. 
     235 */ 
     236 
    215237YAML_DECLARE(int) 
    216238yaml_ostring_extend(yaml_char_t **buffer, size_t *capacity); 
     239 
     240/* 
     241 * Append a string to the end of the base string expanding it if needed. 
     242 */ 
    217243 
    218244YAML_DECLARE(int) 
     
    220246        yaml_char_t **base_buffer, size_t *base_pointer, size_t *base_capacity, 
    221247        yaml_char_t *adj_buffer, size_t adj_pointer); 
     248 
     249/* 
     250 * Basic string operations. 
     251 */ 
    222252 
    223253#define ISTRING(buffer, length) { (buffer), 0, (length) } 
     
    239269     ((string).pointer = (string).length = (string).capacity = 0)) 
    240270 
     271#define IOSTRING_SET(self, string, _buffer, _capacity)                          \ 
     272    (memset((_buffer), 0, (_capacity)),                                         \ 
     273     (string).buffer = (_buffer),                                               \ 
     274     (string).pointer = (string).length = 0,                                    \ 
     275     (string).capacity = (_capacity)) 
     276 
    241277#define OSTRING_INIT(self, string, _capacity)                                   \ 
    242278    (((string).buffer = yaml_malloc(_capacity)) ?                               \ 
     
    273309         0)) 
    274310 
    275 /* 
    276  * String check operations. 
    277  */ 
     311/***************************************************************************** 
     312 * String Tests 
     313 *****************************************************************************/ 
    278314 
    279315/* 
     
    548584      COPY_OCTET((target_string), (source_string))) : 0) 
    549585 
    550 /* 
    551  * Stack and queue management. 
     586/***************************************************************************** 
     587 * Stack and Queue Management 
     588 *****************************************************************************/ 
     589 
     590/* 
     591 * Double the stack capacity. 
    552592 */ 
    553593 
    554594YAML_DECLARE(int) 
    555595yaml_stack_extend(void **list, size_t size, size_t *length, size_t *capacity); 
     596 
     597/* 
     598 * Double the queue capacity. 
     599 */ 
    556600 
    557601YAML_DECLARE(int) 
    558602yaml_queue_extend(void **list, size_t size, 
    559603        size_t *head, size_t *tail, size_t *capacity); 
     604 
     605/* 
     606 * Basic stack operations. 
     607 */ 
    560608 
    561609#define STACK_INIT(self, stack, _capacity)                                      \ 
     
    571619     (stack).list = NULL,                                                       \ 
    572620     (stack).length = (stack).capacity = 0) 
     621 
     622#define STACK_SET(self, stack, _list, _capacity)                                \ 
     623    ((stack).list = (_list),                                                    \ 
     624     (stack).length = 0,                                                        \ 
     625     (stack).capacity = (_capacity)) 
    573626 
    574627#define STACK_EMPTY(self, stack)                                                \ 
     
    590643    ((stack).list[--(stack).length]) 
    591644 
     645/* 
     646 * Basic queue operations. 
     647 */ 
     648 
    592649#define QUEUE_INIT(self, queue, _capacity)                                      \ 
    593650    (((queue).list = yaml_malloc((_capacity)*sizeof(*(queue).list))) ?          \ 
     
    602659     (queue).list = NULL,                                                       \ 
    603660     (queue).head = (queue).tail = (queue).capacity = 0) 
     661 
     662#define QUEUE_SET(self, queue, _list, _capacity)                                \ 
     663    ((queue).list = (_list),                                                    \ 
     664     (queue).head = (queue).tail = 0,                                           \ 
     665     (queue).capacity = (_capacity)) 
    604666 
    605667#define QUEUE_EMPTY(self, queue)                                                \ 
     
    634696         0)) 
    635697 
    636 /* 
    637  * Token initializers. 
    638  */ 
     698/***************************************************************************** 
     699 * Token Initializers 
     700 *****************************************************************************/ 
    639701 
    640702#define TOKEN_INIT(token, _type, _start_mark, _end_mark)                        \ 
     
    680742     (token).data.tag_directive.prefix = (_prefix)) 
    681743 
    682 /* 
    683  * Event initializers. 
    684  */ 
     744/***************************************************************************** 
     745 * Event Initializers 
     746 *****************************************************************************/ 
    685747 
    686748#define EVENT_INIT(event, _type, _start_mark, _end_mark)                        \ 
     
    716778 
    717779#define SCALAR_EVENT_INIT(event, _anchor, _tag, _value, _length,                \ 
    718         _is_plain_implicit, _is_quoted_implicit, _style, _start_mark, _end_mark)    \ 
     780        _is_plain_nonspecific, _is_quoted_nonspecific, _style, _start_mark, _end_mark)  \ 
    719781    (EVENT_INIT((event), YAML_SCALAR_EVENT, (_start_mark), (_end_mark)),        \ 
    720782     (event).data.scalar.anchor = (_anchor),                                    \ 
     
    722784     (event).data.scalar.value = (_value),                                      \ 
    723785     (event).data.scalar.length = (_length),                                    \ 
    724      (event).data.scalar.is_plain_implicit = (_is_plain_implicit),              \ 
    725      (event).data.scalar.is_quoted_implicit = (_is_quoted_implicit),            \ 
     786     (event).data.scalar.is_plain_nonspecific = (_is_plain_nonspecific),        \ 
     787     (event).data.scalar.is_quoted_nonspecific = (_is_quoted_nonspecific),      \ 
    726788     (event).data.scalar.style = (_style)) 
    727789 
    728 #define SEQUENCE_START_EVENT_INIT(event, _anchor, _tag, _is_implicit, _style,   \ 
     790#define SEQUENCE_START_EVENT_INIT(event, _anchor, _tag, _is_nonspecific, _style,    \ 
    729791        _start_mark, _end_mark)                                                 \ 
    730792    (EVENT_INIT((event), YAML_SEQUENCE_START_EVENT, (_start_mark), (_end_mark)),    \ 
    731793     (event).data.sequence_start.anchor = (_anchor),                            \ 
    732794     (event).data.sequence_start.tag = (_tag),                                  \ 
    733      (event).data.sequence_start.is_implicit = (_is_implicit),                  \ 
     795     (event).data.sequence_start.is_nonspecific = (_is_nonspecific),            \ 
    734796     (event).data.sequence_start.style = (_style)) 
    735797 
     
    737799    (EVENT_INIT((event), YAML_SEQUENCE_END_EVENT, (_start_mark), (_end_mark))) 
    738800 
    739 #define MAPPING_START_EVENT_INIT(event, _anchor, _tag, _is_implicit, _style,    \ 
     801#define MAPPING_START_EVENT_INIT(event, _anchor, _tag, _is_nonspecific, _style, \ 
    740802        _start_mark, _end_mark)                                                 \ 
    741803    (EVENT_INIT((event), YAML_MAPPING_START_EVENT, (_start_mark), (_end_mark)), \ 
    742804     (event).data.mapping_start.anchor = (_anchor),                             \ 
    743805     (event).data.mapping_start.tag = (_tag),                                   \ 
    744      (event).data.mapping_start.is_implicit = (_is_implicit),                   \ 
     806     (event).data.mapping_start.is_nonspecific = (_is_nonspecific),             \ 
    745807     (event).data.mapping_start.style = (_style)) 
    746808 
     
    748810    (EVENT_INIT((event), YAML_MAPPING_END_EVENT, (_start_mark), (_end_mark))) 
    749811 
    750 #if 0 
    751  
    752 /* 
    753  * Document initializer. 
    754  */ 
    755  
    756 #define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end,         \ 
    757         document_version_directive,document_tag_directives_start,               \ 
    758         document_tag_directives_end,document_start_implicit,                    \ 
    759         document_end_implicit,document_start_mark,document_end_mark)            \ 
     812/***************************************************************************** 
     813 * Document, Node and Arc Initializers 
     814 *****************************************************************************/ 
     815 
     816#define DOCUMENT_INIT(document, _nodes_list, _nodes_length, _nodes_capacity,    \ 
     817        _version_directive, _tag_directives_list, _tag_directives_length,       \ 
     818        _tag_directives_capacity, _is_start_implicit, _is_end_implicit,         \ 
     819        _start_mark, _end_mark)                                                 \ 
    760820    (memset(&(document), 0, sizeof(yaml_document_t)),                           \ 
    761      (document).nodes.start = (document_nodes_start),                           \ 
    762      (document).nodes.end = (document_nodes_end),                               \ 
    763      (document).nodes.top = (document_nodes_start),                             \ 
    764      (document).version_directive = (document_version_directive),               \ 
    765      (document).tag_directives.start = (document_tag_directives_start),         \ 
    766      (document).tag_directives.end = (document_tag_directives_end),             \ 
    767      (document).start_implicit = (document_start_implicit),                     \ 
    768      (document).end_implicit = (document_end_implicit),                         \ 
    769      (document).start_mark = (document_start_mark),                             \ 
    770      (document).end_mark = (document_end_mark)) 
    771  
    772 /* 
    773  * Node initializers. 
    774  */ 
    775  
    776 #define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark)        \ 
     821     (document).type = YAML_DOCUMENT,                                           \ 
     822     (document).nodes.list = (_nodes_list),                                     \ 
     823     (document).nodes.length = (_nodes_length),                                 \ 
     824     (document).nodes.capacity = (_nodes_capacity),                             \ 
     825     (document).version_directive = (_version_directive),                       \ 
     826     (document).tag_directives.list = (_tag_directives_list),                   \ 
     827     (document).tag_directives.length = (_tag_directives_length),               \ 
     828     (document).tag_directives.capacity = (_tag_directives_capacity),           \ 
     829     (document).is_start_implicit = (_is_start_implicit),                       \ 
     830     (document).is_end_implicit = (_is_end_implicit),                           \ 
     831     (document).start_mark = (_start_mark),                                     \ 
     832     (document).end_mark = (_end_mark)) 
     833 
     834#define NODE_INIT(node, _type, _anchor, _tag, _start_mark, _end_mark)           \ 
    777835    (memset(&(node), 0, sizeof(yaml_node_t)),                                   \ 
    778      (node).type = (node_type),                                                 \ 
    779      (node).tag = (node_tag),                                                   \ 
    780      (node).start_mark = (node_start_mark),                                     \ 
    781      (node).end_mark = (node_end_mark)) 
    782  
    783 #define SCALAR_NODE_INIT(node,node_tag,node_value,node_length,                  \ 
    784         node_style,start_mark,end_mark)                                         \ 
    785     (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)),     \ 
    786      (node).data.scalar.value = (node_value),                                   \ 
    787      (node).data.scalar.length = (node_length),                                 \ 
    788      (node).data.scalar.style = (node_style)) 
    789  
    790 #define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end,       \ 
    791         node_style,start_mark,end_mark)                                         \ 
    792     (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)),   \ 
    793      (node).data.sequence.items.start = (node_items_start),                     \ 
    794      (node).data.sequence.items.end = (node_items_end),                         \ 
    795      (node).data.sequence.items.top = (node_items_start),                       \ 
    796      (node).data.sequence.style = (node_style)) 
    797  
    798 #define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end,        \ 
    799         node_style,start_mark,end_mark)                                         \ 
    800     (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)),    \ 
    801      (node).data.mapping.pairs.start = (node_pairs_start),                      \ 
    802      (node).data.mapping.pairs.end = (node_pairs_end),                          \ 
    803      (node).data.mapping.pairs.top = (node_pairs_start),                        \ 
    804      (node).data.mapping.style = (node_style)) 
    805  
    806 #endif 
     836     (node).type = (_type),                                                     \ 
     837     (node).anchor = (_anchor),                                                 \ 
     838     (node).tag = (_tag),                                                       \ 
     839     (node).start_mark = (_start_mark),                                         \ 
     840     (node).end_mark = (_end_mark)) 
     841 
     842#define SCALAR_NODE_INIT(node, _anchor, _tag, _value, _length, _style,          \ 
     843        _start_mark, _end_mark)                                                 \ 
     844    (NODE_INIT((node), YAML_SCALAR_NODE, (_anchor), (_tag),                     \ 
     845               (_start_mark), (_end_mark)),                                     \ 
     846     (node).data.scalar.value = (_value),                                       \ 
     847     (node).data.scalar.length = (_length),                                     \ 
     848     (node).data.scalar.style = (_style)) 
     849 
     850#define SEQUENCE_NODE_INIT(node, _anchor, _tag, _items_list, _items_length,     \ 
     851        _items_capacity, _style, _start_mark, _end_mark)                        \ 
     852    (NODE_INIT((node), YAML_SEQUENCE_NODE, (_anchor), (_tag),                   \ 
     853               (_start_mark), (_end_mark)),                                     \ 
     854     (node).data.sequence.items.list = (_items_list),                           \ 
     855     (node).data.sequence.items.length = (_items_length),                       \ 
     856     (node).data.sequence.items.capacity = (_items_capacity),                   \ 
     857     (node).data.sequence.style = (_style)) 
     858 
     859#define MAPPING_NODE_INIT(node, _anchor, _tag, _pairs_list, _pairs_length,      \ 
     860        _pairs_capacity, _style, _start_mark, _end_mark)                        \ 
     861    (NODE_INIT((node), YAML_MAPPING_NODE, (_anchor), (_tag),                    \ 
     862               (_start_mark), (_end_mark)),                                     \ 
     863     (node).data.mapping.pairs.list = (_pairs_list),                            \ 
     864     (node).data.mapping.pairs.length = (_pairs_length),                        \ 
     865     (node).data.mapping.pairs.capacity = (_pairs_capacity),                    \ 
     866     (node).data.mapping.style = (_style)) 
     867 
     868#define ARC_INIT(arc, _type, _tag)                                              \ 
     869    (memset(&(arc), 0, sizeof(yaml_arc_t)),                                     \ 
     870     (arc).type = (_type),                                                      \ 
     871     (arc).tag = (_tag)) 
     872 
     873#define SEQUENCE_ITEM_ARC_INIT(arc, _tag, _index)                               \ 
     874    (ARC_INIT((arc), YAML_SEQUENCE_ITEM_ARC, (_tag)),                           \ 
     875     (arc).data.item.index = (_index)) 
     876 
     877#define MAPPING_KEY_ARC_INIT(arc, _tag)                                         \ 
     878    ARC_INIT((arc), YAML_MAPPING_KEY_ARC, (_tag)) 
     879 
     880#define MAPPING_VALUE_ARC_INIT(arc, _tag, _key_type, _key_tag)                  \ 
     881    (ARC_INIT((arc), YAML_MAPPING_VALUE_ARC, (_tag)),                           \ 
     882     (arc).data.value.key.type = (_key_type),                                   \ 
     883     (arc).data.value.key.tag = (_key_tag)) 
     884 
     885#define MAPPING_VALUE_FOR_SCALAR_KEY_ARC_INIT(arc, _tag, _key_tag,              \ 
     886        _key_value, _key_length)                                                \ 
     887    (MAPPING_VALUE_ARC_INIT((arc), (_tag), YAML_SCALAR_NODE, (_key_tag)),       \ 
     888     (arc).data.value.key.data.scalar.value = (_key_value),                     \ 
     889     (arc).data.value.key.data.scalar.length = (_key_length)) 
     890 
     891#define MAPPING_VALUE_FOR_SEQUENCE_KEY_ARC_INIT(arc, _tag, _key_tag)            \ 
     892    MAPPING_VALUE_ARC_INIT((arc), (_tag), YAML_SEQUENCE_NODE, (_key_tag)) 
     893 
     894#define MAPPING_VALUE_FOR_MAPPING_KEY_INIT(arc, _tag, _key_tag)                 \ 
     895    MAPPING_VALUE_ARC_INIT((arc), (_tag), YAML_MAPPING_NODE, (_key_tag)) 
     896 
     897#define INCOMPLETE_NODE_INIT(node, _type, _path_list, _path_length,             \ 
     898        _path_capacity, _mark)                                                  \ 
     899    (memset(&(node), 0, sizeof(yaml_incomplete_node_t)),                        \ 
     900     (node).type = (_type),                                                     \ 
     901     (node).path.list = (_path_list),                                           \ 
     902     (node).path.length = (_path_length),                                       \ 
     903     (node).path.capacity = (_path_capacity),                                   \ 
     904     (node).mark = (_mark)) 
     905 
     906#define INCOMPLETE_SCALAR_NODE_INIT(node, _path_list, _path_length,             \ 
     907        _path_capacity, _value, _length, _is_plain, _mark)                      \ 
     908    (INCOMPLETE_NODE_INIT((node), YAML_SCALAR_NODE, (_path_list),               \ 
     909                          (_path_length), (_path_capacity), (_mark)).           \ 
     910     (node).data.scalar.value = (_value),                                       \ 
     911     (node).data.scalar.length = (_length),                                     \ 
     912     (node).data.scalar.is_plain = (_is_plain)) 
     913 
     914#define INCOMPLETE_SEQUENCE_NODE_INIT(node, _path_list, _path_length,           \ 
     915        _path_capacity, _mark)                                                  \ 
     916    INCOMPLETE_NODE_INIT((node), YAML_SEQUENCE_NODE, (_path_list),              \ 
     917            (_path_length), (_path_capacity), (_mark)) 
     918 
     919#define INCOMPLETE_MAPPING_NODE_INIT(node, _path_list, _path_length,            \ 
     920        _path_capacity, _mark)                                                  \ 
     921    INCOMPLETE_NODE_INIT((node), YAML_MAPPING_NODE, (_path_list),               \ 
     922            (_path_length), (_path_capacity), (_mark)) 
     923 
     924/***************************************************************************** 
     925 * Parser Structures 
     926 *****************************************************************************/ 
    807927 
    808928/* 
     
    10381158    } aliases; 
    10391159 
    1040     /* The currently parsed document. */ 
     1160    /* The document being parsed. */ 
    10411161    yaml_document_t *document; 
    10421162 
    10431163}; 
    10441164 
     1165/***************************************************************************** 
     1166 * Internal Parser API 
     1167 *****************************************************************************/ 
     1168 
     1169/* 
     1170 * Reader: Ensure that the buffer contains at least `length` characters. 
     1171 */ 
     1172 
     1173YAML_DECLARE(int) 
     1174yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); 
     1175 
     1176/* 
     1177 * Scanner: Ensure that the token stack contains at least one token ready. 
     1178 */ 
     1179 
     1180YAML_DECLARE(int) 
     1181yaml_parser_fetch_more_tokens(yaml_parser_t *parser); 
     1182 
     1183/***************************************************************************** 
     1184 * Emitter Structures 
     1185 *****************************************************************************/ 
     1186 
    10451187/* 
    10461188 * The emitter states. 
     
    10481190 
    10491191typedef enum yaml_emitter_state_e { 
    1050     /** Expect STREAM-START. */ 
     1192    /* Expect STREAM-START. */ 
    10511193    YAML_EMIT_STREAM_START_STATE, 
    1052     /** Expect the first DOCUMENT-START or STREAM-END. */ 
     1194    /* Expect the first DOCUMENT-START or STREAM-END. */ 
    10531195    YAML_EMIT_FIRST_DOCUMENT_START_STATE, 
    1054     /** Expect DOCUMENT-START or STREAM-END. */ 
     1196    /* Expect DOCUMENT-START or STREAM-END. */ 
    10551197    YAML_EMIT_DOCUMENT_START_STATE, 
    1056     /** Expect the content of a document. */ 
     1198    /* Expect the content of a document. */ 
    10571199    YAML_EMIT_DOCUMENT_CONTENT_STATE, 
    1058     /** Expect DOCUMENT-END. */ 
     1200    /* Expect DOCUMENT-END. */ 
    10591201    YAML_EMIT_DOCUMENT_END_STATE, 
    1060     /** Expect the first item of a flow sequence. */ 
     1202    /* Expect the first item of a flow sequence. */ 
    10611203    YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, 
    1062     /** Expect an item of a flow sequence. */ 
     1204    /* Expect an item of a flow sequence. */ 
    10631205    YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, 
    1064     /** Expect the first key of a flow mapping. */ 
     1206    /* Expect the first key of a flow mapping. */ 
    10651207    YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, 
    1066     /** Expect a key of a flow mapping. */ 
     1208    /* Expect a key of a flow mapping. */ 
    10671209    YAML_EMIT_FLOW_MAPPING_KEY_STATE, 
    1068     /** Expect a value for a simple key of a flow mapping. */ 
     1210    /* Expect a value for a simple key of a flow mapping. */ 
    10691211    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, 
    1070     /** Expect a value of a flow mapping. */ 
     1212    /* Expect a value of a flow mapping. */ 
    10711213    YAML_EMIT_FLOW_MAPPING_VALUE_STATE, 
    1072     /** Expect the first item of a block sequence. */ 
     1214    /* Expect the first item of a block sequence. */ 
    10731215    YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, 
    1074     /** Expect an item of a block sequence. */ 
     1216    /* Expect an item of a block sequence. */ 
    10751217    YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, 
    1076     /** Expect the first key of a block mapping. */ 
     1218    /* Expect the first key of a block mapping. */ 
    10771219    YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, 
    1078     /** Expect the key of a block mapping. */ 
     1220    /* Expect the key of a block mapping. */ 
    10791221    YAML_EMIT_BLOCK_MAPPING_KEY_STATE, 
    1080     /** Expect a value for a simple key of a block mapping. */ 
     1222    /* Expect a value for a simple key of a block mapping. */ 
    10811223    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, 
    1082     /** Expect a value of a block mapping. */ 
     1224    /* Expect a value of a block mapping. */ 
    10831225    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, 
    1084     /** Expect nothing. */ 
     1226    /* Expect nothing. */ 
    10851227    YAML_EMIT_END_STATE 
    10861228} yaml_emitter_state_t; 
     
    12521394     */ 
    12531395 
     1396    /* The resolve handler. */ 
     1397    yaml_resolver_t *resolver; 
     1398 
     1399    /* The application data to be passed to the resolver. */ 
     1400    void *resolver_data; 
     1401 
    12541402    /* If the stream was already opened? */ 
    12551403    int is_opened; 
     
    12701418    int last_anchor_id; 
    12711419 
    1272     /* The currently emitted document. */ 
     1420    /* The document being emitted. */ 
    12731421    yaml_document_t *document; 
    12741422 
    12751423}; 
    12761424 
    1277 /* 
    1278  * Reader: Ensure that the buffer contains at least `length` characters. 
    1279  */ 
    1280  
    1281 YAML_DECLARE(int) 
    1282 yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); 
    1283  
    1284 /* 
    1285  * Scanner: Ensure that the token stack contains at least one token ready. 
    1286  */ 
    1287  
    1288 YAML_DECLARE(int) 
    1289 yaml_parser_fetch_more_tokens(yaml_parser_t *parser); 
    1290  
Note: See TracChangeset for help on using the changeset viewer.