2 #include "yaml_private.h"
5 * Get the library version.
8 YAML_DECLARE(const char *)
9 yaml_get_version_string(void)
11 return YAML_VERSION_STRING;
15 * Get the library version numbers.
19 yaml_get_version(int *major, int *minor, int *patch)
21 *major = YAML_VERSION_MAJOR;
22 *minor = YAML_VERSION_MINOR;
23 *patch = YAML_VERSION_PATCH;
27 * Allocate a dynamic memory block.
31 yaml_malloc(size_t size)
33 return malloc(size ? size : 1);
37 * Reallocate a dynamic memory block.
41 yaml_realloc(void *ptr, size_t size)
43 return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
47 * Free a dynamic memory block.
60 YAML_DECLARE(yaml_char_t *)
61 yaml_strdup(const yaml_char_t *str)
66 return (yaml_char_t *)strdup((char *)str);
74 yaml_string_extend(yaml_char_t **start,
75 yaml_char_t **pointer, yaml_char_t **end)
77 void *new_start = yaml_realloc(*start, (*end - *start)*2);
79 if (!new_start) return 0;
81 memset(new_start + (*end - *start), 0, *end - *start);
83 *pointer = new_start + (*pointer - *start);
84 *end = new_start + (*end - *start)*2;
91 * Append a string B to a string A.
96 yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
97 yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
99 if (*b_start == *b_pointer)
102 while (*a_end - *a_pointer <= *b_pointer - *b_start) {
103 if (!yaml_string_extend(a_start, a_pointer, a_end))
107 memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
108 *a_pointer += *b_pointer - *b_start;
118 yaml_stack_extend(void **start, void **top, void **end)
120 void *new_start = yaml_realloc(*start, (*end - *start)*2);
122 if (!new_start) return 0;
124 *top = new_start + (*top - *start);
125 *end = new_start + (*end - *start)*2;
132 * Extend or move a queue.
136 yaml_queue_extend(void **start, void **head, void **tail, void **end)
138 /* Check if we need to resize the queue. */
140 if (*start == *head && *tail == *end) {
141 void *new_start = yaml_realloc(*start, (*end - *start)*2);
143 if (!new_start) return 0;
145 *head = new_start + (*head - *start);
146 *tail = new_start + (*tail - *start);
147 *end = new_start + (*end - *start)*2;
151 /* Check if we need to move the queue at the beginning of the buffer. */
154 if (*head != *tail) {
155 memmove(*start, *head, *tail - *head);
157 *tail -= *head - *start;
166 * Create a new parser object.
170 yaml_parser_initialize(yaml_parser_t *parser)
172 assert(parser); /* Non-NULL parser object expected. */
174 memset(parser, 0, sizeof(yaml_parser_t));
175 if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
177 if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
179 if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
181 if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
183 if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
185 if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
187 if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
189 if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
196 BUFFER_DEL(parser, parser->raw_buffer);
197 BUFFER_DEL(parser, parser->buffer);
198 QUEUE_DEL(parser, parser->tokens);
199 STACK_DEL(parser, parser->indents);
200 STACK_DEL(parser, parser->simple_keys);
201 STACK_DEL(parser, parser->states);
202 STACK_DEL(parser, parser->marks);
203 STACK_DEL(parser, parser->tag_directives);
209 * Destroy a parser object.
213 yaml_parser_delete(yaml_parser_t *parser)
215 assert(parser); /* Non-NULL parser object expected. */
217 BUFFER_DEL(parser, parser->raw_buffer);
218 BUFFER_DEL(parser, parser->buffer);
219 while (!QUEUE_EMPTY(parser, parser->tokens)) {
220 yaml_token_delete(&DEQUEUE(parser, parser->tokens));
222 QUEUE_DEL(parser, parser->tokens);
223 STACK_DEL(parser, parser->indents);
224 STACK_DEL(parser, parser->simple_keys);
225 STACK_DEL(parser, parser->states);
226 STACK_DEL(parser, parser->marks);
227 while (!STACK_EMPTY(parser, parser->tag_directives)) {
228 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
229 yaml_free(tag_directive.handle);
230 yaml_free(tag_directive.prefix);
232 STACK_DEL(parser, parser->tag_directives);
234 memset(parser, 0, sizeof(yaml_parser_t));
238 * String read handler.
242 yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
245 yaml_parser_t *parser = data;
247 if (parser->input.string.current == parser->input.string.end) {
252 if (size > (parser->input.string.end - parser->input.string.current)) {
253 size = parser->input.string.end - parser->input.string.current;
256 memcpy(buffer, parser->input.string.current, size);
257 parser->input.string.current += size;
267 yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
270 yaml_parser_t *parser = data;
272 *size_read = fread(buffer, 1, size, parser->input.file);
273 return !ferror(parser->input.file);
277 * Set a string input.
281 yaml_parser_set_input_string(yaml_parser_t *parser,
282 unsigned char *input, size_t size)
284 assert(parser); /* Non-NULL parser object expected. */
285 assert(!parser->read_handler); /* You can set the source only once. */
286 assert(input); /* Non-NULL input string expected. */
288 parser->read_handler = yaml_string_read_handler;
289 parser->read_handler_data = parser;
291 parser->input.string.start = input;
292 parser->input.string.current = input;
293 parser->input.string.end = input+size;
301 yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
303 assert(parser); /* Non-NULL parser object expected. */
304 assert(!parser->read_handler); /* You can set the source only once. */
305 assert(file); /* Non-NULL file object expected. */
307 parser->read_handler = yaml_file_read_handler;
308 parser->read_handler_data = parser;
310 parser->input.file = file;
314 * Set a generic input.
318 yaml_parser_set_input(yaml_parser_t *parser,
319 yaml_read_handler_t *handler, void *data)
321 assert(parser); /* Non-NULL parser object expected. */
322 assert(!parser->read_handler); /* You can set the source only once. */
323 assert(handler); /* Non-NULL read handler expected. */
325 parser->read_handler = handler;
326 parser->read_handler_data = data;
330 * Set the source encoding.
334 yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
336 assert(parser); /* Non-NULL parser object expected. */
337 assert(!parser->encoding); /* Encoding is already set or detected. */
339 parser->encoding = encoding;
343 * Create a new emitter object.
347 yaml_emitter_initialize(yaml_emitter_t *emitter)
349 assert(emitter); /* Non-NULL emitter object expected. */
351 memset(emitter, 0, sizeof(yaml_emitter_t));
352 if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
354 if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
356 if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
358 if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
360 if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
362 if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
369 BUFFER_DEL(emitter, emitter->buffer);
370 BUFFER_DEL(emitter, emitter->raw_buffer);
371 STACK_DEL(emitter, emitter->states);
372 QUEUE_DEL(emitter, emitter->events);
373 STACK_DEL(emitter, emitter->indents);
374 STACK_DEL(emitter, emitter->tag_directives);
380 * Destroy an emitter object.
384 yaml_emitter_delete(yaml_emitter_t *emitter)
386 assert(emitter); /* Non-NULL emitter object expected. */
388 BUFFER_DEL(emitter, emitter->buffer);
389 BUFFER_DEL(emitter, emitter->raw_buffer);
390 STACK_DEL(emitter, emitter->states);
391 while (!QUEUE_EMPTY(emitter, emitter->events)) {
392 yaml_event_delete(&DEQUEUE(emitter, emitter->events));
394 STACK_DEL(emitter, emitter->indents);
395 yaml_event_delete(&emitter->event);
396 while (!STACK_EMPTY(empty, emitter->tag_directives)) {
397 yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
398 yaml_free(tag_directive.handle);
399 yaml_free(tag_directive.prefix);
401 STACK_DEL(emitter, emitter->tag_directives);
403 memset(emitter, 0, sizeof(yaml_emitter_t));
407 * String write handler.
411 yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
413 yaml_emitter_t *emitter = data;
415 if (emitter->output.string.size + *emitter->output.string.size_written
417 memcpy(emitter->output.string.buffer
418 + *emitter->output.string.size_written,
420 emitter->output.string.size
421 - *emitter->output.string.size_written);
422 *emitter->output.string.size_written = emitter->output.string.size;
426 memcpy(emitter->output.string.buffer
427 + *emitter->output.string.size_written, buffer, size);
428 *emitter->output.string.size_written += size;
433 * File write handler.
437 yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
439 yaml_emitter_t *emitter = data;
441 return (fwrite(buffer, 1, size, emitter->output.file) == size);
444 * Set a string output.
448 yaml_emitter_set_output_string(yaml_emitter_t *emitter,
449 unsigned char *output, size_t size, size_t *size_written)
451 assert(emitter); /* Non-NULL emitter object expected. */
452 assert(!emitter->write_handler); /* You can set the output only once. */
453 assert(output); /* Non-NULL output string expected. */
455 emitter->write_handler = yaml_string_write_handler;
456 emitter->write_handler_data = emitter;
458 emitter->output.string.buffer = output;
459 emitter->output.string.size = size;
460 emitter->output.string.size_written = size_written;
469 yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
471 assert(emitter); /* Non-NULL emitter object expected. */
472 assert(!emitter->write_handler); /* You can set the output only once. */
473 assert(file); /* Non-NULL file object expected. */
475 emitter->write_handler = yaml_file_write_handler;
476 emitter->write_handler_data = emitter;
478 emitter->output.file = file;
482 * Set a generic output handler.
486 yaml_emitter_set_output(yaml_emitter_t *emitter,
487 yaml_write_handler_t *handler, void *data)
489 assert(emitter); /* Non-NULL emitter object expected. */
490 assert(!emitter->write_handler); /* You can set the output only once. */
491 assert(handler); /* Non-NULL handler object expected. */
493 emitter->write_handler = handler;
494 emitter->write_handler_data = data;
498 * Set the output encoding.
502 yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
504 assert(emitter); /* Non-NULL emitter object expected. */
505 assert(!emitter->encoding); /* You can set encoding only once. */
507 emitter->encoding = encoding;
511 * Set the canonical output style.
515 yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
517 assert(emitter); /* Non-NULL emitter object expected. */
519 emitter->canonical = (canonical != 0);
523 * Set the indentation increment.
527 yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
529 assert(emitter); /* Non-NULL emitter object expected. */
531 emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
535 * Set the preferred line width.
539 yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
541 assert(emitter); /* Non-NULL emitter object expected. */
543 emitter->best_width = (width >= 0) ? width : -1;
547 * Set if unescaped non-ASCII characters are allowed.
551 yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
553 assert(emitter); /* Non-NULL emitter object expected. */
555 emitter->unicode = (unicode != 0);
559 * Set the preferred line break character.
563 yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
565 assert(emitter); /* Non-NULL emitter object expected. */
567 emitter->line_break = line_break;
571 * Destroy a token object.
575 yaml_token_delete(yaml_token_t *token)
577 assert(token); /* Non-NULL token object expected. */
581 case YAML_TAG_DIRECTIVE_TOKEN:
582 yaml_free(token->data.tag_directive.handle);
583 yaml_free(token->data.tag_directive.prefix);
586 case YAML_ALIAS_TOKEN:
587 yaml_free(token->data.alias.value);
590 case YAML_ANCHOR_TOKEN:
591 yaml_free(token->data.anchor.value);
595 yaml_free(token->data.tag.handle);
596 yaml_free(token->data.tag.suffix);
599 case YAML_SCALAR_TOKEN:
600 yaml_free(token->data.scalar.value);
607 memset(token, 0, sizeof(yaml_token_t));
611 * Destroy an event object.
615 yaml_event_delete(yaml_event_t *event)
617 yaml_tag_directive_t *tag_directive;
619 assert(event); /* Non-NULL event object expected. */
623 case YAML_DOCUMENT_START_EVENT:
624 yaml_free(event->data.document_start.version_directive);
625 for (tag_directive = event->data.document_start.tag_directives.start;
626 tag_directive != event->data.document_start.tag_directives.end;
628 yaml_free(tag_directive->handle);
629 yaml_free(tag_directive->prefix);
631 yaml_free(event->data.document_start.tag_directives.start);
634 case YAML_ALIAS_EVENT:
635 yaml_free(event->data.alias.anchor);
638 case YAML_SCALAR_EVENT:
639 yaml_free(event->data.scalar.anchor);
640 yaml_free(event->data.scalar.tag);
641 yaml_free(event->data.scalar.value);
644 case YAML_SEQUENCE_START_EVENT:
645 yaml_free(event->data.sequence_start.anchor);
646 yaml_free(event->data.sequence_start.tag);
649 case YAML_MAPPING_START_EVENT:
650 yaml_free(event->data.mapping_start.anchor);
651 yaml_free(event->data.mapping_start.tag);
658 memset(event, 0, sizeof(yaml_event_t));