Skip to content
This repository
Browse code

Merge branch 'embed'

* embed:
  fixing rsync
  make some header file adjustments for ruby compile
  updating the version to 2.0
  add the license for libyaml
  fix c file name
  only do have_header checks if we are embedding libyaml
  mkmf has a global for this test
  fix build on windows
  only embed libyaml if the system does not have it
  for compiling on mswin
  embedding libyaml
  • Loading branch information...
commit c2e0c9878416f621b23525870d69d2bc4816fceb 2 parents d5757ea + 978138b
Aaron Patterson authored
31 Manifest.txt
@@ -4,23 +4,36 @@ CHANGELOG.rdoc
4 4 Manifest.txt
5 5 README.rdoc
6 6 Rakefile
7   -ext/psych/emitter.c
8   -ext/psych/emitter.h
9 7 ext/psych/extconf.rb
10   -ext/psych/parser.c
11   -ext/psych/parser.h
12 8 ext/psych/psych.c
13 9 ext/psych/psych.h
14   -ext/psych/to_ruby.c
15   -ext/psych/to_ruby.h
16   -ext/psych/yaml_tree.c
17   -ext/psych/yaml_tree.h
  10 +ext/psych/psych_emitter.c
  11 +ext/psych/psych_emitter.h
  12 +ext/psych/psych_parser.c
  13 +ext/psych/psych_parser.h
  14 +ext/psych/psych_to_ruby.c
  15 +ext/psych/psych_to_ruby.h
  16 +ext/psych/psych_yaml_tree.c
  17 +ext/psych/psych_yaml_tree.h
  18 +ext/psych/yaml/LICENSE
  19 +ext/psych/yaml/api.c
  20 +ext/psych/yaml/config.h
  21 +ext/psych/yaml/dumper.c
  22 +ext/psych/yaml/emitter.c
  23 +ext/psych/yaml/loader.c
  24 +ext/psych/yaml/parser.c
  25 +ext/psych/yaml/reader.c
  26 +ext/psych/yaml/scanner.c
  27 +ext/psych/yaml/writer.c
  28 +ext/psych/yaml/yaml.h
  29 +ext/psych/yaml/yaml_private.h
18 30 lib/psych.rb
19 31 lib/psych/coder.rb
20 32 lib/psych/core_ext.rb
21 33 lib/psych/deprecated.rb
22 34 lib/psych/handler.rb
23 35 lib/psych/handlers/document_stream.rb
  36 +lib/psych/handlers/recorder.rb
24 37 lib/psych/json/ruby_events.rb
25 38 lib/psych/json/stream.rb
26 39 lib/psych/json/tree_builder.rb
@@ -48,6 +61,8 @@ lib/psych/visitors/json_tree.rb
48 61 lib/psych/visitors/to_ruby.rb
49 62 lib/psych/visitors/visitor.rb
50 63 lib/psych/visitors/yaml_tree.rb
  64 +lib/psych/y.rb
  65 +test/psych/handlers/test_recorder.rb
51 66 test/psych/helper.rb
52 67 test/psych/json/test_stream.rb
53 68 test/psych/nodes/test_enumerable.rb
2  Rakefile
@@ -53,7 +53,7 @@ namespace :merge do
53 53 [basedir, 'test', 'psych/'] => [rubydir, 'test', 'psych/'],
54 54 }
55 55
56   - rsync = 'rsync -av --exclude extconf.rb --exclude lib --exclude ".*" --exclude "*.o" --exclude Makefile --exclude mkmf.log --delete'
  56 + rsync = 'rsync -av --exclude lib --exclude ".*" --exclude "*.o" --exclude Makefile --exclude mkmf.log --delete'
57 57
58 58 task :to_ruby do
59 59 mergedirs.each do |from, to|
11 ext/psych/.gitignore
... ... @@ -0,0 +1,11 @@
  1 +/api.c
  2 +/config.h
  3 +/dumper.c
  4 +/emitter.c
  5 +/loader.c
  6 +/parser.c
  7 +/reader.c
  8 +/scanner.c
  9 +/writer.c
  10 +/yaml.h
  11 +/yaml_private.h
41 ext/psych/extconf.rb
... ... @@ -1,21 +1,40 @@
1 1 require 'mkmf'
  2 +require 'fileutils'
2 3
3 4 # :stopdoc:
4 5
5   -RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
  6 +dir_config 'libyaml'
6 7
7   -INCLUDEDIR = RbConfig::CONFIG['includedir']
8   -LIBDIR = RbConfig::CONFIG['libdir']
9   -LIB_DIRS = ['/opt/local/lib', '/usr/local/lib', LIBDIR, '/usr/lib']
10   -libyaml = dir_config 'libyaml', '/opt/local/include', '/opt/local/lib'
  8 +unless find_header('yaml.h') && find_library('yaml', 'yaml_get_version')
  9 + # Embed libyaml since we could not find it.
11 10
12   -def asplode missing
13   - abort "#{missing} is missing. Try 'port install libyaml +universal' " +
14   - "or 'yum install libyaml-devel'"
15   -end
  11 + srcdir = File.expand_path File.dirname __FILE__
  12 + files = Dir.chdir File.join(srcdir, 'yaml') do
  13 + Dir.entries(Dir.pwd).find_all { |f|
  14 + File.file?(f) && File.extname(f) =~ /^\.[hc]/
  15 + }.map { |f| File.expand_path f }
  16 + end
  17 +
  18 + FileUtils.cp_r files, srcdir
  19 +
  20 + if $mswin
  21 + $CFLAGS += " -DYAML_DECLARE_STATIC -DHAVE_CONFIG_H"
  22 + end
16 23
17   -asplode('yaml.h') unless find_header 'yaml.h'
18   -asplode('libyaml') unless find_library 'yaml', 'yaml_get_version'
  24 + have_header 'dlfcn.h'
  25 + have_header 'inttypes.h'
  26 + have_header 'memory.h'
  27 + have_header 'stdint.h'
  28 + have_header 'stdlib.h'
  29 + have_header 'strings.h'
  30 + have_header 'string.h'
  31 + have_header 'sys/stat.h'
  32 + have_header 'sys/types.h'
  33 + have_header 'unistd.h'
  34 +
  35 + find_header 'yaml.h'
  36 + have_header 'config.h'
  37 +end
19 38
20 39 create_makefile 'psych'
21 40
8 ext/psych/psych.h
@@ -9,10 +9,10 @@
9 9
10 10 #include <yaml.h>
11 11
12   -#include <parser.h>
13   -#include <emitter.h>
14   -#include <to_ruby.h>
15   -#include <yaml_tree.h>
  12 +#include <psych_parser.h>
  13 +#include <psych_emitter.h>
  14 +#include <psych_to_ruby.h>
  15 +#include <psych_yaml_tree.h>
16 16
17 17 extern VALUE mPsych;
18 18
0  ext/psych/emitter.c → ext/psych/psych_emitter.c
File renamed without changes
0  ext/psych/emitter.h → ext/psych/psych_emitter.h
File renamed without changes
0  ext/psych/parser.c → ext/psych/psych_parser.c
File renamed without changes
0  ext/psych/parser.h → ext/psych/psych_parser.h
File renamed without changes
0  ext/psych/to_ruby.c → ext/psych/psych_to_ruby.c
File renamed without changes
0  ext/psych/to_ruby.h → ext/psych/psych_to_ruby.h
File renamed without changes
0  ext/psych/yaml_tree.c → ext/psych/psych_yaml_tree.c
File renamed without changes
0  ext/psych/yaml_tree.h → ext/psych/psych_yaml_tree.h
File renamed without changes
19 ext/psych/yaml/LICENSE
... ... @@ -0,0 +1,19 @@
  1 +Copyright (c) 2006 Kirill Simonov
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  4 +this software and associated documentation files (the "Software"), to deal in
  5 +the Software without restriction, including without limitation the rights to
  6 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  7 +of the Software, and to permit persons to whom the Software is furnished to do
  8 +so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in all
  11 +copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19 +SOFTWARE.
1,392 ext/psych/yaml/api.c
... ... @@ -0,0 +1,1392 @@
  1 +
  2 +#include "yaml_private.h"
  3 +
  4 +/*
  5 + * Get the library version.
  6 + */
  7 +
  8 +YAML_DECLARE(const char *)
  9 +yaml_get_version_string(void)
  10 +{
  11 + return YAML_VERSION_STRING;
  12 +}
  13 +
  14 +/*
  15 + * Get the library version numbers.
  16 + */
  17 +
  18 +YAML_DECLARE(void)
  19 +yaml_get_version(int *major, int *minor, int *patch)
  20 +{
  21 + *major = YAML_VERSION_MAJOR;
  22 + *minor = YAML_VERSION_MINOR;
  23 + *patch = YAML_VERSION_PATCH;
  24 +}
  25 +
  26 +/*
  27 + * Allocate a dynamic memory block.
  28 + */
  29 +
  30 +YAML_DECLARE(void *)
  31 +yaml_malloc(size_t size)
  32 +{
  33 + return malloc(size ? size : 1);
  34 +}
  35 +
  36 +/*
  37 + * Reallocate a dynamic memory block.
  38 + */
  39 +
  40 +YAML_DECLARE(void *)
  41 +yaml_realloc(void *ptr, size_t size)
  42 +{
  43 + return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
  44 +}
  45 +
  46 +/*
  47 + * Free a dynamic memory block.
  48 + */
  49 +
  50 +YAML_DECLARE(void)
  51 +yaml_free(void *ptr)
  52 +{
  53 + if (ptr) free(ptr);
  54 +}
  55 +
  56 +/*
  57 + * Duplicate a string.
  58 + */
  59 +
  60 +YAML_DECLARE(yaml_char_t *)
  61 +yaml_strdup(const yaml_char_t *str)
  62 +{
  63 + if (!str)
  64 + return NULL;
  65 +
  66 + return (yaml_char_t *)strdup((char *)str);
  67 +}
  68 +
  69 +/*
  70 + * Extend a string.
  71 + */
  72 +
  73 +YAML_DECLARE(int)
  74 +yaml_string_extend(yaml_char_t **start,
  75 + yaml_char_t **pointer, yaml_char_t **end)
  76 +{
  77 + yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
  78 +
  79 + if (!new_start) return 0;
  80 +
  81 + memset(new_start + (*end - *start), 0, *end - *start);
  82 +
  83 + *pointer = new_start + (*pointer - *start);
  84 + *end = new_start + (*end - *start)*2;
  85 + *start = new_start;
  86 +
  87 + return 1;
  88 +}
  89 +
  90 +/*
  91 + * Append a string B to a string A.
  92 + */
  93 +
  94 +YAML_DECLARE(int)
  95 +yaml_string_join(
  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)
  98 +{
  99 + if (*b_start == *b_pointer)
  100 + return 1;
  101 +
  102 + while (*a_end - *a_pointer <= *b_pointer - *b_start) {
  103 + if (!yaml_string_extend(a_start, a_pointer, a_end))
  104 + return 0;
  105 + }
  106 +
  107 + memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
  108 + *a_pointer += *b_pointer - *b_start;
  109 +
  110 + return 1;
  111 +}
  112 +
  113 +/*
  114 + * Extend a stack.
  115 + */
  116 +
  117 +YAML_DECLARE(int)
  118 +yaml_stack_extend(void **start, void **top, void **end)
  119 +{
  120 + void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
  121 +
  122 + if (!new_start) return 0;
  123 +
  124 + *top = (char *)new_start + ((char *)*top - (char *)*start);
  125 + *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
  126 + *start = new_start;
  127 +
  128 + return 1;
  129 +}
  130 +
  131 +/*
  132 + * Extend or move a queue.
  133 + */
  134 +
  135 +YAML_DECLARE(int)
  136 +yaml_queue_extend(void **start, void **head, void **tail, void **end)
  137 +{
  138 + /* Check if we need to resize the queue. */
  139 +
  140 + if (*start == *head && *tail == *end) {
  141 + void *new_start = yaml_realloc(*start,
  142 + ((char *)*end - (char *)*start)*2);
  143 +
  144 + if (!new_start) return 0;
  145 +
  146 + *head = (char *)new_start + ((char *)*head - (char *)*start);
  147 + *tail = (char *)new_start + ((char *)*tail - (char *)*start);
  148 + *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
  149 + *start = new_start;
  150 + }
  151 +
  152 + /* Check if we need to move the queue at the beginning of the buffer. */
  153 +
  154 + if (*tail == *end) {
  155 + if (*head != *tail) {
  156 + memmove(*start, *head, (char *)*tail - (char *)*head);
  157 + }
  158 + *tail = (char *)*tail - (char *)*head + (char *)*start;
  159 + *head = *start;
  160 + }
  161 +
  162 + return 1;
  163 +}
  164 +
  165 +
  166 +/*
  167 + * Create a new parser object.
  168 + */
  169 +
  170 +YAML_DECLARE(int)
  171 +yaml_parser_initialize(yaml_parser_t *parser)
  172 +{
  173 + assert(parser); /* Non-NULL parser object expected. */
  174 +
  175 + memset(parser, 0, sizeof(yaml_parser_t));
  176 + if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
  177 + goto error;
  178 + if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
  179 + goto error;
  180 + if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
  181 + goto error;
  182 + if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
  183 + goto error;
  184 + if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
  185 + goto error;
  186 + if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
  187 + goto error;
  188 + if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
  189 + goto error;
  190 + if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
  191 + goto error;
  192 +
  193 + return 1;
  194 +
  195 +error:
  196 +
  197 + BUFFER_DEL(parser, parser->raw_buffer);
  198 + BUFFER_DEL(parser, parser->buffer);
  199 + QUEUE_DEL(parser, parser->tokens);
  200 + STACK_DEL(parser, parser->indents);
  201 + STACK_DEL(parser, parser->simple_keys);
  202 + STACK_DEL(parser, parser->states);
  203 + STACK_DEL(parser, parser->marks);
  204 + STACK_DEL(parser, parser->tag_directives);
  205 +
  206 + return 0;
  207 +}
  208 +
  209 +/*
  210 + * Destroy a parser object.
  211 + */
  212 +
  213 +YAML_DECLARE(void)
  214 +yaml_parser_delete(yaml_parser_t *parser)
  215 +{
  216 + assert(parser); /* Non-NULL parser object expected. */
  217 +
  218 + BUFFER_DEL(parser, parser->raw_buffer);
  219 + BUFFER_DEL(parser, parser->buffer);
  220 + while (!QUEUE_EMPTY(parser, parser->tokens)) {
  221 + yaml_token_delete(&DEQUEUE(parser, parser->tokens));
  222 + }
  223 + QUEUE_DEL(parser, parser->tokens);
  224 + STACK_DEL(parser, parser->indents);
  225 + STACK_DEL(parser, parser->simple_keys);
  226 + STACK_DEL(parser, parser->states);
  227 + STACK_DEL(parser, parser->marks);
  228 + while (!STACK_EMPTY(parser, parser->tag_directives)) {
  229 + yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
  230 + yaml_free(tag_directive.handle);
  231 + yaml_free(tag_directive.prefix);
  232 + }
  233 + STACK_DEL(parser, parser->tag_directives);
  234 +
  235 + memset(parser, 0, sizeof(yaml_parser_t));
  236 +}
  237 +
  238 +/*
  239 + * String read handler.
  240 + */
  241 +
  242 +static int
  243 +yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
  244 + size_t *size_read)
  245 +{
  246 + yaml_parser_t *parser = data;
  247 +
  248 + if (parser->input.string.current == parser->input.string.end) {
  249 + *size_read = 0;
  250 + return 1;
  251 + }
  252 +
  253 + if (size > (size_t)(parser->input.string.end
  254 + - parser->input.string.current)) {
  255 + size = parser->input.string.end - parser->input.string.current;
  256 + }
  257 +
  258 + memcpy(buffer, parser->input.string.current, size);
  259 + parser->input.string.current += size;
  260 + *size_read = size;
  261 + return 1;
  262 +}
  263 +
  264 +/*
  265 + * File read handler.
  266 + */
  267 +
  268 +static int
  269 +yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
  270 + size_t *size_read)
  271 +{
  272 + yaml_parser_t *parser = data;
  273 +
  274 + *size_read = fread(buffer, 1, size, parser->input.file);
  275 + return !ferror(parser->input.file);
  276 +}
  277 +
  278 +/*
  279 + * Set a string input.
  280 + */
  281 +
  282 +YAML_DECLARE(void)
  283 +yaml_parser_set_input_string(yaml_parser_t *parser,
  284 + const unsigned char *input, size_t size)
  285 +{
  286 + assert(parser); /* Non-NULL parser object expected. */
  287 + assert(!parser->read_handler); /* You can set the source only once. */
  288 + assert(input); /* Non-NULL input string expected. */
  289 +
  290 + parser->read_handler = yaml_string_read_handler;
  291 + parser->read_handler_data = parser;
  292 +
  293 + parser->input.string.start = input;
  294 + parser->input.string.current = input;
  295 + parser->input.string.end = input+size;
  296 +}
  297 +
  298 +/*
  299 + * Set a file input.
  300 + */
  301 +
  302 +YAML_DECLARE(void)
  303 +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
  304 +{
  305 + assert(parser); /* Non-NULL parser object expected. */
  306 + assert(!parser->read_handler); /* You can set the source only once. */
  307 + assert(file); /* Non-NULL file object expected. */
  308 +
  309 + parser->read_handler = yaml_file_read_handler;
  310 + parser->read_handler_data = parser;
  311 +
  312 + parser->input.file = file;
  313 +}
  314 +
  315 +/*
  316 + * Set a generic input.
  317 + */
  318 +
  319 +YAML_DECLARE(void)
  320 +yaml_parser_set_input(yaml_parser_t *parser,
  321 + yaml_read_handler_t *handler, void *data)
  322 +{
  323 + assert(parser); /* Non-NULL parser object expected. */
  324 + assert(!parser->read_handler); /* You can set the source only once. */
  325 + assert(handler); /* Non-NULL read handler expected. */
  326 +
  327 + parser->read_handler = handler;
  328 + parser->read_handler_data = data;
  329 +}
  330 +
  331 +/*
  332 + * Set the source encoding.
  333 + */
  334 +
  335 +YAML_DECLARE(void)
  336 +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
  337 +{
  338 + assert(parser); /* Non-NULL parser object expected. */
  339 + assert(!parser->encoding); /* Encoding is already set or detected. */
  340 +
  341 + parser->encoding = encoding;
  342 +}
  343 +
  344 +/*
  345 + * Create a new emitter object.
  346 + */
  347 +
  348 +YAML_DECLARE(int)
  349 +yaml_emitter_initialize(yaml_emitter_t *emitter)
  350 +{
  351 + assert(emitter); /* Non-NULL emitter object expected. */
  352 +
  353 + memset(emitter, 0, sizeof(yaml_emitter_t));
  354 + if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
  355 + goto error;
  356 + if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
  357 + goto error;
  358 + if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
  359 + goto error;
  360 + if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
  361 + goto error;
  362 + if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
  363 + goto error;
  364 + if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
  365 + goto error;
  366 +
  367 + return 1;
  368 +
  369 +error:
  370 +
  371 + BUFFER_DEL(emitter, emitter->buffer);
  372 + BUFFER_DEL(emitter, emitter->raw_buffer);
  373 + STACK_DEL(emitter, emitter->states);
  374 + QUEUE_DEL(emitter, emitter->events);
  375 + STACK_DEL(emitter, emitter->indents);
  376 + STACK_DEL(emitter, emitter->tag_directives);
  377 +
  378 + return 0;
  379 +}
  380 +
  381 +/*
  382 + * Destroy an emitter object.
  383 + */
  384 +
  385 +YAML_DECLARE(void)
  386 +yaml_emitter_delete(yaml_emitter_t *emitter)
  387 +{
  388 + assert(emitter); /* Non-NULL emitter object expected. */
  389 +
  390 + BUFFER_DEL(emitter, emitter->buffer);
  391 + BUFFER_DEL(emitter, emitter->raw_buffer);
  392 + STACK_DEL(emitter, emitter->states);
  393 + while (!QUEUE_EMPTY(emitter, emitter->events)) {
  394 + yaml_event_delete(&DEQUEUE(emitter, emitter->events));
  395 + }
  396 + QUEUE_DEL(emitter, emitter->events);
  397 + STACK_DEL(emitter, emitter->indents);
  398 + while (!STACK_EMPTY(empty, emitter->tag_directives)) {
  399 + yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
  400 + yaml_free(tag_directive.handle);
  401 + yaml_free(tag_directive.prefix);
  402 + }
  403 + STACK_DEL(emitter, emitter->tag_directives);
  404 + yaml_free(emitter->anchors);
  405 +
  406 + memset(emitter, 0, sizeof(yaml_emitter_t));
  407 +}
  408 +
  409 +/*
  410 + * String write handler.
  411 + */
  412 +
  413 +static int
  414 +yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
  415 +{
  416 + yaml_emitter_t *emitter = data;
  417 +
  418 + if (emitter->output.string.size + *emitter->output.string.size_written
  419 + < size) {
  420 + memcpy(emitter->output.string.buffer
  421 + + *emitter->output.string.size_written,
  422 + buffer,
  423 + emitter->output.string.size
  424 + - *emitter->output.string.size_written);
  425 + *emitter->output.string.size_written = emitter->output.string.size;
  426 + return 0;
  427 + }
  428 +
  429 + memcpy(emitter->output.string.buffer
  430 + + *emitter->output.string.size_written, buffer, size);
  431 + *emitter->output.string.size_written += size;
  432 + return 1;
  433 +}
  434 +
  435 +/*
  436 + * File write handler.
  437 + */
  438 +
  439 +static int
  440 +yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
  441 +{
  442 + yaml_emitter_t *emitter = data;
  443 +
  444 + return (fwrite(buffer, 1, size, emitter->output.file) == size);
  445 +}
  446 +/*
  447 + * Set a string output.
  448 + */
  449 +
  450 +YAML_DECLARE(void)
  451 +yaml_emitter_set_output_string(yaml_emitter_t *emitter,
  452 + unsigned char *output, size_t size, size_t *size_written)
  453 +{
  454 + assert(emitter); /* Non-NULL emitter object expected. */
  455 + assert(!emitter->write_handler); /* You can set the output only once. */
  456 + assert(output); /* Non-NULL output string expected. */
  457 +
  458 + emitter->write_handler = yaml_string_write_handler;
  459 + emitter->write_handler_data = emitter;
  460 +
  461 + emitter->output.string.buffer = output;
  462 + emitter->output.string.size = size;
  463 + emitter->output.string.size_written = size_written;
  464 + *size_written = 0;
  465 +}
  466 +
  467 +/*
  468 + * Set a file output.
  469 + */
  470 +
  471 +YAML_DECLARE(void)
  472 +yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
  473 +{
  474 + assert(emitter); /* Non-NULL emitter object expected. */
  475 + assert(!emitter->write_handler); /* You can set the output only once. */
  476 + assert(file); /* Non-NULL file object expected. */
  477 +
  478 + emitter->write_handler = yaml_file_write_handler;
  479 + emitter->write_handler_data = emitter;
  480 +
  481 + emitter->output.file = file;
  482 +}
  483 +
  484 +/*
  485 + * Set a generic output handler.
  486 + */
  487 +
  488 +YAML_DECLARE(void)
  489 +yaml_emitter_set_output(yaml_emitter_t *emitter,
  490 + yaml_write_handler_t *handler, void *data)
  491 +{
  492 + assert(emitter); /* Non-NULL emitter object expected. */
  493 + assert(!emitter->write_handler); /* You can set the output only once. */
  494 + assert(handler); /* Non-NULL handler object expected. */
  495 +
  496 + emitter->write_handler = handler;
  497 + emitter->write_handler_data = data;
  498 +}
  499 +
  500 +/*
  501 + * Set the output encoding.
  502 + */
  503 +
  504 +YAML_DECLARE(void)
  505 +yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
  506 +{
  507 + assert(emitter); /* Non-NULL emitter object expected. */
  508 + assert(!emitter->encoding); /* You can set encoding only once. */
  509 +
  510 + emitter->encoding = encoding;
  511 +}
  512 +
  513 +/*
  514 + * Set the canonical output style.
  515 + */
  516 +
  517 +YAML_DECLARE(void)
  518 +yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
  519 +{
  520 + assert(emitter); /* Non-NULL emitter object expected. */
  521 +
  522 + emitter->canonical = (canonical != 0);
  523 +}
  524 +
  525 +/*
  526 + * Set the indentation increment.
  527 + */
  528 +
  529 +YAML_DECLARE(void)
  530 +yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
  531 +{
  532 + assert(emitter); /* Non-NULL emitter object expected. */
  533 +
  534 + emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
  535 +}
  536 +
  537 +/*
  538 + * Set the preferred line width.
  539 + */
  540 +
  541 +YAML_DECLARE(void)
  542 +yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
  543 +{
  544 + assert(emitter); /* Non-NULL emitter object expected. */
  545 +
  546 + emitter->best_width = (width >= 0) ? width : -1;
  547 +}
  548 +
  549 +/*
  550 + * Set if unescaped non-ASCII characters are allowed.
  551 + */
  552 +
  553 +YAML_DECLARE(void)
  554 +yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
  555 +{
  556 + assert(emitter); /* Non-NULL emitter object expected. */
  557 +
  558 + emitter->unicode = (unicode != 0);
  559 +}
  560 +
  561 +/*
  562 + * Set the preferred line break character.
  563 + */
  564 +
  565 +YAML_DECLARE(void)
  566 +yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
  567 +{
  568 + assert(emitter); /* Non-NULL emitter object expected. */
  569 +
  570 + emitter->line_break = line_break;
  571 +}
  572 +
  573 +/*
  574 + * Destroy a token object.
  575 + */
  576 +
  577 +YAML_DECLARE(void)
  578 +yaml_token_delete(yaml_token_t *token)
  579 +{
  580 + assert(token); /* Non-NULL token object expected. */
  581 +
  582 + switch (token->type)
  583 + {
  584 + case YAML_TAG_DIRECTIVE_TOKEN:
  585 + yaml_free(token->data.tag_directive.handle);
  586 + yaml_free(token->data.tag_directive.prefix);
  587 + break;
  588 +
  589 + case YAML_ALIAS_TOKEN:
  590 + yaml_free(token->data.alias.value);
  591 + break;
  592 +
  593 + case YAML_ANCHOR_TOKEN:
  594 + yaml_free(token->data.anchor.value);
  595 + break;
  596 +
  597 + case YAML_TAG_TOKEN:
  598 + yaml_free(token->data.tag.handle);
  599 + yaml_free(token->data.tag.suffix);
  600 + break;
  601 +
  602 + case YAML_SCALAR_TOKEN:
  603 + yaml_free(token->data.scalar.value);
  604 + break;
  605 +
  606 + default:
  607 + break;
  608 + }
  609 +
  610 + memset(token, 0, sizeof(yaml_token_t));
  611 +}
  612 +
  613 +/*
  614 + * Check if a string is a valid UTF-8 sequence.
  615 + *
  616 + * Check 'reader.c' for more details on UTF-8 encoding.
  617 + */
  618 +
  619 +static int
  620 +yaml_check_utf8(yaml_char_t *start, size_t length)
  621 +{
  622 + yaml_char_t *end = start+length;
  623 + yaml_char_t *pointer = start;
  624 +
  625 + while (pointer < end) {
  626 + unsigned char octet;
  627 + unsigned int width;
  628 + unsigned int value;
  629 + size_t k;
  630 +
  631 + octet = pointer[0];
  632 + width = (octet & 0x80) == 0x00 ? 1 :
  633 + (octet & 0xE0) == 0xC0 ? 2 :
  634 + (octet & 0xF0) == 0xE0 ? 3 :
  635 + (octet & 0xF8) == 0xF0 ? 4 : 0;
  636 + value = (octet & 0x80) == 0x00 ? octet & 0x7F :
  637 + (octet & 0xE0) == 0xC0 ? octet & 0x1F :
  638 + (octet & 0xF0) == 0xE0 ? octet & 0x0F :
  639 + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
  640 + if (!width) return 0;
  641 + if (pointer+width > end) return 0;
  642 + for (k = 1; k < width; k ++) {
  643 + octet = pointer[k];
  644 + if ((octet & 0xC0) != 0x80) return 0;
  645 + value = (value << 6) + (octet & 0x3F);
  646 + }
  647 + if (!((width == 1) ||
  648 + (width == 2 && value >= 0x80) ||
  649 + (width == 3 && value >= 0x800) ||
  650 + (width == 4 && value >= 0x10000))) return 0;
  651 +
  652 + pointer += width;
  653 + }
  654 +
  655 + return 1;
  656 +}
  657 +
  658 +/*
  659 + * Create STREAM-START.
  660 + */
  661 +
  662 +YAML_DECLARE(int)
  663 +yaml_stream_start_event_initialize(yaml_event_t *event,
  664 + yaml_encoding_t encoding)
  665 +{
  666 + yaml_mark_t mark = { 0, 0, 0 };
  667 +
  668 + assert(event); /* Non-NULL event object is expected. */
  669 +
  670 + STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
  671 +
  672 + return 1;
  673 +}
  674 +
  675 +/*
  676 + * Create STREAM-END.
  677 + */
  678 +
  679 +YAML_DECLARE(int)
  680 +yaml_stream_end_event_initialize(yaml_event_t *event)
  681 +{
  682 + yaml_mark_t mark = { 0, 0, 0 };
  683 +
  684 + assert(event); /* Non-NULL event object is expected. */
  685 +
  686 + STREAM_END_EVENT_INIT(*event, mark, mark);
  687 +
  688 + return 1;
  689 +}
  690 +
  691 +/*
  692 + * Create DOCUMENT-START.
  693 + */
  694 +
  695 +YAML_DECLARE(int)
  696 +yaml_document_start_event_initialize(yaml_event_t *event,
  697 + yaml_version_directive_t *version_directive,
  698 + yaml_tag_directive_t *tag_directives_start,
  699 + yaml_tag_directive_t *tag_directives_end,
  700 + int implicit)
  701 +{
  702 + struct {
  703 + yaml_error_type_t error;
  704 + } context;
  705 + yaml_mark_t mark = { 0, 0, 0 };
  706 + yaml_version_directive_t *version_directive_copy = NULL;
  707 + struct {
  708 + yaml_tag_directive_t *start;
  709 + yaml_tag_directive_t *end;
  710 + yaml_tag_directive_t *top;
  711 + } tag_directives_copy = { NULL, NULL, NULL };
  712 + yaml_tag_directive_t value = { NULL, NULL };
  713 +
  714 + assert(event); /* Non-NULL event object is expected. */
  715 + assert((tag_directives_start && tag_directives_end) ||
  716 + (tag_directives_start == tag_directives_end));
  717 + /* Valid tag directives are expected. */
  718 +
  719 + if (version_directive) {
  720 + version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
  721 + if (!version_directive_copy) goto error;
  722 + version_directive_copy->major = version_directive->major;
  723 + version_directive_copy->minor = version_directive->minor;
  724 + }
  725 +
  726 + if (tag_directives_start != tag_directives_end) {
  727 + yaml_tag_directive_t *tag_directive;
  728 + if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
  729 + goto error;
  730 + for (tag_directive = tag_directives_start;
  731 + tag_directive != tag_directives_end; tag_directive ++) {
  732 + assert(tag_directive->handle);
  733 + assert(tag_directive->prefix);
  734 + if (!yaml_check_utf8(tag_directive->handle,
  735 + strlen((char *)tag_directive->handle)))
  736 + goto error;
  737 + if (!yaml_check_utf8(tag_directive->prefix,
  738 + strlen((char *)tag_directive->prefix)))
  739 + goto error;
  740 + value.handle = yaml_strdup(tag_directive->handle);
  741 + value.prefix = yaml_strdup(tag_directive->prefix);
  742 + if (!value.handle || !value.prefix) goto error;
  743 + if (!PUSH(&context, tag_directives_copy, value))
  744 + goto error;
  745 + value.handle = NULL;
  746 + value.prefix = NULL;
  747 + }
  748 + }
  749 +
  750 + DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
  751 + tag_directives_copy.start, tag_directives_copy.top,
  752 + implicit, mark, mark);
  753 +
  754 + return 1;
  755 +
  756 +error:
  757 + yaml_free(version_directive_copy);
  758 + while (!STACK_EMPTY(context, tag_directives_copy)) {
  759 + yaml_tag_directive_t value = POP(context, tag_directives_copy);
  760 + yaml_free(value.handle);
  761 + yaml_free(value.prefix);
  762 + }
  763 + STACK_DEL(context, tag_directives_copy);
  764 + yaml_free(value.handle);
  765 + yaml_free(value.prefix);
  766 +
  767 + return 0;
  768 +}
  769 +
  770 +/*
  771 + * Create DOCUMENT-END.
  772 + */
  773 +
  774 +YAML_DECLARE(int)
  775 +yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
  776 +{
  777 + yaml_mark_t mark = { 0, 0, 0 };
  778 +
  779 + assert(event); /* Non-NULL emitter object is expected. */
  780 +
  781 + DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
  782 +
  783 + return 1;
  784 +}
  785 +
  786 +/*
  787 + * Create ALIAS.
  788 + */
  789 +
  790 +YAML_DECLARE(int)
  791 +yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
  792 +{
  793 + yaml_mark_t mark = { 0, 0, 0 };
  794 + yaml_char_t *anchor_copy = NULL;
  795 +
  796 + assert(event); /* Non-NULL event object is expected. */
  797 + assert(anchor); /* Non-NULL anchor is expected. */
  798 +
  799 + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
  800 +
  801 + anchor_copy = yaml_strdup(anchor);
  802 + if (!anchor_copy)
  803 + return 0;
  804 +
  805 + ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
  806 +
  807 + return 1;
  808 +}
  809 +
  810 +/*
  811 + * Create SCALAR.
  812 + */
  813 +
  814 +YAML_DECLARE(int)
  815 +yaml_scalar_event_initialize(yaml_event_t *event,
  816 + yaml_char_t *anchor, yaml_char_t *tag,
  817 + yaml_char_t *value, int length,
  818 + int plain_implicit, int quoted_implicit,
  819 + yaml_scalar_style_t style)
  820 +{
  821 + yaml_mark_t mark = { 0, 0, 0 };
  822 + yaml_char_t *anchor_copy = NULL;
  823 + yaml_char_t *tag_copy = NULL;
  824 + yaml_char_t *value_copy = NULL;
  825 +
  826 + assert(event); /* Non-NULL event object is expected. */
  827 + assert(value); /* Non-NULL anchor is expected. */
  828 +
  829 + if (anchor) {
  830 + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
  831 + anchor_copy = yaml_strdup(anchor);
  832 + if (!anchor_copy) goto error;
  833 + }
  834 +
  835 + if (tag) {
  836 + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
  837 + tag_copy = yaml_strdup(tag);
  838 + if (!tag_copy) goto error;
  839 + }
  840 +
  841 + if (length < 0) {
  842 + length = strlen((char *)value);
  843 + }
  844 +
  845 + if (!yaml_check_utf8(value, length)) goto error;
  846 + value_copy = yaml_malloc(length+1);
  847 + if (!value_copy) goto error;
  848 + memcpy(value_copy, value, length);
  849 + value_copy[length] = '\0';
  850 +
  851 + SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
  852 + plain_implicit, quoted_implicit, style, mark, mark);
  853 +
  854 + return 1;
  855 +
  856 +error:
  857 + yaml_free(anchor_copy);
  858 + yaml_free(tag_copy);
  859 + yaml_free(value_copy);
  860 +
  861 + return 0;
  862 +}
  863 +
  864 +/*
  865 + * Create SEQUENCE-START.
  866 + */
  867 +
  868 +YAML_DECLARE(int)
  869 +yaml_sequence_start_event_initialize(yaml_event_t *event,
  870 + yaml_char_t *anchor, yaml_char_t *tag, int implicit,
  871 + yaml_sequence_style_t style)
  872 +{
  873 + yaml_mark_t mark = { 0, 0, 0 };
  874 + yaml_char_t *anchor_copy = NULL;
  875 + yaml_char_t *tag_copy = NULL;
  876 +
  877 + assert(event); /* Non-NULL event object is expected. */
  878 +
  879 + if (anchor) {
  880 + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
  881 + anchor_copy = yaml_strdup(anchor);
  882 + if (!anchor_copy) goto error;
  883 + }
  884 +
  885 + if (tag) {
  886 + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
  887 + tag_copy = yaml_strdup(tag);
  888 + if (!tag_copy) goto error;
  889 + }
  890 +
  891 + SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
  892 + implicit, style, mark, mark);
  893 +
  894 + return 1;
  895 +
  896 +error:
  897 + yaml_free(anchor_copy);
  898 + yaml_free(tag_copy);
  899 +
  900 + return 0;
  901 +}
  902 +
  903 +/*
  904 + * Create SEQUENCE-END.
  905 + */
  906 +
  907 +YAML_DECLARE(int)
  908 +yaml_sequence_end_event_initialize(yaml_event_t *event)
  909 +{
  910 + yaml_mark_t mark = { 0, 0, 0 };
  911 +
  912 + assert(event); /* Non-NULL event object is expected. */
  913 +
  914 + SEQUENCE_END_EVENT_INIT(*event, mark, mark);
  915 +
  916 + return 1;
  917 +}
  918 +
  919 +/*
  920 + * Create MAPPING-START.
  921 + */
  922 +
  923 +YAML_DECLARE(int)
  924 +yaml_mapping_start_event_initialize(yaml_event_t *event,
  925 + yaml_char_t *anchor, yaml_char_t *tag, int implicit,
  926 + yaml_mapping_style_t style)
  927 +{
  928 + yaml_mark_t mark = { 0, 0, 0 };
  929 + yaml_char_t *anchor_copy = NULL;
  930 + yaml_char_t *tag_copy = NULL;
  931 +
  932 + assert(event); /* Non-NULL event object is expected. */
  933 +
  934 + if (anchor) {
  935 + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
  936 + anchor_copy = yaml_strdup(anchor);
  937 + if (!anchor_copy) goto error;
  938 + }
  939 +
  940 + if (tag) {
  941 + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
  942 + tag_copy = yaml_strdup(tag);
  943 + if (!tag_copy) goto error;
  944 + }
  945 +
  946 + MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
  947 + implicit, style, mark, mark);
  948 +
  949 + return 1;
  950 +
  951 +error:
  952 + yaml_free(anchor_copy);
  953 + yaml_free(tag_copy);
  954 +
  955 + return 0;
  956 +}
  957 +
  958 +/*
  959 + * Create MAPPING-END.
  960 + */
  961 +
  962 +YAML_DECLARE(int)
  963 +yaml_mapping_end_event_initialize(yaml_event_t *event)
  964 +{
  965 + yaml_mark_t mark = { 0, 0, 0 };
  966 +
  967 + assert(event); /* Non-NULL event object is expected. */
  968 +
  969 + MAPPING_END_EVENT_INIT(*event, mark, mark);
  970 +
  971 + return 1;
  972 +}
  973 +
  974 +/*
  975 + * Destroy an event object.
  976 + */
  977 +
  978 +YAML_DECLARE(void)
  979 +yaml_event_delete(yaml_event_t *event)
  980 +{
  981 + yaml_tag_directive_t *tag_directive;
  982 +
  983 + assert(event); /* Non-NULL event object expected. */
  984 +
  985 + switch (event->type)
  986 + {
  987 + case YAML_DOCUMENT_START_EVENT:
  988 + yaml_free(event->data.document_start.version_directive);
  989 + for (tag_directive = event->data.document_start.tag_directives.start;
  990 + tag_directive != event->data.document_start.tag_directives.end;
  991 + tag_directive++) {
  992 + yaml_free(tag_directive->handle);
  993 + yaml_free(tag_directive->prefix);
  994 + }
  995 + yaml_free(event->data.document_start.tag_directives.start);
  996 + break;
  997 +
  998 + case YAML_ALIAS_EVENT:
  999 + yaml_free(event->data.alias.anchor);
  1000 + break;
  1001 +
  1002 + case YAML_SCALAR_EVENT:
  1003 + yaml_free(event->data.scalar.anchor);
  1004 + yaml_free(event->data.scalar.tag);
  1005 + yaml_free(event->data.scalar.value);
  1006 + break;
  1007 +
  1008 + case YAML_SEQUENCE_START_EVENT:
  1009 + yaml_free(event->data.sequence_start.anchor);
  1010 + yaml_free(event->data.sequence_start.tag);
  1011 + break;
  1012 +
  1013 + case YAML_MAPPING_START_EVENT:
  1014 + yaml_free(event->data.mapping_start.anchor);
  1015 + yaml_free(event->data.mapping_start.tag);
  1016 + break;
  1017 +
  1018 + default:
  1019 + break;
  1020 + }
  1021 +
  1022 + memset(event, 0, sizeof(yaml_event_t));
  1023 +}
  1024 +
  1025 +/*
  1026 + * Create a document object.
  1027 + */
  1028 +
  1029 +YAML_DECLARE(int)
  1030 +yaml_document_initialize(yaml_document_t *document,
  1031 + yaml_version_directive_t *version_directive,
  1032 + yaml_tag_directive_t *tag_directives_start,
  1033 + yaml_tag_directive_t *tag_directives_end,
  1034 + int start_implicit, int end_implicit)