summaryrefslogtreecommitdiff
path: root/src/yaml_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/yaml_private.h')
-rw-r--r--src/yaml_private.h965
1 files changed, 783 insertions, 182 deletions
diff --git a/src/yaml_private.h b/src/yaml_private.h
index 6320caf..8fe55f0 100644
--- a/src/yaml_private.h
+++ b/src/yaml_private.h
@@ -25,123 +25,196 @@ YAML_DECLARE(yaml_char_t *)
yaml_strdup(const yaml_char_t *);
/*
- * 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.
+ * Error management.
*/
-YAML_DECLARE(int)
-yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
+#define MEMORY_ERROR_INIT(error) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = YAML_MEMORY_ERROR, \
+ 0)
+
+#define READING_ERROR_INIT(error,error_type,error_problem,error_offset,error_value) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = (error_type), \
+ (error).data.reading.problem = (error_problem), \
+ (error).data.reading.offset = (error_offset), \
+ (error).data.reading.value = (error_value), \
+ 0)
+
+#define LOADING_ERROR_INIT(error,error_type,error_problem,error_problem_mark) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = (error_type), \
+ (error).data.loading.context = NULL, \
+ (error).data.loading.context_mark.index = 0, \
+ (error).data.loading.context_mark.line = 0, \
+ (error).data.loading.context_mark.column = 0, \
+ (error).data.loading.problem = (error_problem), \
+ (error).data.loading.problem_mark = (error_problem_mark), \
+ 0)
+
+#define LOADING_ERROR_WITH_CONTEXT_INIT(error,error_type,error_context,error_context_mark,error_problem,error_problem_mark) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = (error_type), \
+ (error).data.loading.context = (error_context), \
+ (error).data.loading.context_mark = (error_context_mark), \
+ (error).data.loading.problem = (error_problem), \
+ (error).data.loading.problem_mark = (error_problem_mark), \
+ 0)
+
+#define WRITING_ERROR_INIT(error,error_type,error_problem,error_offset) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = (error_type), \
+ (error).data.writing.problem = (error_problem), \
+ (error).data.writing.offset = (error_offset), \
+ 0)
+
+#define DUMPING_ERROR_INIT(error,error_type,error_problem) \
+ (memset(&(error), 0, sizeof(error)), \
+ (error).type = (error_type), \
+ (error).type.dumping.problem = (error_problem), \
+ 0)
+
+#define READER_ERROR_INIT(error,problem,offset) \
+ READING_ERROR_INIT(error,YAML_READER_ERROR,problem,offset,-1)
+
+#define DECODER_ERROR_INIT(error,problem,offset,value) \
+ READING_ERROR_INIT(error,YAML_DECODER_ERROR,problem,offset,value)
+
+#define SCANNER_ERROR_INIT(error,problem,problem_mark) \
+ LOADING_ERROR_INIT(error,YAML_SCANNER_ERROR,problem,problem_mark)
+
+#define SCANNER_ERROR_WITH_CONTEXT_INIT(error,context,context_mark,problem,problem_mark) \
+ LOADING_ERROR_WITH_CONTEXT_INIT(error,YAML_SCANNER_ERROR,context,context_mark,problem,problem_mark)
+
+#define PARSER_ERROR_INIT(error,problem,problem_mark) \
+ LOADING_ERROR_INIT(error,YAML_PARSER_ERROR,problem,problem_mark)
+
+#define PARSER_ERROR_WITH_CONTEXT_INIT(error,context,context_mark,problem,problem_mark) \
+ LOADING_ERROR_WITH_CONTEXT_INIT(error,YAML_PARSER_ERROR,context,context_mark,problem,problem_mark)
+
+#define COMPOSER_ERROR_INIT(error,problem,problem_mark) \
+ LOADING_ERROR_INIT(error,YAML_COMPOSER_ERROR,problem,problem_mark)
+
+#define COMPOSER_ERROR_WITH_CONTEXT_INIT(error,context,context_mark,problem,problem_mark) \
+ LOADING_ERROR_WITH_CONTEXT_INIT(error,YAML_COMPOSER_ERROR,context,context_mark,problem,problem_mark)
+
+#define WRITER_ERROR_INIT(error,problem,offset) \
+ WRITING_ERROR_INIT(error,YAML_WRITER_ERROR,problem,offset)
+
+#define EMITTER_ERROR_INIT(error,context,problem) \
+ DUMPING_ERROR_INIT(error,YAML_EMITTER_ERROR,problem)
+
+#define SERIALIZER_ERROR_INIT(error,context) \
+ DUMPING_ERROR_INIT(error,YAML_SERIALIZER_ERROR,problem)
/*
* The size of the input raw buffer.
*/
-#define INPUT_RAW_BUFFER_SIZE 16384
+#define RAW_INPUT_BUFFER_CAPACITY 16384
/*
* The size of the input buffer.
*
- * It should be possible to decode the whole raw buffer.
+ * The input buffer should be large enough to hold the content of the raw
+ * buffer after it is decoded.
*/
-#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
+#define INPUT_BUFFER_CAPACITY (RAW_INPUT_BUFFER_CAPACITY*3)
/*
* The size of the output buffer.
*/
-#define OUTPUT_BUFFER_SIZE 16384
+#define OUTPUT_BUFFER_CAPACITY 16384
/*
* The size of the output raw buffer.
*
- * It should be possible to encode the whole output buffer.
+ * The raw buffer should be able to hold the content of the output buffer
+ * after it is encoded.
*/
-#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
+#define RAW_OUTPUT_BUFFER_CAPACITY (OUTPUT_BUFFER_CAPACITY*2+2)
/*
* The size of other stacks and queues.
*/
-#define INITIAL_STACK_SIZE 16
-#define INITIAL_QUEUE_SIZE 16
-#define INITIAL_STRING_SIZE 16
+#define INITIAL_STACK_CAPACITY 16
+#define INITIAL_QUEUE_CAPACITY 16
+#define INITIAL_STRING_CAPACITY 16
/*
- * Buffer management.
+ * Input/output buffer management.
*/
-#define BUFFER_INIT(context,buffer,size) \
- (((buffer).start = yaml_malloc(size)) ? \
- ((buffer).last = (buffer).pointer = (buffer).start, \
- (buffer).end = (buffer).start+(size), \
+#define STORAGE_INIT(self,storage,storage_capacity) \
+ (((storage).buffer = yaml_malloc(storage_capacity)) ? \
+ ((storage).pointer = (storage).length = 0, \
+ (buffer).capacity = (storage_capacity) \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
-#define BUFFER_DEL(context,buffer) \
- (yaml_free((buffer).start), \
- (buffer).start = (buffer).pointer = (buffer).end = 0)
+#define STORAGE_DEL(self,storage) \
+ (yaml_free((storage).buffer), \
+ (storage).pointer = (storage).length = (storage).capacity = 0)
/*
* String management.
*/
-typedef struct {
- yaml_char_t *start;
- yaml_char_t *end;
- yaml_char_t *pointer;
+typedef struct yaml_string_s {
+ yaml_char_t *buffer;
+ size_t pointer;
+ size_t capacity;
} yaml_string_t;
YAML_DECLARE(int)
-yaml_string_extend(yaml_char_t **start,
- yaml_char_t **pointer, yaml_char_t **end);
+yaml_string_extend(yaml_char_t **buffer, size_t *capacity);
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);
+ yaml_char_t **base_buffer, size_t *base_pointer, size_t *base_capacity,
+ yaml_char_t *adj_buffer, size_t adj_pointer, size_t adj_capacity);
#define NULL_STRING { NULL, NULL, NULL }
-#define STRING(string,length) { (string), (string)+(length), (string) }
+#define STRING(string,capacity) { (string), 0, (capacity) }
-#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)), \
+#define STRING_INIT(self,string,string_capacity) \
+ (((string).buffer = yaml_malloc(string_capacity)) ? \
+ ((string).pointer = 0, \
+ (string).capacity = (string_capacity), \
+ memset((string).buffer, 0, (string_capacity)), \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = 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, \
+#define STRING_DEL(self,string) \
+ (yaml_free((string).buffer), \
+ (string).buffer = NULL, \
+ ((string).pointer = (string).capacity = 0))
+
+#define STRING_EXTEND(self,string) \
+ ((((string).pointer+5 < (string).capacity) \
+ || yaml_string_extend(&(string).buffer, &(string).capacity)) ? \
+ 1 : \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
+ 0))
+
+#define CLEAR(self,string) \
+ ((string).pointer = 0, \
+ memset((string).buffer, 0, (string).capacity))
+
+#define JOIN(self,base_string,adj_string) \
+ ((yaml_string_join(&(base_string).buffer, &(base_string).pointer, \
+ &(base_string).capacity, (adj_string).buffer, \
+ (adj_string).pointer, (adj_string).capacity)) ? \
+ ((adj_string).pointer = 0, \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
/*
@@ -149,11 +222,24 @@ yaml_string_join(
*/
/*
+ * Get the octet at the specified position.
+ */
+
+#define OCTET_AT(string,offset) \
+ ((string).buffer[(string).pointer+(offset)])
+
+/*
+ * Get the current offset.
+ */
+
+#define OCTET(string) OCTET_AT((string),0)
+
+/*
* Check the octet at the specified position.
*/
#define CHECK_AT(string,octet,offset) \
- ((string).pointer[offset] == (yaml_char_t)(octet))
+ (OCTET_AT((string),(offset)) == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
@@ -167,14 +253,14 @@ yaml_string_join(
*/
#define IS_ALPHA_AT(string,offset) \
- (((string).pointer[offset] >= (yaml_char_t) '0' && \
- (string).pointer[offset] <= (yaml_char_t) '9') || \
- ((string).pointer[offset] >= (yaml_char_t) 'A' && \
- (string).pointer[offset] <= (yaml_char_t) 'Z') || \
- ((string).pointer[offset] >= (yaml_char_t) 'a' && \
- (string).pointer[offset] <= (yaml_char_t) 'z') || \
- (string).pointer[offset] == '_' || \
- (string).pointer[offset] == '-')
+ ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) '9') || \
+ (OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'Z') || \
+ (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'z') || \
+ OCTET_AT((string),(offset)) == '_' || \
+ OCTET_AT((string),(offset)) == '-')
#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
@@ -183,8 +269,8 @@ yaml_string_join(
*/
#define IS_DIGIT_AT(string,offset) \
- (((string).pointer[offset] >= (yaml_char_t) '0' && \
- (string).pointer[offset] <= (yaml_char_t) '9'))
+ ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) '9'))
#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
@@ -193,7 +279,7 @@ yaml_string_join(
*/
#define AS_DIGIT_AT(string,offset) \
- ((string).pointer[offset] - (yaml_char_t) '0')
+ (OCTET_AT((string),(offset)) - (yaml_char_t) '0')
#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
@@ -202,12 +288,12 @@ yaml_string_join(
*/
#define IS_HEX_AT(string,offset) \
- (((string).pointer[offset] >= (yaml_char_t) '0' && \
- (string).pointer[offset] <= (yaml_char_t) '9') || \
- ((string).pointer[offset] >= (yaml_char_t) 'A' && \
- (string).pointer[offset] <= (yaml_char_t) 'F') || \
- ((string).pointer[offset] >= (yaml_char_t) 'a' && \
- (string).pointer[offset] <= (yaml_char_t) 'f'))
+ ((OCTET_AT((string),(offset)) >= (yaml_char_t) '0' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) '9') || \
+ (OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'F') || \
+ (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'f'))
#define IS_HEX(string) IS_HEX_AT((string),0)
@@ -216,13 +302,13 @@ yaml_string_join(
*/
#define AS_HEX_AT(string,offset) \
- (((string).pointer[offset] >= (yaml_char_t) 'A' && \
- (string).pointer[offset] <= (yaml_char_t) 'F') ? \
- ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
- ((string).pointer[offset] >= (yaml_char_t) 'a' && \
- (string).pointer[offset] <= (yaml_char_t) 'f') ? \
- ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
- ((string).pointer[offset] - (yaml_char_t) '0'))
+ ((OCTET_AT((string),(offset)) >= (yaml_char_t) 'A' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'F') ? \
+ (OCTET_AT((string),(offset)) - (yaml_char_t) 'A' + 10) : \
+ (OCTET_AT((string),(offset)) >= (yaml_char_t) 'a' && \
+ OCTET_AT((string),(offset)) <= (yaml_char_t) 'f') ? \
+ (OCTET_AT((string),(offset)) - (yaml_char_t) 'a' + 10) : \
+ (OCTET_AT((string),(offset)) - (yaml_char_t) '0'))
#define AS_HEX(string) AS_HEX_AT((string),0)
@@ -231,7 +317,7 @@ yaml_string_join(
*/
#define IS_ASCII_AT(string,offset) \
- ((string).pointer[offset] <= (yaml_char_t) '\x7F')
+ (OCTET_AT((string),(offset)) <= (yaml_char_t) '\x7F')
#define IS_ASCII(string) IS_ASCII_AT((string),0)
@@ -240,22 +326,22 @@ yaml_string_join(
*/
#define IS_PRINTABLE_AT(string,offset) \
- (((string).pointer[offset] == 0x0A) /* . == #x0A */ \
- || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
- && (string).pointer[offset] <= 0x7E) \
- || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
- && (string).pointer[offset+1] >= 0xA0) \
- || ((string).pointer[offset] > 0xC2 \
- && (string).pointer[offset] < 0xED) \
- || ((string).pointer[offset] == 0xED \
- && (string).pointer[offset+1] < 0xA0) \
- || ((string).pointer[offset] == 0xEE) \
- || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
- && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
- && (string).pointer[offset+2] == 0xBF) \
- && !((string).pointer[offset+1] == 0xBF \
- && ((string).pointer[offset+2] == 0xBE \
- || (string).pointer[offset+2] == 0xBF))))
+ ((OCTET_AT((string),(offset)) == 0x0A) /* . == #x0A */ \
+ || (OCTET_AT((string),(offset)) >= 0x20 /* #x20 <= . <= #x7E */ \
+ && OCTET_AT((string),(offset)) <= 0x7E) \
+ || (OCTET_AT((string),(offset)) == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
+ && OCTET_AT((string),(offset)+1) >= 0xA0) \
+ || (OCTET_AT((string),(offset)) > 0xC2 \
+ && OCTET_AT((string),(offset)) < 0xED) \
+ || (OCTET_AT((string),(offset)) == 0xED \
+ && OCTET_AT((string),(offset)+1) < 0xA0) \
+ || (OCTET_AT((string),(offset)) == 0xEE) \
+ || (OCTET_AT((string),(offset)) == 0xEF /* #xE000 <= . <= #xFFFD */ \
+ && !(OCTET_AT((string),(offset)+1) == 0xBB /* && . != #xFEFF */ \
+ && OCTET_AT((string),(offset)+2) == 0xBF) \
+ && !(OCTET_AT((string),(offset)+1) == 0xBF \
+ && (OCTET_AT((string),(offset)+2) == 0xBE \
+ || OCTET_AT((string),(offset)+2) == 0xBF))))
#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
@@ -358,10 +444,10 @@ yaml_string_join(
*/
#define WIDTH_AT(string,offset) \
- (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
- ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
- ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
- ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
+ ((OCTET_AT((string),(offset)) & 0x80) == 0x00 ? 1 : \
+ (OCTET_AT((string),(offset)) & 0xE0) == 0xC0 ? 2 : \
+ (OCTET_AT((string),(offset)) & 0xF0) == 0xE0 ? 3 : \
+ (OCTET_AT((string),(offset)) & 0xF8) == 0xF0 ? 4 : 0)
#define WIDTH(string) WIDTH_AT((string),0)
@@ -372,99 +458,111 @@ yaml_string_join(
#define MOVE(string) ((string).pointer += WIDTH((string)))
/*
+ * Copy a single octet and bump the pointers.
+ */
+
+#define COPY_OCTET(string_a,string_b) \
+ ((string_a).buffer[(string_a).pointer++] \
+ = (string_b).buffer[(string_b).pointer++])
+
+/*
* Copy a character and move the pointers of both strings.
*/
#define COPY(string_a,string_b) \
- ((*(string_b).pointer & 0x80) == 0x00 ? \
- (*((string_a).pointer++) = *((string_b).pointer++)) : \
- (*(string_b).pointer & 0xE0) == 0xC0 ? \
- (*((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++)) : \
- (*(string_b).pointer & 0xF0) == 0xE0 ? \
- (*((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++)) : \
- (*(string_b).pointer & 0xF8) == 0xF0 ? \
- (*((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++), \
- *((string_a).pointer++) = *((string_b).pointer++)) : 0)
+ ((OCTET(string_b) & 0x80) == 0x00 ? \
+ COPY_OCTET((string_a),(string_b)) : \
+ (OCTET(string_b) & 0xE0) == 0xC0 ? \
+ (COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b))) : \
+ (OCTET(string_b) & 0xF0) == 0xE0 ? \
+ (COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b))) : \
+ (OCTET(string_b) & 0xF8) == 0xF0 ? \
+ (COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b)), \
+ COPY_OCTET((string_a),(string_b))) : 0) \
/*
* Stack and queue management.
*/
YAML_DECLARE(int)
-yaml_stack_extend(void **start, void **top, void **end);
+yaml_stack_extend(void **list, size_t size, size_t *length, size_t *capacity);
YAML_DECLARE(int)
-yaml_queue_extend(void **start, void **head, void **tail, void **end);
+yaml_queue_extend(void **list, size_t size,
+ size_t *head, size_t *tail, size_t *capacity);
-#define STACK_INIT(context,stack,size) \
- (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
- ((stack).top = (stack).start, \
- (stack).end = (stack).start+(size), \
+#define STACK_INIT(self,stack,stack_capacity) \
+ (((stack).list = yaml_malloc((stack_capacity)*sizeof(*(stack).list))) ? \
+ ((stack).length = 0, \
+ (stack).capacity = (stack_capacity), \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
-#define STACK_DEL(context,stack) \
- (yaml_free((stack).start), \
- (stack).start = (stack).top = (stack).end = 0)
+#define STACK_DEL(self,stack) \
+ (yaml_free((stack).list), \
+ (stack).list = NULL, \
+ (stack).length = (stack).capacity = 0)
-#define STACK_EMPTY(context,stack) \
- ((stack).start == (stack).top)
+#define STACK_EMPTY(self,stack) \
+ ((stack).length == 0)
-#define PUSH(context,stack,value) \
- (((stack).top != (stack).end \
- || yaml_stack_extend((void **)&(stack).start, \
- (void **)&(stack).top, (void **)&(stack).end)) ? \
- (*((stack).top++) = value, \
+#define PUSH(self,stack,value) \
+ (((stack).length < (stack).capacity \
+ || yaml_stack_extend((void **)&(stack).list, sizeof(*(stack).list), \
+ &(stack).length, &(stack).capacity)) ? \
+ ((stack).list[(stack).length++] = (value), \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
-#define POP(context,stack) \
- (*(--(stack).top))
+#define POP(self,stack) \
+ ((stack).list[--(stack).length])
-#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), \
+#define QUEUE_INIT(self,queue,queue_capacity) \
+ (((queue).list = yaml_malloc((queue_capacity)*sizeof(*(queue).list))) ? \
+ ((queue).head = (queue).tail = 0, \
+ (queue).capacity = (queue_capacity), \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
-#define QUEUE_DEL(context,queue) \
- (yaml_free((queue).start), \
- (queue).start = (queue).head = (queue).tail = (queue).end = 0)
+#define QUEUE_DEL(self,queue) \
+ (yaml_free((queue).list), \
+ (queue).list = NULL, \
+ (queue).head = (queue).tail = (queue).capacity = 0)
-#define QUEUE_EMPTY(context,queue) \
+#define QUEUE_EMPTY(self,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, \
+#define ENQUEUE(self,queue,value) \
+ (((queue).tail != (queue).capacity \
+ || yaml_queue_extend((void **)&(queue).list, sizeof(*(queue).list), \
+ &(queue).head, &(queue).tail, &(queue).capacity)) ? \
+ ((queue).list[(queue).tail++] = (value), \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = 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, \
+#define DEQUEUE(self,queue) \
+ ((queue).list[(queue).head++])
+
+#define QUEUE_INSERT(self,queue,index,value) \
+ (((queue).tail != (queue).capacity \
+ || yaml_queue_extend((void **)&(queue).list, sizeof(*(queue).list), \
+ &(queue).head, &(queue).tail, &(queue).capacity)) ? \
+ (memmove((queue).list+(queue).head+(index)+1, \
+ (queue).list+(queue).head+(index), \
+ ((queue).tail-(queue).head-(index))*sizeof(*(queue).list)), \
+ (queue).list[(queue).head+(index)] = (value), \
(queue).tail++, \
1) : \
- ((context)->error = YAML_MEMORY_ERROR, \
+ ((self)->error.type = YAML_MEMORY_ERROR, \
0))
/*
@@ -531,49 +629,52 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
(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_tag_directives_list,event_tag_directives_length, \
+ event_tag_directives_capacity,event_is_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))
+ (event).data.document_start.tag_directives.list = (event_tag_directives_list), \
+ (event).data.document_start.tag_directives.length = (event_tag_directives_length), \
+ (event).data.document_start.tag_directives.capacity = (event_tag_directives_capacity), \
+ (event).data.document_start.is_implicit = (event_is_implicit))
-#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
+#define DOCUMENT_END_EVENT_INIT(event,event_is_implicit,start_mark,end_mark) \
(EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
- (event).data.document_end.implicit = (event_implicit))
+ (event).data.document_end.is_implicit = (event_is_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) \
+#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value, \
+ event_length,event_is_plain_implicit,event_is_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.is_plain_implicit = (event_is_plain_implicit), \
+ (event).data.scalar.is_quoted_implicit = (event_is_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_is_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.is_implicit = (event_is_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_is_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.is_implicit = (event_is_implicit), \
(event).data.mapping_start.style = (event_style))
#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
@@ -633,3 +734,503 @@ yaml_queue_extend(void **start, void **head, void **tail, void **end);
(node).data.mapping.pairs.top = (node_pairs_start), \
(node).data.mapping.style = (node_style))
+/*
+ * This structure holds information about a potential simple key.
+ */
+
+typedef struct yaml_simple_key_s {
+ /* Is a simple key possible? */
+ int is_possible;
+ /* Is a simple key required? */
+ int is_required;
+ /* The number of the token. */
+ size_t token_number;
+ /* The position mark. */
+ yaml_mark_t mark;
+} yaml_simple_key_t;
+
+/*
+ * The states of the parser.
+ */
+
+typedef enum yaml_parser_state_e {
+ /* Expect STREAM-START. */
+ YAML_PARSE_STREAM_START_STATE,
+ /* Expect the beginning of an implicit document. */
+ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
+ /* Expect DOCUMENT-START. */
+ YAML_PARSE_DOCUMENT_START_STATE,
+ /* Expect the content of a document. */
+ YAML_PARSE_DOCUMENT_CONTENT_STATE,
+ /* Expect DOCUMENT-END. */
+ YAML_PARSE_DOCUMENT_END_STATE,
+ /* Expect a block node. */
+ YAML_PARSE_BLOCK_NODE_STATE,
+ /* Expect a block node or indentless sequence. */
+ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE,
+ /* Expect a flow node. */
+ YAML_PARSE_FLOW_NODE_STATE,
+ /* Expect the first entry of a block sequence. */
+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
+ /* Expect an entry of a block sequence. */
+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
+ /* Expect an entry of an indentless sequence. */
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
+ /* Expect the first key of a block mapping. */
+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE,
+ /* Expect a block mapping key. */
+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE,
+ /* Expect a block mapping value. */
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
+ /* Expect the first entry of a flow sequence. */
+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
+ /* Expect an entry of a flow sequence. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
+ /* Expect a key of an ordered mapping. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE,
+ /* Expect a value of an ordered mapping. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE,
+ /* Expect the and of an ordered mapping entry. */
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE,
+ /* Expect the first key of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
+ /* Expect a key of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE,
+ /* Expect a value of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
+ /* Expect an empty value of a flow mapping. */
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE,
+ /* Expect nothing. */
+ YAML_PARSE_END_STATE
+} yaml_parser_state_t;
+
+/*
+ * This structure holds aliases data.
+ */
+
+typedef struct yaml_alias_data_s {
+ /* The anchor. */
+ yaml_char_t *anchor;
+ /* The node id. */
+ int index;
+ /* The anchor mark. */
+ yaml_mark_t mark;
+} yaml_alias_data_t;
+
+/*
+ * The structure that holds data used by the file and string readers.
+ */
+
+typedef union yaml_standard_reader_data_u {
+ /* String input data. */
+ yaml_string_t string;
+ /* File input data. */
+ FILE *file;
+} yaml_standard_reader_data_t;
+
+/*
+ * The internal parser structure.
+ */
+
+struct yaml_parser_s {
+
+ /*
+ * Error stuff.
+ */
+
+ yaml_error_t error;
+
+ /*
+ * Reader stuff.
+ */
+
+ /* The read handler. */
+ yaml_reader_t *reader;
+
+ /* The application data to be passed to the reader. */
+ void *reader_data;
+
+ /* Standard (string or file) input data. */
+ yaml_standard_reader_data_t standard_reader_data;
+
+ /* EOF flag. */
+ int is_eof;
+
+ /* The working buffer. */
+ struct {
+ yaml_char_t *buffer;
+ size_t pointer;
+ size_t length;
+ size_t capacity;
+ } input;
+
+ /* The number of unread characters in the buffer. */
+ size_t unread;
+
+ /* The raw buffer. */
+ struct {
+ unsigned char *buffer;
+ size_t pointer;
+ size_t length;
+ size_t capacity;
+ } raw_input;
+
+ /* The input encoding. */
+ yaml_encoding_t encoding;
+
+ /* The offset of the current position (in bytes). */
+ size_t offset;
+
+ /* The mark of the current position. */
+ yaml_mark_t mark;
+
+ /*
+ * Scanner stuff.
+ */
+
+ /* Have we started to scan the input stream? */
+ int is_stream_start_produced;
+
+ /* Have we reached the end of the input stream? */
+ int is_stream_end_produced;
+
+ /* The number of unclosed '[' and '{' indicators. */
+ int flow_level;
+
+ /* The tokens queue. */
+ struct {
+ yaml_token_t *list;
+ size_t head;
+ size_t tail;
+ size_t capacity;
+ } tokens;
+
+ /* The number of tokens fetched from the queue. */
+ size_t tokens_parsed;
+
+ /* Does the tokens queue contain a token ready for dequeueing. */
+ int is_token_available;
+
+ /* The indentation levels stack. */
+ struct {
+ int *list;
+ size_t length;
+ size_t capacity;
+ } indents;
+
+ /* The current indentation level. */
+ int indent;
+
+ /* May a simple key occur at the current position? */
+ int is_simple_key_allowed;
+
+ /* The stack of simple keys. */
+ struct {
+ yaml_simple_key_t *list;
+ size_t length;
+ size_t capacity;
+ } simple_keys;
+
+ /*
+ * Parser stuff.
+ */
+
+ /* The parser states stack. */
+ struct {
+ yaml_parser_state_t *list;
+ size_t length;
+ size_t capacity;
+ } states;
+
+ /* The current parser state. */
+ yaml_parser_state_t state;
+
+ /* The stack of marks. */
+ struct {
+ yaml_mark_t *list;
+ size_t length;
+ size_t capacity;
+ } marks;
+
+ /* The list of TAG directives. */
+ struct {
+ yaml_tag_directive_t *list;
+ size_t length;
+ size_t capacity;
+ } tag_directives;
+
+ /*
+ * Dumper stuff.
+ */
+
+ /* The resolve handler. */
+ yaml_resolver_t *resolver;
+
+ /* The application data to be passed to the resolver. */
+ void *resolver_data;
+
+ /* The alias data. */
+ struct {
+ yaml_alias_data_t *list;
+ size_t length;
+ size_t capacity;
+ } aliases;
+
+ /* The currently parsed document. */
+ yaml_document_t *document;
+
+};
+
+/*
+ * The emitter states.
+ */
+
+typedef enum yaml_emitter_state_e {
+ /** Expect STREAM-START. */
+ YAML_EMIT_STREAM_START_STATE,
+ /** Expect the first DOCUMENT-START or STREAM-END. */
+ YAML_EMIT_FIRST_DOCUMENT_START_STATE,
+ /** Expect DOCUMENT-START or STREAM-END. */
+ YAML_EMIT_DOCUMENT_START_STATE,
+ /** Expect the content of a document. */
+ YAML_EMIT_DOCUMENT_CONTENT_STATE,
+ /** Expect DOCUMENT-END. */
+ YAML_EMIT_DOCUMENT_END_STATE,
+ /** Expect the first item of a flow sequence. */
+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
+ /** Expect an item of a flow sequence. */
+ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
+ /** Expect the first key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
+ /** Expect a key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_KEY_STATE,
+ /** Expect a value for a simple key of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
+ /** Expect a value of a flow mapping. */
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
+ /** Expect the first item of a block sequence. */
+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
+ /** Expect an item of a block sequence. */
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
+ /** Expect the first key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
+ /** Expect the key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
+ /** Expect a value for a simple key of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
+ /** Expect a value of a block mapping. */
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
+ /** Expect nothing. */
+ YAML_EMIT_END_STATE
+} yaml_emitter_state_t;
+
+/*
+ * The structure that holds data used by the file and string readers.
+ */
+
+typedef union yaml_standard_writer_data_u {
+ /* String output data. */
+ yaml_string_t string;
+ size_t *length;
+ /* File output data. */
+ FILE *file;
+} yaml_standard_writer_data_t;
+
+/*
+ * The internals emitter structure.
+ */
+
+struct yaml_emitter_s {
+
+ /*
+ * Error stuff.
+ */
+
+ yaml_error_t error;
+
+ /*
+ * Writer stuff.
+ */
+
+ /* Write handler. */
+ yaml_writer_t *writer;
+
+ /* A pointer for passing to the white handler. */
+ void *writer_data;
+
+ /* Standard (string or file) output data. */
+ yaml_standard_writer_data_t standard_writer_data;
+
+ /* The working buffer. */
+ struct {
+ yaml_char_t *buffer;
+ size_t pointer;
+ size_t length;
+ size_t capacity;
+ } output;
+
+ /* The raw buffer. */
+ struct {
+ yaml_char_t *buffer;
+ size_t pointer;
+ size_t length;
+ size_t capacity;
+ } raw_output;
+
+ /* The stream encoding. */
+ yaml_encoding_t encoding;
+
+ /*
+ * Emitter stuff.
+ */
+
+ /* If the output is in the canonical style? */
+ int is_canonical;
+ /* The number of indentation spaces. */
+ int best_indent;
+ /* The preferred width of the output lines. */
+ int best_width;
+ /* Allow unescaped non-ASCII characters? */
+ int is_unicode;
+ /* The preferred line break. */
+ yaml_break_t line_break;
+
+ /* The stack of states. */
+ struct {
+ yaml_emitter_state_t *list;
+ size_t length;
+ size_t capacity;
+ } states;
+
+ /* The current emitter state. */
+ yaml_emitter_state_t state;
+
+ /* The event queue. */
+ struct {
+ yaml_event_t *list;
+ size_t head;
+ size_t tail;
+ size_t capacity;
+ } events;
+
+ /* The stack of indentation levels. */
+ struct {
+ int *list;
+ size_t length;
+ size_t capacity;
+ } indents;
+
+ /* The list of tag directives. */
+ struct {
+ yaml_tag_directive_t *list;
+ size_t length;
+ size_t capacity;
+ } tag_directives;
+
+ /* The current indentation level. */
+ int indent;
+
+ /* The current flow level. */
+ int flow_level;
+
+ /* Is it the document root context? */
+ int is_root_context;
+ /* Is it a sequence context? */
+ int is_sequence_context;
+ /* Is it a mapping context? */
+ int is_mapping_context;
+ /* Is it a simple mapping key context? */
+ int is_simple_key_context;
+
+ /* The current line. */
+ int line;
+ /* The current column. */
+ int column;
+ /* If the last character was a whitespace? */
+ int whitespace;
+ /* If the last character was an indentation character (' ', '-', '?', ':')? */
+ int indention;
+
+ /* Anchor analysis. */
+ struct {
+ /* The anchor value. */
+ yaml_char_t *anchor;
+ /* The anchor length. */
+ size_t anchor_length;
+ /* Is it an alias? */
+ int is_alias;
+ } anchor_data;
+
+ /* Tag analysis. */
+ struct {
+ /* The tag handle. */
+ yaml_char_t *handle;
+ /* The tag handle length. */
+ size_t handle_length;
+ /* The tag suffix. */
+ yaml_char_t *suffix;
+ /* The tag suffix length. */
+ size_t suffix_length;
+ } tag_data;
+
+ /* Scalar analysis. */
+ struct {
+ /* The scalar value. */
+ yaml_char_t *value;
+ /* The scalar length. */
+ size_t length;
+ /* Does the scalar contain line breaks? */
+ int is_multiline;
+ /* Can the scalar be expessed in the flow plain style? */
+ int is_flow_plain_allowed;
+ /* Can the scalar be expressed in the block plain style? */
+ int is_block_plain_allowed;
+ /* Can the scalar be expressed in the single quoted style? */
+ int is_single_quoted_allowed;
+ /* Can the scalar be expressed in the literal or folded styles? */
+ int is_block_allowed;
+ /* The output style. */
+ yaml_scalar_style_t style;
+ } scalar_data;
+
+ /*
+ * Dumper stuff.
+ */
+
+ /* If the stream was already opened? */
+ int is_opened;
+ /* If the stream was already closed? */
+ int is_closed;
+
+ /* The information associated with the document nodes. */
+ struct {
+ /* The number of references. */
+ size_t references;
+ /* The anchor id. */
+ int anchor;
+ /* If the node has been emitted? */
+ int is_serialized;
+ } *anchors;
+
+ /* The last assigned anchor id. */
+ int last_anchor_id;
+
+ /* The currently emitted document. */
+ yaml_document_t *document;
+
+};
+
+/*
+ * 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);
+