X-Git-Url: http://andersk.mit.edu/gitweb/libyaml.git/blobdiff_plain/e35af832e9765e72b3ee3e337b2bfb958e3c5962..HEAD:/include/yaml.h diff --git a/include/yaml.h b/include/yaml.h index 0408a67..c225908 100644 --- a/include/yaml.h +++ b/include/yaml.h @@ -4,7 +4,7 @@ * * Include the header file with the code: * @code - * #include + * #include * @endcode */ @@ -26,7 +26,9 @@ extern "C" { /** The public API declaration. */ -#ifdef WIN32 +#if defined(__MINGW32__) +# define YAML_DECLARE(type) type +#elif defined(WIN32) # if defined(YAML_DECLARE_STATIC) # define YAML_DECLARE(type) type # elif defined(YAML_DECLARE_EXPORT) @@ -59,9 +61,9 @@ yaml_get_version_string(void); /** * Get the library version numbers. * - * @param[out] major Major version number. - * @param[out] minor Minor version number. - * @param[out] patch Patch version number. + * @param[out] major Major version number. + * @param[out] minor Minor version number. + * @param[out] patch Patch version number. */ YAML_DECLARE(void) @@ -78,7 +80,7 @@ yaml_get_version(int *major, int *minor, int *patch); typedef unsigned char yaml_char_t; /** The version directive data. */ -typedef struct { +typedef struct yaml_version_directive_s { /** The major version number. */ int major; /** The minor version number. */ @@ -86,7 +88,7 @@ typedef struct { } yaml_version_directive_t; /** The tag directive data. */ -typedef struct { +typedef struct yaml_tag_directive_s { /** The tag handle. */ yaml_char_t *handle; /** The tag prefix. */ @@ -94,38 +96,55 @@ typedef struct { } yaml_tag_directive_t; /** The stream encoding. */ -typedef enum { +typedef enum yaml_encoding_e { + /** Let the parser choose the encoding. */ YAML_ANY_ENCODING, + /** The default UTF-8 encoding. */ YAML_UTF8_ENCODING, + /** The UTF-16-LE encoding with BOM. */ YAML_UTF16LE_ENCODING, + /** The UTF-16-BE encoding with BOM. */ YAML_UTF16BE_ENCODING } yaml_encoding_t; /** Line break types. */ -typedef enum { +typedef enum yaml_break_e { + /** Let the parser choose the break type. */ YAML_ANY_BREAK, + /** Use CR for line breaks (Mac style). */ YAML_CR_BREAK, + /** Use LN for line breaks (Unix style). */ YAML_LN_BREAK, + /** Use CR LN for line breaks (DOS style). */ YAML_CRLN_BREAK } yaml_break_t; /** Many bad things could happen with the parser and emitter. */ -typedef enum { +typedef enum yaml_error_type_e { + /** No error is produced. */ YAML_NO_ERROR, + /** Cannot allocate or reallocate a block of memory. */ YAML_MEMORY_ERROR, + /** Cannot read or decode the input stream. */ YAML_READER_ERROR, + /** Cannot scan the input stream. */ YAML_SCANNER_ERROR, + /** Cannot parse the input stream. */ YAML_PARSER_ERROR, + /** Cannot compose a YAML document. */ + YAML_COMPOSER_ERROR, + /** Cannot write to the output stream. */ YAML_WRITER_ERROR, + /** Cannot emit a YAML stream. */ YAML_EMITTER_ERROR } yaml_error_type_t; /** The pointer position. */ -typedef struct { +typedef struct yaml_mark_s { /** The position index. */ size_t index; @@ -144,31 +163,43 @@ typedef struct { */ /** Scalar styles. */ -typedef enum { +typedef enum yaml_scalar_style_e { + /** Let the emitter choose the style. */ YAML_ANY_SCALAR_STYLE, + /** The plain scalar style. */ YAML_PLAIN_SCALAR_STYLE, + /** The single-quoted scalar style. */ YAML_SINGLE_QUOTED_SCALAR_STYLE, + /** The double-quoted scalar style. */ YAML_DOUBLE_QUOTED_SCALAR_STYLE, + /** The literal scalar style. */ YAML_LITERAL_SCALAR_STYLE, + /** The folded scalar style. */ YAML_FOLDED_SCALAR_STYLE } yaml_scalar_style_t; /** Sequence styles. */ -typedef enum { +typedef enum yaml_sequence_style_e { + /** Let the emitter choose the style. */ YAML_ANY_SEQUENCE_STYLE, + /** The block sequence style. */ YAML_BLOCK_SEQUENCE_STYLE, + /** The flow sequence style. */ YAML_FLOW_SEQUENCE_STYLE } yaml_sequence_style_t; /** Mapping styles. */ -typedef enum { +typedef enum yaml_mapping_style_e { + /** Let the emitter choose the style. */ YAML_ANY_MAPPING_STYLE, + /** The block mapping style. */ YAML_BLOCK_MAPPING_STYLE, + /** The flow mapping style. */ YAML_FLOW_MAPPING_STYLE /* YAML_FLOW_SET_MAPPING_STYLE */ } yaml_mapping_style_t; @@ -181,39 +212,61 @@ typedef enum { */ /** Token types. */ -typedef enum { +typedef enum yaml_token_type_e { + /** An empty token. */ YAML_NO_TOKEN, + /** A STREAM-START token. */ YAML_STREAM_START_TOKEN, + /** A STREAM-END token. */ YAML_STREAM_END_TOKEN, + /** A VERSION-DIRECTIVE token. */ YAML_VERSION_DIRECTIVE_TOKEN, + /** A TAG-DIRECTIVE token. */ YAML_TAG_DIRECTIVE_TOKEN, + /** A DOCUMENT-START token. */ YAML_DOCUMENT_START_TOKEN, + /** A DOCUMENT-END token. */ YAML_DOCUMENT_END_TOKEN, + /** A BLOCK-SEQUENCE-START token. */ YAML_BLOCK_SEQUENCE_START_TOKEN, + /** A BLOCK-MAPPING-START token. */ YAML_BLOCK_MAPPING_START_TOKEN, + /** A BLOCK-END token. */ YAML_BLOCK_END_TOKEN, + /** A FLOW-SEQUENCE-START token. */ YAML_FLOW_SEQUENCE_START_TOKEN, + /** A FLOW-SEQUENCE-END token. */ YAML_FLOW_SEQUENCE_END_TOKEN, + /** A FLOW-MAPPING-START token. */ YAML_FLOW_MAPPING_START_TOKEN, + /** A FLOW-MAPPING-END token. */ YAML_FLOW_MAPPING_END_TOKEN, + /** A BLOCK-ENTRY token. */ YAML_BLOCK_ENTRY_TOKEN, + /** A FLOW-ENTRY token. */ YAML_FLOW_ENTRY_TOKEN, + /** A KEY token. */ YAML_KEY_TOKEN, + /** A VALUE token. */ YAML_VALUE_TOKEN, + /** An ALIAS token. */ YAML_ALIAS_TOKEN, + /** An ANCHOR token. */ YAML_ANCHOR_TOKEN, + /** A TAG token. */ YAML_TAG_TOKEN, + /** A SCALAR token. */ YAML_SCALAR_TOKEN } yaml_token_type_t; /** The token structure. */ -typedef struct { +typedef struct yaml_token_s { /** The token type. */ yaml_token_type_t type; @@ -285,7 +338,7 @@ typedef struct { /** * Free any memory allocated for a token object. * - * @param[in] token A token object. + * @param[in,out] token A token object. */ YAML_DECLARE(void) @@ -299,27 +352,38 @@ yaml_token_delete(yaml_token_t *token); */ /** Event types. */ -typedef enum { +typedef enum yaml_event_type_e { + /** An empty event. */ YAML_NO_EVENT, + /** A STREAM-START event. */ YAML_STREAM_START_EVENT, + /** A STREAM-END event. */ YAML_STREAM_END_EVENT, + /** A DOCUMENT-START event. */ YAML_DOCUMENT_START_EVENT, + /** A DOCUMENT-END event. */ YAML_DOCUMENT_END_EVENT, + /** An ALIAS event. */ YAML_ALIAS_EVENT, + /** A SCALAR event. */ YAML_SCALAR_EVENT, + /** A SEQUENCE-START event. */ YAML_SEQUENCE_START_EVENT, + /** A SEQUENCE-END event. */ YAML_SEQUENCE_END_EVENT, + /** A MAPPING-START event. */ YAML_MAPPING_START_EVENT, + /** A MAPPING-END event. */ YAML_MAPPING_END_EVENT } yaml_event_type_t; /** The event structure. */ -typedef struct { +typedef struct yaml_event_s { /** The event type. */ yaml_event_type_t type; @@ -406,9 +470,9 @@ typedef struct { } data; - /** The beginning of the token. */ + /** The beginning of the event. */ yaml_mark_t start_mark; - /** The end of the token. */ + /** The end of the event. */ yaml_mark_t end_mark; } yaml_event_t; @@ -416,7 +480,8 @@ typedef struct { /** * Create the STREAM-START event. * - * @param[in] event An empty event object. + * @param[out] event An empty event object. + * @param[in] encoding The stream encoding. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -428,7 +493,7 @@ yaml_stream_start_event_initialize(yaml_event_t *event, /** * Create the STREAM-END event. * - * @param[in] event An empty event object. + * @param[out] event An empty event object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -442,11 +507,15 @@ yaml_stream_end_event_initialize(yaml_event_t *event); * The @a implicit argument is considered as a stylistic parameter and may be * ignored by the emitter. * - * @param[in] event An empty event object. - * @param[in] version_directive The %YAML directive value or @c NULL. - * @param[in] tag_directives_start The beginning of the %TAG directives list. - * @param[in] tag_directives_end The end of the %TAG directives list. - * @param[in] implicit If the document start indicator is implicit. + * @param[out] event An empty event object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] implicit If the document start indicator is + * implicit. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -464,8 +533,8 @@ yaml_document_start_event_initialize(yaml_event_t *event, * The @a implicit argument is considered as a stylistic parameter and may be * ignored by the emitter. * - * @param[in] event An empty event object. - * @param[in] implicit If the document end indicator is implicit. + * @param[out] event An empty event object. + * @param[in] implicit If the document end indicator is implicit. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -476,8 +545,8 @@ yaml_document_end_event_initialize(yaml_event_t *event, int implicit); /** * Create an ALIAS event. * - * @param[in] event An empty event object. - * @param[in] anchor The anchor value. + * @param[out] event An empty event object. + * @param[in] anchor The anchor value. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -493,14 +562,16 @@ yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); * Either the @a tag attribute or one of the @a plain_implicit and * @a quoted_implicit flags must be set. * - * @param[in] event An empty event object. - * @param[in] anchor The scalar anchor or @c NULL. - * @param[in] tag The scalar tag or @c NULL. - * @param[in] value The scalar value. - * @param[in] length The length of the scalar value. - * @param[in] plain_implicit If the tag may be omitted for the plain style. - * @param[in] quoted_implicit If the tag may be omitted for any non-plain style. - * @param[in] style The scalar style. + * @param[out] event An empty event object. + * @param[in] anchor The scalar anchor or @c NULL. + * @param[in] tag The scalar tag or @c NULL. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] plain_implicit If the tag may be omitted for the plain + * style. + * @param[in] quoted_implicit If the tag may be omitted for any + * non-plain style. + * @param[in] style The scalar style. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -508,7 +579,7 @@ yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); YAML_DECLARE(int) yaml_scalar_event_initialize(yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, - yaml_char_t *value, size_t length, + yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style); @@ -519,11 +590,11 @@ yaml_scalar_event_initialize(yaml_event_t *event, * * Either the @a tag attribute or the @a implicit flag must be set. * - * @param[in] event An empty event object. - * @param[in] anchor The sequence anchor or @c NULL. - * @param[in] tag The sequence tag or @c NULL. - * @param[in] implicit If the tag may be omitted. - * @param[in] style The sequence style. + * @param[out] event An empty event object. + * @param[in] anchor The sequence anchor or @c NULL. + * @param[in] tag The sequence tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The sequence style. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -536,7 +607,7 @@ yaml_sequence_start_event_initialize(yaml_event_t *event, /** * Create a SEQUENCE-END event. * - * @param[in] event An empty event object. + * @param[out] event An empty event object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -551,11 +622,11 @@ yaml_sequence_end_event_initialize(yaml_event_t *event); * * Either the @a tag attribute or the @a implicit flag must be set. * - * @param[in] event An empty event object. - * @param[in] anchor The mapping anchor or @c NULL. - * @param[in] tag The mapping tag or @c NULL. - * @param[in] implicit If the tag may be omitted. - * @param[in] style The mapping style. + * @param[out] event An empty event object. + * @param[in] anchor The mapping anchor or @c NULL. + * @param[in] tag The mapping tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The mapping style. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -568,7 +639,7 @@ yaml_mapping_start_event_initialize(yaml_event_t *event, /** * Create a MAPPING-END event. * - * @param[in] event An empty event object. + * @param[out] event An empty event object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -579,7 +650,7 @@ yaml_mapping_end_event_initialize(yaml_event_t *event); /** * Free any memory allocated for an event object. * - * @param[in] event An event object. + * @param[in,out] event An event object. */ YAML_DECLARE(void) @@ -587,6 +658,310 @@ yaml_event_delete(yaml_event_t *event); /** @} */ +/** + * @defgroup nodes Nodes + * @{ + */ + +/** The tag @c !!null with the only possible value: @c null. */ +#define YAML_NULL_TAG "tag:yaml.org,2002:null" +/** The tag @c !!bool with the values: @c true and @c false. */ +#define YAML_BOOL_TAG "tag:yaml.org,2002:bool" +/** The tag @c !!str for string values. */ +#define YAML_STR_TAG "tag:yaml.org,2002:str" +/** The tag @c !!int for integer values. */ +#define YAML_INT_TAG "tag:yaml.org,2002:int" +/** The tag @c !!float for float values. */ +#define YAML_FLOAT_TAG "tag:yaml.org,2002:float" +/** The tag @c !!timestamp for date and time values. */ +#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp" + +/** The tag @c !!seq is used to denote sequences. */ +#define YAML_SEQ_TAG "tag:yaml.org,2002:seq" +/** The tag @c !!map is used to denote mapping. */ +#define YAML_MAP_TAG "tag:yaml.org,2002:map" + +/** The default scalar tag is @c !!str. */ +#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG +/** The default sequence tag is @c !!seq. */ +#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG +/** The default mapping tag is @c !!map. */ +#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG + +/** Node types. */ +typedef enum yaml_node_type_e { + /** An empty node. */ + YAML_NO_NODE, + + /** A scalar node. */ + YAML_SCALAR_NODE, + /** A sequence node. */ + YAML_SEQUENCE_NODE, + /** A mapping node. */ + YAML_MAPPING_NODE +} yaml_node_type_t; + +/** The forward definition of a document node structure. */ +typedef struct yaml_node_s yaml_node_t; + +/** An element of a sequence node. */ +typedef int yaml_node_item_t; + +/** An element of a mapping node. */ +typedef struct yaml_node_pair_s { + /** The key of the element. */ + int key; + /** The value of the element. */ + int value; +} yaml_node_pair_t; + +/** The node structure. */ +struct yaml_node_s { + + /** The node type. */ + yaml_node_type_t type; + + /** The node tag. */ + yaml_char_t *tag; + + /** The node data. */ + union { + + /** The scalar parameters (for @c YAML_SCALAR_NODE). */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */ + struct { + /** The stack of sequence items. */ + struct { + /** The beginning of the stack. */ + yaml_node_item_t *start; + /** The end of the stack. */ + yaml_node_item_t *end; + /** The top of the stack. */ + yaml_node_item_t *top; + } items; + /** The sequence style. */ + yaml_sequence_style_t style; + } sequence; + + /** The mapping parameters (for @c YAML_MAPPING_NODE). */ + struct { + /** The stack of mapping pairs (key, value). */ + struct { + /** The beginning of the stack. */ + yaml_node_pair_t *start; + /** The end of the stack. */ + yaml_node_pair_t *end; + /** The top of the stack. */ + yaml_node_pair_t *top; + } pairs; + /** The mapping style. */ + yaml_mapping_style_t style; + } mapping; + + } data; + + /** The beginning of the node. */ + yaml_mark_t start_mark; + /** The end of the node. */ + yaml_mark_t end_mark; + +}; + +/** The document structure. */ +typedef struct yaml_document_s { + + /** The document nodes. */ + struct { + /** The beginning of the stack. */ + yaml_node_t *start; + /** The end of the stack. */ + yaml_node_t *end; + /** The top of the stack. */ + yaml_node_t *top; + } nodes; + + /** The version directive. */ + yaml_version_directive_t *version_directive; + + /** The list of tag directives. */ + struct { + /** The beginning of the tag directives list. */ + yaml_tag_directive_t *start; + /** The end of the tag directives list. */ + yaml_tag_directive_t *end; + } tag_directives; + + /** Is the document start indicator implicit? */ + int start_implicit; + /** Is the document end indicator implicit? */ + int end_implicit; + + /** The beginning of the document. */ + yaml_mark_t start_mark; + /** The end of the document. */ + yaml_mark_t end_mark; + +} yaml_document_t; + +/** + * Create a YAML document. + * + * @param[out] document An empty document object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] start_implicit If the document start indicator is + * implicit. + * @param[in] end_implicit If the document end indicator is + * implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_initialize(yaml_document_t *document, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int start_implicit, int end_implicit); + +/** + * Delete a YAML document and all its nodes. + * + * @param[in,out] document A document object. + */ + +YAML_DECLARE(void) +yaml_document_delete(yaml_document_t *document); + +/** + * Get a node of a YAML document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * @param[in] document A document object. + * @param[in] index The node id. + * + * @returns the node objct or @c NULL if @c node_id is out of range. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_node(yaml_document_t *document, int index); + +/** + * Get the root of a YAML document node. + * + * The root object is the first object added to the document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * An empty document produced by the parser signifies the end of a YAML + * stream. + * + * @param[in] document A document object. + * + * @returns the node object or @c NULL if the document is empty. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_root_node(yaml_document_t *document); + +/** + * Create a SCALAR node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The scalar tag. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] style The scalar style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_scalar(yaml_document_t *document, + yaml_char_t *tag, yaml_char_t *value, int length, + yaml_scalar_style_t style); + +/** + * Create a SEQUENCE node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_sequence(yaml_document_t *document, + yaml_char_t *tag, yaml_sequence_style_t style); + +/** + * Create a MAPPING node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_mapping(yaml_document_t *document, + yaml_char_t *tag, yaml_mapping_style_t style); + +/** + * Add an item to a SEQUENCE node. + * + * @param[in,out] document A document object. + * @param[in] sequence The sequence node id. + * @param[in] item The item node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_sequence_item(yaml_document_t *document, + int sequence, int item); + +/** + * Add a pair of a key and a value to a MAPPING node. + * + * @param[in,out] document A document object. + * @param[in] mapping The mapping node id. + * @param[in] key The key node id. + * @param[in] value The value node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_mapping_pair(yaml_document_t *document, + int mapping, int key, int value); + +/** @} */ + /** * @defgroup parser Parser Definitions * @{ @@ -599,11 +974,11 @@ yaml_event_delete(yaml_event_t *event); * source. The handler should write not more than @a size bytes to the @a * buffer. The number of written bytes should be set to the @a length variable. * - * @param[in] data A pointer to an application data specified by - * @c yaml_parser_set_read_handler. - * @param[out] buffer The buffer to write the data from the source. - * @param[in] size The size of the buffer. - * @param[out] size_read The actual number of bytes read from the source. + * @param[in,out] data A pointer to an application data specified by + * yaml_parser_set_input(). + * @param[out] buffer The buffer to write the data from the source. + * @param[in] size The size of the buffer. + * @param[out] size_read The actual number of bytes read from the source. * * @returns On success, the handler should return @c 1. If the handler failed, * the returned value should be @c 0. On EOF, the handler should set the @@ -617,7 +992,7 @@ typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, * This structure holds information about a potential simple key. */ -typedef struct { +typedef struct yaml_simple_key_s { /** Is a simple key possible? */ int possible; @@ -634,33 +1009,70 @@ typedef struct { /** * The states of the parser. */ -typedef enum { +typedef enum yaml_parser_state_e { + /** Expect STREAM-START. */ YAML_PARSE_STREAM_START_STATE, + /** Expect the beginning of an implicit document. */ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START. */ YAML_PARSE_DOCUMENT_START_STATE, + /** Expect the content of a document. */ YAML_PARSE_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ YAML_PARSE_DOCUMENT_END_STATE, + /** Expect a block node. */ YAML_PARSE_BLOCK_NODE_STATE, + /** Expect a block node or indentless sequence. */ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, + /** Expect a flow node. */ YAML_PARSE_FLOW_NODE_STATE, + /** Expect the first entry of a block sequence. */ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a block sequence. */ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, + /** Expect an entry of an indentless sequence. */ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, + /** Expect the first key of a block mapping. */ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect a block mapping key. */ YAML_PARSE_BLOCK_MAPPING_KEY_STATE, + /** Expect a block mapping value. */ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, + /** Expect the first entry of a flow sequence. */ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a flow sequence. */ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, + /** Expect a key of an ordered mapping. */ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, + /** Expect a value of an ordered mapping. */ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, + /** Expect the and of an ordered mapping entry. */ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, + /** Expect the first key of a flow mapping. */ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ YAML_PARSE_FLOW_MAPPING_KEY_STATE, + /** Expect a value of a flow mapping. */ YAML_PARSE_FLOW_MAPPING_VALUE_STATE, + /** Expect an empty value of a flow mapping. */ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, + /** Expect nothing. */ YAML_PARSE_END_STATE } yaml_parser_state_t; +/** + * This structure holds aliases data. + */ + +typedef struct yaml_alias_data_s { + /** The anchor. */ + yaml_char_t *anchor; + /** The node id. */ + int index; + /** The anchor mark. */ + yaml_mark_t mark; +} yaml_alias_data_t; + /** * The parser structure. * @@ -668,7 +1080,7 @@ typedef enum { * family of functions. */ -typedef struct { +typedef struct yaml_parser_s { /** * @name Error handling @@ -710,11 +1122,11 @@ typedef struct { /** String input data. */ struct { /** The string start pointer. */ - unsigned char *start; + const unsigned char *start; /** The string end pointer. */ - unsigned char *end; + const unsigned char *end; /** The string current position. */ - unsigned char *current; + const unsigned char *current; } string; /** File input data. */ @@ -868,15 +1280,37 @@ typedef struct { * @} */ + /** + * @name Dumper stuff + * @{ + */ + + /** The alias data. */ + struct { + /** The beginning of the list. */ + yaml_alias_data_t *start; + /** The end of the list. */ + yaml_alias_data_t *end; + /** The top of the list. */ + yaml_alias_data_t *top; + } aliases; + + /** The currently parsed document. */ + yaml_document_t *document; + + /** + * @} + */ + } yaml_parser_t; /** * Initialize a parser. * * This function creates a new parser object. An application is responsible - * for destroying the object using the @c yaml_parser_delete function. + * for destroying the object using the yaml_parser_delete() function. * - * @param[in] parser An empty parser object. + * @param[out] parser An empty parser object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -887,7 +1321,7 @@ yaml_parser_initialize(yaml_parser_t *parser); /** * Destroy a parser. * - * @param[in] parser A parser object. + * @param[in,out] parser A parser object. */ YAML_DECLARE(void) @@ -900,14 +1334,14 @@ yaml_parser_delete(yaml_parser_t *parser); * exists. The application is responsible for destroing @a input after * destroying the @a parser. * - * @param[in] parser A parser object. - * @param[in] input A source data. - * @param[in] size The length of the source data in bytes. + * @param[in,out] parser A parser object. + * @param[in] input A source data. + * @param[in] size The length of the source data in bytes. */ YAML_DECLARE(void) yaml_parser_set_input_string(yaml_parser_t *parser, - unsigned char *input, size_t size); + const unsigned char *input, size_t size); /** * Set a file input. @@ -915,8 +1349,8 @@ yaml_parser_set_input_string(yaml_parser_t *parser, * @a file should be a file object open for reading. The application is * responsible for closing the @a file. * - * @param[in] parser A parser object. - * @param[in] file An open file. + * @param[in,out] parser A parser object. + * @param[in] file An open file. */ YAML_DECLARE(void) @@ -925,9 +1359,10 @@ yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); /** * Set a generic input handler. * - * @param[in] parser A parser object. - * @param[in] handler A read handler. - * @param[in] data Any application data for passing to the read handler. + * @param[in,out] parser A parser object. + * @param[in] handler A read handler. + * @param[in] data Any application data for passing to the read + * handler. */ YAML_DECLARE(void) @@ -937,8 +1372,8 @@ yaml_parser_set_input(yaml_parser_t *parser, /** * Set the source encoding. * - * @param[in] parser A parser object. - * @param[in] encoding The source encoding. + * @param[in,out] parser A parser object. + * @param[in] encoding The source encoding. */ YAML_DECLARE(void) @@ -955,11 +1390,12 @@ yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); * An application is responsible for freeing any buffers associated with the * produced token object using the @c yaml_token_delete function. * - * An application must not alternate the calls of @c yaml_parser_scan with the - * calls of @c yaml_parser_parse. Doing this will break the parser. + * An application must not alternate the calls of yaml_parser_scan() with the + * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break + * the parser. * - * @param[in] parser A parser object. - * @param[in] token An empty token object. + * @param[in,out] parser A parser object. + * @param[out] token An empty token object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -976,13 +1412,14 @@ yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); * @c YAML_STREAM_END_EVENT. * * An application is responsible for freeing any buffers associated with the - * produced event object using the @c yaml_event_delete function. + * produced event object using the yaml_event_delete() function. * - * An application must not alternate the calls of @c yaml_parser_scan with the - * calls of @c yaml_parser_parse. Doing this will break the parser. + * An application must not alternate the calls of yaml_parser_parse() with the + * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the + * parser. * - * @param[in] parser A parser object. - * @param[in] event An empty event object. + * @param[in,out] parser A parser object. + * @param[out] event An empty event object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -990,6 +1427,31 @@ yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); YAML_DECLARE(int) yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); +/** + * Parse the input stream and produce the next YAML document. + * + * Call this function subsequently to produce a sequence of documents + * constituting the input stream. + * + * If the produced document has no root node, it means that the document + * end has been reached. + * + * An application is responsible for freeing any data associated with the + * produced document object using the yaml_document_delete() function. + * + * An application must not alternate the calls of yaml_parser_load() with the + * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break + * the parser. + * + * @param[in,out] parser A parser object. + * @param[out] document An empty document object. + * + * @return @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); + /** @} */ /** @@ -1004,10 +1466,10 @@ yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); * characters to the output. The handler should write @a size bytes of the * @a buffer to the output. * - * @param[in] data A pointer to an application data specified by - * @c yaml_emitter_set_write_handler. - * @param[out] buffer The buffer with bytes to be written. - * @param[in] size The size of the buffer. + * @param[in,out] data A pointer to an application data specified by + * yaml_emitter_set_output(). + * @param[in] buffer The buffer with bytes to be written. + * @param[in] size The size of the buffer. * * @returns On success, the handler should return @c 1. If the handler failed, * the returned value should be @c 0. @@ -1016,27 +1478,57 @@ yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size); /** The emitter states. */ -typedef enum { +typedef enum yaml_emitter_state_e { + /** Expect STREAM-START. */ YAML_EMIT_STREAM_START_STATE, + /** Expect the first DOCUMENT-START or STREAM-END. */ YAML_EMIT_FIRST_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START or STREAM-END. */ YAML_EMIT_DOCUMENT_START_STATE, + /** Expect the content of a document. */ YAML_EMIT_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ YAML_EMIT_DOCUMENT_END_STATE, + /** Expect the first item of a flow sequence. */ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a flow sequence. */ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, + /** Expect the first key of a flow mapping. */ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ YAML_EMIT_FLOW_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a flow mapping. */ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a flow mapping. */ YAML_EMIT_FLOW_MAPPING_VALUE_STATE, + /** Expect the first item of a block sequence. */ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a block sequence. */ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, + /** Expect the first key of a block mapping. */ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect the key of a block mapping. */ YAML_EMIT_BLOCK_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a block mapping. */ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a block mapping. */ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, + /** Expect nothing. */ YAML_EMIT_END_STATE } yaml_emitter_state_t; + +/* This is needed for C++ */ + +typedef struct yaml_anchors_s { + /** The number of references. */ + int references; + /** The anchor id. */ + int anchor; + /** If the node has been emitted? */ + int serialized; +} yaml_anchors_t; + /** * The emitter structure. * @@ -1044,7 +1536,7 @@ typedef enum { * family of functions. */ -typedef struct { +typedef struct yaml_emitter_s { /** * @name Error handling @@ -1202,6 +1694,8 @@ typedef struct { int whitespace; /** If the last character was an indentation character (' ', '-', '?', ':')? */ int indention; + /** If an explicit document end is required? */ + int open_ended; /** Anchor analysis. */ struct { @@ -1249,15 +1743,38 @@ typedef struct { * @} */ + /** + * @name Dumper stuff + * @{ + */ + + /** If the stream was already opened? */ + int opened; + /** If the stream was already closed? */ + int closed; + + /** The information associated with the document nodes. */ + yaml_anchors_t *anchors; + + /** The last assigned anchor id. */ + int last_anchor_id; + + /** The currently emitted document. */ + yaml_document_t *document; + + /** + * @} + */ + } yaml_emitter_t; /** * Initialize an emitter. * * This function creates a new emitter object. An application is responsible - * for destroying the object using the @c yaml_emitter_delete function. + * for destroying the object using the yaml_emitter_delete() function. * - * @param[in] emitter An empty parser object. + * @param[out] emitter An empty parser object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -1268,7 +1785,7 @@ yaml_emitter_initialize(yaml_emitter_t *emitter); /** * Destroy an emitter. * - * @param[in] emitter An emitter object. + * @param[in,out] emitter An emitter object. */ YAML_DECLARE(void) @@ -1282,10 +1799,11 @@ yaml_emitter_delete(yaml_emitter_t *emitter); * bytes. If the buffer is smaller than required, the emitter produces the * YAML_WRITE_ERROR error. * - * @param[in] emitter An emitter object. - * @param[in] output An output buffer. - * @param[in] size The buffer size. - * @param[in] size_written The pointer to save the number of written bytes. + * @param[in,out] emitter An emitter object. + * @param[in] output An output buffer. + * @param[in] size The buffer size. + * @param[in] size_written The pointer to save the number of written + * bytes. */ YAML_DECLARE(void) @@ -1298,8 +1816,8 @@ yaml_emitter_set_output_string(yaml_emitter_t *emitter, * @a file should be a file object open for writing. The application is * responsible for closing the @a file. * - * @param[in] emitter An emitter object. - * @param[in] file An open file. + * @param[in,out] emitter An emitter object. + * @param[in] file An open file. */ YAML_DECLARE(void) @@ -1308,9 +1826,10 @@ yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file); /** * Set a generic output handler. * - * @param[in] emitter An emitter object. - * @param[in] handler A write handler. - * @param[in] data Any application data for passing to the write handler. + * @param[in,out] emitter An emitter object. + * @param[in] handler A write handler. + * @param[in] data Any application data for passing to the write + * handler. */ YAML_DECLARE(void) @@ -1320,8 +1839,8 @@ yaml_emitter_set_output(yaml_emitter_t *emitter, /** * Set the output encoding. * - * @param[in] emitter An emitter object. - * @param[in] encoding The output encoding. + * @param[in,out] emitter An emitter object. + * @param[in] encoding The output encoding. */ YAML_DECLARE(void) @@ -1331,8 +1850,8 @@ yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding); * Set if the output should be in the "canonical" format as in the YAML * specification. * - * @param[in] emitter An emitter object. - * @param[in] canonical If the output is canonical. + * @param[in,out] emitter An emitter object. + * @param[in] canonical If the output is canonical. */ YAML_DECLARE(void) @@ -1341,8 +1860,8 @@ yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical); /** * Set the intendation increment. * - * @param[in] emitter An emitter object. - * @param[in] indent The indentation increment (1 < . < 10). + * @param[in,out] emitter An emitter object. + * @param[in] indent The indentation increment (1 < . < 10). */ YAML_DECLARE(void) @@ -1351,8 +1870,8 @@ yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent); /** * Set the preferred line width. @c -1 means unlimited. * - * @param[in] emitter An emitter object. - * @param[in] width The preferred line width. + * @param[in,out] emitter An emitter object. + * @param[in] width The preferred line width. */ YAML_DECLARE(void) @@ -1361,8 +1880,8 @@ yaml_emitter_set_width(yaml_emitter_t *emitter, int width); /** * Set if unescaped non-ASCII characters are allowed. * - * @param[in] emitter An emitter object. - * @param[in] unicode If unescaped Unicode characters are allowed. + * @param[in,out] emitter An emitter object. + * @param[in] unicode If unescaped Unicode characters are allowed. */ YAML_DECLARE(void) @@ -1371,8 +1890,8 @@ yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode); /** * Set the preferred line break. * - * @param[in] emitter An emitter object. - * @param[in] line_break The preferred line break. + * @param[in,out] emitter An emitter object. + * @param[in] line_break The preferred line break. */ YAML_DECLARE(void) @@ -1381,13 +1900,13 @@ yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); /** * Emit an event. * - * The event object may be generated using the @c yaml_parser_parse function. + * The event object may be generated using the yaml_parser_parse() function. * The emitter takes the responsibility for the event object and destroys its * content after it is emitted. The event object is destroyed even if the * function fails. * - * @param[in] emitter An emitter object. - * @param[in] event An event object. + * @param[in,out] emitter An emitter object. + * @param[in,out] event An event object. * * @returns @c 1 if the function succeeded, @c 0 on error. */ @@ -1395,10 +1914,53 @@ yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); YAML_DECLARE(int) yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); +/** + * Start a YAML stream. + * + * This function should be used before yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter); + +/** + * Finish a YAML stream. + * + * This function should be used after yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter); + +/** + * Emit a YAML document. + * + * The documen object may be generated using the yaml_parser_load() function + * or the yaml_document_initialize() function. The emitter takes the + * responsibility for the document object and destroys its content after + * it is emitted. The document object is destroyed even if the function fails. + * + * @param[in,out] emitter An emitter object. + * @param[in,out] document A document object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); + /** * Flush the accumulated characters to the output. * - * @param[in] emitter An emitter object. + * @param[in,out] emitter An emitter object. * * @returns @c 1 if the function succeeded, @c 0 on error. */