Changeset 267
- 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
