Skip to content
Snippets Groups Projects
Commit 747036491060 authored by Kirill Simonov's avatar Kirill Simonov
Browse files

Minor API updates.

parent 67f0051717c9
No related branches found
No related tags found
No related merge requests found
......@@ -7,5 +7,5 @@
* the terms of the MIT license; see the file LICENCE for more details.
*****************************************************************************/
/*
/*****************************************************************************
* General guidelines.
......@@ -11,10 +11,32 @@
* General guidelines.
*
* Naming conventions: all functions exported by LibYAML starts with the `yaml_` prefix;
* types starts with `yaml_` and ends with `_t`; macros and enumerations starts
* with `YAML_`.
*****************************************************************************/
/*
* Basic conventions.
*
* All functions exported by exported by LibYAML starts with the the prefix
* `yaml_`; types starts with `yaml_` and ends with `_t`; macros and
* enumeration values start with `YAML_`.
*
* A function may serve as method for an object or a particular type; such
* functions start with `yaml_<type>`. A type constructor is named
* `yaml_<type>_new()`, a type destructor is named `yaml_<type>_delete()`.
*
* A function signifies whether it succeeded or failed with its return value;
* typically it is `1` for success, `0` for failure. Functions that return a
* pointer may indicate an error condition by returning `NULL`. Functions that
* never fail commonly do not return any value. For most of the functions, an
* error value means that the function is unable to allocate some memory
* buffer. For parsing and emitting functions, detailed information on the
* nature of the error could be obtained.
*
* LibYAML provides two active objects: parsers and emitters and three passive
* objects: tokens, events and documents.
*
*
*
*
* FIXME: Calling conventions.
* FIXME: Memory allocation.
* FIXME: Errors and exceptions.
* FIXME: And so on, and so forth.
......@@ -16,8 +38,12 @@
*
* FIXME: Calling conventions.
* FIXME: Memory allocation.
* FIXME: Errors and exceptions.
* FIXME: And so on, and so forth.
*
*
*
*
*/
......@@ -269,5 +295,5 @@
YAML_DECLARE(int)
yaml_error_message(yaml_error_t *error, char *buffer, size_t capacity);
/******************************************************************************
/*****************************************************************************
* Basic Types
......@@ -273,5 +299,5 @@
* Basic Types
******************************************************************************/
*****************************************************************************/
/*
* The character type (UTF-8 octet).
......@@ -347,5 +373,5 @@
YAML_CRLN_BREAK
} yaml_break_t;
/******************************************************************************
/*****************************************************************************
* Node Styles
......@@ -351,5 +377,5 @@
* Node Styles
******************************************************************************/
*****************************************************************************/
/*
* Scalar styles.
......@@ -402,5 +428,5 @@
YAML_ANY_SEQUENCE_STYLE,
/* The flow sequence style. */
YAML_FLOW_SEQUENCE_STYLE
YAML_FLOW_SEQUENCE_STYLE,
/* The block sequence style. */
......@@ -406,5 +432,5 @@
/* The block sequence style. */
YAML_BLOCK_SEQUENCE_STYLE,
YAML_BLOCK_SEQUENCE_STYLE
} yaml_sequence_style_t;
/*
......@@ -430,5 +456,5 @@
YAML_FLOW_MAPPING_STYLE
} yaml_mapping_style_t;
/******************************************************************************
/*****************************************************************************
* Tokens
......@@ -434,5 +460,5 @@
* Tokens
******************************************************************************/
*****************************************************************************/
/*
* Token types.
......@@ -680,5 +706,5 @@
YAML_DECLARE(void)
yaml_token_clear(yaml_token_t *token);
/******************************************************************************
/*****************************************************************************
* Events
......@@ -684,5 +710,5 @@
* Events
******************************************************************************/
*****************************************************************************/
/*
* Event types.
......@@ -1220,5 +1246,5 @@
YAML_DECLARE(int)
yaml_event_create_mapping_end(yaml_event_t *event);
/******************************************************************************
/*****************************************************************************
* Documents and Nodes
......@@ -1224,5 +1250,5 @@
* Documents and Nodes
******************************************************************************/
*****************************************************************************/
/*
* Well-known scalar tags.
......@@ -1260,7 +1286,7 @@
typedef enum yaml_document_type_e {
/* An empty uninitialized document. */
YAML_NO_DOCUMENT.
YAML_NO_DOCUMENT,
/* A YAML document. */
YAML_DOCUMENT
......@@ -1382,7 +1408,7 @@
* node object is destroyed when the document containing it is destroyed.
*/
struct yaml_node_s {
typedef struct yaml_node_s {
/* The node type. */
yaml_node_type_t type;
......@@ -1442,7 +1468,7 @@
/* The end of the node. */
yaml_mark_t end_mark;
};
} yaml_node_t;
/*
* The incomplete node object.
......@@ -1818,6 +1844,62 @@
yaml_mapping_style_t style);
/*
* Add an item to a SEQUENCE node.
*
* The order in which items are added to a sequence coincides with the order
* they are emitted into the output stream.
*
* Arguments:
*
* - `document`: a document object.
*
* - `sequence_id`: the id of a sequence node; could be negative. It is a
* fatal error if `sequence_id` does not refer to an existing sequence node.
*
* - `item_id`: the id of an item node; could be negative. It is a fatal error
* if `item_id` does not refer to an existing node. Note that it is possible
* for `item_id` to coincide with `sequence_id`, which means that the
* sequence recursively contains itself.
*
* Returns: `1` on success, `0` on error. The function may fail if it cannot
* allocate memory for internal buffers.
*/
YAML_DECLARE(int)
yaml_document_append_sequence_item(yaml_document_t *document,
int sequence_id, int item_id);
/*
* Add a pair of a key and a value to a MAPPING node.
*
* The order in which (key, value) pairs are added to a mapping coincides with
* the order in which they are presented in the output stream. Note that the
* mapping key order is a presentation detail and should not used to convey any
* information. An ordered mapping could be represented as a sequence of
* single-paired mappings.
*
* Arguments:
*
* - `document`: a document object.
*
* - `mapping_id`: the id of a mapping node; could be negative. It is a
* fatal error if `mapping_id` does not refer to an existing mapping node.
*
* - `key_id`: the id of a key node; could be negative. It is a fatal error
* if `key_id` does not refer to an existing node.
*
* - `value_id`: the id of a value node; could be negative. It is a fatal
* error if `value_id` does not refer to an existing node.
*
* Returns: `1` on success, `0` on error. The function may fail if it cannot
* allocate memory for internal buffers.
*/
YAML_DECLARE(int)
yaml_document_append_mapping_pair(yaml_document_t *document,
int mapping_id, int key_id, int value_id);
/*
* Get the value of a `!!null` SCALAR node.
*
* Use this function to ensure that the given node is a scalar, the node tag is
......@@ -1893,7 +1975,7 @@
* `tag:yaml.org,2002:int` and the node value is a valid integer. In this
* case, the function parses the node value and returns an integer number. The
* function recognizes decimal, hexdecimal and octal numbers including negative
* numbers.
* numbers. The function uses `strtol()` for string-to-integer conversion.
*
* Arguments:
*
......@@ -1910,7 +1992,7 @@
YAML_DECLARE(int)
yaml_document_get_int_node(yaml_document_t *document, int node_id,
int *value);
long *value);
/*
* Get the value of a `!!float` SCALAR node.
......@@ -1919,7 +2001,9 @@
* `tag:yaml.org,2002:float` and the node value is a valid float value. In
* this case, the function parses the node value and returns a float number.
* The function recognizes float values in exponential and fixed notation as
* well as special values `.nan`, `.inf` and `-.inf`.
* well as special values `.nan`, `.inf` and `-.inf`. The function uses
* `strtod()` for string-to-float conversion. The `.nan`, `.inf` and `-.inf`
* values are generated as `0.0/0.0`, `1.0/0.0` and `-1.0/0.0` respectively.
*
* Arguments:
*
......@@ -2094,7 +2178,7 @@
YAML_DECLARE(int)
yaml_document_add_int_node(yaml_document_t *document, int *node_id,
int value);
long value);
/*
* Add a `!!float` SCALAR node to the document.
......@@ -2166,61 +2250,5 @@
YAML_DECLARE(int)
yaml_document_add_map_node(yaml_document_t *document, int *node_id);
/*
* Add an item to a SEQUENCE node.
*
* The order in which items are added to a sequence coincides with the order
* they are emitted into the output stream.
*
* Arguments:
*
* - `document`: a document object.
*
* - `sequence_id`: the id of a sequence node; could be negative. It is a
* fatal error if `sequence_id` does not refer to an existing sequence node.
*
* - `item_id`: the id of an item node; could be negative. It is a fatal error
* if `item_id` does not refer to an existing node. Note that it is possible
* for `item_id` to coincide with `sequence_id`, which means that the
* sequence recursively contains itself.
*
* Returns: `1` on success, `0` on error. The function may fail if it cannot
* allocate memory for internal buffers.
*/
YAML_DECLARE(int)
yaml_document_append_sequence_item(yaml_document_t *document,
int sequence_id, int item_id);
/*
* Add a pair of a key and a value to a MAPPING node.
*
* The order in which (key, value) pairs are added to a mapping coincides with
* the order in which they are presented in the output stream. Note that the
* mapping key order is a presentation detail and should not used to convey any
* information. An ordered mapping could be represented as a sequence of
* single-paired mappings.
*
* Arguments:
*
* - `document`: a document object.
*
* - `mapping_id`: the id of a mapping node; could be negative. It is a
* fatal error if `mapping_id` does not refer to an existing mapping node.
*
* - `key_id`: the id of a key node; could be negative. It is a fatal error
* if `key_id` does not refer to an existing node.
*
* - `value_id`: the id of a value node; could be negative. It is a fatal
* error if `value_id` does not refer to an existing node.
*
* Returns: `1` on success, `0` on error. The function may fail if it cannot
* allocate memory for internal buffers.
*/
YAML_DECLARE(int)
yaml_document_append_mapping_pair(yaml_document_t *document,
int mapping_id, int key_id, int value_id);
/******************************************************************************
/*****************************************************************************
* Callback Definitions
......@@ -2226,5 +2254,5 @@
* Callback Definitions
******************************************************************************/
*****************************************************************************/
/*
* The prototype of a read handler.
......@@ -2305,7 +2333,7 @@
*/
typedef int yaml_resolver_t(void *data, yaml_incomplete_node_t *node,
yaml_char_t **tag);
/******************************************************************************
const yaml_char_t **tag);
/*****************************************************************************
* Parser Definitions
......@@ -2311,5 +2339,5 @@
* Parser Definitions
******************************************************************************/
*****************************************************************************/
/*
* An opaque definition of the parser object.
......@@ -2359,7 +2387,7 @@
*/
YAML_DECLARE(void)
yaml_parser_clear(yaml_parser_t *parser);
yaml_parser_reset(yaml_parser_t *parser);
/*
* Get the parser error.
......@@ -2617,5 +2645,5 @@
yaml_parser_parse_single_document(yaml_parser_t *parser,
yaml_document_t *document);
/******************************************************************************
/*****************************************************************************
* Emitter Definitions
......@@ -2621,5 +2649,5 @@
* Emitter Definitions
******************************************************************************/
*****************************************************************************/
/*
* An opaque definition of the emitter object.
......@@ -2669,7 +2697,7 @@
*/
YAML_DECLARE(void)
yaml_emitter_clear(yaml_emitter_t *emitter);
yaml_emitter_reset(yaml_emitter_t *emitter);
/*
* Get the emitter error.
......
This diff is collapsed.
......@@ -183,6 +183,9 @@
*/
static int
yaml_emitter_valid_utf8(yaml_emitter_t *emitter, yaml_istring_t string);
static int
yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
yaml_version_directive_t version_directive);
......@@ -1148,6 +1151,6 @@
yaml_scalar_style_t style = event->data.scalar.style;
int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
if (no_tag && !event->data.scalar.is_plain_implicit
&& !event->data.scalar.is_quoted_implicit) {
if (no_tag && !event->data.scalar.is_plain_nonspecific
&& !event->data.scalar.is_quoted_nonspecific) {
return EMITTER_ERROR_INIT(emitter,
......@@ -1153,5 +1156,5 @@
return EMITTER_ERROR_INIT(emitter,
"neither tag nor implicit flags are specified");
"neither tag nor nonspecific flags are specified");
}
if (style == YAML_ANY_SCALAR_STYLE)
......@@ -1171,7 +1174,7 @@
if (!emitter->scalar_data.length
&& (emitter->flow_level || emitter->is_simple_key_context))
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
if (no_tag && !event->data.scalar.is_plain_implicit)
if (no_tag && !event->data.scalar.is_plain_nonspecific)
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
}
......@@ -1188,7 +1191,7 @@
style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
}
if (no_tag && !event->data.scalar.is_quoted_implicit
if (no_tag && !event->data.scalar.is_quoted_nonspecific
&& style != YAML_PLAIN_SCALAR_STYLE)
{
emitter->tag_data.handle = (yaml_char_t *)"!";
......@@ -1308,6 +1311,50 @@
}
/*
* Verify that a string is a valid UTF-8 sequence.
*
* Check 'reader.c' for more details on UTF-8 encoding.
*/
static int
yaml_emitter_valid_utf8(yaml_emitter_t *emitter, yaml_istring_t string)
{
while (string.pointer < string.length)
{
unsigned char octet;
unsigned int width;
unsigned int value;
size_t idx;
octet = OCTET(string);
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
value = (octet & 0x80) == 0x00 ? octet & 0x7F :
(octet & 0xE0) == 0xC0 ? octet & 0x1F :
(octet & 0xF0) == 0xE0 ? octet & 0x0F :
(octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
if (!width) return 0;
if (string.pointer+width > string.length) return 0;
for (idx = 1; idx < width; idx ++) {
octet = OCTET_AT(string, idx);
if ((octet & 0xC0) != 0x80) return 0;
value = (value << 6) + (octet & 0x3F);
}
if (!((width == 1) ||
(width == 2 && value >= 0x80) ||
(width == 3 && value >= 0x800) ||
(width == 4 && value >= 0x10000))) return 0;
string.pointer += width;
}
return 1;
}
/*
* Check if a %TAG directive is valid.
*/
......@@ -1320,6 +1367,16 @@
yaml_istring_t prefix = ISTRING(tag_directive.prefix,
strlen((char *)tag_directive.prefix));
if (!yaml_emitter_valid_utf8(emitter, handle)) {
return EMITTER_ERROR_INIT(emitter,
"tag handle is not a valid UTF-8 string");
}
if (!yaml_emitter_valid_utf8(emitter, prefix)) {
return EMITTER_ERROR_INIT(emitter,
"tag prefix is not a valid UTF-8 string");
}
if (!handle.length) {
return EMITTER_ERROR_INIT(emitter, "tag handle must not be empty");
}
......@@ -1359,6 +1416,12 @@
{
yaml_istring_t string = ISTRING(anchor, strlen((char *)anchor));
if (!yaml_emitter_valid_utf8(emitter, string)) {
return EMITTER_ERROR_INIT(emitter, is_alias ?
"alias value is not a valid UTF-8 string" :
"anchor value is not a valid UTF-8 string");
}
if (!string.length) {
return EMITTER_ERROR_INIT(emitter, is_alias ?
"alias value must not be empty" :
......@@ -1392,6 +1455,11 @@
yaml_istring_t string = ISTRING(tag, strlen((char *)tag));
size_t idx;
if (!yaml_emitter_valid_utf8(emitter, string)) {
return EMITTER_ERROR_INIT(emitter,
"tag value is not a valid UTF-8 string");
}
if (!string.length) {
return EMITTER_ERROR_INIT(emitter, "tag value must not be empty");
}
......@@ -1450,6 +1518,11 @@
int mixed = 0;
int leading = 0;
if (!yaml_emitter_valid_utf8(emitter, string)) {
return EMITTER_ERROR_INIT(emitter,
"scalar value is not a valid UTF-8 string");
}
emitter->scalar_data.value = value;
emitter->scalar_data.length = length;
......@@ -1689,8 +1762,8 @@
return 0;
}
if (event->data.scalar.tag && (emitter->is_canonical ||
(!event->data.scalar.is_plain_implicit
&& !event->data.scalar.is_quoted_implicit))) {
(!event->data.scalar.is_plain_nonspecific
&& !event->data.scalar.is_quoted_nonspecific))) {
if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
return 0;
}
......@@ -1706,7 +1779,7 @@
return 0;
}
if (event->data.sequence_start.tag && (emitter->is_canonical ||
!event->data.sequence_start.is_implicit)) {
!event->data.sequence_start.is_nonspecific)) {
if (!yaml_emitter_analyze_tag(emitter,
event->data.sequence_start.tag))
return 0;
......@@ -1720,7 +1793,7 @@
return 0;
}
if (event->data.mapping_start.tag && (emitter->is_canonical ||
!event->data.mapping_start.is_implicit)) {
!event->data.mapping_start.is_nonspecific)) {
if (!yaml_emitter_analyze_tag(emitter,
event->data.mapping_start.tag))
return 0;
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment