summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-07-21 13:50:32 +0000
committerxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-07-21 13:50:32 +0000
commit5622ba37906eb127d93c166131d2df3a1f6f39d8 (patch)
tree5631d3505c5aae1735c6c49cc22e0f228bf13a8c
parentcfa84b17c967e07717b2e2bc688582e823dcd1cc (diff)
downloadlibyaml-5622ba37906eb127d93c166131d2df3a1f6f39d8.tar.gz
Refactor internal and external API.
git-svn-id: http://svn.pyyaml.org/libyaml/trunk@208 18f92427-320e-0410-9341-c67f048884a3
-rw-r--r--include/yaml.h710
-rw-r--r--src/api.c648
-rw-r--r--src/parser.c1202
-rw-r--r--src/reader.c205
-rw-r--r--src/scanner.c1654
-rw-r--r--src/yaml_private.h205
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/run-parser.c46
-rw-r--r--tests/run-scanner.c46
-rw-r--r--tests/test-reader.c114
-rw-r--r--tests/test-version.c5
11 files changed, 2018 insertions, 2819 deletions
diff --git a/include/yaml.h b/include/yaml.h
index f195bf4..ab1cf6a 100644
--- a/include/yaml.h
+++ b/include/yaml.h
@@ -147,7 +147,6 @@ typedef enum {
YAML_FOLDED_SCALAR_STYLE
} yaml_scalar_style_t;
-
/** Sequence styles. */
typedef enum {
YAML_ANY_SEQUENCE_STYLE,
@@ -161,7 +160,8 @@ typedef enum {
YAML_ANY_MAPPING_STYLE,
YAML_BLOCK_MAPPING_STYLE,
- YAML_FLOW_MAPPING_STYLE
+ YAML_FLOW_MAPPING_STYLE,
+ YAML_FLOW_SET_MAPPING_STYLE
} yaml_mapping_style_t;
/** @} */
@@ -173,6 +173,8 @@ typedef enum {
/** Token types. */
typedef enum {
+ YAML_NO_TOKEN,
+
YAML_STREAM_START_TOKEN,
YAML_STREAM_END_TOKEN,
@@ -232,20 +234,16 @@ typedef struct {
struct {
/** The tag handle. */
yaml_char_t *handle;
-
/** The tag suffix. */
yaml_char_t *suffix;
} tag;
/** The scalar value (for @c YAML_SCALAR_TOKEN). */
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;
@@ -254,7 +252,6 @@ typedef struct {
struct {
/** The major version number. */
int major;
-
/** The minor version number. */
int minor;
} version_directive;
@@ -263,181 +260,21 @@ typedef struct {
struct {
/** The tag handle. */
yaml_char_t *handle;
-
/** The tag prefix. */
yaml_char_t *prefix;
} tag_directive;
+
} data;
/** The beginning of the token. */
yaml_mark_t start_mark;
-
/** The end of the token. */
yaml_mark_t end_mark;
} yaml_token_t;
/**
- * Create a new token without assigning any data.
- *
- * This function can be used for constructing indicator tokens:
- * @c YAML_DOCUMENT_START, @c YAML_DOCUMENT_END,
- * @c YAML_BLOCK_SEQUENCE_START_TOKEN, @c YAML_BLOCK_MAPPING_START_TOKEN,
- * @c YAML_BLOCK_END_TOKEN,
- * @c YAML_FLOW_SEQUENCE_START_TOKEN, @c YAML_FLOW_SEQUENCE_END_TOKEN,
- * @c YAML_FLOW_MAPPING_START_TOKEN, @c YAML_FLOW_MAPPING_END_TOKEN,
- * @c YAML_BLOCK_ENTRY_TOKEN, @c YAML_FLOW_ENTRY_TOKEN,
- * @c YAML_KEY_TOKEN, @c YAML_VALUE_TOKEN.
- *
- * @param[in] type The token type.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_token_new(yaml_token_type_t type,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_STREAM_START_TOKEN token with the specified encoding.
- *
- * @param[in] encoding The stream encoding.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_stream_start_token_new(yaml_encoding_t encoding,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_STREAM_END_TOKEN token.
- *
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_VERSION_DIRECTIVE_TOKEN token with the specified
- * version numbers.
- *
- * @param[in] major The major version number.
- * @param[in] minor The minor version number.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_version_directive_token_new(int major, int minor,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_TAG_DIRECTIVE_TOKEN token with the specified tag
- * handle and prefix.
- *
- * Note that the @a handle and the @a prefix pointers will be freed by
- * the token descructor.
- *
- * @param[in] handle The tag handle.
- * @param[in] prefix The tag prefix.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_tag_directive_token_new(yaml_char_t *handle, yaml_char_t *prefix,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_ALIAS_TOKEN token with the specified anchor.
- *
- * Note that the @a anchor pointer will be freed by the token descructor.
- *
- * @param[in] anchor The anchor.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_alias_token_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_ANCHOR_TOKEN token with the specified anchor.
- *
- * Note that the @a anchor pointer will be freed by the token descructor.
- *
- * @param[in] anchor The anchor.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_anchor_token_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_TAG_TOKEN token with the specified tag handle and
- * suffix.
- *
- * Note that the @a handle and the @a suffix pointers will be freed by
- * the token descructor.
- *
- * @param[in] handle The tag handle.
- * @param[in] suffix The tag suffix.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_tag_token_new(yaml_char_t *handle, yaml_char_t *suffix,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_SCALAR_TOKEN token with the specified scalar value,
- * length, and style.
- *
- * Note that the scalar value may contain the @c NUL character, therefore
- * the value length is also required. The scalar value always ends with
- * @c NUL.
- *
- * Note that the @a value pointer will be freed by the token descructor.
- *
- * @param[in] value The scalar value.
- * @param[in] length The value length.
- * @param[in] style The scalar style.
- * @param[in] start_mark The beginning of the token.
- * @param[in] end_mark The end of the token.
- *
- * @returns A new token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_scalar_token_new(yaml_char_t *value, size_t length,
- yaml_scalar_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Destroy a token object.
+ * Free any memory allocated for a token object.
*
* @param[in] token A token object.
*/
@@ -454,6 +291,8 @@ yaml_token_delete(yaml_token_t *token);
/** Event types. */
typedef enum {
+ YAML_NO_EVENT,
+
YAML_STREAM_START_EVENT,
YAML_STREAM_END_EVENT,
@@ -489,8 +328,15 @@ typedef struct {
struct {
/** The version directive. */
yaml_version_directive_t *version_directive;
+
/** The list of tag directives. */
- yaml_tag_directive_t **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 indicator implicit? */
int implicit;
} document_start;
@@ -553,167 +399,13 @@ typedef struct {
/** The beginning of the token. */
yaml_mark_t start_mark;
-
/** The end of the token. */
yaml_mark_t end_mark;
-} yaml_event_t;
-
-/**
- * Create a new @c YAML_STREAM_START_EVENT event.
- *
- * @param[in] encoding The stream encoding.
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_stream_start_event_new(yaml_encoding_t encoding,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_STREAM_END_TOKEN event.
- *
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_DOCUMENT_START_EVENT event.
- *
- * @param[in] version_directive The version directive or @c NULL.
- * @param[in] tag_directives A list of tag directives or @c NULL.
- * @param[in] implicit Is the document indicator present?
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_document_start_event_new(yaml_version_directive_t *version_directive,
- yaml_tag_directive_t **tag_directives, int implicit,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_DOCUMENT_END_EVENT event.
- *
- * @param[in] implicit Is the document end indicator present?
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_document_end_event_new(int implicit,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_ALIAS_EVENT event.
- *
- * @param[in] anchor The anchor value.
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_alias_event_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_SCALAR_EVENT event.
- *
- * @param[in] anchor The anchor value or @c NULL.
- * @param[in] tag The tag value or @c NULL.
- * @param[in] value The scalar value.
- * @param[in] length The length of the scalar value.
- * @param[in] plain_implicit Is the tag optional for the plain style?
- * @param[in] quoted_implicit Is the tag optional for any non-plain style?
- * @param[in] style The scalar style.
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- yaml_char_t *value, size_t length,
- int plain_implicit, int quoted_implicit,
- yaml_scalar_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_SEQUENCE_START_EVENT event.
- *
- * @param[in] anchor The anchor value or @c NULL.
- * @param[in] tag The tag value or @c NULL.
- * @param[in] implicit Is the tag optional?
- * @param[in] style The sequence style.
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_sequence_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- int implicit, yaml_sequence_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_SEQUENCE_END_EVENT event.
- *
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-YAML_DECLARE(yaml_event_t *)
-yaml_sequence_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_MAPPING_START_EVENT event.
- *
- * @param[in] anchor The anchor value or @c NULL.
- * @param[in] tag The tag value or @c NULL.
- * @param[in] implicit Is the tag optional?
- * @param[in] style The mapping style.
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_mapping_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- int implicit, yaml_mapping_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark);
-
-/**
- * Create a new @c YAML_MAPPING_END_EVENT event.
- *
- * @param[in] start_mark The beginning of the event.
- * @param[in] end_mark The end of the event.
- *
- * @returns A new event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark);
+} yaml_event_t;
/**
- * Destroy an event object.
+ * Free any memory allocated for an event object.
*
* @param[in] event An event object.
*/
@@ -750,41 +442,19 @@ typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size,
size_t *size_read);
/**
- * This structure holds a string input specified by
- * @c yaml_parser_set_input_string.
- */
-
-typedef struct {
- /** The string start pointer. */
- unsigned char *start;
-
- /** The string end pointer. */
- unsigned char *end;
-
- /** The string current position. */
- unsigned char *current;
-} yaml_string_input_t;
-
-/**
* This structure holds information about a potential simple key.
*/
typedef struct {
+ /** Is a simple key possible? */
+ int possible;
+
/** Is a simple key required? */
int required;
/** The number of the token. */
size_t token_number;
- /** The position index. */
- size_t index;
-
- /** The position line. */
- size_t line;
-
- /** The position column. */
- size_t column;
-
/** The position mark. */
yaml_mark_t mark;
} yaml_simple_key_t;
@@ -793,7 +463,6 @@ typedef struct {
* The states of the parser.
*/
typedef enum {
- YAML_PARSE_END_STATE,
YAML_PARSE_STREAM_START_STATE,
YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
YAML_PARSE_DOCUMENT_START_STATE,
@@ -816,7 +485,8 @@ typedef enum {
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
YAML_PARSE_FLOW_MAPPING_KEY_STATE,
YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
- YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE,
+ YAML_PARSE_END_STATE
} yaml_parser_state_t;
/**
@@ -835,22 +505,16 @@ typedef struct {
/** Error type. */
yaml_error_type_t error;
-
/** Error description. */
const char *problem;
-
/** The byte about which the problem occured. */
size_t problem_offset;
-
/** The problematic value (@c -1 is none). */
int problem_value;
-
/** The problem position. */
yaml_mark_t problem_mark;
-
/** The error context. */
const char *context;
-
/** The context position. */
yaml_mark_t context_mark;
@@ -869,29 +533,51 @@ typedef struct {
/** A pointer for passing to the read handler. */
void *read_handler_data;
+ /** Standard (string or file) input data. */
+ union {
+ /** String input data. */
+ struct {
+ /** The string start pointer. */
+ unsigned char *start;
+ /** The string end pointer. */
+ unsigned char *end;
+ /** The string current position. */
+ unsigned char *current;
+ } string;
+
+ /** File input data. */
+ FILE *file;
+ } input;
+
/** EOF flag */
int eof;
- /** The pointer to the beginning of the working buffer. */
- yaml_char_t *buffer;
-
- /** The pointer to the end of the working buffer. */
- yaml_char_t *buffer_end;
-
- /** The pointer to the current character in the working buffer. */
- yaml_char_t *pointer;
-
- /** The number of unread characters in the working buffer. */
+ /** The working buffer. */
+ struct {
+ /* The beginning of the buffer. */
+ yaml_char_t *start;
+ /* The end of the buffer. */
+ yaml_char_t *end;
+ /* The current position of the buffer. */
+ yaml_char_t *pointer;
+ /* The last filled position of the buffer. */
+ yaml_char_t *last;
+ } buffer;
+
+ /* The number of unread characters in the buffer. */
size_t unread;
- /** The pointer to the beginning of the raw buffer. */
- unsigned char *raw_buffer;
-
- /** The pointer to the current character in the raw buffer. */
- unsigned char *raw_pointer;
-
- /** The number of unread bytes in the raw buffer. */
- size_t raw_unread;
+ /** The raw buffer. */
+ struct {
+ /** The beginning of the buffer. */
+ unsigned char *start;
+ /** The end of the buffer. */
+ unsigned char *end;
+ /** The current position of the buffer. */
+ unsigned char *pointer;
+ /** The last filled position of the buffer. */
+ unsigned char *last;
+ } raw_buffer;
/** The input encoding. */
yaml_encoding_t encoding;
@@ -899,17 +585,8 @@ typedef struct {
/** The offset of the current position (in bytes). */
size_t offset;
- /** The index of the current position (in characters). */
- size_t index;
-
- /** The line of the current position (starting from @c 0). */
- size_t line;
-
- /** The column of the current position (starting from @c 0). */
- size_t column;
-
- /* String input structure. */
- yaml_string_input_t string_input;
+ /** The mark of the current position. */
+ yaml_mark_t mark;
/**
* @}
@@ -929,29 +606,33 @@ typedef struct {
/** The number of unclosed '[' and '{' indicators. */
int flow_level;
- /** The tokens queue, which contains the current produced tokens. */
- yaml_token_t **tokens;
-
- /** The size of the tokens queue. */
- size_t tokens_size;
-
- /** The head of the tokens queue. */
- size_t tokens_head;
-
- /** The tail of the tokens queue. */
- size_t tokens_tail;
-
- /** The number of tokens fetched from the tokens queue. */
+ /** The tokens queue. */
+ struct {
+ /** The beginning of the tokens queue. */
+ yaml_token_t *start;
+ /** The end of the tokens queue. */
+ yaml_token_t *end;
+ /** The head of the tokens queue. */
+ yaml_token_t *head;
+ /** The tail of the tokens queue. */
+ yaml_token_t *tail;
+ } tokens;
+
+ /** The number of tokens fetched from the queue. */
size_t tokens_parsed;
- /** The stack of indentation levels. */
- int *indents;
-
- /** The size of the indents stack. */
- size_t indents_size;
+ /* Does the tokens queue contain a token ready for dequeueing. */
+ int token_available;
- /** The number of items in the indents stack. */
- size_t indents_length;
+ /** The indentation levels stack. */
+ struct {
+ /** The beginning of the stack. */
+ int *start;
+ /** The end of the stack. */
+ int *end;
+ /** The top of the stack. */
+ int *top;
+ } indents;
/** The current indentation level. */
int indent;
@@ -959,11 +640,15 @@ typedef struct {
/** May a simple key occur at the current position? */
int simple_key_allowed;
- /** The stack of potential simple keys. */
- yaml_simple_key_t **simple_keys;
-
- /** The size of the simple keys stack. */
- size_t simple_keys_size;
+ /** The stack of simple keys. */
+ struct {
+ /** The beginning of the stack. */
+ yaml_simple_key_t *start;
+ /** The end of the stack. */
+ yaml_simple_key_t *end;
+ /** The top of the stack. */
+ yaml_simple_key_t *top;
+ } simple_keys;
/**
* @}
@@ -975,40 +660,37 @@ typedef struct {
*/
/** The parser states stack. */
- yaml_parser_state_t *states;
-
- /** The size of the parser states stack. */
- size_t states_size;
-
- /** The number of items in the parser states stack. */
- size_t states_length;
+ struct {
+ /** The beginning of the stack. */
+ yaml_parser_state_t *start;
+ /** The end of the stack. */
+ yaml_parser_state_t *end;
+ /** The top of the stack. */
+ yaml_parser_state_t *top;
+ } states;
/** The current parser state. */
yaml_parser_state_t state;
/** The stack of marks. */
- yaml_mark_t *marks;
-
- /** The size of the marks stack. */
- size_t marks_size;
-
- /** The number of items in the marks stack. */
- size_t marks_length;
-
- /** The current event. */
- yaml_event_t *current_event;
-
- /** The YAML version directive. */
- yaml_version_directive_t *version_directive;
+ struct {
+ /** The beginning of the stack. */
+ yaml_mark_t *start;
+ /** The end of the stack. */
+ yaml_mark_t *end;
+ /** The top of the stack. */
+ yaml_mark_t *top;
+ } marks;
/** The list of TAG directives. */
- yaml_tag_directive_t **tag_directives;
-
- /** The size of the TAG directives list. */
- size_t tag_directives_size;
-
- /** The number of items in the TAG directives list. */
- size_t tag_directives_length;
+ struct {
+ /** The beginning of the list. */
+ yaml_tag_directive_t *start;
+ /** The end of the list. */
+ yaml_tag_directive_t *end;
+ /** The top of the list. */
+ yaml_tag_directive_t *top;
+ } tag_directives;
/**
* @}
@@ -1017,16 +699,18 @@ typedef struct {
} yaml_parser_t;
/**
- * Create a new parser.
+ * 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.
*
- * @returns A new parser object; @c NULL on error.
+ * @param[in] parser An empty parser object.
+ *
+ * @returns #c 1 if the function succeeded, @c 0 on error.
*/
-YAML_DECLARE(yaml_parser_t *)
-yaml_parser_new(void);
+YAML_DECLARE(int)
+yaml_parser_initialize(yaml_parser_t *parser);
/**
* Destroy a parser.
@@ -1090,141 +774,65 @@ YAML_DECLARE(void)
yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
/**
- * Get the next token.
+ * Scan the input stream and produce the next token.
*
- * The token is removed from the internal token queue and the application is
- * responsible for destroing the token object.
- *
- * @param[in] parser A parser object.
+ * Call the function subsequently to produce a sequence of tokens corresponding
+ * to the input stream. The initial token has the type
+ * @c YAML_STREAM_START_TOKEN while the ending token has the type
+ * @c YAML_STREAM_END_TOKEN.
*
- * @returns A token object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_get_token(yaml_parser_t *parser);
-
-/**
- * Peek the next token.
+ * An application is responsible for freeing any buffers associated with the
+ * produced token object using the @c yaml_token_delete function.
*
- * The token is not removed from the internal token queue and will be returned
- * again on a subsequent call of @c yaml_parser_get_token or
- * @c yaml_parser_peek_token. The application should not destroy the token
- * object.
+ * 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.
*
* @param[in] parser A parser object.
+ * @param[in] token An empty token object.
*
- * @returns A token object, or @c NULL on error.
+ * @returns @c 1 if the function succeeded, @c 0 on error.
*/
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_peek_token(yaml_parser_t *parser);
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
/**
- * Get the next event.
+ * Parse the input stream and produce the next parsing event.
*
- * The application is responsible for destroing the event object.
+ * Call the function subsequently to produce a sequence of events corresponding
+ * to the input stream. The initial event has the type
+ * @c YAML_STREAM_START_EVENT while the ending event has the type
+ * @c YAML_STREAM_END_EVENT.
*
- * @param[in] parser A parser object.
+ * An application is responsible for freeing any buffers associated with the
+ * produced event object using the @c yaml_event_delete function.
*
- * @returns An event object, or @c NULL on error.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_get_event(yaml_parser_t *parser);
-
-/**
- * Peek the next event.
- *
- * The event will be returned again on a subsequent call of
- * @c yaml_parser_get_event or @c yaml_parser_peek_event. The application
- * should not destroy the event object.
+ * 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.
*
* @param[in] parser A parser object.
+ * @param[in] event An empty event object.
*
- * @returns An event object, or @c NULL on error.
+ * @returns @c 1 if the function succeeded, @c 0 on error.
*/
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_peek_event(yaml_parser_t *parser);
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
/** @} */
/*
typedef struct {
} yaml_emitter_t;
-*/
-
-/**
- * @defgroup internal Internal Definitions
- * @{
- */
-
-/**
- * Allocate a dynamic memory block.
- *
- * @param[in] size Size of a memory block, \c 0 is valid.
- *
- * @returns @c yaml_malloc returns a pointer to a newly allocated memory block,
- * or @c NULL if it failed.
- */
-
-YAML_DECLARE(void *)
-yaml_malloc(size_t size);
-
-/**
- * Reallocate a dynamic memory block.
- *
- * @param[in] ptr A pointer to an existing memory block, \c NULL is
- * valid.
- * @param[in] size A size of a new block, \c 0 is valid.
- *
- * @returns @c yaml_realloc returns a pointer to a reallocated memory block,
- * or @c NULL if it failed.
- */
-
-YAML_DECLARE(void *)
-yaml_realloc(void *ptr, size_t size);
-
-/**
- * Free a dynamic memory block.
- *
- * @param[in] ptr A pointer to an existing memory block, \c NULL is
- * valid.
- */
-
-YAML_DECLARE(void)
-yaml_free(void *ptr);
-
-/** The initial size for various buffers. */
-
-#define YAML_DEFAULT_SIZE 16
-
-/** The size of the raw buffer. */
-
-#define YAML_RAW_BUFFER_SIZE 16384
-
-/**
- * The size of the buffer.
- *
- * We allocate enough space for decoding the whole raw buffer.
- */
-
-#define YAML_BUFFER_SIZE (YAML_RAW_BUFFER_SIZE*3)
-
-/**
- * Ensure that the buffer contains at least @a length characters.
- *
- * @param[in] parser A parser object.
- * @param[in] length The number of characters in the buffer.
- *
- * @returns @c 1 on success, @c 0 on error.
- */
YAML_DECLARE(int)
-yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
-/** @} */
+YAML_DECLARE(int)
+yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
+ yaml_encoding_t encoding);
+*/
#ifdef __cplusplus
}
diff --git a/src/api.c b/src/api.c
index 85271a5..0dd3c42 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1,11 +1,9 @@
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "yaml_private.h"
-#include <yaml.h>
-
-#include <assert.h>
+/*
+ * Get the library version.
+ */
YAML_DECLARE(const char *)
yaml_get_version_string(void)
@@ -13,6 +11,10 @@ yaml_get_version_string(void)
return YAML_VERSION_STRING;
}
+/*
+ * Get the library version numbers.
+ */
+
YAML_DECLARE(void)
yaml_get_version(int *major, int *minor, int *patch)
{
@@ -52,118 +54,152 @@ yaml_free(void *ptr)
}
/*
- * Create a new parser object.
+ * Duplicate a string.
*/
-YAML_DECLARE(yaml_parser_t *)
-yaml_parser_new(void)
+YAML_DECLARE(char *)
+yaml_strdup(const char *str)
{
- yaml_parser_t *parser;
-
- /* Allocate the parser structure. */
-
- parser = yaml_malloc(sizeof(yaml_parser_t));
- if (!parser) goto error;
-
- memset(parser, 0, sizeof(yaml_parser_t));
+ return strdup(str);
+}
- /* Allocate the raw buffer. */
+/*
+ * Extend a string.
+ */
- parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
- if (!parser->raw_buffer) goto error;
- memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE);
+YAML_DECLARE(int)
+yaml_string_extend(yaml_char_t **start,
+ yaml_char_t **pointer, yaml_char_t **end)
+{
+ void *new_start = yaml_realloc(*start, (*end - *start)*2);
- parser->raw_pointer = parser->raw_buffer;
- parser->raw_unread = 0;
+ if (!new_start) return 0;
- /* Allocate the character buffer. */
+ memset(new_start + (*end - *start), 0, *end - *start);
- parser->buffer = yaml_malloc(YAML_BUFFER_SIZE);
- if (!parser->buffer) goto error;
- memset(parser->buffer, 0, YAML_BUFFER_SIZE);
+ *pointer = new_start + (*pointer - *start);
+ *end = new_start + (*end - *start)*2;
+ *start = new_start;
- parser->buffer_end = parser->buffer;
- parser->pointer = parser->buffer;
- parser->unread = 0;
+ return 1;
+}
- /* Allocate the tokens queue. */
+/*
+ * Append a string B to a string A.
+ */
- parser->tokens = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_token_t *));
- if (!parser->tokens) goto error;
- memset(parser->tokens, 0, YAML_DEFAULT_SIZE*sizeof(yaml_token_t *));
+YAML_DECLARE(int)
+yaml_string_join(
+ yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
+ yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
+{
+ if (*b_start == *b_pointer)
+ return 1;
- parser->tokens_size = YAML_DEFAULT_SIZE;
- parser->tokens_head = 0;
- parser->tokens_tail = 0;
- parser->tokens_parsed = 0;
+ while (*a_end - *a_pointer <= *b_pointer - *b_start) {
+ if (!yaml_string_extend(a_start, a_pointer, a_end))
+ return 0;
+ }
- /* Allocate the indents stack. */
+ memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
+ *a_pointer += *b_pointer - *b_start;
- parser->indents = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(int));
- if (!parser->indents) goto error;
- memset(parser->indents, 0, YAML_DEFAULT_SIZE*sizeof(int));
+ return 1;
+}
- parser->indents_size = YAML_DEFAULT_SIZE;
- parser->indents_length = 0;
+/*
+ * Extend a stack.
+ */
- /* Allocate the stack of potential simple keys. */
+YAML_DECLARE(int)
+yaml_stack_extend(void **start, void **top, void **end)
+{
+ void *new_start = yaml_realloc(*start, (*end - *start)*2);
- parser->simple_keys = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_simple_key_t *));
- if (!parser->simple_keys) goto error;
- memset(parser->simple_keys, 0, YAML_DEFAULT_SIZE*sizeof(yaml_simple_key_t *));
+ if (!new_start) return 0;
- parser->simple_keys_size = YAML_DEFAULT_SIZE;
+ *top = new_start + (*top - *start);
+ *end = new_start + (*end - *start)*2;
+ *start = new_start;
- /* Allocate the stack of parser states. */
+ return 1;
+}
- parser->states = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_parser_state_t));
- if (!parser->states) goto error;
- memset(parser->states, 0, YAML_DEFAULT_SIZE*sizeof(yaml_parser_state_t));
+/*
+ * Extend or move a queue.
+ */
- parser->states_size = YAML_DEFAULT_SIZE;
+YAML_DECLARE(int)
+yaml_queue_extend(void **start, void **head, void **tail, void **end)
+{
+ /* Check if we need to resize the queue. */
- /* Set the initial state. */
+ if (*start == *head && *tail == *end) {
+ void *new_start = yaml_realloc(*start, (*end - *start)*2);
- parser->state = YAML_PARSE_STREAM_START_STATE;
+ if (!new_start) return 0;
- /* Allocate the stack of marks. */
+ *head = new_start + (*head - *start);
+ *tail = new_start + (*tail - *start);
+ *end = new_start + (*end - *start)*2;
+ *start = new_start;
+ }
- parser->marks = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_mark_t));
- if (!parser->marks) goto error;
- memset(parser->marks, 0, YAML_DEFAULT_SIZE*sizeof(yaml_mark_t));
+ /* Check if we need to move the queue at the beginning of the buffer. */
- parser->marks_size = YAML_DEFAULT_SIZE;
+ if (*tail == *end) {
+ if (*head != *tail) {
+ memmove(*start, *head, *tail - *head);
+ }
+ *tail -= *head - *start;
+ *head = *start;
+ }
- /* Allocate the list of TAG directives. */
+ return 1;
+}
- parser->tag_directives = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
- if (!parser->tag_directives) goto error;
- memset(parser->tag_directives, 0, YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
- parser->tag_directives_size = YAML_DEFAULT_SIZE;
+/*
+ * Create a new parser object.
+ */
- /* Done. */
+YAML_DECLARE(int)
+yaml_parser_initialize(yaml_parser_t *parser)
+{
+ assert(parser); /* Non-NULL parser object expected. */
- return parser;
+ memset(parser, 0, sizeof(yaml_parser_t));
+ if (!BUFFER_INIT(parser, parser->raw_buffer, RAW_BUFFER_SIZE))
+ goto error;
+ if (!BUFFER_INIT(parser, parser->buffer, BUFFER_SIZE))
+ goto error;
+ if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
+ goto error;
+ if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
+ goto error;
- /* On error, free allocated buffers. */
+ return 1;
error:
- if (!parser) return NULL;
-
- yaml_free(parser->tag_directives);
- yaml_free(parser->marks);
- yaml_free(parser->states);
- yaml_free(parser->simple_keys);
- yaml_free(parser->indents);
- yaml_free(parser->tokens);
- yaml_free(parser->buffer);
- yaml_free(parser->raw_buffer);
+ BUFFER_DEL(parser, parser->raw_buffer);
+ BUFFER_DEL(parser, parser->buffer);
+ QUEUE_DEL(parser, parser->tokens);
+ STACK_DEL(parser, parser->indents);
+ STACK_DEL(parser, parser->simple_keys);
+ STACK_DEL(parser, parser->states);
+ STACK_DEL(parser, parser->marks);
+ STACK_DEL(parser, parser->tag_directives);
- yaml_free(parser);
-
- return NULL;
+ return 0;
}
/*
@@ -175,18 +211,24 @@ yaml_parser_delete(yaml_parser_t *parser)
{
assert(parser); /* Non-NULL parser object expected. */
- /*yaml_free(parser->tag_directives);*/
- yaml_free(parser->marks);
- yaml_free(parser->states);
- yaml_free(parser->simple_keys);
- yaml_free(parser->indents);
- yaml_free(parser->tokens);
- yaml_free(parser->buffer);
- yaml_free(parser->raw_buffer);
+ BUFFER_DEL(parser, parser->raw_buffer);
+ BUFFER_DEL(parser, parser->buffer);
+ while (!QUEUE_EMPTY(parser, parser->tokens)) {
+ yaml_token_delete(&DEQUEUE(parser, parser->tokens));
+ }
+ QUEUE_DEL(parser, parser->tokens);
+ STACK_DEL(parser, parser->indents);
+ STACK_DEL(parser, parser->simple_keys);
+ STACK_DEL(parser, parser->states);
+ STACK_DEL(parser, parser->marks);
+ while (!STACK_EMPTY(parser, parser->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+ STACK_DEL(parser, parser->tag_directives);
memset(parser, 0, sizeof(yaml_parser_t));
-
- yaml_free(parser);
}
/*
@@ -197,19 +239,19 @@ static int
yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- yaml_string_input_t *input = data;
+ yaml_parser_t *parser = data;
- if (input->current == input->end) {
+ if (parser->input.string.current == parser->input.string.end) {
*size_read = 0;
return 1;
}
- if (size > (input->end - input->current)) {
- size = input->end - input->current;
+ if (size > (parser->input.string.end - parser->input.string.current)) {
+ size = parser->input.string.end - parser->input.string.current;
}
- memcpy(buffer, input->current, size);
- input->current += size;
+ memcpy(buffer, parser->input.string.current, size);
+ parser->input.string.current += size;
*size_read = size;
return 1;
}
@@ -222,8 +264,10 @@ static int
yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
size_t *size_read)
{
- *size_read = fread(buffer, 1, size, (FILE *)data);
- return !ferror((FILE *)data);
+ yaml_parser_t *parser = data;
+
+ *size_read = fread(buffer, 1, size, parser->input.file);
+ return !ferror(parser->input.file);
}
/*
@@ -238,12 +282,12 @@ yaml_parser_set_input_string(yaml_parser_t *parser,
assert(!parser->read_handler); /* You can set the source only once. */
assert(input); /* Non-NULL input string expected. */
- parser->string_input.start = input;
- parser->string_input.current = input;
- parser->string_input.end = input+size;
-
parser->read_handler = yaml_string_read_handler;
- parser->read_handler_data = &parser->string_input;
+ parser->read_handler_data = parser;
+
+ parser->input.string.start = input;
+ parser->input.string.current = input;
+ parser->input.string.end = input+size;
}
/*
@@ -258,7 +302,9 @@ yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
assert(file); /* Non-NULL file object expected. */
parser->read_handler = yaml_file_read_handler;
- parser->read_handler_data = file;
+ parser->read_handler_data = parser;
+
+ parser->input.file = file;
}
/*
@@ -291,174 +337,6 @@ yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
}
/*
- * Create a token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_token_new(yaml_token_type_t type,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_malloc(sizeof(yaml_token_t));
-
- if (!token) return NULL;
-
- memset(token, 0, sizeof(yaml_token_t));
-
- token->type = type;
- token->start_mark = start_mark;
- token->end_mark = end_mark;
-
- return token;
-}
-
-/*
- * Create a STREAM-START token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_stream_start_token_new(yaml_encoding_t encoding,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_STREAM_START_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.stream_start.encoding = encoding;
-
- return token;
-}
-
-/*
- * Create a STREAM-END token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_STREAM_END_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- return token;
-}
-
-/*
- * Create a VERSION-DIRECTIVE token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_version_directive_token_new(int major, int minor,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_VERSION_DIRECTIVE_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.version_directive.major = major;
- token->data.version_directive.minor = minor;
-
- return token;
-}
-
-/*
- * Create a TAG-DIRECTIVE token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_tag_directive_token_new(yaml_char_t *handle, yaml_char_t *prefix,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_TAG_DIRECTIVE_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.tag_directive.handle = handle;
- token->data.tag_directive.prefix = prefix;
-
- return token;
-}
-
-/*
- * Create an ALIAS token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_alias_token_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_ALIAS_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.alias.value = anchor;
-
- return token;
-}
-
-/*
- * Create an ANCHOR token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_anchor_token_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_ANCHOR_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.anchor.value = anchor;
-
- return token;
-}
-
-/*
- * Create a TAG token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_tag_token_new(yaml_char_t *handle, yaml_char_t *suffix,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_TAG_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.tag.handle = handle;
- token->data.tag.suffix = suffix;
-
- return token;
-}
-
-/*
- * Create a SCALAR token.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_scalar_token_new(yaml_char_t *value, size_t length,
- yaml_scalar_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_token_t *token = yaml_token_new(YAML_SCALAR_TOKEN,
- start_mark, end_mark);
-
- if (!token) return NULL;
-
- token->data.scalar.value = value;
- token->data.scalar.length = length;
- token->data.scalar.style = style;
-
- return token;
-}
-
-/*
* Destroy a token object.
*/
@@ -493,205 +371,6 @@ yaml_token_delete(yaml_token_t *token)
}
memset(token, 0, sizeof(yaml_token_t));
-
- yaml_free(token);
-}
-
-/*
- * Create an event.
- */
-
-static yaml_event_t *
-yaml_event_new(yaml_event_type_t type,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_malloc(sizeof(yaml_event_t));
-
- if (!event) return NULL;
-
- memset(event, 0, sizeof(yaml_event_t));
-
- event->type = type;
- event->start_mark = start_mark;
- event->end_mark = end_mark;
-
- return event;
-}
-
-/*
- * Create a STREAM-START event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_stream_start_event_new(yaml_encoding_t encoding,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_STREAM_START_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.stream_start.encoding = encoding;
-
- return event;
-}
-
-/*
- * Create a STREAM-END event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- return yaml_event_new(YAML_STREAM_END_EVENT, start_mark, end_mark);
-}
-
-/*
- * Create a DOCUMENT-START event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_document_start_event_new(yaml_version_directive_t *version_directive,
- yaml_tag_directive_t **tag_directives, int implicit,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_START_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.document_start.version_directive = version_directive;
- event->data.document_start.tag_directives = tag_directives;
- event->data.document_start.implicit = implicit;
-
- return event;
-}
-
-/*
- * Create a DOCUMENT-END event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_document_end_event_new(int implicit,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_END_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.document_end.implicit = implicit;
-
- return event;
-}
-
-/*
- * Create an ALIAS event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_alias_event_new(yaml_char_t *anchor,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_ALIAS_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.alias.anchor = anchor;
-
- return event;
-}
-
-/*
- * Create a SCALAR event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- yaml_char_t *value, size_t length,
- int plain_implicit, int quoted_implicit,
- yaml_scalar_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_SCALAR_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.scalar.anchor = anchor;
- event->data.scalar.tag = tag;
- event->data.scalar.value = value;
- event->data.scalar.length = length;
- event->data.scalar.plain_implicit = plain_implicit;
- event->data.scalar.quoted_implicit = quoted_implicit;
- event->data.scalar.style = style;
-
- return event;
-}
-
-/*
- * Create a SEQUENCE-START event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_sequence_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- int implicit, yaml_sequence_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_SEQUENCE_START_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.sequence_start.anchor = anchor;
- event->data.sequence_start.tag = tag;
- event->data.sequence_start.implicit = implicit;
- event->data.sequence_start.style = style;
-
- return event;
-}
-
-/*
- * Create a SEQUENCE-END event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_sequence_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- return yaml_event_new(YAML_SEQUENCE_END_EVENT, start_mark, end_mark);
-}
-
-/*
- * Create a MAPPING-START event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_mapping_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
- int implicit, yaml_mapping_style_t style,
- yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- yaml_event_t *event = yaml_event_new(YAML_MAPPING_START_EVENT,
- start_mark, end_mark);
-
- if (!event) return NULL;
-
- event->data.mapping_start.anchor = anchor;
- event->data.mapping_start.tag = tag;
- event->data.mapping_start.implicit = implicit;
- event->data.mapping_start.style = style;
-
- return event;
-}
-
-/*
- * Create a MAPPING-END event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
-{
- return yaml_event_new(YAML_MAPPING_END_EVENT, start_mark, end_mark);
}
/*
@@ -701,22 +380,21 @@ yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
YAML_DECLARE(void)
yaml_event_delete(yaml_event_t *event)
{
+ yaml_tag_directive_t *tag_directive;
+
assert(event); /* Non-NULL event object expected. */
switch (event->type)
{
case YAML_DOCUMENT_START_EVENT:
- /*yaml_free(event->data.document_start.version_directive);
- if (event->data.document_start.tag_directives) {
- yaml_tag_directive_t **tag_directive;
- for (tag_directive = event->data.document_start.tag_directives;
- *tag_directive; tag_directive++) {
- yaml_free((*tag_directive)->handle);
- yaml_free((*tag_directive)->prefix);
- yaml_free(*tag_directive);
- }
- yaml_free(event->data.document_start.tag_directives);
- }*/
+ yaml_free(event->data.document_start.version_directive);
+ for (tag_directive = event->data.document_start.tag_directives.start;
+ tag_directive != event->data.document_start.tag_directives.end;
+ tag_directive++) {
+ yaml_free(tag_directive->handle);
+ yaml_free(tag_directive->prefix);
+ }
+ yaml_free(event->data.document_start.tag_directives.start);
break;
case YAML_ALIAS_EVENT:
@@ -741,7 +419,5 @@ yaml_event_delete(yaml_event_t *event)
}
memset(event, 0, sizeof(yaml_event_t));
-
- yaml_free(event);
}
diff --git a/src/parser.c b/src/parser.c
index af3aad8..fe9e171 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -39,23 +39,99 @@
* flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
*/
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "yaml_private.h"
-#include <yaml.h>
+/*
+ * Event initializers.
+ */
-#include <assert.h>
+#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
+ (memset(&(event), 0, sizeof(yaml_event_t)), \
+ (event).type = (event_type), \
+ (event).start_mark = (event_start_mark), \
+ (event).end_mark = (event_end_mark))
+
+#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.stream_start.encoding = (event_encoding))
+
+#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
+
+#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \
+ event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.document_start.version_directive = (event_version_directive), \
+ (event).data.document_start.tag_directives.start = (event_tag_directives_start), \
+ (event).data.document_start.tag_directives.end = (event_tag_directives_end), \
+ (event).data.document_start.implicit = (event_implicit))
+
+#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
+ (event).data.document_end.implicit = (event_implicit))
+
+#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
+ (event).data.alias.anchor = (event_anchor))
+
+#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
+ event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
+ (event).data.scalar.anchor = (event_anchor), \
+ (event).data.scalar.tag = (event_tag), \
+ (event).data.scalar.value = (event_value), \
+ (event).data.scalar.length = (event_length), \
+ (event).data.scalar.plain_implicit = (event_plain_implicit), \
+ (event).data.scalar.quoted_implicit = (event_quoted_implicit), \
+ (event).data.scalar.style = (event_style))
+
+#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
+ event_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.sequence_start.anchor = (event_anchor), \
+ (event).data.sequence_start.tag = (event_tag), \
+ (event).data.sequence_start.implicit = (event_implicit), \
+ (event).data.sequence_start.style = (event_style))
+
+#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
+
+#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
+ event_implicit,event_style,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
+ (event).data.mapping_start.anchor = (event_anchor), \
+ (event).data.mapping_start.tag = (event_tag), \
+ (event).data.mapping_start.implicit = (event_implicit), \
+ (event).data.mapping_start.style = (event_style))
+
+#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
+ (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
/*
- * Public API declarations.
+ * Peek the next token in the token queue.
*/
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_get_event(yaml_parser_t *parser);
+#define PEEK_TOKEN(parser) \
+ ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
+ parser->tokens.head : NULL)
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_peek_event(yaml_parser_t *parser);
+/*
+ * Remove the next token from the queue (must be called after PEEK_TOKEN).
+ */
+
+#define SKIP_TOKEN(parser) \
+ (parser->token_available = 0, \
+ parser->tokens_parsed ++, \
+ parser->stream_end_produced = \
+ (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \
+ parser->tokens.head ++)
+
+/*
+ * Public API declarations.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
/*
* Error handling.
@@ -71,126 +147,109 @@ yaml_parser_set_parser_error_context(yaml_parser_t *parser,
const char *problem, yaml_mark_t problem_mark);
/*
- * Buffers and lists.
+ * State functions.
*/
static int
-yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
- size_t item_size);
+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
static int
-yaml_parser_append_tag_directive(yaml_parser_t *parser,
- yaml_tag_directive_t *tag_directive);
+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
static int
-yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state);
+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
+ int implicit);
static int
-yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark);
-
-/*
- * State functions.
- */
+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_state_machine(yaml_parser_t *parser);
-
-static yaml_event_t *
-yaml_parser_parse_stream_start(yaml_parser_t *parser);
-
-static yaml_event_t *
-yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit);
-
-static yaml_event_t *
-yaml_parser_parse_document_content(yaml_parser_t *parser);
-
-static yaml_event_t *
-yaml_parser_parse_document_end(yaml_parser_t *parser);
+static int
+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_node(yaml_parser_t *parser,
+static int
+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
int block, int indentless_sequence);
-static yaml_event_t *
-yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first);
+static int
+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
-static yaml_event_t *
-yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser);
+static int
+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first);
+static int
+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
-static yaml_event_t *
-yaml_parser_parse_block_mapping_value(yaml_parser_t *parser);
+static int
+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first);
+static int
+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser);
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser);
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser);
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
+ yaml_event_t *event);
-static yaml_event_t *
-yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first);
+static int
+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first);
-static yaml_event_t *
-yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty);
+static int
+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event, int empty);
/*
* Utility functions.
*/
-static yaml_event_t *
-yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark);
+static int
+yaml_parser_process_empty_scalar(yaml_parser_t *parser,
+ yaml_event_t *event, yaml_mark_t mark);
static int
-yaml_parser_process_directives(yaml_parser_t *parser);
+yaml_parser_process_directives(yaml_parser_t *parser,
+ yaml_version_directive_t **version_directive_ref,
+ yaml_tag_directive_t **tag_directives_start_ref,
+ yaml_tag_directive_t **tag_directives_end_ref);
+
+static int
+yaml_parser_append_tag_directive(yaml_parser_t *parser,
+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
/*
- * Get the next event and advance the parser.
+ * Get the next event.
*/
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_get_event(yaml_parser_t *parser)
+YAML_DECLARE(int)
+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
{
- yaml_event_t *value;
+ assert(parser); /* Non-NULL parser object is expected. */
+ assert(event); /* Non-NULL event object is expected. */
- /* Update the current event if needed. */
-
- if (!parser->current_event) {
- parser->current_event = yaml_parser_state_machine(parser);
- }
+ /* No events after the end of the stream or error. */
- /* Return and clear the current event. */
+ if (parser->stream_end_produced || parser->error ||
+ parser->state == YAML_PARSE_END_STATE) {
+ memset(event, 0, sizeof(yaml_event_t));
- value = parser->current_event;
- parser->current_event = NULL;
- return value;
-}
-
-/*
- * Peek the next event.
- */
-
-YAML_DECLARE(yaml_event_t *)
-yaml_parser_peek_event(yaml_parser_t *parser)
-{
- yaml_event_t *value;
-
- /* Update the current event if needed. */
-
- if (!parser->current_event) {
- parser->current_event = yaml_parser_state_machine(parser);
+ return 1;
}
- /* Return the current event. */
+ /* Generate the next event. */
- return parser->current_event;
+ return yaml_parser_state_machine(parser, event);
}
/*
@@ -222,163 +281,88 @@ yaml_parser_set_parser_error_context(yaml_parser_t *parser,
return 0;
}
-/*
- * Double a list.
- */
-
-static int
-yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
- size_t item_size)
-{
- void *new_buffer = yaml_realloc(*buffer, item_size*(*size)*2);
-
- if (!new_buffer) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- memset(new_buffer+item_size*(*size), 0, item_size*(*size));
-
- *buffer = new_buffer;
- *size *= 2;
-
- return 1;
-}
-
-/*
- * Push a tag directive to the directive list.
- */
-
-static int
-yaml_parser_append_tag_directive(yaml_parser_t *parser,
- yaml_tag_directive_t *tag_directive)
-{
- if (parser->tag_directives_length == parser->tag_directives_size-1) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->tag_directives,
- &parser->tag_directives_size, sizeof(yaml_tag_directive_t)))
- return 0;
- }
-
- parser->tag_directives[parser->tag_directives_length++] = tag_directive;
- parser->tag_directives[parser->tag_directives_length] = NULL;
- return 1;
-}
-
-/*
- * Push a state to the state stack.
- */
-
-static int
-yaml_parser_append_state(yaml_parser_t *parser, yaml_parser_state_t state)
-{
- if (parser->states_length == parser->states_size-1) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->states,
- &parser->states_size, sizeof(yaml_parser_state_t)))
- return 0;
- }
-
- parser->states[parser->states_length++] = state;
- return 1;
-}
-
-/*
- * Push a mark to the mark stack.
- */
-
-static int
-yaml_parser_append_mark(yaml_parser_t *parser, yaml_mark_t mark)
-{
- if (parser->marks_length == parser->marks_size-1) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->marks,
- &parser->marks_size, sizeof(yaml_mark_t)))
- return 0;
- }
-
- parser->marks[parser->marks_length++] = mark;
- return 1;
-}
/*
* State dispatcher.
*/
-static yaml_event_t *
-yaml_parser_state_machine(yaml_parser_t *parser)
+static int
+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
{
- assert (parser->state != YAML_PARSE_END_STATE);
-
switch (parser->state)
{
case YAML_PARSE_STREAM_START_STATE:
- return yaml_parser_parse_stream_start(parser);
+ return yaml_parser_parse_stream_start(parser, event);
case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
- return yaml_parser_parse_document_start(parser, 1);
+ return yaml_parser_parse_document_start(parser, event, 1);
case YAML_PARSE_DOCUMENT_START_STATE:
- return yaml_parser_parse_document_start(parser, 0);
+ return yaml_parser_parse_document_start(parser, event, 0);
case YAML_PARSE_DOCUMENT_CONTENT_STATE:
- return yaml_parser_parse_document_content(parser);
+ return yaml_parser_parse_document_content(parser, event);
case YAML_PARSE_DOCUMENT_END_STATE:
- return yaml_parser_parse_document_end(parser);
+ return yaml_parser_parse_document_end(parser, event);
case YAML_PARSE_BLOCK_NODE_STATE:
- return yaml_parser_parse_node(parser, 1, 0);
+ return yaml_parser_parse_node(parser, event, 1, 0);
case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
- return yaml_parser_parse_node(parser, 1, 1);
+ return yaml_parser_parse_node(parser, event, 1, 1);
case YAML_PARSE_FLOW_NODE_STATE:
- return yaml_parser_parse_node(parser, 0, 0);
+ return yaml_parser_parse_node(parser, event, 0, 0);
case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
- return yaml_parser_parse_block_sequence_entry(parser, 1);
+ return yaml_parser_parse_block_sequence_entry(parser, event, 1);
case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_block_sequence_entry(parser, 0);
+ return yaml_parser_parse_block_sequence_entry(parser, event, 0);
case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_indentless_sequence_entry(parser);
+ return yaml_parser_parse_indentless_sequence_entry(parser, event);
case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
- return yaml_parser_parse_block_mapping_key(parser, 1);
+ return yaml_parser_parse_block_mapping_key(parser, event, 1);
case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
- return yaml_parser_parse_block_mapping_key(parser, 0);
+ return yaml_parser_parse_block_mapping_key(parser, event, 0);
case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
- return yaml_parser_parse_block_mapping_value(parser);
+ return yaml_parser_parse_block_mapping_value(parser, event);
case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
- return yaml_parser_parse_flow_sequence_entry(parser, 1);
+ return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
- return yaml_parser_parse_flow_sequence_entry(parser, 0);
+ return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_key(parser);
+ return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_value(parser);
+ return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
- return yaml_parser_parse_flow_sequence_entry_mapping_end(parser);
+ return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
- return yaml_parser_parse_flow_mapping_key(parser, 1);
+ return yaml_parser_parse_flow_mapping_key(parser, event, 1);
case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
- return yaml_parser_parse_flow_mapping_key(parser, 0);
+ return yaml_parser_parse_flow_mapping_key(parser, event, 0);
case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
- return yaml_parser_parse_flow_mapping_value(parser, 0);
+ return yaml_parser_parse_flow_mapping_value(parser, event, 0);
case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
- return yaml_parser_parse_flow_mapping_value(parser, 1);
+ return yaml_parser_parse_flow_mapping_value(parser, event, 1);
+
+ default:
+ assert(1); /* Invalid state. */
}
- assert(1);
}
/*
@@ -387,28 +371,25 @@ yaml_parser_state_machine(yaml_parser_t *parser)
* ************
*/
-static yaml_event_t *
-yaml_parser_parse_stream_start(yaml_parser_t *parser)
+static int
+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
{
yaml_token_t *token;
- yaml_event_t *event;
-
- token = yaml_parser_get_token(parser);
- if (!token) return NULL;
- assert(token->type == YAML_STREAM_START_TOKEN);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
- event = yaml_stream_start_event_new(token->data.stream_start.encoding,
- token->start_mark, token->start_mark);
- yaml_token_delete(token);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
+ if (token->type != YAML_STREAM_START_TOKEN) {
+ return yaml_parser_set_parser_error(parser,
+ "did not found expected <stream-start>", token->start_mark);
}
parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
+ STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
+ token->start_mark, token->start_mark);
+ SKIP_TOKEN(parser);
- return event;
+ return 1;
}
/*
@@ -419,14 +400,19 @@ yaml_parser_parse_stream_start(yaml_parser_t *parser)
* *************************
*/
-static yaml_event_t *
-yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit)
+static int
+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
+ int implicit)
{
yaml_token_t *token;
- yaml_event_t *event;
+ yaml_version_directive_t *version_directive = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ } tag_directives = { NULL, NULL };
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
/* Parse an implicit document. */
@@ -435,18 +421,14 @@ yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit)
token->type != YAML_DOCUMENT_START_TOKEN &&
token->type != YAML_STREAM_END_TOKEN)
{
- if (!yaml_parser_process_directives(parser)) return NULL;
- if (!yaml_parser_append_state(parser, YAML_PARSE_DOCUMENT_END_STATE))
- return NULL;
+ if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
+ return 0;
+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
+ return 0;
parser->state = YAML_PARSE_BLOCK_NODE_STATE;
- event = yaml_document_start_event_new(
- parser->version_directive, parser->tag_directives, 1,
+ DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
token->start_mark, token->start_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ return 1;
}
/* Parse an explicit document. */
@@ -455,44 +437,48 @@ yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit)
{
yaml_mark_t start_mark, end_mark;
start_mark = token->start_mark;
- if (!yaml_parser_process_directives(parser)) return NULL;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ if (!yaml_parser_process_directives(parser, &version_directive,
+ &tag_directives.start, &tag_directives.end))
+ return 0;
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
if (token->type != YAML_DOCUMENT_START_TOKEN) {
yaml_parser_set_parser_error(parser,
"did not found expected <document start>", token->start_mark);
- return NULL;
+ goto error;
}
- token = yaml_parser_get_token(parser);
- end_mark = token->end_mark;
- yaml_token_delete(token);
- if (!yaml_parser_append_state(parser, YAML_PARSE_DOCUMENT_END_STATE))
- return NULL;
+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
+ goto error;
parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
- event = yaml_document_start_event_new(
- parser->version_directive, parser->tag_directives, 0,
+ end_mark = token->end_mark;
+ DOCUMENT_START_EVENT_INIT(*event, version_directive,
+ tag_directives.start, tag_directives.end, 0,
start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ SKIP_TOKEN(parser);
+ version_directive = NULL;
+ tag_directives.start = tag_directives.end = NULL;
+ return 1;
}
/* Parse the stream end. */
else
{
- token = yaml_parser_get_token(parser);
parser->state = YAML_PARSE_END_STATE;
- event = yaml_stream_end_event_new(token->start_mark, token->end_mark);
- yaml_token_delete(token);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
}
+
+error:
+ yaml_free(version_directive);
+ while (tag_directives.start != tag_directives.end) {
+ yaml_free(tag_directives.end[-1].handle);
+ yaml_free(tag_directives.end[-1].prefix);
+ tag_directives.end --;
+ }
+ yaml_free(tag_directives.start);
+ return 0;
}
/*
@@ -501,24 +487,25 @@ yaml_parser_parse_document_start(yaml_parser_t *parser, int implicit)
* ***********
*/
-static yaml_event_t *
-yaml_parser_parse_document_content(yaml_parser_t *parser)
+static int
+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
{
yaml_token_t *token;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
token->type == YAML_TAG_DIRECTIVE_TOKEN ||
token->type == YAML_DOCUMENT_START_TOKEN ||
token->type == YAML_DOCUMENT_END_TOKEN ||
token->type == YAML_STREAM_END_TOKEN) {
- parser->state = parser->states[--parser->states_length];
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ parser->state = POP(parser, parser->states);
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
}
else {
- return yaml_parser_parse_node(parser, 1, 0);
+ return yaml_parser_parse_node(parser, event, 1, 0);
}
}
@@ -530,48 +517,36 @@ yaml_parser_parse_document_content(yaml_parser_t *parser)
* *************
*/
-static yaml_event_t *
-yaml_parser_parse_document_end(yaml_parser_t *parser)
+static int
+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
{
yaml_token_t *token;
- yaml_event_t *event;
yaml_mark_t start_mark, end_mark;
int implicit = 1;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
start_mark = end_mark = token->start_mark;
while (token->type == YAML_DOCUMENT_END_TOKEN) {
end_mark = token->end_mark;
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
implicit = 0;
}
- parser->version_directive = NULL;
- parser->tag_directives = NULL;
- parser->tag_directives = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
- if (!parser->tag_directives) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
+ while (!STACK_EMPTY(parser, parser->tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
}
- memset(parser->tag_directives, 0, YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *));
- parser->tag_directives_size = YAML_DEFAULT_SIZE;
- parser->tag_directives_length = 0;
-
-
- event = yaml_document_end_event_new(implicit, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
parser->state = YAML_PARSE_DOCUMENT_START_STATE;
+ DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
- return event;
+ return 1;
}
/*
@@ -603,12 +578,11 @@ yaml_parser_parse_document_end(yaml_parser_t *parser)
* ******
*/
-static yaml_event_t *
-yaml_parser_parse_node(yaml_parser_t *parser,
+static int
+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
int block, int indentless_sequence)
{
yaml_token_t *token;
- yaml_event_t *event;
yaml_char_t *anchor = NULL;
yaml_char_t *tag_handle = NULL;
yaml_char_t *tag_suffix = NULL;
@@ -616,22 +590,16 @@ yaml_parser_parse_node(yaml_parser_t *parser,
yaml_mark_t start_mark, end_mark, tag_mark;
int implicit;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_ALIAS_TOKEN)
{
- parser->state = parser->states[--parser->states_length];
- token = yaml_parser_get_token(parser);
- event = yaml_alias_event_new(token->data.alias.value,
+ parser->state = POP(parser, parser->states);
+ ALIAS_EVENT_INIT(*event, token->data.alias.value,
token->start_mark, token->end_mark);
- if (!event) {
- yaml_token_delete(token);
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- yaml_free(token);
- return event;
+ SKIP_TOKEN(parser);
+ return 1;
}
else
@@ -640,42 +608,38 @@ yaml_parser_parse_node(yaml_parser_t *parser,
if (token->type == YAML_ANCHOR_TOKEN)
{
- token = yaml_parser_get_token(parser);
anchor = token->data.anchor.value;
start_mark = token->start_mark;
end_mark = token->end_mark;
- yaml_free(token);
- token = yaml_parser_peek_token(parser);
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
if (!token) goto error;
if (token->type == YAML_TAG_TOKEN)
{
- token = yaml_parser_get_token(parser);
tag_handle = token->data.tag.handle;
tag_suffix = token->data.tag.suffix;
tag_mark = token->start_mark;
end_mark = token->end_mark;
- yaml_free(token);
- token = yaml_parser_peek_token(parser);
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
if (!token) goto error;
}
}
else if (token->type == YAML_TAG_TOKEN)
{
- token = yaml_parser_get_token(parser);
tag_handle = token->data.tag.handle;
tag_suffix = token->data.tag.suffix;
start_mark = tag_mark = token->start_mark;
end_mark = token->end_mark;
- yaml_free(token);
- token = yaml_parser_peek_token(parser);
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
if (!token) goto error;
if (token->type == YAML_ANCHOR_TOKEN)
{
- token = yaml_parser_get_token(parser);
anchor = token->data.anchor.value;
end_mark = token->end_mark;
- yaml_free(token);
- token = yaml_parser_peek_token(parser);
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
if (!token) goto error;
}
}
@@ -687,18 +651,19 @@ yaml_parser_parse_node(yaml_parser_t *parser,
tag_handle = tag_suffix = NULL;
}
else {
- yaml_tag_directive_t **tag_directive = parser->tag_directives;
- for (tag_directive = parser->tag_directives;
- *tag_directive; tag_directive++) {
- if (strcmp((char *)(*tag_directive)->handle, (char *)tag_handle) == 0) {
- size_t prefix_len = strlen((char *)(*tag_directive)->prefix);
+ yaml_tag_directive_t *tag_directive;
+ for (tag_directive = parser->tag_directives.start;
+ tag_directive != parser->tag_directives.top;
+ tag_directive ++) {
+ if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
+ size_t prefix_len = strlen((char *)tag_directive->prefix);
size_t suffix_len = strlen((char *)tag_suffix);
tag = yaml_malloc(prefix_len+suffix_len+1);
if (!tag) {
parser->error = YAML_MEMORY_ERROR;
goto error;
}
- memcpy(tag, (*tag_directive)->prefix, prefix_len);
+ memcpy(tag, tag_directive->prefix, prefix_len);
memcpy(tag+prefix_len, tag_suffix, suffix_len);
tag[prefix_len+suffix_len] = '\0';
yaml_free(tag_handle);
@@ -707,7 +672,7 @@ yaml_parser_parse_node(yaml_parser_t *parser,
break;
}
}
- if (!*tag_directive) {
+ if (!tag) {
yaml_parser_set_parser_error_context(parser,
"while parsing a node", start_mark,
"found undefined tag handle", tag_mark);
@@ -720,16 +685,14 @@ yaml_parser_parse_node(yaml_parser_t *parser,
if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
end_mark = token->end_mark;
parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
- event = yaml_sequence_start_event_new(anchor, tag, implicit,
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
- if (!event) goto error;
- return event;
+ return 1;
}
else {
if (token->type == YAML_SCALAR_TOKEN) {
int plain_implicit = 0;
int quoted_implicit = 0;
- token = yaml_parser_get_token(parser);
end_mark = token->end_mark;
if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
|| (tag && strcmp((char *)tag, "!") == 0)) {
@@ -738,57 +701,41 @@ yaml_parser_parse_node(yaml_parser_t *parser,
else if (!tag) {
quoted_implicit = 1;
}
- parser->state = parser->states[--parser->states_length];
- event = yaml_scalar_event_new(anchor, tag,
+ parser->state = POP(parser, parser->states);
+ SCALAR_EVENT_INIT(*event, anchor, tag,
token->data.scalar.value, token->data.scalar.length,
plain_implicit, quoted_implicit,
token->data.scalar.style, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- yaml_token_delete(token);
- goto error;
- }
- yaml_free(token);
+ SKIP_TOKEN(parser);
+ return 1;
}
else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
end_mark = token->end_mark;
parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
- event = yaml_sequence_start_event_new(anchor, tag, implicit,
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- goto error;
- }
+ return 1;
}
else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
end_mark = token->end_mark;
parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
- event = yaml_mapping_start_event_new(anchor, tag, implicit,
+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- goto error;
- }
+ return 1;
}
else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
end_mark = token->end_mark;
parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
- event = yaml_sequence_start_event_new(anchor, tag, implicit,
+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- goto error;
- }
+ return 1;
}
else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
end_mark = token->end_mark;
parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
- event = yaml_mapping_start_event_new(anchor, tag, implicit,
+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- goto error;
- }
+ return 1;
}
else if (anchor || tag) {
yaml_char_t *value = yaml_malloc(1);
@@ -797,15 +744,11 @@ yaml_parser_parse_node(yaml_parser_t *parser,
goto error;
}
value[0] = '\0';
- parser->state = parser->states[--parser->states_length];
- event = yaml_scalar_event_new(anchor, tag, value, 0,
+ parser->state = POP(parser, parser->states);
+ SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
implicit, 0, YAML_PLAIN_SCALAR_STYLE,
start_mark, end_mark);
- if (!event) {
- yaml_free(value);
- parser->error = YAML_MEMORY_ERROR;
- goto error;
- }
+ return 1;
}
else {
yaml_parser_set_parser_error_context(parser,
@@ -814,7 +757,6 @@ yaml_parser_parse_node(yaml_parser_t *parser,
"did not found expected node content", token->start_mark);
goto error;
}
- return event;
}
}
@@ -824,7 +766,7 @@ error:
yaml_free(tag_suffix);
yaml_free(tag);
- return NULL;
+ return 0;
}
/*
@@ -833,63 +775,55 @@ error:
* ******************** *********** * *********
*/
-static yaml_event_t *
-yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first)
+static int
+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_event_t *event;
if (first) {
- token = yaml_parser_get_token(parser);
- if (!yaml_parser_append_mark(parser, token->start_mark)) {
- yaml_token_delete(token);
- return NULL;
- }
- yaml_token_delete(token);
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
}
- token = yaml_parser_get_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_BLOCK_ENTRY_TOKEN)
{
yaml_mark_t mark = token->end_mark;
- yaml_token_delete(token);
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
token->type != YAML_BLOCK_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 1, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 0);
}
else {
parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
- return yaml_parser_process_empty_scalar(parser, mark);
+ return yaml_parser_process_empty_scalar(parser, event, mark);
}
}
else if (token->type == YAML_BLOCK_END_TOKEN)
{
- parser->state = parser->states[--parser->states_length];
- parser->marks_length --;
- event = yaml_sequence_end_event_new(token->start_mark, token->end_mark);
- yaml_token_delete(token);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ parser->state = POP(parser, parser->states);
+ POP(parser, parser->marks);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
}
else
{
- yaml_parser_set_parser_error_context(parser,
- "while parsing a block collection", parser->marks[parser->marks_length-1],
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block collection", POP(parser, parser->marks),
"did not found expected '-' indicator", token->start_mark);
- yaml_token_delete(token);
- return NULL;
}
}
@@ -899,42 +833,41 @@ yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, int first)
* *********** *
*/
-static yaml_event_t *
-yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser)
+static int
+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event)
{
yaml_token_t *token;
- yaml_event_t *event;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_BLOCK_ENTRY_TOKEN)
{
yaml_mark_t mark = token->end_mark;
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
+ token->type != YAML_KEY_TOKEN &&
+ token->type != YAML_VALUE_TOKEN &&
token->type != YAML_BLOCK_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 1, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 0);
}
else {
parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
- return yaml_parser_process_empty_scalar(parser, mark);
+ return yaml_parser_process_empty_scalar(parser, event, mark);
}
}
else
{
- parser->state = parser->states[--parser->states_length];
- event = yaml_sequence_end_event_new(token->start_mark, token->start_mark);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ parser->state = POP(parser, parser->states);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
+ return 1;
}
}
@@ -950,64 +883,56 @@ yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser)
* *********
*/
-static yaml_event_t *
-yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first)
+static int
+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_event_t *event;
if (first) {
- token = yaml_parser_get_token(parser);
- if (!yaml_parser_append_mark(parser, token->start_mark)) {
- yaml_token_delete(token);
- return NULL;
- }
- yaml_token_delete(token);
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
}
- token = yaml_parser_get_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_KEY_TOKEN)
{
yaml_mark_t mark = token->end_mark;
- yaml_token_delete(token);
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_KEY_TOKEN &&
token->type != YAML_VALUE_TOKEN &&
token->type != YAML_BLOCK_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 1, 1);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 1);
}
else {
parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
- return yaml_parser_process_empty_scalar(parser, mark);
+ return yaml_parser_process_empty_scalar(parser, event, mark);
}
}
else if (token->type == YAML_BLOCK_END_TOKEN)
{
- parser->state = parser->states[--parser->states_length];
- parser->marks_length --;
- event = yaml_mapping_end_event_new(token->start_mark, token->end_mark);
- yaml_token_delete(token);
- if (!event) {
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ parser->state = POP(parser, parser->states);
+ POP(parser, parser->marks);
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
}
else
{
- yaml_parser_set_parser_error_context(parser,
- "while parsing a block mapping", parser->marks[parser->marks_length-1],
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a block mapping", POP(parser, parser->marks),
"did not found expected key", token->start_mark);
- yaml_token_delete(token);
- return NULL;
}
}
@@ -1023,39 +948,39 @@ yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, int first)
*
*/
-static yaml_event_t *
-yaml_parser_parse_block_mapping_value(yaml_parser_t *parser)
+static int
+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event)
{
yaml_token_t *token;
- yaml_event_t *event;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_VALUE_TOKEN)
{
yaml_mark_t mark = token->end_mark;
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_KEY_TOKEN &&
token->type != YAML_VALUE_TOKEN &&
token->type != YAML_BLOCK_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 1, 1);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 1, 1);
}
else {
parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
- return yaml_parser_process_empty_scalar(parser, mark);
+ return yaml_parser_process_empty_scalar(parser, event, mark);
}
}
else
{
parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
}
}
@@ -1073,64 +998,59 @@ yaml_parser_parse_block_mapping_value(yaml_parser_t *parser)
* *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first)
+static int
+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_event_t *event;
if (first) {
- token = yaml_parser_get_token(parser);
- if (!yaml_parser_append_mark(parser, token->start_mark)) {
- yaml_token_delete(token);
- return NULL;
- }
- yaml_token_delete(token);
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
}
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
{
if (!first) {
if (token->type == YAML_FLOW_ENTRY_TOKEN) {
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
}
else {
- yaml_parser_set_parser_error_context(parser,
- "while parsing a flow sequence", parser->marks[parser->marks_length-1],
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow sequence", POP(parser, parser->marks),
"did not found expected ',' or ']'", token->start_mark);
- return NULL;
}
}
if (token->type == YAML_KEY_TOKEN) {
- token = yaml_parser_get_token(parser);
parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
- event = yaml_mapping_start_event_new(NULL, NULL,
+ MAPPING_START_EVENT_INIT(*event, NULL, NULL,
1, YAML_FLOW_MAPPING_STYLE,
token->start_mark, token->end_mark);
- yaml_token_delete(token);
- return event;
+ SKIP_TOKEN(parser);
+ return 1;
}
else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
}
- parser->state = parser->states[--parser->states_length];
- parser->marks_length --;
- token = yaml_parser_get_token(parser);
- event = yaml_sequence_end_event_new(token->start_mark, token->end_mark);
- yaml_token_delete(token);
- return event;
+ parser->state = POP(parser, parser->states);
+ POP(parser, parser->marks);
+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
}
/*
@@ -1139,27 +1059,27 @@ yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, int first)
* *** *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser)
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event)
{
yaml_token_t *token;
- yaml_event_t *event;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
&& token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
else {
+ yaml_mark_t mark = token->end_mark;
+ SKIP_TOKEN(parser);
parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
- event = yaml_parser_process_empty_scalar(parser, token->end_mark);
- yaml_token_delete(token);
- return event;
+ return yaml_parser_process_empty_scalar(parser, event, mark);
}
}
@@ -1169,28 +1089,29 @@ yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser)
* ***** *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser)
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event)
{
yaml_token_t *token;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type == YAML_VALUE_TOKEN) {
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_FLOW_ENTRY_TOKEN
&& token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
}
parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
}
/*
@@ -1199,17 +1120,19 @@ yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser)
* *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser)
+static int
+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
+ yaml_event_t *event)
{
yaml_token_t *token;
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
- return yaml_mapping_end_event_new(token->start_mark, token->start_mark);
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
+ return 1;
}
/*
@@ -1226,71 +1149,68 @@ yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser)
* * *** *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first)
+static int
+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
+ yaml_event_t *event, int first)
{
yaml_token_t *token;
- yaml_event_t *event;
if (first) {
- token = yaml_parser_get_token(parser);
- if (!yaml_parser_append_mark(parser, token->start_mark)) {
- yaml_token_delete(token);
- return NULL;
- }
- yaml_token_delete(token);
+ token = PEEK_TOKEN(parser);
+ if (!PUSH(parser, parser->marks, token->start_mark))
+ return 0;
+ SKIP_TOKEN(parser);
}
- token = yaml_parser_peek_token(parser);
- if (!token) return;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
{
if (!first) {
if (token->type == YAML_FLOW_ENTRY_TOKEN) {
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
}
else {
- yaml_parser_set_parser_error_context(parser,
- "while parsing a flow mapping", parser->marks[parser->marks_length-1],
+ return yaml_parser_set_parser_error_context(parser,
+ "while parsing a flow mapping", POP(parser, parser->marks),
"did not found expected ',' or '}'", token->start_mark);
- return NULL;
}
}
if (token->type == YAML_KEY_TOKEN) {
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_VALUE_TOKEN
&& token->type != YAML_FLOW_ENTRY_TOKEN
&& token->type != YAML_FLOW_MAPPING_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
else {
parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
}
}
else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
}
- parser->state = parser->states[--parser->states_length];
- parser->marks_length --;
- token = yaml_parser_get_token(parser);
- event = yaml_mapping_end_event_new(token->start_mark, token->end_mark);
- yaml_token_delete(token);
- return event;
+ parser->state = POP(parser, parser->states);
+ POP(parser, parser->marks);
+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
+ SKIP_TOKEN(parser);
+ return 1;
}
/*
@@ -1299,63 +1219,59 @@ yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, int first)
* * ***** *
*/
-static yaml_event_t *
-yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty)
+static int
+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
+ yaml_event_t *event, int empty)
{
yaml_token_t *token;
- yaml_event_t *event;
- token = yaml_parser_peek_token(parser);
- if (!token) return;
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (empty) {
parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ return yaml_parser_process_empty_scalar(parser, event,
+ token->start_mark);
}
if (token->type == YAML_VALUE_TOKEN) {
- yaml_token_delete(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return NULL;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) return 0;
if (token->type != YAML_FLOW_ENTRY_TOKEN
&& token->type != YAML_FLOW_MAPPING_END_TOKEN) {
- if (!yaml_parser_append_state(parser,
+ if (!PUSH(parser, parser->states,
YAML_PARSE_FLOW_MAPPING_KEY_STATE))
- return NULL;
- return yaml_parser_parse_node(parser, 0, 0);
+ return 0;
+ return yaml_parser_parse_node(parser, event, 0, 0);
}
}
parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
- return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
}
/*
* Generate an empty scalar event.
*/
-static yaml_event_t *
-yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark)
+static int
+yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
+ yaml_mark_t mark)
{
- yaml_event_t *event;
yaml_char_t *value;
value = yaml_malloc(1);
if (!value) {
parser->error = YAML_MEMORY_ERROR;
- return NULL;
+ return 0;
}
value[0] = '\0';
- event = yaml_scalar_event_new(NULL, NULL, value, 0,
+ SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
- if (!event) {
- yaml_free(value);
- parser->error = YAML_MEMORY_ERROR;
- return NULL;
- }
- return event;
+ return 1;
}
/*
@@ -1363,41 +1279,53 @@ yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark)
*/
static int
-yaml_parser_process_directives(yaml_parser_t *parser)
+yaml_parser_process_directives(yaml_parser_t *parser,
+ yaml_version_directive_t **version_directive_ref,
+ yaml_tag_directive_t **tag_directives_start_ref,
+ yaml_tag_directive_t **tag_directives_end_ref)
{
yaml_tag_directive_t default_tag_directives[] = {
{(yaml_char_t *)"!", (yaml_char_t *)"!"},
{(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
{NULL, NULL}
};
- yaml_tag_directive_t *ref;
yaml_tag_directive_t *default_tag_directive;
- yaml_tag_directive_t **tag_directive;
+ yaml_version_directive_t *version_directive = NULL;
+ struct {
+ yaml_tag_directive_t *start;
+ yaml_tag_directive_t *end;
+ yaml_tag_directive_t *top;
+ } tag_directives = { NULL, NULL, NULL };
yaml_token_t *token;
- token = yaml_parser_peek_token(parser);
- if (!token) return 0;
+ if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
+ goto error;
+
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
token->type == YAML_TAG_DIRECTIVE_TOKEN)
{
if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
- if (parser->version_directive) {
- return yaml_parser_set_parser_error(parser,
+ if (version_directive) {
+ yaml_parser_set_parser_error(parser,
"found duplicate %YAML directive", token->start_mark);
+ goto error;
}
if (token->data.version_directive.major != 1
&& token->data.version_directive.minor != 1) {
- return yaml_parser_set_parser_error(parser,
+ yaml_parser_set_parser_error(parser,
"found incompatible YAML document", token->start_mark);
+ goto error;
}
- parser->version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
- if (!parser->version_directive) {
+ version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
+ if (!version_directive) {
parser->error = YAML_MEMORY_ERROR;
- return 0;
+ goto error;
}
- parser->version_directive->major = token->data.version_directive.major;
- parser->version_directive->minor = token->data.version_directive.minor;
+ version_directive->major = token->data.version_directive.major;
+ version_directive->minor = token->data.version_directive.minor;
}
else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
@@ -1405,70 +1333,84 @@ yaml_parser_process_directives(yaml_parser_t *parser)
token->data.tag_directive.handle,
token->data.tag_directive.prefix
};
- for (tag_directive = parser->tag_directives;
- *tag_directive; tag_directive++) {
- if (strcmp((char *)value.handle,
- (char *)(*tag_directive)->handle) == 0) {
- return yaml_parser_set_parser_error(parser,
- "found duplicate %TAG directive", token->start_mark);
- }
- }
- ref = yaml_malloc(sizeof(yaml_tag_directive_t));
- if (!ref) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- *ref = value;
- if (!yaml_parser_append_tag_directive(parser, ref)) {
- yaml_free(ref);
- return 0;
- }
+ if (!yaml_parser_append_tag_directive(parser, value, 0,
+ token->start_mark))
+ goto error;
+ if (!PUSH(parser, tag_directives, value))
+ goto error;
}
- yaml_free(yaml_parser_get_token(parser));
- token = yaml_parser_peek_token(parser);
- if (!token) return 0;
- }
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if (!token) goto error;
+ }
+
for (default_tag_directive = default_tag_directives;
default_tag_directive->handle; default_tag_directive++) {
- int found = 0;
- for (tag_directive = parser->tag_directives;
- *tag_directive; tag_directive++) {
- if (strcmp((char *)default_tag_directive->handle,
- (char *)(*tag_directive)->handle) == 0) {
- found = 1;
- break;
- }
+ if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
+ token->start_mark))
+ goto error;
+ }
+
+ if (version_directive_ref) {
+ *version_directive_ref = version_directive;
+ }
+ if (tag_directives_start_ref) {
+ if (STACK_EMPTY(parser, tag_directives)) {
+ *tag_directives_start_ref = *tag_directives_end_ref = NULL;
}
- if (!found) {
- ref = yaml_malloc(sizeof(yaml_tag_directive_t));
- if (!ref) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- ref->handle = yaml_malloc(strlen((char *)default_tag_directive->handle)+1);
- if (!ref->handle) {
- yaml_free(ref);
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- ref->prefix = yaml_malloc(strlen((char *)default_tag_directive->prefix)+1);
- if (!ref->prefix) {
- yaml_free(ref->handle);
- yaml_free(ref);
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- memcpy(ref->handle, default_tag_directive->handle,
- strlen((char *)default_tag_directive->handle)+1);
- memcpy(ref->prefix, default_tag_directive->prefix,
- strlen((char *)default_tag_directive->prefix)+1);
- if (!yaml_parser_append_tag_directive(parser, ref)) {
- yaml_free(ref);
- return 0;
- }
+ else {
+ *tag_directives_start_ref = tag_directives.start;
+ *tag_directives_end_ref = tag_directives.end;
}
}
+
return 1;
+
+error:
+ yaml_free(version_directive);
+ while (!STACK_EMPTY(parser, tag_directives)) {
+ yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
+ yaml_free(tag_directive.handle);
+ yaml_free(tag_directive.prefix);
+ }
+ STACK_DEL(parser, tag_directives);
+ return 0;
+}
+
+static int
+yaml_parser_append_tag_directive(yaml_parser_t *parser,
+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
+{
+ yaml_tag_directive_t *tag_directive;
+ yaml_tag_directive_t copy = { NULL, NULL };
+ int length;
+
+ for (tag_directive = parser->tag_directives.start;
+ tag_directive != parser->tag_directives.top; tag_directive ++) {
+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
+ if (allow_duplicates)
+ return 1;
+ return yaml_parser_set_parser_error(parser,
+ "found duplicate %TAG directive", mark);
+ }
+ }
+
+ copy.handle = (yaml_char_t *)yaml_strdup((char *)value.handle);
+ copy.prefix = (yaml_char_t *)yaml_strdup((char *)value.prefix);
+ if (!copy.handle || !copy.prefix) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
+
+ if (!PUSH(parser, parser->tag_directives, copy))
+ goto error;
+
+ return 1;
+
+error:
+ yaml_free(copy.handle);
+ yaml_free(copy.prefix);
+ return 0;
}
diff --git a/src/reader.c b/src/reader.c
index 9cc8e7b..99a51db 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -1,11 +1,22 @@
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "yaml_private.h"
-#include <yaml.h>
+/*
+ * Declarations.
+ */
+
+static int
+yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
+ size_t offset, int value);
-#include <assert.h>
+static int
+yaml_parser_update_raw_buffer(yaml_parser_t *parser);
+
+static int
+yaml_parser_determine_encoding(yaml_parser_t *parser);
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
/*
* Set the reader error and return 0.
@@ -24,61 +35,25 @@ yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
}
/*
- * Update the raw buffer.
+ * Byte order marks.
*/
-static int
-yaml_parser_update_raw_buffer(yaml_parser_t *parser)
-{
- size_t size_read = 0;
-
- /* Return if the raw buffer is full. */
-
- if (parser->raw_unread == YAML_RAW_BUFFER_SIZE) return 1;
-
- /* Return on EOF. */
-
- if (parser->eof) return 1;
-
- /* Move the remaining bytes in the raw buffer to the beginning. */
-
- if (parser->raw_unread && parser->raw_buffer < parser->raw_pointer) {
- memmove(parser->raw_buffer, parser->raw_pointer, parser->raw_unread);
- }
- parser->raw_pointer = parser->raw_buffer;
-
- /* Call the read handler to fill the buffer. */
-
- if (!parser->read_handler(parser->read_handler_data,
- parser->raw_buffer + parser->raw_unread,
- YAML_RAW_BUFFER_SIZE - parser->raw_unread,
- &size_read)) {
- return yaml_parser_set_reader_error(parser, "Input error",
- parser->offset, -1);
- }
- parser->raw_unread += size_read;
- if (!size_read) {
- parser->eof = 1;
- }
-
- return 1;
-}
+#define BOM_UTF8 "\xef\xbb\xbf"
+#define BOM_UTF16LE "\xff\xfe"
+#define BOM_UTF16BE "\xfe\xff"
/*
* Determine the input stream encoding by checking the BOM symbol. If no BOM is
* found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
*/
-#define BOM_UTF8 "\xef\xbb\xbf"
-#define BOM_UTF16LE "\xff\xfe"
-#define BOM_UTF16BE "\xfe\xff"
-
static int
yaml_parser_determine_encoding(yaml_parser_t *parser)
{
/* Ensure that we had enough bytes in the raw buffer. */
- while (!parser->eof && parser->raw_unread < 3) {
+ while (!parser->eof
+ && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
if (!yaml_parser_update_raw_buffer(parser)) {
return 0;
}
@@ -86,25 +61,22 @@ yaml_parser_determine_encoding(yaml_parser_t *parser)
/* Determine the encoding. */
- if (parser->raw_unread >= 2
- && !memcmp(parser->raw_pointer, BOM_UTF16LE, 2)) {
+ if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
parser->encoding = YAML_UTF16LE_ENCODING;
- parser->raw_pointer += 2;
- parser->raw_unread -= 2;
+ parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
- else if (parser->raw_unread >= 2
- && !memcmp(parser->raw_pointer, BOM_UTF16BE, 2)) {
+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
parser->encoding = YAML_UTF16BE_ENCODING;
- parser->raw_pointer += 2;
- parser->raw_unread -= 2;
+ parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
- else if (parser->raw_unread >= 3
- && !memcmp(parser->raw_pointer, BOM_UTF8, 3)) {
+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
parser->encoding = YAML_UTF8_ENCODING;
- parser->raw_pointer += 3;
- parser->raw_unread -= 3;
+ parser->raw_buffer.pointer += 3;
parser->offset += 3;
}
else {
@@ -115,7 +87,52 @@ yaml_parser_determine_encoding(yaml_parser_t *parser)
}
/*
- * Ensure that the buffer contains at least length characters.
+ * Update the raw buffer.
+ */
+
+static int
+yaml_parser_update_raw_buffer(yaml_parser_t *parser)
+{
+ size_t size_read = 0;
+
+ /* Return if the raw buffer is full. */
+
+ if (parser->raw_buffer.start == parser->raw_buffer.pointer
+ && parser->raw_buffer.last == parser->raw_buffer.end)
+ return 1;
+
+ /* Return on EOF. */
+
+ if (parser->eof) return 1;
+
+ /* Move the remaining bytes in the raw buffer to the beginning. */
+
+ if (parser->raw_buffer.start < parser->raw_buffer.pointer
+ && parser->raw_buffer.pointer < parser->raw_buffer.last) {
+ memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
+ parser->raw_buffer.last - parser->raw_buffer.pointer);
+ }
+ parser->raw_buffer.last -=
+ parser->raw_buffer.pointer - parser->raw_buffer.start;
+ parser->raw_buffer.pointer = parser->raw_buffer.start;
+
+ /* Call the read handler to fill the buffer. */
+
+ if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
+ parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
+ return yaml_parser_set_reader_error(parser, "Input error",
+ parser->offset, -1);
+ }
+ parser->raw_buffer.last += size_read;
+ if (!size_read) {
+ parser->eof = 1;
+ }
+
+ return 1;
+}
+
+/*
+ * Ensure that the buffer contains at least `length` characters.
* Return 1 on success, 0 on failure.
*
* The length is supposed to be significantly less that the buffer size.
@@ -124,9 +141,11 @@ yaml_parser_determine_encoding(yaml_parser_t *parser)
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
{
+ assert(parser->read_handler); /* Read handler must be set. */
+
/* If the EOF flag is set and the raw buffer is empty, do nothing. */
- if (parser->eof && !parser->raw_unread)
+ if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
return 1;
/* Return if the buffer contains enough characters. */
@@ -143,16 +162,16 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Move the unread characters to the beginning of the buffer. */
- if (parser->buffer < parser->pointer
- && parser->pointer < parser->buffer_end) {
- size_t size = parser->buffer_end - parser->pointer;
- memmove(parser->buffer, parser->pointer, size);
- parser->pointer = parser->buffer;
- parser->buffer_end = parser->buffer + size;
+ if (parser->buffer.start < parser->buffer.pointer
+ && parser->buffer.pointer < parser->buffer.last) {
+ size_t size = parser->buffer.last - parser->buffer.pointer;
+ memmove(parser->buffer.start, parser->buffer.pointer, size);
+ parser->buffer.pointer = parser->buffer.start;
+ parser->buffer.last = parser->buffer.start + size;
}
- else if (parser->pointer == parser->buffer_end) {
- parser->pointer = parser->buffer;
- parser->buffer_end = parser->buffer;
+ else if (parser->buffer.pointer == parser->buffer.last) {
+ parser->buffer.pointer = parser->buffer.start;
+ parser->buffer.last = parser->buffer.start;
}
/* Fill the buffer until it has enough characters. */
@@ -165,13 +184,14 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Decode the raw buffer. */
- while (parser->raw_unread)
+ while (parser->raw_buffer.pointer != parser->raw_buffer.last)
{
unsigned int value, value2;
int incomplete = 0;
unsigned char octet;
unsigned int width;
int k, low, high;
+ int raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
/* Decode the next character. */
@@ -201,7 +221,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Determine the length of the UTF-8 sequence. */
- octet = parser->raw_pointer[0];
+ octet = parser->raw_buffer.pointer[0];
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
@@ -216,7 +236,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Check if the raw buffer contains an incomplete character. */
- if (width > parser->raw_unread) {
+ if (width > raw_unread) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"Incomplete UTF-8 octet sequence",
@@ -237,7 +257,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
for (k = 1; k < width; k ++)
{
- octet = parser->raw_pointer[k];
+ octet = parser->raw_buffer.pointer[k];
/* Check if the octet is valid. */
@@ -304,7 +324,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Check for incomplete UTF-16 character. */
- if (parser->raw_unread < 2) {
+ if (raw_unread < 2) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"Incomplete UTF-16 character",
@@ -316,8 +336,8 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Get the character. */
- value = parser->raw_pointer[low]
- + (parser->raw_pointer[high] << 8);
+ value = parser->raw_buffer.pointer[low]
+ + (parser->raw_buffer.pointer[high] << 8);
/* Check for unexpected low surrogate area. */
@@ -334,7 +354,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Check for incomplete surrogate pair. */
- if (parser->raw_unread < 4) {
+ if (raw_unread < 4) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"Incomplete UTF-16 surrogate pair",
@@ -346,8 +366,8 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Get the next character. */
- unsigned int value2 = parser->raw_pointer[low+2]
- + (parser->raw_pointer[high+2] << 8);
+ unsigned int value2 = parser->raw_buffer.pointer[low+2]
+ + (parser->raw_buffer.pointer[high+2] << 8);
/* Check for a low surrogate area. */
@@ -390,33 +410,32 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* Move the raw pointers. */
- parser->raw_pointer += width;
- parser->raw_unread -= width;
+ parser->raw_buffer.pointer += width;
parser->offset += width;
/* Finally put the character into the buffer. */
/* 0000 0000-0000 007F -> 0xxxxxxx */
if (value <= 0x7F) {
- *(parser->buffer_end++) = value;
+ *(parser->buffer.last++) = value;
}
/* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
else if (value <= 0x7FF) {
- *(parser->buffer_end++) = 0xC0 + (value >> 6);
- *(parser->buffer_end++) = 0x80 + (value & 0x3F);
+ *(parser->buffer.last++) = 0xC0 + (value >> 6);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
else if (value <= 0xFFFF) {
- *(parser->buffer_end++) = 0xE0 + (value >> 12);
- *(parser->buffer_end++) = 0x80 + ((value >> 6) & 0x3F);
- *(parser->buffer_end++) = 0x80 + (value & 0x3F);
+ *(parser->buffer.last++) = 0xE0 + (value >> 12);
+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
else {
- *(parser->buffer_end++) = 0xF0 + (value >> 18);
- *(parser->buffer_end++) = 0x80 + ((value >> 12) & 0x3F);
- *(parser->buffer_end++) = 0x80 + ((value >> 6) & 0x3F);
- *(parser->buffer_end++) = 0x80 + (value & 0x3F);
+ *(parser->buffer.last++) = 0xF0 + (value >> 18);
+ *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
parser->unread ++;
@@ -425,7 +444,7 @@ yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
/* On EOF, put NUL into the buffer and return. */
if (parser->eof) {
- *(parser->buffer_end++) = '\0';
+ *(parser->buffer.last++) = '\0';
parser->unread ++;
return 1;
}
diff --git a/src/scanner.c b/src/scanner.c
index 7500f42..90a8979 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -475,30 +475,24 @@
* BLOCK-END
*/
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <yaml.h>
-
-#include <assert.h>
+#include "yaml_private.h"
/*
* Ensure that the buffer contains the required number of characters.
* Return 1 on success, 0 on failure (reader error or memory error).
*/
-#define UPDATE(parser,length) \
- (parser->unread >= (length) \
- ? 1 \
+#define CACHE(parser,length) \
+ (parser->unread >= (length) \
+ ? 1 \
: yaml_parser_update_buffer(parser, (length)))
/*
* Check the octet at the specified position.
*/
-#define CHECK_AT(parser,octet,offset) \
- (parser->pointer[offset] == (yaml_char_t)(octet))
+#define CHECK_AT(parser,octet,offset) \
+ (parser->buffer.pointer[offset] == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
@@ -511,15 +505,15 @@
* character, a digit, '_', or '-'.
*/
-#define IS_ALPHA_AT(parser,offset) \
- ((parser->pointer[offset] >= (yaml_char_t) '0' && \
- parser->pointer[offset] <= (yaml_char_t) '9') || \
- (parser->pointer[offset] >= (yaml_char_t) 'A' && \
- parser->pointer[offset] <= (yaml_char_t) 'Z') || \
- (parser->pointer[offset] >= (yaml_char_t) 'a' && \
- parser->pointer[offset] <= (yaml_char_t) 'z') || \
- parser->pointer[offset] == '_' || \
- parser->pointer[offset] == '-')
+#define IS_ALPHA_AT(parser,offset) \
+ ((parser->buffer.pointer[offset] >= (yaml_char_t) '0' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) '9') || \
+ (parser->buffer.pointer[offset] >= (yaml_char_t) 'A' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'Z') || \
+ (parser->buffer.pointer[offset] >= (yaml_char_t) 'a' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'z') || \
+ parser->buffer.pointer[offset] == '_' || \
+ parser->buffer.pointer[offset] == '-')
#define IS_ALPHA(parser) IS_ALPHA_AT(parser,0)
@@ -527,9 +521,9 @@
* Check if the character at the specified position is a digit.
*/
-#define IS_DIGIT_AT(parser,offset) \
- ((parser->pointer[offset] >= (yaml_char_t) '0' && \
- parser->pointer[offset] <= (yaml_char_t) '9'))
+#define IS_DIGIT_AT(parser,offset) \
+ ((parser->buffer.pointer[offset] >= (yaml_char_t) '0' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) '9'))
#define IS_DIGIT(parser) IS_DIGIT_AT(parser,0)
@@ -537,8 +531,8 @@
* Get the value of a digit.
*/
-#define AS_DIGIT_AT(parser,offset) \
- (parser->pointer[offset] - (yaml_char_t) '0')
+#define AS_DIGIT_AT(parser,offset) \
+ (parser->buffer.pointer[offset] - (yaml_char_t) '0')
#define AS_DIGIT(parser) AS_DIGIT_AT(parser,0)
@@ -546,13 +540,13 @@
* Check if the character at the specified position is a hex-digit.
*/
-#define IS_HEX_AT(parser,offset) \
- ((parser->pointer[offset] >= (yaml_char_t) '0' && \
- parser->pointer[offset] <= (yaml_char_t) '9') || \
- (parser->pointer[offset] >= (yaml_char_t) 'A' && \
- parser->pointer[offset] <= (yaml_char_t) 'F') || \
- (parser->pointer[offset] >= (yaml_char_t) 'a' && \
- parser->pointer[offset] <= (yaml_char_t) 'f'))
+#define IS_HEX_AT(parser,offset) \
+ ((parser->buffer.pointer[offset] >= (yaml_char_t) '0' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) '9') || \
+ (parser->buffer.pointer[offset] >= (yaml_char_t) 'A' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'F') || \
+ (parser->buffer.pointer[offset] >= (yaml_char_t) 'a' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'f'))
#define IS_HEX(parser) IS_HEX_AT(parser,0)
@@ -560,14 +554,14 @@
* Get the value of a hex-digit.
*/
-#define AS_HEX_AT(parser,offset) \
- ((parser->pointer[offset] >= (yaml_char_t) 'A' && \
- parser->pointer[offset] <= (yaml_char_t) 'F') ? \
- (parser->pointer[offset] - (yaml_char_t) 'A' + 10) : \
- (parser->pointer[offset] >= (yaml_char_t) 'a' && \
- parser->pointer[offset] <= (yaml_char_t) 'f') ? \
- (parser->pointer[offset] - (yaml_char_t) 'a' + 10) : \
- (parser->pointer[offset] - (yaml_char_t) '0'))
+#define AS_HEX_AT(parser,offset) \
+ ((parser->buffer.pointer[offset] >= (yaml_char_t) 'A' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'F') ? \
+ (parser->buffer.pointer[offset] - (yaml_char_t) 'A' + 10) : \
+ (parser->buffer.pointer[offset] >= (yaml_char_t) 'a' && \
+ parser->buffer.pointer[offset] <= (yaml_char_t) 'f') ? \
+ (parser->buffer.pointer[offset] - (yaml_char_t) 'a' + 10) : \
+ (parser->buffer.pointer[offset] - (yaml_char_t) '0'))
#define AS_HEX(parser) AS_HEX_AT(parser,0)
@@ -583,9 +577,9 @@
* Check if the character at the specified position is BOM.
*/
-#define IS_BOM_AT(parser,offset) \
- (CHECK_AT(parser,'\xEF',(offset)) \
- && CHECK_AT(parser,'\xBB',(offset)+1) \
+#define IS_BOM_AT(parser,offset) \
+ (CHECK_AT(parser,'\xEF',(offset)) \
+ && CHECK_AT(parser,'\xBB',(offset)+1) \
&& CHECK_AT(parser,'\xBF',(offset)+1)) /* BOM (#xFEFF) */
#define IS_BOM(parser) IS_BOM_AT(parser,0)
@@ -619,21 +613,21 @@
* Check if the character at the specified position is a line break.
*/
-#define IS_BREAK_AT(parser,offset) \
- (CHECK_AT(parser,'\r',(offset)) /* CR (#xD)*/ \
- || CHECK_AT(parser,'\n',(offset)) /* LF (#xA) */ \
- || (CHECK_AT(parser,'\xC2',(offset)) \
- && CHECK_AT(parser,'\x85',(offset)+1)) /* NEL (#x85) */ \
- || (CHECK_AT(parser,'\xE2',(offset)) \
- && CHECK_AT(parser,'\x80',(offset)+1) \
- && CHECK_AT(parser,'\xA8',(offset)+2)) /* LS (#x2028) */ \
- || (CHECK_AT(parser,'\xE2',(offset)) \
- && CHECK_AT(parser,'\x80',(offset)+1) \
+#define IS_BREAK_AT(parser,offset) \
+ (CHECK_AT(parser,'\r',(offset)) /* CR (#xD)*/ \
+ || CHECK_AT(parser,'\n',(offset)) /* LF (#xA) */ \
+ || (CHECK_AT(parser,'\xC2',(offset)) \
+ && CHECK_AT(parser,'\x85',(offset)+1)) /* NEL (#x85) */ \
+ || (CHECK_AT(parser,'\xE2',(offset)) \
+ && CHECK_AT(parser,'\x80',(offset)+1) \
+ && CHECK_AT(parser,'\xA8',(offset)+2)) /* LS (#x2028) */ \
+ || (CHECK_AT(parser,'\xE2',(offset)) \
+ && CHECK_AT(parser,'\x80',(offset)+1) \
&& CHECK_AT(parser,'\xA9',(offset)+2))) /* PS (#x2029) */
#define IS_BREAK(parser) IS_BREAK_AT(parser,0)
-#define IS_CRLF_AT(parser,offset) \
+#define IS_CRLF_AT(parser,offset) \
(CHECK_AT(parser,'\r',(offset)) && CHECK_AT(parser,'\n',(offset)+1))
#define IS_CRLF(parser) IS_CRLF_AT(parser,0)
@@ -642,7 +636,7 @@
* Check if the character is a line break or NUL.
*/
-#define IS_BREAKZ_AT(parser,offset) \
+#define IS_BREAKZ_AT(parser,offset) \
(IS_BREAK_AT(parser,(offset)) || IS_Z_AT(parser,(offset)))
#define IS_BREAKZ(parser) IS_BREAKZ_AT(parser,0)
@@ -651,7 +645,7 @@
* Check if the character is a line break, space, or NUL.
*/
-#define IS_SPACEZ_AT(parser,offset) \
+#define IS_SPACEZ_AT(parser,offset) \
(IS_SPACE_AT(parser,(offset)) || IS_BREAKZ_AT(parser,(offset)))
#define IS_SPACEZ(parser) IS_SPACEZ_AT(parser,0)
@@ -660,7 +654,7 @@
* Check if the character is a line break, space, tab, or NUL.
*/
-#define IS_BLANKZ_AT(parser,offset) \
+#define IS_BLANKZ_AT(parser,offset) \
(IS_BLANK_AT(parser,(offset)) || IS_BREAKZ_AT(parser,(offset)))
#define IS_BLANKZ(parser) IS_BLANKZ_AT(parser,0)
@@ -669,11 +663,11 @@
* Determine the width of the character.
*/
-#define WIDTH_AT(parser,offset) \
- ((parser->pointer[(offset)] & 0x80) == 0x00 ? 1 : \
- (parser->pointer[(offset)] & 0xE0) == 0xC0 ? 2 : \
- (parser->pointer[(offset)] & 0xF0) == 0xE0 ? 3 : \
- (parser->pointer[(offset)] & 0xF8) == 0xF0 ? 4 : 0)
+#define WIDTH_AT(parser,offset) \
+ ((parser->buffer.pointer[offset] & 0x80) == 0x00 ? 1 : \
+ (parser->buffer.pointer[offset] & 0xE0) == 0xC0 ? 2 : \
+ (parser->buffer.pointer[offset] & 0xF0) == 0xE0 ? 3 : \
+ (parser->buffer.pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
#define WIDTH(parser) WIDTH_AT(parser,0)
@@ -681,156 +675,157 @@
* Advance the buffer pointer.
*/
-#define FORWARD(parser) \
- (parser->index ++, \
- parser->column ++, \
- parser->unread --, \
- parser->pointer += WIDTH(parser))
-
-#define FORWARD_LINE(parser) \
- (IS_CRLF(parser) ? \
- (parser->index += 2, \
- parser->column = 0, \
- parser->line ++, \
- parser->unread -= 2, \
- parser->pointer += 2) : \
- IS_BREAK(parser) ? \
- (parser->index ++, \
- parser->column = 0, \
- parser->line ++, \
- parser->unread --, \
- parser->pointer += WIDTH(parser)) : 0)
-
-/*
- * Resize a string if needed.
- */
+#define SKIP(parser) \
+ (parser->mark.index ++, \
+ parser->mark.column ++, \
+ parser->unread --, \
+ parser->buffer.pointer += WIDTH(parser))
-#define RESIZE(parser,string) \
- ((string).pointer-(string).buffer+5 < (string).size ? 1 : \
- yaml_parser_resize_string(parser, &(string)))
+#define SKIP_LINE(parser) \
+ (IS_CRLF(parser) ? \
+ (parser->mark.index += 2, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread -= 2, \
+ parser->buffer.pointer += 2) : \
+ IS_BREAK(parser) ? \
+ (parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --, \
+ parser->buffer.pointer += WIDTH(parser)) : 0)
/*
* Copy a character to a string buffer and advance pointers.
*/
-#define COPY(parser,string) \
- (((*parser->pointer & 0x80) == 0x00 ? \
- (*((string).pointer++) = *(parser->pointer++)) : \
- (*parser->pointer & 0xE0) == 0xC0 ? \
- (*((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++)) : \
- (*parser->pointer & 0xF0) == 0xE0 ? \
- (*((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++)) : \
- (*parser->pointer & 0xF8) == 0xF0 ? \
- (*((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++)) : 0), \
- parser->index ++, \
- parser->column ++, \
- parser->unread --)
+#define READ(parser,string) \
+ (STRING_EXTEND(parser,string) ? \
+ (((*parser->buffer.pointer & 0x80) == 0x00 ? \
+ (*((string).pointer++) = *(parser->buffer.pointer++)) : \
+ (*parser->buffer.pointer & 0xE0) == 0xC0 ? \
+ (*((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++)) : \
+ (*parser->buffer.pointer & 0xF0) == 0xE0 ? \
+ (*((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++)) : \
+ (*parser->buffer.pointer & 0xF8) == 0xF0 ? \
+ (*((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++)) : 0), \
+ parser->mark.index ++, \
+ parser->mark.column ++, \
+ parser->unread --, \
+ 1) : 0)
/*
* Copy a line break character to a string buffer and advance pointers.
*/
-#define COPY_LINE(parser,string) \
- ((CHECK_AT(parser,'\r',0) && CHECK_AT(parser,'\n',1)) ? /* CR LF -> LF */ \
+#define READ_LINE(parser,string) \
+ (STRING_EXTEND(parser,string) ? \
+ (((CHECK_AT(parser,'\r',0) && CHECK_AT(parser,'\n',1)) ? /* CR LF -> LF */ \
(*((string).pointer++) = (yaml_char_t) '\n', \
- parser->pointer += 2, \
- parser->index += 2, \
- parser->column = 0, \
- parser->line ++, \
+ parser->buffer.pointer += 2, \
+ parser->mark.index += 2, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
parser->unread -= 2) : \
(CHECK_AT(parser,'\r',0) || CHECK_AT(parser,'\n',0)) ? /* CR|LF -> LF */ \
(*((string).pointer++) = (yaml_char_t) '\n', \
- parser->pointer ++, \
- parser->index ++, \
- parser->column = 0, \
- parser->line ++, \
+ parser->buffer.pointer ++, \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
parser->unread --) : \
(CHECK_AT(parser,'\xC2',0) && CHECK_AT(parser,'\x85',1)) ? /* NEL -> LF */ \
(*((string).pointer++) = (yaml_char_t) '\n', \
- parser->pointer += 2, \
- parser->index ++, \
- parser->column = 0, \
- parser->line ++, \
+ parser->buffer.pointer += 2, \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
parser->unread --) : \
(CHECK_AT(parser,'\xE2',0) && \
CHECK_AT(parser,'\x80',1) && \
(CHECK_AT(parser,'\xA8',2) || \
CHECK_AT(parser,'\xA9',2))) ? /* LS|PS -> LS|PS */ \
- (*((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++), \
- *((string).pointer++) = *(parser->pointer++), \
- parser->index ++, \
- parser->column = 0, \
- parser->line ++, \
- parser->unread --) : 0)
+ (*((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ *((string).pointer++) = *(parser->buffer.pointer++), \
+ parser->mark.index ++, \
+ parser->mark.column = 0, \
+ parser->mark.line ++, \
+ parser->unread --) : 0), \
+ 1) : 0)
/*
- * Append a string to another string and clear the former string.
+ * Token initializers.
*/
-#define JOIN(parser,head_string,tail_string) \
- (yaml_parser_join_string(parser, &(head_string), &(tail_string)) && \
- yaml_parser_clear_string(parser, &(tail_string)))
+#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
+ (memset(&(token), 0, sizeof(yaml_token_t)), \
+ (token).type = (token_type), \
+ (token).start_mark = (token_start_mark), \
+ (token).end_mark = (token_end_mark))
-/*
- * Public API declarations.
- */
+#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
+ (token).data.stream_start.encoding = (token_encoding))
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_get_token(yaml_parser_t *parser);
+#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_peek_token(yaml_parser_t *parser);
-
-/*
- * Error handling.
- */
+#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
+ (token).data.alias.value = (token_value))
-static int
-yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
- yaml_mark_t context_mark, const char *problem);
+#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
+ (token).data.anchor.value = (token_value))
-static yaml_mark_t
-yaml_parser_get_mark(yaml_parser_t *parser);
+#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
+ (token).data.tag.handle = (token_handle), \
+ (token).data.tag.suffix = (token_suffix))
-/*
- * Buffers and lists.
- */
+#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
+ (token).data.scalar.value = (token_value), \
+ (token).data.scalar.length = (token_length), \
+ (token).data.scalar.style = (token_style))
-typedef struct {
- yaml_char_t *buffer;
- yaml_char_t *pointer;
- size_t size;
-} yaml_string_t;
+#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
+ (token).data.version_directive.major = (token_major), \
+ (token).data.version_directive.minor = (token_minor))
-static yaml_string_t
-yaml_parser_new_string(yaml_parser_t *parser);
+#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
+ (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
+ (token).data.tag_directive.handle = (token_handle), \
+ (token).data.tag_directive.prefix = (token_prefix))
-static int
-yaml_parser_resize_string(yaml_parser_t *parser, yaml_string_t *string);
+/*
+ * Public API declarations.
+ */
-static int
-yaml_parser_join_string(yaml_parser_t *parser,
- yaml_string_t *string1, yaml_string_t *string2);
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
-static int
-yaml_parser_clear_string(yaml_parser_t *parser, yaml_string_t *string);
+/*
+ * Error handling.
+ */
static int
-yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
- size_t item_size);
+yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
+ yaml_mark_t context_mark, const char *problem);
/*
* High-level token API.
*/
-static int
+YAML_DECLARE(int)
yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
static int
@@ -856,17 +851,6 @@ static int
yaml_parser_decrease_flow_level(yaml_parser_t *parser);
/*
- * Token manipulation.
- */
-
-static int
-yaml_parser_append_token(yaml_parser_t *parser, yaml_token_t *token);
-
-static int
-yaml_parser_insert_token(yaml_parser_t *parser,
- int number, yaml_token_t *token);
-
-/*
* Indentation treatment.
*/
@@ -936,8 +920,8 @@ yaml_parser_fetch_plain_scalar(yaml_parser_t *parser);
static int
yaml_parser_scan_to_next_token(yaml_parser_t *parser);
-static yaml_token_t *
-yaml_parser_scan_directive(yaml_parser_t *parser);
+static int
+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token);
static int
yaml_parser_scan_directive_name(yaml_parser_t *parser,
@@ -955,12 +939,12 @@ static int
yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix);
-static yaml_token_t *
-yaml_parser_scan_anchor(yaml_parser_t *parser,
+static int
+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
yaml_token_type_t type);
-static yaml_token_t *
-yaml_parser_scan_tag(yaml_parser_t *parser);
+static int
+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token);
static int
yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
@@ -974,178 +958,57 @@ static int
yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
yaml_mark_t start_mark, yaml_string_t *string);
-static yaml_token_t *
-yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal);
+static int
+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int literal);
static int
yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
int *indent, yaml_string_t *breaks,
yaml_mark_t start_mark, yaml_mark_t *end_mark);
-static yaml_token_t *
-yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single);
+static int
+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int single);
-static yaml_token_t *
-yaml_parser_scan_plain_scalar(yaml_parser_t *parser);
+static int
+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token);
/*
- * Get the next token and remove it from the tokens queue.
+ * Get the next token.
*/
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_get_token(yaml_parser_t *parser)
+YAML_DECLARE(int)
+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
{
- yaml_token_t *token;
-
assert(parser); /* Non-NULL parser object is expected. */
- assert(!parser->stream_end_produced); /* No tokens after STREAM-END. */
-
- /* Ensure that the tokens queue contains enough tokens. */
-
- if (!yaml_parser_fetch_more_tokens(parser)) return NULL;
-
- /* Fetch the next token from the queue. */
-
- token = parser->tokens[parser->tokens_head];
+ assert(token); /* Non-NULL token object is expected. */
- /* Move the queue head. */
+ /* No tokens after STREAM-END or error. */
- parser->tokens[parser->tokens_head++] = NULL;
+ if (parser->stream_end_produced || parser->error) {
+ memset(token, 0, sizeof(yaml_token_t));
- parser->tokens_parsed++;
-
- if (token->type == YAML_STREAM_END_TOKEN) {
- parser->stream_end_produced = 1;
+ return 1;
}
- return token;
-}
-
-/*
- * Get the next token, but don't remove it from the queue.
- */
-
-YAML_DECLARE(yaml_token_t *)
-yaml_parser_peek_token(yaml_parser_t *parser)
-{
- assert(parser); /* Non-NULL parser object is expected. */
- assert(!parser->stream_end_produced); /* No tokens after STREAM-END. */
-
/* Ensure that the tokens queue contains enough tokens. */
- if (!yaml_parser_fetch_more_tokens(parser)) return NULL;
-
- /* Fetch the next token from the queue. */
-
- return parser->tokens[parser->tokens_head];
-}
-
-/*
- * Create a new string.
- */
-
-static yaml_string_t
-yaml_parser_new_string(yaml_parser_t *parser)
-{
- yaml_string_t string = { NULL, NULL, 0 };
-
- string.buffer = yaml_malloc(YAML_DEFAULT_SIZE);
- if (!string.buffer) {
- parser->error = YAML_MEMORY_ERROR;
- return string;
- }
-
- memset(string.buffer, 0, YAML_DEFAULT_SIZE);
- string.pointer = string.buffer;
- string.size = YAML_DEFAULT_SIZE;
-
- return string;
-}
-
-/*
- * Double the size of a string.
- */
-
-static int
-yaml_parser_resize_string(yaml_parser_t *parser, yaml_string_t *string)
-{
- yaml_char_t *new_buffer = yaml_realloc(string->buffer, string->size*2);
-
- if (!new_buffer) {
- yaml_free(string->buffer);
- string->buffer = NULL;
- string->pointer = NULL;
- string->size = 0;
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- memset(new_buffer+string->size, 0, string->size);
-
- string->pointer = new_buffer + (string->pointer-string->buffer);
- string->buffer = new_buffer;
- string->size *= 2;
-
- return 1;
-}
-
-/*
- * Append a string to another string.
- */
-
-static int
-yaml_parser_join_string(yaml_parser_t *parser,
- yaml_string_t *string1, yaml_string_t *string2)
-{
- if (string2->buffer == string2->pointer) return 1;
-
- while (string1->pointer - string1->buffer + string2->pointer - string2->buffer + 1
- > string1->size) {
- if (!yaml_parser_resize_string(parser, string1)) return 0;
+ if (!parser->token_available) {
+ if (!yaml_parser_fetch_more_tokens(parser))
+ return 0;
}
- memcpy(string1->pointer, string2->buffer, string2->pointer-string2->buffer);
- string1->pointer += string2->pointer-string2->buffer;
-
- return 1;
-}
-
-/*
- * Fill the string with NULs and move the pointer to the beginning.
- */
-
-static int
-yaml_parser_clear_string(yaml_parser_t *parser, yaml_string_t *string)
-{
- if (string->buffer == string->pointer) return 1;
-
- memset(string->buffer, 0, string->pointer-string->buffer);
-
- string->pointer = string->buffer;
-
- return 1;
-}
-
-/*
- * Double a list.
- */
-
-static int
-yaml_parser_resize_list(yaml_parser_t *parser, void **buffer, size_t *size,
- size_t item_size)
-{
- void *new_buffer = yaml_realloc(*buffer, item_size*(*size)*2);
+ /* Fetch the next token from the queue. */
+
+ *token = DEQUEUE(parser, parser->tokens);
+ parser->token_available = 0;
+ parser->tokens_parsed ++;
- if (!new_buffer) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
+ if (token->type == YAML_STREAM_END_TOKEN) {
+ parser->stream_end_produced = 1;
}
- memset(new_buffer+item_size*(*size), 0, item_size*(*size));
-
- *buffer = new_buffer;
- *size *= 2;
-
return 1;
}
@@ -1161,34 +1024,20 @@ yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
parser->context = context;
parser->context_mark = context_mark;
parser->problem = problem;
- parser->problem_mark = yaml_parser_get_mark(parser);
+ parser->problem_mark = parser->mark;
return 0;
}
/*
- * Get the mark for the current buffer position.
- */
-
-static yaml_mark_t
-yaml_parser_get_mark(yaml_parser_t *parser)
-{
- yaml_mark_t mark = { parser->index, parser->line, parser->column };
-
- return mark;
-}
-
-
-/*
* Ensure that the tokens queue contains at least one token which can be
* returned to the Parser.
*/
-static int
+YAML_DECLARE(int)
yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
{
int need_more_tokens;
- int k;
/* While we need more tokens to fetch, do it. */
@@ -1200,7 +1049,7 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
need_more_tokens = 0;
- if (parser->tokens_head == parser->tokens_tail)
+ if (parser->tokens.head == parser->tokens.tail)
{
/* Queue is empty. */
@@ -1208,15 +1057,17 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
}
else
{
+ yaml_simple_key_t *simple_key;
+
/* Check if any potential simple key may occupy the head position. */
if (!yaml_parser_stale_simple_keys(parser))
return 0;
- for (k = 0; k <= parser->flow_level; k++) {
- yaml_simple_key_t *simple_key = parser->simple_keys[k];
- if (simple_key
- && (simple_key->token_number == parser->tokens_parsed)) {
+ for (simple_key = parser->simple_keys.start;
+ simple_key != parser->simple_keys.top; simple_key++) {
+ if (simple_key->possible
+ && simple_key->token_number == parser->tokens_parsed) {
need_more_tokens = 1;
break;
}
@@ -1234,6 +1085,8 @@ yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
return 0;
}
+ parser->token_available = 1;
+
return 1;
}
@@ -1246,7 +1099,7 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
{
/* Ensure that the buffer is initialized. */
- if (!UPDATE(parser, 1))
+ if (!CACHE(parser, 1))
return 0;
/* Check if we just started scanning. Fetch STREAM-START then. */
@@ -1266,7 +1119,7 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
/* Check the indentation level against the current column. */
- if (!yaml_parser_unroll_indent(parser, parser->column))
+ if (!yaml_parser_unroll_indent(parser, parser->mark.column))
return 0;
/*
@@ -1274,7 +1127,7 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
* of the longest indicators ('--- ' and '... ').
*/
- if (!UPDATE(parser, 4))
+ if (!CACHE(parser, 4))
return 0;
/* Is it the end of the stream? */
@@ -1284,12 +1137,12 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
/* Is it a directive? */
- if (parser->column == 0 && CHECK(parser, '%'))
+ if (parser->mark.column == 0 && CHECK(parser, '%'))
return yaml_parser_fetch_directive(parser);
/* Is it the document start indicator? */
- if (parser->column == 0
+ if (parser->mark.column == 0
&& CHECK_AT(parser, '-', 0)
&& CHECK_AT(parser, '-', 1)
&& CHECK_AT(parser, '-', 2)
@@ -1299,7 +1152,7 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
/* Is it the document end indicator? */
- if (parser->column == 0
+ if (parser->mark.column == 0
&& CHECK_AT(parser, '.', 0)
&& CHECK_AT(parser, '.', 1)
&& CHECK_AT(parser, '.', 2)
@@ -1421,8 +1274,9 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
* If we don't determine the token type so far, it is an error.
*/
- return yaml_parser_set_scanner_error(parser, "while scanning for the next token",
- yaml_parser_get_mark(parser), "found character that cannot start any token");
+ return yaml_parser_set_scanner_error(parser,
+ "while scanning for the next token", parser->mark,
+ "found character that cannot start any token");
}
/*
@@ -1433,14 +1287,13 @@ yaml_parser_fetch_next_token(yaml_parser_t *parser)
static int
yaml_parser_stale_simple_keys(yaml_parser_t *parser)
{
- int level;
+ yaml_simple_key_t *simple_key;
/* Check for a potential simple key for each flow level. */
- for (level = 0; level <= parser->flow_level; level++)
+ for (simple_key = parser->simple_keys.start;
+ simple_key != parser->simple_keys.top; simple_key ++)
{
- yaml_simple_key_t *simple_key = parser->simple_keys[level];
-
/*
* The specification requires that a simple key
*
@@ -1448,8 +1301,9 @@ yaml_parser_stale_simple_keys(yaml_parser_t *parser)
* - is shorter than 1024 characters.
*/
- if (simple_key && (simple_key->line < parser->line ||
- simple_key->index+1024 < parser->index)) {
+ if (simple_key->possible
+ && (simple_key->mark.line < parser->mark.line
+ || simple_key->mark.index+1024 < parser->mark.index)) {
/* Check if the potential simple key to be removed is required. */
@@ -1459,8 +1313,7 @@ yaml_parser_stale_simple_keys(yaml_parser_t *parser)
"could not found expected ':'");
}
- yaml_free(simple_key);
- parser->simple_keys[level] = NULL;
+ simple_key->possible = 0;
}
}
@@ -1481,7 +1334,8 @@ yaml_parser_save_simple_key(yaml_parser_t *parser)
* level.
*/
- int required = (!parser->flow_level && parser->indent == parser->column);
+ int required = (!parser->flow_level
+ && parser->indent == parser->mark.column);
/*
* A simple key is required only when it is the first token in the current
@@ -1496,21 +1350,13 @@ yaml_parser_save_simple_key(yaml_parser_t *parser)
if (parser->simple_key_allowed)
{
- yaml_simple_key_t simple_key = { required,
- parser->tokens_parsed + parser->tokens_tail - parser->tokens_head,
- parser->index, parser->line, parser->column,
- yaml_parser_get_mark(parser) };
+ yaml_simple_key_t simple_key = { 1, required,
+ parser->tokens_parsed + parser->tokens.tail - parser->tokens.head,
+ parser->mark };
if (!yaml_parser_remove_simple_key(parser)) return 0;
- parser->simple_keys[parser->flow_level] =
- yaml_malloc(sizeof(yaml_simple_key_t));
- if (!parser->simple_keys[parser->flow_level]) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- *(parser->simple_keys[parser->flow_level]) = simple_key;
+ *(parser->simple_keys.top-1) = simple_key;
}
return 1;
@@ -1523,9 +1369,9 @@ yaml_parser_save_simple_key(yaml_parser_t *parser)
static int
yaml_parser_remove_simple_key(yaml_parser_t *parser)
{
- yaml_simple_key_t *simple_key = parser->simple_keys[parser->flow_level];
+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
- if (simple_key)
+ if (simple_key->possible)
{
/* If the key is required, it is an error. */
@@ -1534,12 +1380,11 @@ yaml_parser_remove_simple_key(yaml_parser_t *parser)
"while scanning a simple key", simple_key->mark,
"could not found expected ':'");
}
+ }
- /* Remove the key from the list. */
+ /* Remove the key from the stack. */
- yaml_free(simple_key);
- parser->simple_keys[parser->flow_level] = NULL;
- }
+ simple_key->possible = 0;
return 1;
}
@@ -1551,17 +1396,16 @@ yaml_parser_remove_simple_key(yaml_parser_t *parser)
static int
yaml_parser_increase_flow_level(yaml_parser_t *parser)
{
- /* Check if we need to resize the list. */
+ yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } };
- if (parser->flow_level == parser->simple_keys_size-1) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->simple_keys,
- &parser->simple_keys_size, sizeof(yaml_simple_key_t *)))
- return 0;
- }
+ /* Reset the simple key on the next level. */
- /* Increase the flow level and reset the simple key. */
+ if (!PUSH(parser, parser->simple_keys, empty_simple_key))
+ return 0;
+
+ /* Increase the flow level. */
- parser->simple_keys[++parser->flow_level] = NULL;
+ parser->flow_level++;
return 1;
}
@@ -1573,75 +1417,11 @@ yaml_parser_increase_flow_level(yaml_parser_t *parser)
static int
yaml_parser_decrease_flow_level(yaml_parser_t *parser)
{
- assert(parser->flow_level); /* Greater than 0. */
- assert(!parser->simple_keys[parser->flow_level]); /* Must be removed. */
-
- parser->flow_level --;
-
- return 1;
-}
-
-/*
- * Add a token to the tail of the tokens queue.
- */
-
-static int
-yaml_parser_append_token(yaml_parser_t *parser, yaml_token_t *token)
-{
- return yaml_parser_insert_token(parser, -1, token);
-}
-
-/*
- * Insert the token into the tokens queue. The number parameter is the
- * ordinal number of the token. If the number is equal to -1, add the token
- * to the tail of the queue.
- */
-
-static int
-yaml_parser_insert_token(yaml_parser_t *parser,
- int number, yaml_token_t *token)
-{
- /* The index of the token in the queue. */
-
- int index = (number == -1)
- ? parser->tokens_tail - parser->tokens_head
- : number - parser->tokens_parsed;
-
- assert(index >= 0 && index <= (parser->tokens_tail-parser->tokens_head));
-
- /* Check if we need to resize the queue. */
-
- if (parser->tokens_head == 0 && parser->tokens_tail == parser->tokens_size) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->tokens,
- &parser->tokens_size, sizeof(yaml_token_t *)))
- return 0;
- }
-
- /* Check if we need to move the queue to the beginning of the buffer. */
-
- if (parser->tokens_tail == parser->tokens_size)
- {
- if (parser->tokens_head < parser->tokens_tail) {
- memmove(parser->tokens, parser->tokens+parser->tokens_head,
- sizeof(yaml_token_t *)*(parser->tokens_tail-parser->tokens_head));
- }
- parser->tokens_tail -= parser->tokens_head;
- parser->tokens_head = 0;
+ if (parser->flow_level) {
+ parser->flow_level --;
+ POP(parser, parser->simple_keys);
}
- /* Check if we need to free space within the queue. */
-
- if (index < (parser->tokens_tail-parser->tokens_head)) {
- memmove(parser->tokens+parser->tokens_head+index+1,
- parser->tokens+parser->tokens_head+index,
- sizeof(yaml_token_t *)*(parser->tokens_tail-parser->tokens_head-index));
- }
-
- /* Insert the token. */
-
- parser->tokens[parser->tokens_head+index] = token;
- parser->tokens_tail ++;
-
return 1;
}
@@ -1656,7 +1436,7 @@ static int
yaml_parser_roll_indent(yaml_parser_t *parser, int column,
int number, yaml_token_type_t type, yaml_mark_t mark)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* In the flow context, do nothing. */
@@ -1665,35 +1445,28 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column,
if (parser->indent < column)
{
- /* Check if we need to expand the indents stack. */
-
- if (parser->indents_length == parser->indents_size) {
- if (!yaml_parser_resize_list(parser, (void **)&parser->indents,
- &parser->indents_size, sizeof(int)))
- return 0;
- }
-
/*
* Push the current indentation level to the stack and set the new
* indentation level.
*/
- parser->indents[parser->indents_length++] = parser->indent;
+ if (!PUSH(parser, parser->indents, parser->indent))
+ return 0;
+
parser->indent = column;
- /* Create a token. */
+ /* Create a token and insert it into the queue. */
- token = yaml_token_new(type, mark, mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Insert the token into the queue. */
+ TOKEN_INIT(token, type, mark, mark);
- if (!yaml_parser_insert_token(parser, number, token)) {
- yaml_token_delete(token);
- return 0;
+ if (number == -1) {
+ if (!ENQUEUE(parser, parser->tokens, token))
+ return 0;
+ }
+ else {
+ if (!QUEUE_INSERT(parser,
+ parser->tokens, number - parser->tokens_parsed, token))
+ return 0;
}
}
@@ -1710,7 +1483,7 @@ yaml_parser_roll_indent(yaml_parser_t *parser, int column,
static int
yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* In the flow context, do nothing. */
@@ -1721,28 +1494,16 @@ yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
while (parser->indent > column)
{
- yaml_mark_t mark = yaml_parser_get_mark(parser);
+ /* Create a token and append it to the queue. */
- /* Create a token. */
+ TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
- token = yaml_token_new(YAML_BLOCK_END_TOKEN, mark, mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
-
- /* Append the token to the queue. */
-
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
- return 0;
- }
/* Pop the indentation level. */
- assert(parser->indents_length); /* Non-empty stack expected. */
-
- parser->indent = parser->indents[--parser->indents_length];
+ parser->indent = POP(parser, parser->indents);
}
return 1;
@@ -1755,13 +1516,18 @@ yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
static int
yaml_parser_fetch_stream_start(yaml_parser_t *parser)
{
- yaml_mark_t mark = yaml_parser_get_mark(parser);
- yaml_token_t *token;
+ yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } };
+ yaml_token_t token;
/* Set the initial indentation. */
parser->indent = -1;
+ /* Initialize the simple key stack. */
+
+ if (!PUSH(parser, parser->simple_keys, simple_key))
+ return 0;
+
/* A simple key is allowed at the beginning of the stream. */
parser->simple_key_allowed = 1;
@@ -1770,20 +1536,13 @@ yaml_parser_fetch_stream_start(yaml_parser_t *parser)
parser->stream_start_produced = 1;
- /* Create the STREAM-START token. */
+ /* Create the STREAM-START token and append it to the queue. */
- token = yaml_stream_start_token_new(parser->encoding, mark, mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Append the token to the queue. */
+ STREAM_START_TOKEN_INIT(token, parser->encoding,
+ parser->mark, parser->mark);
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -1795,8 +1554,7 @@ yaml_parser_fetch_stream_start(yaml_parser_t *parser)
static int
yaml_parser_fetch_stream_end(yaml_parser_t *parser)
{
- yaml_mark_t mark = yaml_parser_get_mark(parser);
- yaml_token_t *token;
+ yaml_token_t token;
/* Reset the indentation level. */
@@ -1810,32 +1568,24 @@ yaml_parser_fetch_stream_end(yaml_parser_t *parser)
parser->simple_key_allowed = 0;
- /* Create the STREAM-END token. */
+ /* Create the STREAM-END token and append it to the queue. */
- token = yaml_stream_end_token_new(mark, mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Append the token to the queue. */
+ STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark);
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
/*
- * Produce the YAML-DIRECTIVE or TAG-DIRECTIVE token.
+ * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
*/
static int
yaml_parser_fetch_directive(yaml_parser_t *parser)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* Reset the indentation level. */
@@ -1851,13 +1601,13 @@ yaml_parser_fetch_directive(yaml_parser_t *parser)
/* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
- token = yaml_parser_scan_directive(parser);
- if (!token) return 0;
+ if (!yaml_parser_scan_directive(parser, &token))
+ return 0;
/* Append the token to the queue. */
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
@@ -1873,7 +1623,7 @@ yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
yaml_token_type_t type)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* Reset the indentation level. */
@@ -1889,28 +1639,22 @@ yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
- FORWARD(parser);
- FORWARD(parser);
- FORWARD(parser);
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Create the DOCUMENT-START or DOCUMENT-END token. */
- token = yaml_token_new(type, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ TOKEN_INIT(token, type, start_mark, end_mark);
/* Append the token to the queue. */
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -1924,7 +1668,7 @@ yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
yaml_token_type_t type)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* The indicators '[' and '{' may start a simple key. */
@@ -1942,24 +1686,18 @@ yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
/* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
- token = yaml_token_new(type, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ TOKEN_INIT(token, type, start_mark, end_mark);
/* Append the token to the queue. */
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -1973,7 +1711,7 @@ yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
yaml_token_type_t type)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* Reset any potential simple key on the current flow level. */
@@ -1991,24 +1729,18 @@ yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
/* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
- token = yaml_token_new(type, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ TOKEN_INIT(token, type, start_mark, end_mark);
/* Append the token to the queue. */
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -2021,7 +1753,7 @@ static int
yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* Reset any potential simple keys on the current flow level. */
@@ -2034,24 +1766,16 @@ yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
- /* Create the FLOW-ENTRY token. */
+ /* Create the FLOW-ENTRY token and append it to the queue. */
- token = yaml_token_new(YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
- /* Append the token to the queue. */
-
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -2064,7 +1788,7 @@ static int
yaml_parser_fetch_block_entry(yaml_parser_t *parser)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* Check if the scanner is in the block context. */
@@ -2073,15 +1797,14 @@ yaml_parser_fetch_block_entry(yaml_parser_t *parser)
/* Check if we are allowed to start a new entry. */
if (!parser->simple_key_allowed) {
- return yaml_parser_set_scanner_error(parser, NULL,
- yaml_parser_get_mark(parser),
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
"block sequence entries are not allowed in this context");
}
/* Add the BLOCK-SEQUENCE-START token if needed. */
- if (!yaml_parser_roll_indent(parser, parser->column, -1,
- YAML_BLOCK_SEQUENCE_START_TOKEN, yaml_parser_get_mark(parser)))
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark))
return 0;
}
else
@@ -2104,24 +1827,16 @@ yaml_parser_fetch_block_entry(yaml_parser_t *parser)
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
- /* Create the BLOCK-ENTRY token. */
+ /* Create the BLOCK-ENTRY token and append it to the queue. */
- token = yaml_token_new(YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Append the token to the queue. */
+ TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -2134,7 +1849,7 @@ static int
yaml_parser_fetch_key(yaml_parser_t *parser)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
/* In the block context, additional checks are required. */
@@ -2143,15 +1858,14 @@ yaml_parser_fetch_key(yaml_parser_t *parser)
/* Check if we are allowed to start a new key (not nessesary simple). */
if (!parser->simple_key_allowed) {
- return yaml_parser_set_scanner_error(parser, NULL,
- yaml_parser_get_mark(parser),
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
"mapping keys are not allowed in this context");
}
/* Add the BLOCK-MAPPING-START token if needed. */
- if (!yaml_parser_roll_indent(parser, parser->column, -1,
- YAML_BLOCK_MAPPING_START_TOKEN, yaml_parser_get_mark(parser)))
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
return 0;
}
@@ -2166,24 +1880,16 @@ yaml_parser_fetch_key(yaml_parser_t *parser)
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
- /* Create the KEY token. */
+ /* Create the KEY token and append it to the queue. */
- token = yaml_token_new(YAML_KEY_TOKEN, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Append the token to the queue. */
+ TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark);
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -2196,40 +1902,32 @@ static int
yaml_parser_fetch_value(yaml_parser_t *parser)
{
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token;
+ yaml_token_t token;
+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
/* Have we found a simple key? */
- if (parser->simple_keys[parser->flow_level])
+ if (simple_key->possible)
{
- yaml_simple_key_t *simple_key = parser->simple_keys[parser->flow_level];
-
- /* Create the KEY token. */
- token = yaml_token_new(YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ /* Create the KEY token and insert it into the queue. */
- /* Insert the token into the queue. */
+ TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
- if (!yaml_parser_insert_token(parser, simple_key->token_number, token)) {
- yaml_token_delete(token);
+ if (!QUEUE_INSERT(parser, parser->tokens,
+ simple_key->token_number - parser->tokens_parsed, token))
return 0;
- }
/* In the block context, we may need to add the BLOCK-MAPPING-START token. */
- if (!yaml_parser_roll_indent(parser, simple_key->column,
+ if (!yaml_parser_roll_indent(parser, simple_key->mark.column,
simple_key->token_number,
YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark))
return 0;
- /* Remove the simple key from the list. */
+ /* Remove the simple key. */
- yaml_free(simple_key);
- parser->simple_keys[parser->flow_level] = NULL;
+ simple_key->possible = 0;
/* A simple key cannot follow another simple key. */
@@ -2246,15 +1944,14 @@ yaml_parser_fetch_value(yaml_parser_t *parser)
/* Check if we are allowed to start a complex value. */
if (!parser->simple_key_allowed) {
- return yaml_parser_set_scanner_error(parser, NULL,
- yaml_parser_get_mark(parser),
+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
"mapping values are not allowed in this context");
}
/* Add the BLOCK-MAPPING-START token if needed. */
- if (!yaml_parser_roll_indent(parser, parser->column, -1,
- YAML_BLOCK_MAPPING_START_TOKEN, yaml_parser_get_mark(parser)))
+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
return 0;
}
@@ -2265,24 +1962,16 @@ yaml_parser_fetch_value(yaml_parser_t *parser)
/* Consume the token. */
- start_mark = yaml_parser_get_mark(parser);
- FORWARD(parser);
- end_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
+ SKIP(parser);
+ end_mark = parser->mark;
- /* Create the VALUE token. */
+ /* Create the VALUE token and append it to the queue. */
- token = yaml_token_new(YAML_VALUE_TOKEN, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
-
- /* Append the token to the queue. */
+ TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark);
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token))
return 0;
- }
return 1;
}
@@ -2294,7 +1983,7 @@ yaml_parser_fetch_value(yaml_parser_t *parser)
static int
yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* An anchor or an alias could be a simple key. */
@@ -2305,18 +1994,15 @@ yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
parser->simple_key_allowed = 0;
- /* Create the ALIAS or ANCHOR token. */
-
- token = yaml_parser_scan_anchor(parser, type);
- if (!token) return 0;
+ /* Create the ALIAS or ANCHOR token and append it to the queue. */
- /* Append the token to the queue. */
+ if (!yaml_parser_scan_anchor(parser, &token, type))
+ return 0;
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
-
return 1;
}
@@ -2327,7 +2013,7 @@ yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
static int
yaml_parser_fetch_tag(yaml_parser_t *parser)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* A tag could be a simple key. */
@@ -2338,15 +2024,13 @@ yaml_parser_fetch_tag(yaml_parser_t *parser)
parser->simple_key_allowed = 0;
- /* Create the TAG token. */
-
- token = yaml_parser_scan_tag(parser);
- if (!token) return 0;
+ /* Create the TAG token and append it to the queue. */
- /* Append the token to the queue. */
+ if (!yaml_parser_scan_tag(parser, &token))
+ return 0;
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
@@ -2360,7 +2044,7 @@ yaml_parser_fetch_tag(yaml_parser_t *parser)
static int
yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* Remove any potential simple keys. */
@@ -2371,15 +2055,13 @@ yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
parser->simple_key_allowed = 1;
- /* Create the SCALAR token. */
-
- token = yaml_parser_scan_block_scalar(parser, literal);
- if (!token) return 0;
+ /* Create the SCALAR token and append it to the queue. */
- /* Append the token to the queue. */
+ if (!yaml_parser_scan_block_scalar(parser, &token, literal))
+ return 0;
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
@@ -2393,7 +2075,7 @@ yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
static int
yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* A plain scalar could be a simple key. */
@@ -2404,15 +2086,13 @@ yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
parser->simple_key_allowed = 0;
- /* Create the SCALAR token. */
-
- token = yaml_parser_scan_flow_scalar(parser, single);
- if (!token) return 0;
+ /* Create the SCALAR token and append it to the queue. */
- /* Append the token to the queue. */
+ if (!yaml_parser_scan_flow_scalar(parser, &token, single))
+ return 0;
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
@@ -2426,7 +2106,7 @@ yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
static int
yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
{
- yaml_token_t *token;
+ yaml_token_t token;
/* A plain scalar could be a simple key. */
@@ -2437,15 +2117,13 @@ yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
parser->simple_key_allowed = 0;
- /* Create the SCALAR token. */
+ /* Create the SCALAR token and append it to the queue. */
- token = yaml_parser_scan_plain_scalar(parser);
- if (!token) return 0;
-
- /* Append the token to the queue. */
+ if (!yaml_parser_scan_plain_scalar(parser, &token))
+ return 0;
- if (!yaml_parser_append_token(parser, token)) {
- yaml_token_delete(token);
+ if (!ENQUEUE(parser, parser->tokens, token)) {
+ yaml_token_delete(&token);
return 0;
}
@@ -2465,10 +2143,10 @@ yaml_parser_scan_to_next_token(yaml_parser_t *parser)
{
/* Allow the BOM mark to start a line. */
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
- if (parser->column == 0 && IS_BOM(parser))
- FORWARD(parser);
+ if (parser->mark.column == 0 && IS_BOM(parser))
+ SKIP(parser);
/*
* Eat whitespaces.
@@ -2480,21 +2158,21 @@ yaml_parser_scan_to_next_token(yaml_parser_t *parser)
* after '-', '?', or ':' (complex value).
*/
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
while (CHECK(parser,' ') ||
((parser->flow_level || !parser->simple_key_allowed) &&
CHECK(parser, '\t'))) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) return 0;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
}
/* Eat a comment until a line break. */
if (CHECK(parser, '#')) {
while (!IS_BREAKZ(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) return 0;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
}
}
@@ -2502,8 +2180,8 @@ yaml_parser_scan_to_next_token(yaml_parser_t *parser)
if (IS_BREAK(parser))
{
- if (!UPDATE(parser, 2)) return 0;
- FORWARD_LINE(parser);
+ if (!CACHE(parser, 2)) return 0;
+ SKIP_LINE(parser);
/* In the block context, a new line may start a simple key. */
@@ -2532,20 +2210,19 @@ yaml_parser_scan_to_next_token(yaml_parser_t *parser)
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*/
-static yaml_token_t *
-yaml_parser_scan_directive(yaml_parser_t *parser)
+int
+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
{
yaml_mark_t start_mark, end_mark;
yaml_char_t *name = NULL;
int major, minor;
yaml_char_t *handle = NULL, *prefix = NULL;
- yaml_token_t *token = NULL;
/* Eat '%'. */
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
- FORWARD(parser);
+ SKIP(parser);
/* Scan the directive name. */
@@ -2562,16 +2239,12 @@ yaml_parser_scan_directive(yaml_parser_t *parser)
&major, &minor))
goto error;
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Create a VERSION-DIRECTIVE token. */
- token = yaml_version_directive_token_new(major, minor,
+ VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor,
start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
}
/* Is it a TAG directive? */
@@ -2584,16 +2257,12 @@ yaml_parser_scan_directive(yaml_parser_t *parser)
&handle, &prefix))
goto error;
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Create a TAG-DIRECTIVE token. */
- token = yaml_tag_directive_token_new(handle, prefix,
+ TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix,
start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
}
/* Unknown directive. */
@@ -2607,15 +2276,17 @@ yaml_parser_scan_directive(yaml_parser_t *parser)
/* Eat the rest of the line including any comments. */
+ if (!CACHE(parser, 1)) goto error;
+
while (IS_BLANK(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
if (CHECK(parser, '#')) {
while (!IS_BREAKZ(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
}
@@ -2630,20 +2301,19 @@ yaml_parser_scan_directive(yaml_parser_t *parser)
/* Eat a line break. */
if (IS_BREAK(parser)) {
- if (!UPDATE(parser, 2)) goto error;
- FORWARD_LINE(parser);
+ if (!CACHE(parser, 2)) goto error;
+ SKIP_LINE(parser);
}
yaml_free(name);
- return token;
+ return 1;
error:
- yaml_free(token);
yaml_free(prefix);
yaml_free(handle);
yaml_free(name);
- return NULL;
+ return 0;
}
/*
@@ -2660,24 +2330,23 @@ static int
yaml_parser_scan_directive_name(yaml_parser_t *parser,
yaml_mark_t start_mark, yaml_char_t **name)
{
- yaml_string_t string = yaml_parser_new_string(parser);
+ yaml_string_t string = NULL_STRING;
- if (!string.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
/* Consume the directive name. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_ALPHA(parser))
{
- if (!RESIZE(parser, string)) goto error;
- COPY(parser, string);
- if (!UPDATE(parser, 1)) goto error;
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Check if the name is empty. */
- if (string.buffer == string.pointer) {
+ if (string.start == string.pointer) {
yaml_parser_set_scanner_error(parser, "while scanning a directive",
start_mark, "cannot found expected directive name");
goto error;
@@ -2691,12 +2360,12 @@ yaml_parser_scan_directive_name(yaml_parser_t *parser,
goto error;
}
- *name = string.buffer;
+ *name = string.start;
return 1;
error:
- yaml_free(string.buffer);
+ STRING_DEL(parser, string);
return 0;
}
@@ -2714,11 +2383,11 @@ yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
{
/* Eat whitespaces. */
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
while (IS_BLANK(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) return 0;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
}
/* Consume the major version number. */
@@ -2733,7 +2402,7 @@ yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
start_mark, "did not find expected digit or '.' character");
}
- FORWARD(parser);
+ SKIP(parser);
/* Consume the minor version number. */
@@ -2764,7 +2433,7 @@ yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
/* Repeat while the next character is digit. */
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
while (IS_DIGIT(parser))
{
@@ -2777,9 +2446,9 @@ yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
value = value*10 + AS_DIGIT(parser);
- FORWARD(parser);
+ SKIP(parser);
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
}
/* Check if the number was present. */
@@ -2811,11 +2480,11 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Eat whitespaces. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_BLANK(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
/* Scan a handle. */
@@ -2825,7 +2494,7 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Expect a whitespace. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (!IS_BLANK(parser)) {
yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
@@ -2836,8 +2505,8 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Eat whitespaces. */
while (IS_BLANK(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
/* Scan a prefix. */
@@ -2847,7 +2516,7 @@ yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
/* Expect a whitespace or line break. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (!IS_BLANKZ(parser)) {
yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
@@ -2866,35 +2535,33 @@ error:
return 0;
}
-static yaml_token_t *
-yaml_parser_scan_anchor(yaml_parser_t *parser,
+static int
+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
yaml_token_type_t type)
{
int length = 0;
yaml_mark_t start_mark, end_mark;
- yaml_token_t *token = NULL;
- yaml_string_t string = yaml_parser_new_string(parser);
+ yaml_string_t string = NULL_STRING;
- if (!string.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
/* Eat the indicator character. */
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
- FORWARD(parser);
+ SKIP(parser);
/* Consume the value. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_ALPHA(parser)) {
- if (!RESIZE(parser, string)) goto error;
- COPY(parser, string);
- if (!UPDATE(parser, 1)) goto error;
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
length ++;
}
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/*
* Check if length of the anchor is greater than 0 and it is followed by
@@ -2914,19 +2581,17 @@ yaml_parser_scan_anchor(yaml_parser_t *parser,
/* Create a token. */
- token = type == YAML_ANCHOR_TOKEN ?
- yaml_anchor_token_new(string.buffer, start_mark, end_mark) :
- yaml_alias_token_new(string.buffer, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
+ if (type == YAML_ANCHOR_TOKEN) {
+ ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
+ }
+ else {
+ ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
}
- return token;
+ return 1;
error:
- yaml_free(string.buffer);
- yaml_free(token);
+ STRING_DEL(parser, string);
return 0;
}
@@ -2934,19 +2599,18 @@ error:
* Scan a TAG token.
*/
-static yaml_token_t *
-yaml_parser_scan_tag(yaml_parser_t *parser)
+static int
+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
{
yaml_char_t *handle = NULL;
yaml_char_t *suffix = NULL;
- yaml_token_t *token = NULL;
yaml_mark_t start_mark, end_mark;
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
/* Check if the tag is in the canonical form. */
- if (!UPDATE(parser, 2)) goto error;
+ if (!CACHE(parser, 2)) goto error;
if (CHECK_AT(parser, '<', 1))
{
@@ -2958,8 +2622,8 @@ yaml_parser_scan_tag(yaml_parser_t *parser)
/* Eat '!<' */
- FORWARD(parser);
- FORWARD(parser);
+ SKIP(parser);
+ SKIP(parser);
/* Consume the tag value. */
@@ -2974,7 +2638,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser)
goto error;
}
- FORWARD(parser);
+ SKIP(parser);
}
else
{
@@ -3010,7 +2674,8 @@ yaml_parser_scan_tag(yaml_parser_t *parser)
handle[1] = '\0';
/*
- * A special case: the '!' tag.
+ * A special case: the '!' tag. Set the handle to '' and the
+ * suffix to '!'.
*/
if (suffix[0] == '\0') {
@@ -3023,7 +2688,7 @@ yaml_parser_scan_tag(yaml_parser_t *parser)
/* Check the character which ends the tag. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (!IS_BLANKZ(parser)) {
yaml_parser_set_scanner_error(parser, "while scanning a tag",
@@ -3031,22 +2696,18 @@ yaml_parser_scan_tag(yaml_parser_t *parser)
goto error;
}
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Create a token. */
- token = yaml_tag_token_new(handle, suffix, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
+ TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark);
- return token;
+ return 1;
error:
yaml_free(handle);
yaml_free(suffix);
- return NULL;
+ return 0;
}
/*
@@ -3057,13 +2718,13 @@ static int
yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
yaml_mark_t start_mark, yaml_char_t **handle)
{
- yaml_string_t string = yaml_parser_new_string(parser);
+ yaml_string_t string = NULL_STRING;
- if (!string.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
/* Check the initial '!' character. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (!CHECK(parser, '!')) {
yaml_parser_set_scanner_error(parser, directive ?
@@ -3074,25 +2735,23 @@ yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
/* Copy the '!' character. */
- COPY(parser, string);
+ if (!READ(parser, string)) goto error;
/* Copy all subsequent alphabetical and numerical characters. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_ALPHA(parser))
{
- if (!RESIZE(parser, string)) goto error;
- COPY(parser, string);
- if (!UPDATE(parser, 1)) goto error;
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Check if the trailing character is '!' and copy it. */
if (CHECK(parser, '!'))
{
- if (!RESIZE(parser, string)) goto error;
- COPY(parser, string);
+ if (!READ(parser, string)) goto error;
}
else
{
@@ -3102,19 +2761,19 @@ yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
* URI.
*/
- if (directive && !(string.buffer[0] == '!' && string.buffer[1] == '\0')) {
+ if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) {
yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
start_mark, "did not find expected '!'");
goto error;
}
}
- *handle = string.buffer;
+ *handle = string.start;
return 1;
error:
- yaml_free(string.buffer);
+ STRING_DEL(parser, string);
return 0;
}
@@ -3127,14 +2786,17 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
{
size_t length = head ? strlen((char *)head) : 0;
- yaml_string_t string = yaml_parser_new_string(parser);
+ yaml_string_t string = NULL_STRING;
- if (!string.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
/* Resize the string to include the head. */
- while (string.size <= length) {
- if (!yaml_parser_resize_string(parser, &string)) goto error;
+ while (string.end - string.start <= length) {
+ if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
+ parser->error = YAML_MEMORY_ERROR;
+ goto error;
+ }
}
/*
@@ -3144,13 +2806,13 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
*/
if (length > 1) {
- memcpy(string.buffer, head+1, length-1);
+ memcpy(string.start, head+1, length-1);
string.pointer += length-1;
}
/* Scan the tag. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
/*
* The set of characters that may appear in URI is as follows:
@@ -3168,8 +2830,6 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
CHECK(parser, '\'') || CHECK(parser, '(') || CHECK(parser, ')') ||
CHECK(parser, '[') || CHECK(parser, ']') || CHECK(parser, '%'))
{
- if (!RESIZE(parser, string)) goto error;
-
/* Check if it is a URI-escape sequence. */
if (CHECK(parser, '%')) {
@@ -3177,28 +2837,31 @@ yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
directive, start_mark, &string)) goto error;
}
else {
- COPY(parser, string);
+ if (!READ(parser, string)) goto error;
}
length ++;
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Check if the tag is non-empty. */
if (!length) {
+ if (!STRING_EXTEND(parser, string))
+ goto error;
+
yaml_parser_set_scanner_error(parser, directive ?
"while parsing a %TAG directive" : "while parsing a tag",
start_mark, "did not find expected tag URI");
goto error;
}
- *uri = string.buffer;
+ *uri = string.start;
return 1;
error:
- yaml_free(string.buffer);
+ STRING_DEL(parser, string);
return 0;
}
@@ -3220,7 +2883,7 @@ yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
/* Check for a URI-escaped octet. */
- if (!UPDATE(parser, 3)) return 0;
+ if (!CACHE(parser, 3)) return 0;
if (!(CHECK(parser, '%') && IS_HEX_AT(parser, 1) && IS_HEX_AT(parser, 2))) {
return yaml_parser_set_scanner_error(parser, directive ?
@@ -3260,9 +2923,9 @@ yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
/* Copy the octet and move the pointers. */
*(string->pointer++) = octet;
- FORWARD(parser);
- FORWARD(parser);
- FORWARD(parser);
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
} while (--width);
@@ -3273,34 +2936,34 @@ yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
* Scan a block scalar.
*/
-static yaml_token_t *
-yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
+static int
+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int literal)
{
yaml_mark_t start_mark;
yaml_mark_t end_mark;
- yaml_string_t string = yaml_parser_new_string(parser);
- yaml_string_t leading_break = yaml_parser_new_string(parser);
- yaml_string_t trailing_breaks = yaml_parser_new_string(parser);
- yaml_token_t *token = NULL;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
int chomping = 0;
int increment = 0;
int indent = 0;
int leading_blank = 0;
int trailing_blank = 0;
- if (!string.buffer) goto error;
- if (!leading_break.buffer) goto error;
- if (!trailing_breaks.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
/* Eat the indicator '|' or '>'. */
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
- FORWARD(parser);
+ SKIP(parser);
/* Scan the additional block scalar indicators. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
/* Check for a chomping indicator. */
@@ -3310,11 +2973,11 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
chomping = CHECK(parser, '+') ? +1 : -1;
- FORWARD(parser);
+ SKIP(parser);
/* Check for an indentation indicator. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (IS_DIGIT(parser))
{
@@ -3330,7 +2993,7 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
increment = AS_DIGIT(parser);
- FORWARD(parser);
+ SKIP(parser);
}
}
@@ -3346,29 +3009,30 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
increment = AS_DIGIT(parser);
- FORWARD(parser);
+ SKIP(parser);
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
if (CHECK(parser, '+') || CHECK(parser, '-')) {
chomping = CHECK(parser, '+') ? +1 : -1;
- FORWARD(parser);
+
+ SKIP(parser);
}
}
/* Eat whitespaces and comments to the end of the line. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_BLANK(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
if (CHECK(parser, '#')) {
while (!IS_BREAKZ(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) goto error;
+ SKIP(parser);
+ if (!CACHE(parser, 1)) goto error;
}
}
@@ -3383,11 +3047,11 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
/* Eat a line break. */
if (IS_BREAK(parser)) {
- if (!UPDATE(parser, 2)) goto error;
- FORWARD_LINE(parser);
+ if (!CACHE(parser, 2)) goto error;
+ SKIP_LINE(parser);
}
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Set the intendation level if it was specified. */
@@ -3402,9 +3066,9 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
/* Scan the block scalar content. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
- while (parser->column == indent && !IS_Z(parser))
+ while (parser->mark.column == indent && !IS_Z(parser))
{
/*
* We are at the beginning of a non-empty line.
@@ -3416,25 +3080,27 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
/* Check if we need to fold the leading line break. */
- if (!literal && (*leading_break.buffer == '\n')
+ if (!literal && (*leading_break.start == '\n')
&& !leading_blank && !trailing_blank)
{
/* Do we need to join the lines by space? */
- if (*trailing_breaks.buffer == '\0') {
- if (!RESIZE(parser, string)) goto error;
+ if (*trailing_breaks.start == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
*(string.pointer ++) = ' ';
}
- yaml_parser_clear_string(parser, &leading_break);
+ CLEAR(parser, leading_break);
}
else {
if (!JOIN(parser, string, leading_break)) goto error;
+ CLEAR(parser, leading_break);
}
/* Append the remaining line breaks. */
if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
/* Is it a leading whitespace? */
@@ -3443,16 +3109,15 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
/* Consume the current line. */
while (!IS_BREAKZ(parser)) {
- if (!RESIZE(parser, string)) goto error;
- COPY(parser, string);
- if (!UPDATE(parser, 1)) goto error;
+ if (!READ(parser, string)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Consume the line break. */
- if (!UPDATE(parser, 2)) goto error;
+ if (!CACHE(parser, 2)) goto error;
- COPY_LINE(parser, leading_break);
+ if (!READ_LINE(parser, leading_break)) goto error;
/* Eat the following intendation spaces and line breaks. */
@@ -3471,25 +3136,21 @@ yaml_parser_scan_block_scalar(yaml_parser_t *parser, int literal)
/* Create a token. */
- token = yaml_scalar_token_new(string.buffer, string.pointer-string.buffer,
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
- return token;
+ return 1;
error:
- yaml_free(string.buffer);
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
- return NULL;
+ return 0;
}
/*
@@ -3504,7 +3165,7 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
{
int max_indent = 0;
- *end_mark = yaml_parser_get_mark(parser);
+ *end_mark = parser->mark;
/* Eat the intendation spaces and line breaks. */
@@ -3512,19 +3173,19 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
{
/* Eat the intendation spaces. */
- if (!UPDATE(parser, 1)) return 0;
+ if (!CACHE(parser, 1)) return 0;
- while ((!*indent || parser->column < *indent) && IS_SPACE(parser)) {
- FORWARD(parser);
- if (!UPDATE(parser, 1)) return 0;
+ while ((!*indent || parser->mark.column < *indent) && IS_SPACE(parser)) {
+ SKIP(parser);
+ if (!CACHE(parser, 1)) return 0;
}
- if (parser->column > max_indent)
- max_indent = parser->column;
+ if (parser->mark.column > max_indent)
+ max_indent = parser->mark.column;
/* Check for a tab character messing the intendation. */
- if ((!*indent || parser->column < *indent) && IS_TAB(parser)) {
+ if ((!*indent || parser->mark.column < *indent) && IS_TAB(parser)) {
return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
start_mark, "found a tab character where an intendation space is expected");
}
@@ -3535,10 +3196,9 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
/* Consume the line break. */
- if (!UPDATE(parser, 2)) return 0;
- if (!RESIZE(parser, *breaks)) return 0;
- COPY_LINE(parser, *breaks);
- *end_mark = yaml_parser_get_mark(parser);
+ if (!CACHE(parser, 2)) return 0;
+ if (!READ_LINE(parser, *breaks)) return 0;
+ *end_mark = parser->mark;
}
/* Determine the indentation level if needed. */
@@ -3558,28 +3218,28 @@ yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
* Scan a quoted scalar.
*/
-static yaml_token_t *
-yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
+static int
+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
+ int single)
{
yaml_mark_t start_mark;
yaml_mark_t end_mark;
- yaml_string_t string = yaml_parser_new_string(parser);
- yaml_string_t leading_break = yaml_parser_new_string(parser);
- yaml_string_t trailing_breaks = yaml_parser_new_string(parser);
- yaml_string_t whitespaces = yaml_parser_new_string(parser);
- yaml_token_t *token = NULL;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
+ yaml_string_t whitespaces = NULL_STRING;
int leading_blanks;
- if (!string.buffer) goto error;
- if (!leading_break.buffer) goto error;
- if (!trailing_breaks.buffer) goto error;
- if (!whitespaces.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
/* Eat the left quote. */
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
- FORWARD(parser);
+ SKIP(parser);
/* Consume the content of the quoted scalar. */
@@ -3587,9 +3247,9 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
{
/* Check that there are no document indicators at the beginning of the line. */
- if (!UPDATE(parser, 4)) goto error;
+ if (!CACHE(parser, 4)) goto error;
- if (parser->column == 0 &&
+ if (parser->mark.column == 0 &&
((CHECK_AT(parser, '-', 0) &&
CHECK_AT(parser, '-', 1) &&
CHECK_AT(parser, '-', 2)) ||
@@ -3613,8 +3273,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
/* Consume non-blank characters. */
- if (!UPDATE(parser, 2)) goto error;
- if (!RESIZE(parser, string)) goto error;
+ if (!CACHE(parser, 2)) goto error;
leading_blanks = 0;
@@ -3624,9 +3283,10 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
if (single && CHECK_AT(parser, '\'', 0) && CHECK_AT(parser, '\'', 1))
{
+ if (!STRING_EXTEND(parser, string)) goto error;
*(string.pointer++) = '\'';
- FORWARD(parser);
- FORWARD(parser);
+ SKIP(parser);
+ SKIP(parser);
}
/* Check for the right quote. */
@@ -3640,9 +3300,9 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
else if (!single && CHECK(parser, '\\') && IS_BREAK_AT(parser, 1))
{
- if (!UPDATE(parser, 3)) goto error;
- FORWARD(parser);
- FORWARD_LINE(parser);
+ if (!CACHE(parser, 3)) goto error;
+ SKIP(parser);
+ SKIP_LINE(parser);
leading_blanks = 1;
break;
}
@@ -3653,9 +3313,11 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
{
int code_length = 0;
+ if (!STRING_EXTEND(parser, string)) goto error;
+
/* Check the escape character. */
- switch (parser->pointer[1])
+ switch (parser->buffer.pointer[1])
{
case '0':
*(string.pointer++) = '\0';
@@ -3750,8 +3412,8 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
goto error;
}
- FORWARD(parser);
- FORWARD(parser);
+ SKIP(parser);
+ SKIP(parser);
/* Consume an arbitrary escape code. */
@@ -3762,7 +3424,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
/* Scan the character value. */
- if (!UPDATE(parser, code_length)) goto error;
+ if (!CACHE(parser, code_length)) goto error;
for (k = 0; k < code_length; k ++) {
if (!IS_HEX_AT(parser, k)) {
@@ -3803,7 +3465,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
/* Advance the pointer. */
for (k = 0; k < code_length; k ++) {
- FORWARD(parser);
+ SKIP(parser);
}
}
}
@@ -3812,11 +3474,10 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
{
/* It is a non-escaped non-blank character. */
- COPY(parser, string);
+ if (!READ(parser, string)) goto error;
}
- if (!UPDATE(parser, 2)) goto error;
- if (!RESIZE(parser, string)) goto error;
+ if (!CACHE(parser, 2)) goto error;
}
/* Check if we are at the end of the scalar. */
@@ -3826,7 +3487,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
/* Consume blank characters. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_BLANK(parser) || IS_BREAK(parser))
{
@@ -3835,116 +3496,112 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, int single)
/* Consume a space or a tab character. */
if (!leading_blanks) {
- if (!RESIZE(parser, whitespaces)) goto error;
- COPY(parser, whitespaces);
+ if (!READ(parser, whitespaces)) goto error;
}
else {
- FORWARD(parser);
+ SKIP(parser);
}
}
else
{
- if (!UPDATE(parser, 2)) goto error;
+ if (!CACHE(parser, 2)) goto error;
/* Check if it is a first line break. */
if (!leading_blanks)
{
- yaml_parser_clear_string(parser, &whitespaces);
- COPY_LINE(parser, leading_break);
+ CLEAR(parser, whitespaces);
+ if (!READ_LINE(parser, leading_break)) goto error;
leading_blanks = 1;
}
else
{
- if (!RESIZE(parser, trailing_breaks)) goto error;
- COPY_LINE(parser, trailing_breaks);
+ if (!READ_LINE(parser, trailing_breaks)) goto error;
}
}
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Join the whitespaces or fold line breaks. */
- if (!RESIZE(parser, string)) goto error;
-
if (leading_blanks)
{
/* Do we need to fold line breaks? */
- if (leading_break.buffer[0] == '\n') {
- if (trailing_breaks.buffer[0] == '\0') {
+ if (leading_break.start[0] == '\n') {
+ if (trailing_breaks.start[0] == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
*(string.pointer++) = ' ';
}
else {
if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
}
- yaml_parser_clear_string(parser, &leading_break);
+ CLEAR(parser, leading_break);
}
else {
if (!JOIN(parser, string, leading_break)) goto error;
if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, leading_break);
+ CLEAR(parser, trailing_breaks);
}
}
else
{
if (!JOIN(parser, string, whitespaces)) goto error;
+ CLEAR(parser, whitespaces);
}
}
/* Eat the right quote. */
- FORWARD(parser);
+ SKIP(parser);
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
/* Create a token. */
- token = yaml_scalar_token_new(string.buffer, string.pointer-string.buffer,
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
- yaml_free(whitespaces.buffer);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
- return token;
+ return 1;
error:
- yaml_free(string.buffer);
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
- yaml_free(whitespaces.buffer);
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
- return NULL;
+ return 0;
}
/*
* Scan a plain scalar.
*/
-static yaml_token_t *
-yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
+static int
+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
{
yaml_mark_t start_mark;
yaml_mark_t end_mark;
- yaml_string_t string = yaml_parser_new_string(parser);
- yaml_string_t leading_break = yaml_parser_new_string(parser);
- yaml_string_t trailing_breaks = yaml_parser_new_string(parser);
- yaml_string_t whitespaces = yaml_parser_new_string(parser);
- yaml_token_t *token = NULL;
+ yaml_string_t string = NULL_STRING;
+ yaml_string_t leading_break = NULL_STRING;
+ yaml_string_t trailing_breaks = NULL_STRING;
+ yaml_string_t whitespaces = NULL_STRING;
int leading_blanks = 0;
int indent = parser->indent+1;
- if (!string.buffer) goto error;
- if (!leading_break.buffer) goto error;
- if (!trailing_breaks.buffer) goto error;
- if (!whitespaces.buffer) goto error;
+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
- start_mark = yaml_parser_get_mark(parser);
+ start_mark = parser->mark;
/* Consume the content of the plain scalar. */
@@ -3952,9 +3609,9 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
{
/* Check for a document indicator. */
- if (!UPDATE(parser, 4)) goto error;
+ if (!CACHE(parser, 4)) goto error;
- if (parser->column == 0 &&
+ if (parser->mark.column == 0 &&
((CHECK_AT(parser, '-', 0) &&
CHECK_AT(parser, '-', 1) &&
CHECK_AT(parser, '-', 2)) ||
@@ -3992,26 +3649,28 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
/* Check if we need to join whitespaces and breaks. */
- if (leading_blanks || whitespaces.buffer != whitespaces.pointer)
+ if (leading_blanks || whitespaces.start != whitespaces.pointer)
{
- if (!RESIZE(parser, string)) goto error;
-
if (leading_blanks)
{
/* Do we need to fold line breaks? */
- if (leading_break.buffer[0] == '\n') {
- if (trailing_breaks.buffer[0] == '\0') {
+ if (leading_break.start[0] == '\n') {
+ if (trailing_breaks.start[0] == '\0') {
+ if (!STRING_EXTEND(parser, string)) goto error;
*(string.pointer++) = ' ';
}
else {
if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, trailing_breaks);
}
- yaml_parser_clear_string(parser, &leading_break);
+ CLEAR(parser, leading_break);
}
else {
if (!JOIN(parser, string, leading_break)) goto error;
if (!JOIN(parser, string, trailing_breaks)) goto error;
+ CLEAR(parser, leading_break);
+ CLEAR(parser, trailing_breaks);
}
leading_blanks = 0;
@@ -4019,18 +3678,17 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
else
{
if (!JOIN(parser, string, whitespaces)) goto error;
+ CLEAR(parser, whitespaces);
}
}
/* Copy the character. */
- if (!RESIZE(parser, string)) goto error;
-
- COPY(parser, string);
+ if (!READ(parser, string)) goto error;
- end_mark = yaml_parser_get_mark(parser);
+ end_mark = parser->mark;
- if (!UPDATE(parser, 2)) goto error;
+ if (!CACHE(parser, 2)) goto error;
}
/* Is it the end? */
@@ -4040,7 +3698,7 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
/* Consume blank characters. */
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
while (IS_BLANK(parser) || IS_BREAK(parser))
{
@@ -4048,7 +3706,7 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
{
/* Check for tab character that abuse intendation. */
- if (leading_blanks && parser->column < indent && IS_TAB(parser)) {
+ if (leading_blanks && parser->mark.column < indent && IS_TAB(parser)) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found a tab character that violate intendation");
goto error;
@@ -4057,48 +3715,42 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
/* Consume a space or a tab character. */
if (!leading_blanks) {
- if (!RESIZE(parser, whitespaces)) goto error;
- COPY(parser, whitespaces);
+ if (!READ(parser, whitespaces)) goto error;
}
else {
- FORWARD(parser);
+ SKIP(parser);
}
}
else
{
- if (!UPDATE(parser, 2)) goto error;
+ if (!CACHE(parser, 2)) goto error;
/* Check if it is a first line break. */
if (!leading_blanks)
{
- yaml_parser_clear_string(parser, &whitespaces);
- COPY_LINE(parser, leading_break);
+ CLEAR(parser, whitespaces);
+ if (!READ_LINE(parser, leading_break)) goto error;
leading_blanks = 1;
}
else
{
- if (!RESIZE(parser, trailing_breaks)) goto error;
- COPY_LINE(parser, trailing_breaks);
+ if (!READ_LINE(parser, trailing_breaks)) goto error;
}
}
- if (!UPDATE(parser, 1)) goto error;
+ if (!CACHE(parser, 1)) goto error;
}
/* Check intendation level. */
- if (!parser->flow_level && parser->column < indent)
+ if (!parser->flow_level && parser->mark.column < indent)
break;
}
/* Create a token. */
- token = yaml_scalar_token_new(string.buffer, string.pointer-string.buffer,
+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
- if (!token) {
- parser->error = YAML_MEMORY_ERROR;
- return 0;
- }
/* Note that we change the 'simple_key_allowed' flag. */
@@ -4106,18 +3758,18 @@ yaml_parser_scan_plain_scalar(yaml_parser_t *parser)
parser->simple_key_allowed = 1;
}
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
- yaml_free(whitespaces.buffer);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
- return token;
+ return 1;
error:
- yaml_free(string.buffer);
- yaml_free(leading_break.buffer);
- yaml_free(trailing_breaks.buffer);
- yaml_free(whitespaces.buffer);
+ STRING_DEL(parser, string);
+ STRING_DEL(parser, leading_break);
+ STRING_DEL(parser, trailing_breaks);
+ STRING_DEL(parser, whitespaces);
- return NULL;
+ return 0;
}
diff --git a/src/yaml_private.h b/src/yaml_private.h
new file mode 100644
index 0000000..d7ac644
--- /dev/null
+++ b/src/yaml_private.h
@@ -0,0 +1,205 @@
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <yaml.h>
+
+#include <assert.h>
+
+/*
+ * Memory management.
+ */
+
+YAML_DECLARE(void *)
+yaml_malloc(size_t size);
+
+YAML_DECLARE(void *)
+yaml_realloc(void *ptr, size_t size);
+
+YAML_DECLARE(void)
+yaml_free(void *ptr);
+
+YAML_DECLARE(char *)
+yaml_strdup(const char *);
+
+/*
+ * Reader: Ensure that the buffer contains at least `length` characters.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+
+/*
+ * Scanner: Ensure that the token stack contains at least one token ready.
+ */
+
+YAML_DECLARE(int)
+yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
+
+/*
+ * The size of the raw buffer.
+ */
+
+#define RAW_BUFFER_SIZE 16384
+
+/*
+ * The size of the buffer.
+ *
+ * It should be possible to decode the whole raw buffer.
+ */
+
+#define BUFFER_SIZE (RAW_BUFFER_SIZE*3)
+
+/*
+ * The size of other stacks and queues.
+ */
+
+#define INITIAL_STACK_SIZE 16
+#define INITIAL_QUEUE_SIZE 16
+#define INITIAL_STRING_SIZE 16
+
+/*
+ * Buffer management.
+ */
+
+#define BUFFER_INIT(context,buffer,size) \
+ (((buffer).start = yaml_malloc(size)) ? \
+ ((buffer).last = (buffer).pointer = (buffer).start, \
+ (buffer).end = (buffer).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define BUFFER_DEL(context,buffer) \
+ (yaml_free((buffer).start), \
+ (buffer).start = (buffer).pointer = (buffer).end = 0)
+
+/*
+ * String management.
+ */
+
+typedef struct {
+ yaml_char_t *start;
+ yaml_char_t *end;
+ yaml_char_t *pointer;
+} yaml_string_t;
+
+YAML_DECLARE(int)
+yaml_string_extend(yaml_char_t **start,
+ yaml_char_t **pointer, yaml_char_t **end);
+
+YAML_DECLARE(int)
+yaml_string_join(
+ yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
+ yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
+
+#define NULL_STRING { NULL, NULL, NULL }
+
+#define STRING_INIT(context,string,size) \
+ (((string).start = yaml_malloc(size)) ? \
+ ((string).pointer = (string).start, \
+ (string).end = (string).start+(size), \
+ memset((string).start, 0, (size)), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define STRING_DEL(context,string) \
+ (yaml_free((string).start), \
+ (string).start = (string).pointer = (string).end = 0)
+
+#define STRING_EXTEND(context,string) \
+ (((string).pointer+5 < (string).end) \
+ || yaml_string_extend(&(string).start, \
+ &(string).pointer, &(string).end))
+
+#define CLEAR(context,string) \
+ ((string).pointer = (string).start, \
+ memset((string).start, 0, (string).end-(string).start))
+
+#define JOIN(context,string_a,string_b) \
+ ((yaml_string_join(&(string_a).start, &(string_a).pointer, \
+ &(string_a).end, &(string_b).start, \
+ &(string_b).pointer, &(string_b).end)) ? \
+ ((string_b).pointer = (string_b).start, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+/*
+ * Stack and queue management.
+ */
+
+YAML_DECLARE(int)
+yaml_stack_extend(void **start, void **top, void **end);
+
+YAML_DECLARE(int)
+yaml_queue_extend(void **start, void **head, void **tail, void **end);
+
+#define STACK_INIT(context,stack,size) \
+ (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
+ ((stack).top = (stack).start, \
+ (stack).end = (stack).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define STACK_DEL(context,stack) \
+ (yaml_free((stack).start), \
+ (stack).start = (stack).top = (stack).end = 0)
+
+#define STACK_EMPTY(context,stack) \
+ ((stack).start == (stack).top)
+
+#define PUSH(context,stack,value) \
+ (((stack).top != (stack).end \
+ || yaml_stack_extend((void **)&(stack).start, \
+ (void **)&(stack).top, (void **)&(stack).end)) ? \
+ (*((stack).top++) = value, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define POP(context,stack) \
+ (*(--(stack).top))
+
+#define QUEUE_INIT(context,queue,size) \
+ (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
+ ((queue).head = (queue).tail = (queue).start, \
+ (queue).end = (queue).start+(size), \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define QUEUE_DEL(context,queue) \
+ (yaml_free((queue).start), \
+ (queue).start = (queue).head = (queue).tail = (queue).end = 0)
+
+#define QUEUE_EMPTY(context,queue) \
+ ((queue).head == (queue).tail)
+
+#define ENQUEUE(context,queue,value) \
+ (((queue).tail != (queue).end \
+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
+ (*((queue).tail++) = value, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
+#define DEQUEUE(context,queue) \
+ (*((queue).head++))
+
+#define QUEUE_INSERT(context,queue,index,value) \
+ (((queue).tail != (queue).end \
+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
+ (memmove((queue).head+(index)+1,(queue).head+(index), \
+ ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
+ *((queue).head+(index)) = value, \
+ (queue).tail++, \
+ 1) : \
+ ((context)->error = YAML_MEMORY_ERROR, \
+ 0))
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8f69907..e2f9e9c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
LDADD = $(top_builddir)/src/libyaml.la
TESTS = test-version test-reader
-check_PROGRAMS = test-version test-reader
+check_PROGRAMS = test-version test-reader run-scanner run-parser
diff --git a/tests/run-parser.c b/tests/run-parser.c
new file mode 100644
index 0000000..16f4ce1
--- /dev/null
+++ b/tests/run-parser.c
@@ -0,0 +1,46 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_event_t event;
+ int done = 0;
+ int count = 0;
+
+ if (argc != 2) {
+ printf("Usage: %s file.yaml\n", argv[0]);
+ return 0;
+ }
+ file = fopen(argv[1], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done)
+ {
+ assert(yaml_parser_parse(&parser, &event));
+
+ done = (event.type == YAML_STREAM_END_EVENT);
+
+ yaml_event_delete(&event);
+
+ count ++;
+ }
+
+ yaml_parser_delete(&parser);
+
+ fclose(file);
+
+ printf("Parsing the file '%s': %d events\n", argv[1], count);
+
+ return 0;
+}
+
diff --git a/tests/run-scanner.c b/tests/run-scanner.c
new file mode 100644
index 0000000..e3a67f2
--- /dev/null
+++ b/tests/run-scanner.c
@@ -0,0 +1,46 @@
+#include <yaml.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+int
+main(int argc, char *argv[])
+{
+ FILE *file;
+ yaml_parser_t parser;
+ yaml_token_t token;
+ int done = 0;
+ int count = 0;
+
+ if (argc != 2) {
+ printf("Usage: %s file.yaml\n", argv[0]);
+ return 0;
+ }
+ file = fopen(argv[1], "rb");
+ assert(file);
+
+ assert(yaml_parser_initialize(&parser));
+
+ yaml_parser_set_input_file(&parser, file);
+
+ while (!done)
+ {
+ assert(yaml_parser_scan(&parser, &token));
+
+ done = (token.type == YAML_STREAM_END_TOKEN);
+
+ yaml_token_delete(&token);
+
+ count ++;
+ }
+
+ yaml_parser_delete(&parser);
+
+ fclose(file);
+
+ printf("Parsing the file '%s': %d tokens\n", argv[1], count);
+
+ return 0;
+}
+
diff --git a/tests/test-reader.c b/tests/test-reader.c
index c5ce279..49dc874 100644
--- a/tests/test-reader.c
+++ b/tests/test-reader.c
@@ -1,5 +1,8 @@
#include <yaml.h>
+YAML_DECLARE(int)
+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
+
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
@@ -101,14 +104,15 @@ test_case boms[] = {
{"no bom (utf-8)", "Hi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!", 13},
{"bom (utf-8)", "\xef\xbb\xbfHi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!", 13},
{"bom (utf-16-le)", "\xff\xfeH\x00i\x00 \x00i\x00s\x00 \x00\x1f\x04@\x04""8\x04""2\x04""5\x04""B\x04!", 13},
- {"bom (utf-16-be)", "\xfe\xff\x00H\x00i\x00 \x00i\x00s\x00 \x04\x1f\x04@\x04""8\x04""2\x04""5\x04""B!", 13}
+ {"bom (utf-16-be)", "\xfe\xff\x00H\x00i\x00 \x00i\x00s\x00 \x04\x1f\x04@\x04""8\x04""2\x04""5\x04""B!", 13},
+ {NULL, NULL, 0}
};
char *bom_original = "Hi is \xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82";
int check_utf8_sequences(void)
{
- yaml_parser_t *parser;
+ yaml_parser_t parser;
int failed = 0;
int k;
printf("checking utf-8 sequences...\n");
@@ -121,10 +125,9 @@ int check_utf8_sequences(void)
printf("\t%s:\n", title);
while(1) {
while (*end != '|' && *end != '!') end++;
- parser = yaml_parser_new();
- assert(parser);
- yaml_parser_set_input_string(parser, (unsigned char *)start, end-start);
- result = yaml_parser_update_buffer(parser, end-start);
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, (unsigned char *)start, end-start);
+ result = yaml_parser_update_buffer(&parser, end-start);
if (result != check) {
printf("\t\t- ");
failed ++;
@@ -132,22 +135,22 @@ int check_utf8_sequences(void)
else {
printf("\t\t+ ");
}
- if (!parser->error) {
+ if (!parser.error) {
printf("(no error)\n");
}
- else if (parser->error == YAML_READER_ERROR) {
- if (parser->problem_value != -1) {
+ else if (parser.error == YAML_READER_ERROR) {
+ if (parser.problem_value != -1) {
printf("(reader error: %s: #%X at %d)\n",
- parser->problem, parser->problem_value, parser->problem_offset);
+ parser.problem, parser.problem_value, parser.problem_offset);
}
else {
printf("(reader error: %s at %d)\n",
- parser->problem, parser->problem_offset);
+ parser.problem, parser.problem_offset);
}
}
if (*end == '!') break;
start = ++end;
- yaml_parser_delete(parser);
+ yaml_parser_delete(&parser);
};
printf("\n");
}
@@ -157,7 +160,7 @@ int check_utf8_sequences(void)
int check_boms(void)
{
- yaml_parser_t *parser;
+ yaml_parser_t parser;
int failed = 0;
int k;
printf("checking boms...\n");
@@ -169,28 +172,27 @@ int check_boms(void)
char *end = start;
while (*end != '!') end++;
printf("\t%s: ", title);
- parser = yaml_parser_new();
- assert(parser);
- yaml_parser_set_input_string(parser, (unsigned char *)start, end-start);
- result = yaml_parser_update_buffer(parser, end-start);
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, (unsigned char *)start, end-start);
+ result = yaml_parser_update_buffer(&parser, end-start);
if (!result) {
- printf("- (reader error: %s at %d)\n", parser->problem, parser->problem_offset);
+ printf("- (reader error: %s at %d)\n", parser.problem, parser.problem_offset);
failed++;
}
else {
- if (parser->unread != check) {
- printf("- (length=%d while expected length=%d)\n", parser->unread, check);
+ if (parser.unread != check) {
+ printf("- (length=%d while expected length=%d)\n", parser.unread, check);
failed++;
}
- else if (memcmp(parser->buffer, bom_original, check) != 0) {
- printf("- (value '%s' does not equal to the original value '%s')\n", parser->buffer, bom_original);
+ else if (memcmp(parser.buffer.start, bom_original, check) != 0) {
+ printf("- (value '%s' does not equal to the original value '%s')\n", parser.buffer.start, bom_original);
failed++;
}
else {
printf("+\n");
}
}
- yaml_parser_delete(parser);
+ yaml_parser_delete(&parser);
}
printf("checking boms: %d fail(s)\n", failed);
return failed;
@@ -200,7 +202,7 @@ int check_boms(void)
int check_long_utf8(void)
{
- yaml_parser_t *parser;
+ yaml_parser_t parser;
int k = 0;
int j;
int failed = 0;
@@ -221,18 +223,17 @@ int check_long_utf8(void)
buffer[k++] = '\xaf';
}
}
- parser = yaml_parser_new();
- assert(parser);
- yaml_parser_set_input_string(parser, buffer, 3+LONG*2);
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, buffer, 3+LONG*2);
for (k = 0; k < LONG; k++) {
- if (!parser->unread) {
- if (!yaml_parser_update_buffer(parser, 1)) {
- printf("\treader error: %s at %d\n", parser->problem, parser->problem_offset);
+ if (!parser.unread) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
failed = 1;
break;
}
}
- if (!parser->unread) {
+ if (!parser.unread) {
printf("\tnot enough characters at %d\n", k);
failed = 1;
break;
@@ -245,27 +246,27 @@ int check_long_utf8(void)
ch0 = '\xd0';
ch1 = '\xaf';
}
- if (parser->pointer[0] != ch0 || parser->pointer[1] != ch1) {
+ if (parser.buffer.pointer[0] != ch0 || parser.buffer.pointer[1] != ch1) {
printf("\tincorrect UTF-8 sequence: %X %X instead of %X %X\n",
- (int)parser->pointer[0], (int)parser->pointer[1],
+ (int)parser.buffer.pointer[0], (int)parser.buffer.pointer[1],
(int)ch0, (int)ch1);
failed = 1;
break;
}
- parser->pointer += 2;
- parser->unread -= 1;
+ parser.buffer.pointer += 2;
+ parser.unread -= 1;
}
if (!failed) {
- if (!yaml_parser_update_buffer(parser, 1)) {
- printf("\treader error: %s at %d\n", parser->problem, parser->problem_offset);
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
failed = 1;
}
- else if (parser->pointer[0] != '\0') {
- printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser->pointer[0], parser->eof, parser->unread);
+ else if (parser.buffer.pointer[0] != '\0') {
+ printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser.buffer.pointer[0], parser.eof, parser.unread);
failed = 1;
}
}
- yaml_parser_delete(parser);
+ yaml_parser_delete(&parser);
free(buffer);
printf("checking a long utf8 sequence: %d fail(s)\n", failed);
return failed;
@@ -273,7 +274,7 @@ int check_long_utf8(void)
int check_long_utf16(void)
{
- yaml_parser_t *parser;
+ yaml_parser_t parser;
int k = 0;
int j;
int failed = 0;
@@ -293,18 +294,17 @@ int check_long_utf16(void)
buffer[k++] = '\x04';
}
}
- parser = yaml_parser_new();
- assert(parser);
- yaml_parser_set_input_string(parser, buffer, 2+LONG*2);
+ yaml_parser_initialize(&parser);
+ yaml_parser_set_input_string(&parser, buffer, 2+LONG*2);
for (k = 0; k < LONG; k++) {
- if (!parser->unread) {
- if (!yaml_parser_update_buffer(parser, 1)) {
- printf("\treader error: %s at %d\n", parser->problem, parser->problem_offset);
+ if (!parser.unread) {
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
failed = 1;
break;
}
}
- if (!parser->unread) {
+ if (!parser.unread) {
printf("\tnot enough characters at %d\n", k);
failed = 1;
break;
@@ -317,27 +317,27 @@ int check_long_utf16(void)
ch0 = '\xd0';
ch1 = '\xaf';
}
- if (parser->pointer[0] != ch0 || parser->pointer[1] != ch1) {
+ if (parser.buffer.pointer[0] != ch0 || parser.buffer.pointer[1] != ch1) {
printf("\tincorrect UTF-8 sequence: %X %X instead of %X %X\n",
- (int)parser->pointer[0], (int)parser->pointer[1],
+ (int)parser.buffer.pointer[0], (int)parser.buffer.pointer[1],
(int)ch0, (int)ch1);
failed = 1;
break;
}
- parser->pointer += 2;
- parser->unread -= 1;
+ parser.buffer.pointer += 2;
+ parser.unread -= 1;
}
if (!failed) {
- if (!yaml_parser_update_buffer(parser, 1)) {
- printf("\treader error: %s at %d\n", parser->problem, parser->problem_offset);
+ if (!yaml_parser_update_buffer(&parser, 1)) {
+ printf("\treader error: %s at %d\n", parser.problem, parser.problem_offset);
failed = 1;
}
- else if (parser->pointer[0] != '\0') {
- printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser->pointer[0], parser->eof, parser->unread);
+ else if (parser.buffer.pointer[0] != '\0') {
+ printf("\texpected NUL, found %X (eof=%d, unread=%d)\n", (int)parser.buffer.pointer[0], parser.eof, parser.unread);
failed = 1;
}
}
- yaml_parser_delete(parser);
+ yaml_parser_delete(&parser);
free(buffer);
printf("checking a long utf16 sequence: %d fail(s)\n", failed);
return failed;
diff --git a/tests/test-version.c b/tests/test-version.c
index ab4f93c..5982f7d 100644
--- a/tests/test-version.c
+++ b/tests/test-version.c
@@ -16,5 +16,10 @@ main(void)
sprintf(buf, "%d.%d.%d", major, minor, patch);
assert(strcmp(buf, yaml_get_version_string()) == 0);
+ /* Print structure sizes. */
+ printf("sizeof(token) = %d\n", sizeof(yaml_token_t));
+ printf("sizeof(event) = %d\n", sizeof(yaml_event_t));
+ printf("sizeof(parser) = %d\n", sizeof(yaml_parser_t));
+
return 0;
}