Changeset 267 for libyaml/trunk
- Timestamp:
- 01/19/08 08:54:22 (4 years ago)
- Location:
- libyaml/trunk
- Files:
-
- 4 modified
-
include/yaml.h (modified) (17 diffs)
-
src/api.c (modified) (28 diffs)
-
src/emitter.c (modified) (12 diffs)
-
src/yaml_private.h (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libyaml/trunk/include/yaml.h
r266 r267 8 8 *****************************************************************************/ 9 9 10 /* 10 /***************************************************************************** 11 11 * 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 * 16 38 * 17 39 * FIXME: Calling conventions. … … 19 41 * FIXME: Errors and exceptions. 20 42 * FIXME: And so on, and so forth. 43 * 44 * 45 * 46 * 21 47 */ 22 48 … … 270 296 yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity); 271 297 272 /***************************************************************************** *298 /***************************************************************************** 273 299 * Basic Types 274 ***************************************************************************** */300 *****************************************************************************/ 275 301 276 302 /* … … 348 374 } yaml_break_t; 349 375 350 /***************************************************************************** *376 /***************************************************************************** 351 377 * Node Styles 352 ***************************************************************************** */378 *****************************************************************************/ 353 379 354 380 /* … … 403 429 404 430 /* The flow sequence style. */ 405 YAML_FLOW_SEQUENCE_STYLE 431 YAML_FLOW_SEQUENCE_STYLE, 406 432 /* The block sequence style. */ 407 YAML_BLOCK_SEQUENCE_STYLE ,433 YAML_BLOCK_SEQUENCE_STYLE 408 434 } yaml_sequence_style_t; 409 435 … … 431 457 } yaml_mapping_style_t; 432 458 433 /***************************************************************************** *459 /***************************************************************************** 434 460 * Tokens 435 ***************************************************************************** */461 *****************************************************************************/ 436 462 437 463 /* … … 681 707 yaml_token_clear(yaml_token_t *token); 682 708 683 /***************************************************************************** *709 /***************************************************************************** 684 710 * Events 685 ***************************************************************************** */711 *****************************************************************************/ 686 712 687 713 /* … … 1221 1247 yaml_event_create_mapping_end(yaml_event_t *event); 1222 1248 1223 /***************************************************************************** *1249 /***************************************************************************** 1224 1250 * Documents and Nodes 1225 ***************************************************************************** */1251 *****************************************************************************/ 1226 1252 1227 1253 /* … … 1261 1287 typedef enum yaml_document_type_e { 1262 1288 /* An empty uninitialized document. */ 1263 YAML_NO_DOCUMENT .1289 YAML_NO_DOCUMENT, 1264 1290 1265 1291 /* A YAML document. */ … … 1383 1409 */ 1384 1410 1385 struct yaml_node_s {1411 typedef struct yaml_node_s { 1386 1412 1387 1413 /* The node type. */ … … 1443 1469 yaml_mark_t end_mark; 1444 1470 1445 } ;1471 } yaml_node_t; 1446 1472 1447 1473 /* … … 1819 1845 1820 1846 /* 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 is1824 * 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 not1826 * 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 is1844 * `tag:yaml.org,2002:bool` and the node value is a valid boolean value. The1845 * 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 the1856 * function succeeds and `value` is not `NULL`, the node value is saved to1857 * `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 is1868 * `tag:yaml.org,2002:str` and the node value is a string that does not contain1869 * the NUL character. In this case, the function returns the node value. The1870 * 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 the1881 * function succeeds and `value` is not `NULL`, the node value is saved to1882 * `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 is1893 * `tag:yaml.org,2002:int` and the node value is a valid integer. In this1894 * case, the function parses the node value and returns an integer number. The1895 * function recognizes decimal, hexdecimal and octal numbers including negative1896 * 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 the1907 * function succeeds and `value` is not `NULL`, the node value is saved to1908 * `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 is1919 * `tag:yaml.org,2002:float` and the node value is a valid float value. In1920 * this case, the function parses the node value and returns a float number.1921 * The function recognizes float values in exponential and fixed notation as1922 * 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 the1933 * function succeeds and `value` is not `NULL`, the node value is saved to1934 * `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 node1945 * tag is `tag:yaml.org,2002:seq`. In this case, the function returns the list1946 * of nodes that belong to the sequence. The produced list is valid until the1947 * 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 the1961 * function succeeds and `items` is not `NULL`, the list of sequence items is1962 * 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 node1973 * tag is `tag:yaml.org,2002:map`. In this case, the function returns the list1974 * of node pairs (key, value) that belong to the sequence. The produced list1975 * 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 the1989 * function succeeds and `pairs` is not `NULL`, the list of mapping pairs is1990 * 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 cannot2012 * allocate memory for new buffers. If the function succeeds, the id of the2013 * 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 cannot2037 * allocate memory for new buffers. If the function succeeds, the id of the2038 * 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 if2061 * `value` is a valid UTF-8 string, but if it is not so, the emitter will2062 * fail to emit the node.2063 *2064 * Returns: `1` on success, `0` on error. The function may fail if it cannot2065 * allocate memory for new buffers. If the function succeeds, the id of the2066 * 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 cannot2091 * allocate memory for new buffers. If the function succeeds, the id of the2092 * 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 cannot2117 * allocate memory for new buffers. If the function succeeds, the id of the2118 * 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 cannot2140 * allocate memory for new buffers. If the function succeeds, the id of the2141 * 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 cannot2162 * allocate memory for new buffers. If the function succeeds, the id of the2163 * 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 /*2170 1847 * Add an item to a SEQUENCE node. 2171 1848 * … … 2223 1900 int mapping_id, int key_id, int value_id); 2224 1901 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 1919 YAML_DECLARE(int) 1920 yaml_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 1942 YAML_DECLARE(int) 1943 yaml_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 1967 YAML_DECLARE(int) 1968 yaml_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 1993 YAML_DECLARE(int) 1994 yaml_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 2021 YAML_DECLARE(int) 2022 yaml_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 2049 YAML_DECLARE(int) 2050 yaml_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 2077 YAML_DECLARE(int) 2078 yaml_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 2100 YAML_DECLARE(int) 2101 yaml_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 2125 YAML_DECLARE(int) 2126 yaml_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 2153 YAML_DECLARE(int) 2154 yaml_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 2179 YAML_DECLARE(int) 2180 yaml_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 2205 YAML_DECLARE(int) 2206 yaml_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 2228 YAML_DECLARE(int) 2229 yaml_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 2250 YAML_DECLARE(int) 2251 yaml_document_add_map_node(yaml_document_t *document, int *node_id); 2252 2253 /***************************************************************************** 2226 2254 * Callback Definitions 2227 ***************************************************************************** */2255 *****************************************************************************/ 2228 2256 2229 2257 /* … … 2306 2334 2307 2335 typedef 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 /***************************************************************************** 2311 2339 * Parser Definitions 2312 ***************************************************************************** */2340 *****************************************************************************/ 2313 2341 2314 2342 /* … … 2360 2388 2361 2389 YAML_DECLARE(void) 2362 yaml_parser_ clear(yaml_parser_t *parser);2390 yaml_parser_reset(yaml_parser_t *parser); 2363 2391 2364 2392 /* … … 2618 2646 yaml_document_t *document); 2619 2647 2620 /***************************************************************************** *2648 /***************************************************************************** 2621 2649 * Emitter Definitions 2622 ***************************************************************************** */2650 *****************************************************************************/ 2623 2651 2624 2652 /* … … 2670 2698 2671 2699 YAML_DECLARE(void) 2672 yaml_emitter_ clear(yaml_emitter_t *emitter);2700 yaml_emitter_reset(yaml_emitter_t *emitter); 2673 2701 2674 2702 /* -
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 *****************************************************************************/ 1 9 2 10 #include "yaml_private.h" 3 11 4 /* 5 * Get the library version. 12 /***************************************************************************** 13 * Version Information 14 *****************************************************************************/ 15 16 /* 17 * Get the library version as a static string. 6 18 */ 7 19 … … 24 36 } 25 37 38 /***************************************************************************** 39 * Memory Management 40 *****************************************************************************/ 41 26 42 /* 27 43 * Allocate a dynamic memory block. … … 66 82 return (yaml_char_t *)strdup((char *)str); 67 83 } 84 85 /***************************************************************************** 86 * Error Handling 87 *****************************************************************************/ 68 88 69 89 /* … … 171 191 } 172 192 193 /***************************************************************************** 194 * String, Stack and Queue Management 195 *****************************************************************************/ 173 196 174 197 /* … … 264 287 } 265 288 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 *****************************************************************************/ 688 292 689 293 /* … … 713 317 assert(token); /* Non-NULL token object expected. */ 714 318 715 yaml_token_ destroy(token);319 yaml_token_clear(token); 716 320 yaml_free(token); 717 321 } … … 726 330 assert(token); /* Non-NULL token object is expected. */ 727 331 assert(model); /* Non-NULL model token object is expected. */ 332 assert(!token->type); /* The token must be empty. */ 728 333 729 334 memset(token, 0, sizeof(yaml_token_t)); 730 335 731 336 token->type = model->type; 337 token->start_mark = model->start_mark; 338 token->end_mark = model->end_mark; 732 339 733 340 switch (token->type) … … 790 397 791 398 error: 792 yaml_token_ destroy(token);399 yaml_token_clear(token); 793 400 794 401 return 0; … … 796 403 797 404 /* 798 * Destroya token object.799 */ 800 801 YAML_DECLARE(void) 802 yaml_token_ destroy(yaml_token_t *token)405 * Clear a token object. 406 */ 407 408 YAML_DECLARE(void) 409 yaml_token_clear(yaml_token_t *token) 803 410 { 804 411 assert(token); /* Non-NULL token object expected. */ … … 835 442 } 836 443 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 *****************************************************************************/ 880 447 881 448 /* … … 905 472 assert(event); /* Non-NULL event object expected. */ 906 473 907 yaml_event_ destroy(event);474 yaml_event_clear(event); 908 475 yaml_free(event); 909 476 } … … 922 489 assert(event); /* Non-NULL event object is expected. */ 923 490 assert(model); /* Non-NULL model event object is expected. */ 491 assert(!event->type); /* The event must be empty. */ 924 492 925 493 memset(event, 0, sizeof(yaml_event_t)); 926 494 927 495 event->type = model->type; 496 event->start_mark = model->start_mark; 497 event->end_mark = model->end_mark; 928 498 929 499 switch (event->type) … … 989 559 model->data.scalar.length+1); 990 560 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; 995 565 event->data.scalar.style = model->data.scalar.style; 996 566 break; … … 1005 575 yaml_strdup(model->data.sequence_start.tag))) 1006 576 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; 1009 579 event->data.sequence_start.style = 1010 580 model->data.sequence_start.style; … … 1020 590 yaml_strdup(model->data.mapping_start.tag))) 1021 591 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; 1024 594 event->data.mapping_start.style = 1025 595 model->data.mapping_start.style; … … 1033 603 1034 604 error: 1035 yaml_event_ destroy(event);605 yaml_event_clear(event); 1036 606 1037 607 return 0; … … 1039 609 1040 610 /* 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 614 YAML_DECLARE(void) 615 yaml_event_clear(yaml_event_t *event) 1365 616 { 1366 617 struct { … … 1410 661 } 1411 662 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 667 YAML_DECLARE(int) 668 yaml_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 685 YAML_DECLARE(int) 686 yaml_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 702 YAML_DECLARE(int) 703 yaml_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) 1424 707 { 1425 708 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 }; 1433 712 yaml_version_directive_t *version_directive_copy = NULL; 1434 713 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. */ 1448 722 1449 723 if (version_directive) { 1450 724 version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 1451 725 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)) 1459 731 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) 1466 740 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;1477 741 } 1478 742 } 1479 743 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); 1483 747 1484 748 return 1; 1485 749 1486 750 error: 1487 STACK_DEL(&context, nodes);1488 751 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); 1491 754 yaml_free(value.handle); 1492 755 yaml_free(value.prefix); 1493 756 } 1494 STACK_DEL(&context, tag_directives_copy); 1495 yaml_free(value.handle); 1496 yaml_free(value.prefix); 757 STACK_DEL(&self, tag_directives_copy); 1497 758 1498 759 return 0; … … 1500 761 1501 762 /* 1502 * Destroy a document object. 763 * Create DOCUMENT-END. 764 */ 765 766 YAML_DECLARE(int) 767 yaml_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 783 YAML_DECLARE(int) 784 yaml_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 806 YAML_DECLARE(int) 807 yaml_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 849 error: 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 861 YAML_DECLARE(int) 862 yaml_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 890 error: 891 yaml_free(anchor_copy); 892 yaml_free(tag_copy); 893 894 return 0; 895 } 896 897 /* 898 * Create SEQUENCE-END. 899 */ 900 901 YAML_DECLARE(int) 902 yaml_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 918 YAML_DECLARE(int) 919 yaml_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 947 error: 948 yaml_free(anchor_copy); 949 yaml_free(tag_copy); 950 951 return 0; 952 } 953 954 /* 955 * Create MAPPING-END. 956 */ 957 958 YAML_DECLARE(int) 959 yaml_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 979 YAML_DECLARE(yaml_document_t *) 980 yaml_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. 1503 994 */ 1504 995 1505 996 YAML_DECLARE(void) 1506 997 yaml_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 1009 YAML_DECLARE(int) 1010 yaml_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 1103 error: 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 1119 YAML_DECLARE(void) 1120 yaml_document_clear(yaml_document_t *document) 1507 1121 { 1508 1122 struct { 1509 1123 yaml_error_type_t error; 1510 } context;1124 } self; 1511 1125 yaml_tag_directive_t *tag_directive; 1512 1126 1513 context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */1127 self.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */ 1514 1128 1515 1129 assert(document); /* Non-NULL document object is expected. */ 1130 1131 if (!document->type) 1132 return; 1516 1133 1517 1134 while (!STACK_EMPTY(&context, document->nodes)) { … … 1532 1149 } 1533 1150 } 1534 STACK_DEL(& context, document->nodes);1151 STACK_DEL(&self, document->nodes); 1535 1152 1536 1153 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); 1544 1160 1545 1161 memset(document, 0, sizeof(yaml_document_t)); 1546 1162 } 1547 1163 1548 /** 1164 /* 1165 * Create a document. 1166 */ 1167 1168 YAML_DECLARE(int) 1169 yaml_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 1226 error: 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 /* 1549 1242 * Get a document node. 1550 1243 */ 1551 1244 1552 1245 YAML_DECLARE(yaml_node_t *) 1553 yaml_document_get_node(yaml_document_t *document, int index)1246 yaml_document_get_node(yaml_document_t *document, int node_id) 1554 1247 { 1555 1248 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; 1559 1257 } 1560 1258 return NULL; 1561 1259 } 1562 1260 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 1578 1261 /* 1579 1262 * Add a scalar node to a document. … … 1581 1264 1582 1265 YAML_DECLARE(int) 1583 yaml_document_add_scalar(yaml_document_t *document, 1584 yaml_char_t *tag, yaml_char_t *value, int length, 1266 yaml_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, 1585 1269 yaml_scalar_style_t style) 1586 1270 { 1587 1271 struct { 1588 yaml_error_t ype_terror;1589 } context;1272 yaml_error_t error; 1273 } self; 1590 1274 yaml_mark_t mark = { 0, 0, 0 }; 1275 yaml_char_t *anchor_copy = NULL; 1591 1276 yaml_char_t *tag_copy = NULL; 1592 1277 yaml_char_t *value_copy = NULL; … … 1594 1279 1595 1280 assert(document); /* Non-NULL document object is expected. */ 1281 assert(document->type); /* Initialized document is required. */ 1282 assert(tag); /* Non-NULL tag is expected. */ 1596 1283 assert(value); /* Non-NULL value is expected. */ 1597 1284 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 1603 1290 tag_copy = yaml_strdup(tag); 1604 1291 if (!tag_copy) goto error; … … 1608 1295 } 1609 1296 1610 if (!yaml_valid_utf8(value, length)) goto error;1611 1297 value_copy = yaml_malloc(length+1); 1612 1298 if (!value_copy) goto error; … … 1614 1300 value_copy[length] = '\0'; 1615 1301 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; 1620 1311 1621 1312 error: 1313 yaml_free(anchor_copy); 1622 1314 yaml_free(tag_copy); 1623 1315 yaml_free(value_copy); … … 1631 1323 1632 1324 YAML_DECLARE(int) 1633 yaml_document_add_sequence(yaml_document_t *document, 1634 yaml_char_t *tag, yaml_sequence_style_t style) 1325 yaml_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) 1635 1328 { 1636 1329 struct { 1637 yaml_error_t ype_terror;1638 } context;1330 yaml_error_t error; 1331 } self; 1639 1332 yaml_mark_t mark = { 0, 0, 0 }; 1333 yaml_char_t *anchor_copy = NULL; 1640 1334 yaml_char_t *tag_copy = NULL; 1641 1335 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 }; 1646 1340 yaml_node_t node; 1647 1341 1648 1342 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 1655 1351 tag_copy = yaml_strdup(tag); 1656 1352 if (!tag_copy) goto error; 1657 1353 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; 1665 1365 1666 1366 error: 1667 STACK_DEL(&context, items); 1367 STACK_DEL(&self, items); 1368 yaml_free(anchor_copy); 1668 1369 yaml_free(tag_copy); 1669 1370 … … 1676 1377 1677 1378 YAML_DECLARE(int) 1678 yaml_document_add_mapping(yaml_document_t *document, 1679 yaml_char_t *tag, yaml_mapping_style_t style) 1379 yaml_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) 1680 1382 { 1681 1383 struct { 1682 yaml_error_t ype_terror;1683 } context;1384 yaml_error_t error; 1385 } self; 1684 1386 yaml_mark_t mark = { 0, 0, 0 }; 1387 yaml_char_t *anchor_copy = NULL; 1685 1388 yaml_char_t *tag_copy = NULL; 1686 1389 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 }; 1691 1394 yaml_node_t node; 1692 1395 1693 1396 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 1700 1405 tag_copy = yaml_strdup(tag); 1701 1406 if (!tag_copy) goto error; 1702 1407 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; 1710 1419 1711 1420 error: 1712 STACK_DEL(&context, pairs); 1421 STACK_DEL(&self, pairs); 1422 yaml_free(anchor_copy); 1713 1423 yaml_free(tag_copy); 1714 1424 … … 1722 1432 YAML_DECLARE(int) 1723 1433 yaml_document_append_sequence_item(yaml_document_t *document, 1724 int sequence , int item)1434 int sequence_id, int item_id) 1725 1435 { 1726 1436 struct { 1727 yaml_error_t ype_terror;1728 } context;1437 yaml_error_t error; 1438 } self; 1729 1439 1730 1440 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); 1733 1451 /* 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); 1737 1453 /* 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)) 1741 1459 return 0; 1742 1460 … … 1750 1468 YAML_DECLARE(int) 1751 1469 yaml_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) 1753 1471 { 1754 1472 struct { 1755 yaml_error_t ype_terror;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 }; 1758 1476 1759 1477 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); 1762 1491 /* 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); 1766 1493 /* 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); 1768 1495 /* 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 1510 YAML_DECLARE(int) 1511 yaml_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 1550 YAML_DECLARE(int) 1551 yaml_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 1604 YAML_DECLARE(int) 1605 yaml_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 1642 YAML_DECLARE(int) 1643 yaml_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 1700 YAML_DECLARE(int) 1701 yaml_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 1797 YAML_DECLARE(int) 1798 yaml_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 1836 YAML_DECLARE(int) 1837 yaml_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 1875 YAML_DECLARE(int) 1876 yaml_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 1886 YAML_DECLARE(int) 1887 yaml_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 1898 YAML_DECLARE(int) 1899 yaml_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 1910 YAML_DECLARE(int) 1911 yaml_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 1928 YAML_DECLARE(int) 1929 yaml_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 1974 YAML_DECLARE(int) 1975 yaml_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 1985 YAML_DECLARE(int) 1986 yaml_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 2000 static int 2001 yaml_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 2025 static int 2026 yaml_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 2039 static int 2040 yaml_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 2061 static int 2062 yaml_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 2085 static int 2086 yaml_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 2195 YAML_DECLARE(yaml_parser_t *) 2196 yaml_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 2224 error: 2225 yaml_parser_delete(parser); 2226 2227 return NULL; 2228 } 2229 2230 /* 2231 * Deallocate a parser object. 2232 */ 2233 2234 YAML_DECLARE(void) 2235 yaml_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 2265 YAML_DECLARE(void) 2266 yaml_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 2305 YAML_DECLARE(yaml_error_t *) 2306 yaml_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 2317 YAML_DECLARE(void) 2318 yaml_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 2337 YAML_DECLARE(void) 2338 yaml_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 2354 YAML_DECLARE(void) 2355 yaml_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 2370 YAML_DECLARE(void) 2371 yaml_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 2384 YAML_DECLARE(void) 2385 yaml_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 2400 YAML_DECLARE(void) 2401 yaml_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 2417 YAML_DECLARE(yaml_emitter_t *) 2418 yaml_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 2441 error: 2442 yaml_emitter_delete(emitter); 2443 2444 return NULL; 2445 } 2446 2447 /* 2448 * Destroy an emitter object. 2449 */ 2450 2451 YAML_DECLARE(void) 2452 yaml_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 2480 YAML_DECLARE(void) 2481 yaml_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 2516 YAML_DECLARE(yaml_error_t *) 2517 yaml_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 2528 YAML_DECLARE(void) 2529 yaml_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 2551 YAML_DECLARE(void) 2552 yaml_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 2568 YAML_DECLARE(void) 2569 yaml_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 2584 YAML_DECLARE(void) 2585 yaml_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 2598 YAML_DECLARE(void) 2599 yaml_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 2614 YAML_DECLARE(void) 2615 yaml_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 2627 YAML_DECLARE(void) 2628 yaml_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 2639 YAML_DECLARE(void) 2640 yaml_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 2651 YAML_DECLARE(void) 2652 yaml_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 2663 YAML_DECLARE(void) 2664 yaml_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 2675 YAML_DECLARE(void) 2676 yaml_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 182 182 * Analyzers. 183 183 */ 184 185 static int 186 yaml_emitter_valid_utf8(yaml_emitter_t *emitter, yaml_istring_t string); 184 187 185 188 static int … … 1149 1152 int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); 1150 1153 1151 if (no_tag && !event->data.scalar.is_plain_ implicit1152 && !event->data.scalar.is_quoted_ implicit) {1154 if (no_tag && !event->data.scalar.is_plain_nonspecific 1155 && !event->data.scalar.is_quoted_nonspecific) { 1153 1156 return EMITTER_ERROR_INIT(emitter, 1154 "neither tag nor implicitflags are specified");1157 "neither tag nor nonspecific flags are specified"); 1155 1158 } 1156 1159 … … 1172 1175 && (emitter->flow_level || emitter->is_simple_key_context)) 1173 1176 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) 1175 1178 style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 1176 1179 } … … 1189 1192 } 1190 1193 1191 if (no_tag && !event->data.scalar.is_quoted_ implicit1194 if (no_tag && !event->data.scalar.is_quoted_nonspecific 1192 1195 && style != YAML_PLAIN_SCALAR_STYLE) 1193 1196 { … … 1309 1312 1310 1313 /* 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 1319 static int 1320 yaml_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 /* 1311 1358 * Check if a %TAG directive is valid. 1312 1359 */ … … 1321 1368 strlen((char *)tag_directive.prefix)); 1322 1369 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 1323 1380 if (!handle.length) { 1324 1381 return EMITTER_ERROR_INIT(emitter, "tag handle must not be empty"); … … 1359 1416 { 1360 1417 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 } 1361 1424 1362 1425 if (!string.length) { … … 1392 1455 yaml_istring_t string = ISTRING(tag, strlen((char *)tag)); 1393 1456 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 } 1394 1462 1395 1463 if (!string.length) { … … 1451 1519 int leading = 0; 1452 1520 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 1453 1526 emitter->scalar_data.value = value; 1454 1527 emitter->scalar_data.length = length; … … 1690 1763 } 1691 1764 if (event->data.scalar.tag && (emitter->is_canonical || 1692 (!event->data.scalar.is_plain_ implicit1693 && !event->data.scalar.is_quoted_ implicit))) {1765 (!event->data.scalar.is_plain_nonspecific 1766 && !event->data.scalar.is_quoted_nonspecific))) { 1694 1767 if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) 1695 1768 return 0; … … 1707 1780 } 1708 1781 if (event->data.sequence_start.tag && (emitter->is_canonical || 1709 !event->data.sequence_start.is_ implicit)) {1782 !event->data.sequence_start.is_nonspecific)) { 1710 1783 if (!yaml_emitter_analyze_tag(emitter, 1711 1784 event->data.sequence_start.tag)) … … 1721 1794 } 1722 1795 if (event->data.mapping_start.tag && (emitter->is_canonical || 1723 !event->data.mapping_start.is_ implicit)) {1796 !event->data.mapping_start.is_nonspecific)) { 1724 1797 if (!yaml_emitter_analyze_tag(emitter, 1725 1798 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 *****************************************************************************/ 1 9 2 10 #if HAVE_CONFIG_H … … 8 16 #include <assert.h> 9 17 #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 *****************************************************************************/ 14 25 15 26 YAML_DECLARE(void *) … … 25 36 yaml_strdup(const yaml_char_t *); 26 37 27 /* 28 * Error management.29 * /38 /***************************************************************************** 39 * Error Management 40 *****************************************************************************/ 30 41 31 42 /* … … 129 140 RESOLVER_ERROR_INIT((self)->error, YAML_RESOLVER_ERROR, _problem) 130 141 142 /***************************************************************************** 143 * Buffer Sizes 144 *****************************************************************************/ 145 131 146 /* 132 147 * The size of the input raw buffer. … … 139 154 * 140 155 * 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. 142 160 */ 143 161 … … 167 185 #define INITIAL_STRING_CAPACITY 16 168 186 169 /* 170 * String management.171 * /187 /***************************************************************************** 188 * String Management 189 *****************************************************************************/ 172 190 173 191 /* … … 203 221 204 222 /* 205 * Separate type for non-UTF-8 i/o strings.223 * A separate type for non-UTF-8 i/o strings. 206 224 */ 207 225 … … 213 231 } yaml_raw_iostring_t; 214 232 233 /* 234 * Double the string capacity. 235 */ 236 215 237 YAML_DECLARE(int) 216 238 yaml_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 */ 217 243 218 244 YAML_DECLARE(int) … … 220 246 yaml_char_t **base_buffer, size_t *base_pointer, size_t *base_capacity, 221 247 yaml_char_t *adj_buffer, size_t adj_pointer); 248 249 /* 250 * Basic string operations. 251 */ 222 252 223 253 #define ISTRING(buffer, length) { (buffer), 0, (length) } … … 239 269 ((string).pointer = (string).length = (string).capacity = 0)) 240 270 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 241 277 #define OSTRING_INIT(self, string, _capacity) \ 242 278 (((string).buffer = yaml_malloc(_capacity)) ? \ … … 273 309 0)) 274 310 275 /* 276 * String check operations.277 * /311 /***************************************************************************** 312 * String Tests 313 *****************************************************************************/ 278 314 279 315 /* … … 548 584 COPY_OCTET((target_string), (source_string))) : 0) 549 585 550 /* 551 * Stack and queue management. 586 /***************************************************************************** 587 * Stack and Queue Management 588 *****************************************************************************/ 589 590 /* 591 * Double the stack capacity. 552 592 */ 553 593 554 594 YAML_DECLARE(int) 555 595 yaml_stack_extend(void **list, size_t size, size_t *length, size_t *capacity); 596 597 /* 598 * Double the queue capacity. 599 */ 556 600 557 601 YAML_DECLARE(int) 558 602 yaml_queue_extend(void **list, size_t size, 559 603 size_t *head, size_t *tail, size_t *capacity); 604 605 /* 606 * Basic stack operations. 607 */ 560 608 561 609 #define STACK_INIT(self, stack, _capacity) \ … … 571 619 (stack).list = NULL, \ 572 620 (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)) 573 626 574 627 #define STACK_EMPTY(self, stack) \ … … 590 643 ((stack).list[--(stack).length]) 591 644 645 /* 646 * Basic queue operations. 647 */ 648 592 649 #define QUEUE_INIT(self, queue, _capacity) \ 593 650 (((queue).list = yaml_malloc((_capacity)*sizeof(*(queue).list))) ? \ … … 602 659 (queue).list = NULL, \ 603 660 (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)) 604 666 605 667 #define QUEUE_EMPTY(self, queue) \ … … 634 696 0)) 635 697 636 /* 637 * Token initializers.638 * /698 /***************************************************************************** 699 * Token Initializers 700 *****************************************************************************/ 639 701 640 702 #define TOKEN_INIT(token, _type, _start_mark, _end_mark) \ … … 680 742 (token).data.tag_directive.prefix = (_prefix)) 681 743 682 /* 683 * Event initializers.684 * /744 /***************************************************************************** 745 * Event Initializers 746 *****************************************************************************/ 685 747 686 748 #define EVENT_INIT(event, _type, _start_mark, _end_mark) \ … … 716 778 717 779 #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) \ 719 781 (EVENT_INIT((event), YAML_SCALAR_EVENT, (_start_mark), (_end_mark)), \ 720 782 (event).data.scalar.anchor = (_anchor), \ … … 722 784 (event).data.scalar.value = (_value), \ 723 785 (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), \ 726 788 (event).data.scalar.style = (_style)) 727 789 728 #define SEQUENCE_START_EVENT_INIT(event, _anchor, _tag, _is_ implicit, _style,\790 #define SEQUENCE_START_EVENT_INIT(event, _anchor, _tag, _is_nonspecific, _style, \ 729 791 _start_mark, _end_mark) \ 730 792 (EVENT_INIT((event), YAML_SEQUENCE_START_EVENT, (_start_mark), (_end_mark)), \ 731 793 (event).data.sequence_start.anchor = (_anchor), \ 732 794 (event).data.sequence_start.tag = (_tag), \ 733 (event).data.sequence_start.is_ implicit = (_is_implicit),\795 (event).data.sequence_start.is_nonspecific = (_is_nonspecific), \ 734 796 (event).data.sequence_start.style = (_style)) 735 797 … … 737 799 (EVENT_INIT((event), YAML_SEQUENCE_END_EVENT, (_start_mark), (_end_mark))) 738 800 739 #define MAPPING_START_EVENT_INIT(event, _anchor, _tag, _is_ implicit, _style,\801 #define MAPPING_START_EVENT_INIT(event, _anchor, _tag, _is_nonspecific, _style, \ 740 802 _start_mark, _end_mark) \ 741 803 (EVENT_INIT((event), YAML_MAPPING_START_EVENT, (_start_mark), (_end_mark)), \ 742 804 (event).data.mapping_start.anchor = (_anchor), \ 743 805 (event).data.mapping_start.tag = (_tag), \ 744 (event).data.mapping_start.is_ implicit = (_is_implicit),\806 (event).data.mapping_start.is_nonspecific = (_is_nonspecific), \ 745 807 (event).data.mapping_start.style = (_style)) 746 808 … … 748 810 (EVENT_INIT((event), YAML_MAPPING_END_EVENT, (_start_mark), (_end_mark))) 749 811 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) \ 760 820 (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) \ 777 835 (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 *****************************************************************************/ 807 927 808 928 /* … … 1038 1158 } aliases; 1039 1159 1040 /* The currently parsed document. */1160 /* The document being parsed. */ 1041 1161 yaml_document_t *document; 1042 1162 1043 1163 }; 1044 1164 1165 /***************************************************************************** 1166 * Internal Parser API 1167 *****************************************************************************/ 1168 1169 /* 1170 * Reader: Ensure that the buffer contains at least `length` characters. 1171 */ 1172 1173 YAML_DECLARE(int) 1174 yaml_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 1180 YAML_DECLARE(int) 1181 yaml_parser_fetch_more_tokens(yaml_parser_t *parser); 1182 1183 /***************************************************************************** 1184 * Emitter Structures 1185 *****************************************************************************/ 1186 1045 1187 /* 1046 1188 * The emitter states. … … 1048 1190 1049 1191 typedef enum yaml_emitter_state_e { 1050 /* *Expect STREAM-START. */1192 /* Expect STREAM-START. */ 1051 1193 YAML_EMIT_STREAM_START_STATE, 1052 /* *Expect the first DOCUMENT-START or STREAM-END. */1194 /* Expect the first DOCUMENT-START or STREAM-END. */ 1053 1195 YAML_EMIT_FIRST_DOCUMENT_START_STATE, 1054 /* *Expect DOCUMENT-START or STREAM-END. */1196 /* Expect DOCUMENT-START or STREAM-END. */ 1055 1197 YAML_EMIT_DOCUMENT_START_STATE, 1056 /* *Expect the content of a document. */1198 /* Expect the content of a document. */ 1057 1199 YAML_EMIT_DOCUMENT_CONTENT_STATE, 1058 /* *Expect DOCUMENT-END. */1200 /* Expect DOCUMENT-END. */ 1059 1201 YAML_EMIT_DOCUMENT_END_STATE, 1060 /* *Expect the first item of a flow sequence. */1202 /* Expect the first item of a flow sequence. */ 1061 1203 YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, 1062 /* *Expect an item of a flow sequence. */1204 /* Expect an item of a flow sequence. */ 1063 1205 YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, 1064 /* *Expect the first key of a flow mapping. */1206 /* Expect the first key of a flow mapping. */ 1065 1207 YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, 1066 /* *Expect a key of a flow mapping. */1208 /* Expect a key of a flow mapping. */ 1067 1209 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. */ 1069 1211 YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, 1070 /* *Expect a value of a flow mapping. */1212 /* Expect a value of a flow mapping. */ 1071 1213 YAML_EMIT_FLOW_MAPPING_VALUE_STATE, 1072 /* *Expect the first item of a block sequence. */1214 /* Expect the first item of a block sequence. */ 1073 1215 YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, 1074 /* *Expect an item of a block sequence. */1216 /* Expect an item of a block sequence. */ 1075 1217 YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, 1076 /* *Expect the first key of a block mapping. */1218 /* Expect the first key of a block mapping. */ 1077 1219 YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, 1078 /* *Expect the key of a block mapping. */1220 /* Expect the key of a block mapping. */ 1079 1221 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. */ 1081 1223 YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, 1082 /* *Expect a value of a block mapping. */1224 /* Expect a value of a block mapping. */ 1083 1225 YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, 1084 /* *Expect nothing. */1226 /* Expect nothing. */ 1085 1227 YAML_EMIT_END_STATE 1086 1228 } yaml_emitter_state_t; … … 1252 1394 */ 1253 1395 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 1254 1402 /* If the stream was already opened? */ 1255 1403 int is_opened; … … 1270 1418 int last_anchor_id; 1271 1419 1272 /* The currently emitted document. */1420 /* The document being emitted. */ 1273 1421 yaml_document_t *document; 1274 1422 1275 1423 }; 1276 1424 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
