00001
00002 #include "yaml_private.h"
00003
00004
00005
00006
00007
00008 YAML_DECLARE(const char *)
00009 yaml_get_version_string(void)
00010 {
00011 return YAML_VERSION_STRING;
00012 }
00013
00014
00015
00016
00017
00018 YAML_DECLARE(void)
00019 yaml_get_version(int *major, int *minor, int *patch)
00020 {
00021 *major = YAML_VERSION_MAJOR;
00022 *minor = YAML_VERSION_MINOR;
00023 *patch = YAML_VERSION_PATCH;
00024 }
00025
00026
00027
00028
00029
00030 YAML_DECLARE(void *)
00031 yaml_malloc(size_t size)
00032 {
00033 return malloc(size ? size : 1);
00034 }
00035
00036
00037
00038
00039
00040 YAML_DECLARE(void *)
00041 yaml_realloc(void *ptr, size_t size)
00042 {
00043 return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
00044 }
00045
00046
00047
00048
00049
00050 YAML_DECLARE(void)
00051 yaml_free(void *ptr)
00052 {
00053 if (ptr) free(ptr);
00054 }
00055
00056
00057
00058
00059
00060 YAML_DECLARE(yaml_char_t *)
00061 yaml_strdup(const yaml_char_t *str)
00062 {
00063 if (!str)
00064 return NULL;
00065
00066 return (yaml_char_t *)strdup((char *)str);
00067 }
00068
00069
00070
00071
00072
00073 YAML_DECLARE(int)
00074 yaml_string_extend(yaml_char_t **start,
00075 yaml_char_t **pointer, yaml_char_t **end)
00076 {
00077 yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
00078
00079 if (!new_start) return 0;
00080
00081 memset(new_start + (*end - *start), 0, *end - *start);
00082
00083 *pointer = new_start + (*pointer - *start);
00084 *end = new_start + (*end - *start)*2;
00085 *start = new_start;
00086
00087 return 1;
00088 }
00089
00090
00091
00092
00093
00094 YAML_DECLARE(int)
00095 yaml_string_join(
00096 yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
00097 yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
00098 {
00099 if (*b_start == *b_pointer)
00100 return 1;
00101
00102 while (*a_end - *a_pointer <= *b_pointer - *b_start) {
00103 if (!yaml_string_extend(a_start, a_pointer, a_end))
00104 return 0;
00105 }
00106
00107 memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
00108 *a_pointer += *b_pointer - *b_start;
00109
00110 return 1;
00111 }
00112
00113
00114
00115
00116
00117 YAML_DECLARE(int)
00118 yaml_stack_extend(void **start, void **top, void **end)
00119 {
00120 void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
00121
00122 if (!new_start) return 0;
00123
00124 *top = (char *)new_start + ((char *)*top - (char *)*start);
00125 *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
00126 *start = new_start;
00127
00128 return 1;
00129 }
00130
00131
00132
00133
00134
00135 YAML_DECLARE(int)
00136 yaml_queue_extend(void **start, void **head, void **tail, void **end)
00137 {
00138
00139
00140 if (*start == *head && *tail == *end) {
00141 void *new_start = yaml_realloc(*start,
00142 ((char *)*end - (char *)*start)*2);
00143
00144 if (!new_start) return 0;
00145
00146 *head = (char *)new_start + ((char *)*head - (char *)*start);
00147 *tail = (char *)new_start + ((char *)*tail - (char *)*start);
00148 *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
00149 *start = new_start;
00150 }
00151
00152
00153
00154 if (*tail == *end) {
00155 if (*head != *tail) {
00156 memmove(*start, *head, (char *)*tail - (char *)*head);
00157 }
00158 *tail = (char *)*tail - (char *)*head + (char *)*start;
00159 *head = *start;
00160 }
00161
00162 return 1;
00163 }
00164
00165
00166
00167
00168
00169
00170 YAML_DECLARE(int)
00171 yaml_parser_initialize(yaml_parser_t *parser)
00172 {
00173 assert(parser);
00174
00175 memset(parser, 0, sizeof(yaml_parser_t));
00176 if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
00177 goto error;
00178 if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
00179 goto error;
00180 if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
00181 goto error;
00182 if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
00183 goto error;
00184 if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
00185 goto error;
00186 if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
00187 goto error;
00188 if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
00189 goto error;
00190 if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
00191 goto error;
00192
00193 return 1;
00194
00195 error:
00196
00197 BUFFER_DEL(parser, parser->raw_buffer);
00198 BUFFER_DEL(parser, parser->buffer);
00199 QUEUE_DEL(parser, parser->tokens);
00200 STACK_DEL(parser, parser->indents);
00201 STACK_DEL(parser, parser->simple_keys);
00202 STACK_DEL(parser, parser->states);
00203 STACK_DEL(parser, parser->marks);
00204 STACK_DEL(parser, parser->tag_directives);
00205
00206 return 0;
00207 }
00208
00209
00210
00211
00212
00213 YAML_DECLARE(void)
00214 yaml_parser_delete(yaml_parser_t *parser)
00215 {
00216 assert(parser);
00217
00218 BUFFER_DEL(parser, parser->raw_buffer);
00219 BUFFER_DEL(parser, parser->buffer);
00220 while (!QUEUE_EMPTY(parser, parser->tokens)) {
00221 yaml_token_delete(&DEQUEUE(parser, parser->tokens));
00222 }
00223 QUEUE_DEL(parser, parser->tokens);
00224 STACK_DEL(parser, parser->indents);
00225 STACK_DEL(parser, parser->simple_keys);
00226 STACK_DEL(parser, parser->states);
00227 STACK_DEL(parser, parser->marks);
00228 while (!STACK_EMPTY(parser, parser->tag_directives)) {
00229 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
00230 yaml_free(tag_directive.handle);
00231 yaml_free(tag_directive.prefix);
00232 }
00233 STACK_DEL(parser, parser->tag_directives);
00234
00235 memset(parser, 0, sizeof(yaml_parser_t));
00236 }
00237
00238
00239
00240
00241
00242 static int
00243 yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
00244 size_t *size_read)
00245 {
00246 yaml_parser_t *parser = data;
00247
00248 if (parser->input.string.current == parser->input.string.end) {
00249 *size_read = 0;
00250 return 1;
00251 }
00252
00253 if (size > (size_t)(parser->input.string.end
00254 - parser->input.string.current)) {
00255 size = parser->input.string.end - parser->input.string.current;
00256 }
00257
00258 memcpy(buffer, parser->input.string.current, size);
00259 parser->input.string.current += size;
00260 *size_read = size;
00261 return 1;
00262 }
00263
00264
00265
00266
00267
00268 static int
00269 yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
00270 size_t *size_read)
00271 {
00272 yaml_parser_t *parser = data;
00273
00274 *size_read = fread(buffer, 1, size, parser->input.file);
00275 return !ferror(parser->input.file);
00276 }
00277
00278
00279
00280
00281
00282 YAML_DECLARE(void)
00283 yaml_parser_set_input_string(yaml_parser_t *parser,
00284 const unsigned char *input, size_t size)
00285 {
00286 assert(parser);
00287 assert(!parser->read_handler);
00288 assert(input);
00289
00290 parser->read_handler = yaml_string_read_handler;
00291 parser->read_handler_data = parser;
00292
00293 parser->input.string.start = input;
00294 parser->input.string.current = input;
00295 parser->input.string.end = input+size;
00296 }
00297
00298
00299
00300
00301
00302 YAML_DECLARE(void)
00303 yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
00304 {
00305 assert(parser);
00306 assert(!parser->read_handler);
00307 assert(file);
00308
00309 parser->read_handler = yaml_file_read_handler;
00310 parser->read_handler_data = parser;
00311
00312 parser->input.file = file;
00313 }
00314
00315
00316
00317
00318
00319 YAML_DECLARE(void)
00320 yaml_parser_set_input(yaml_parser_t *parser,
00321 yaml_read_handler_t *handler, void *data)
00322 {
00323 assert(parser);
00324 assert(!parser->read_handler);
00325 assert(handler);
00326
00327 parser->read_handler = handler;
00328 parser->read_handler_data = data;
00329 }
00330
00331
00332
00333
00334
00335 YAML_DECLARE(void)
00336 yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
00337 {
00338 assert(parser);
00339 assert(!parser->encoding);
00340
00341 parser->encoding = encoding;
00342 }
00343
00344
00345
00346
00347
00348 YAML_DECLARE(int)
00349 yaml_emitter_initialize(yaml_emitter_t *emitter)
00350 {
00351 assert(emitter);
00352
00353 memset(emitter, 0, sizeof(yaml_emitter_t));
00354 if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
00355 goto error;
00356 if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
00357 goto error;
00358 if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
00359 goto error;
00360 if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
00361 goto error;
00362 if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
00363 goto error;
00364 if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
00365 goto error;
00366
00367 return 1;
00368
00369 error:
00370
00371 BUFFER_DEL(emitter, emitter->buffer);
00372 BUFFER_DEL(emitter, emitter->raw_buffer);
00373 STACK_DEL(emitter, emitter->states);
00374 QUEUE_DEL(emitter, emitter->events);
00375 STACK_DEL(emitter, emitter->indents);
00376 STACK_DEL(emitter, emitter->tag_directives);
00377
00378 return 0;
00379 }
00380
00381
00382
00383
00384
00385 YAML_DECLARE(void)
00386 yaml_emitter_delete(yaml_emitter_t *emitter)
00387 {
00388 assert(emitter);
00389
00390 BUFFER_DEL(emitter, emitter->buffer);
00391 BUFFER_DEL(emitter, emitter->raw_buffer);
00392 STACK_DEL(emitter, emitter->states);
00393 while (!QUEUE_EMPTY(emitter, emitter->events)) {
00394 yaml_event_delete(&DEQUEUE(emitter, emitter->events));
00395 }
00396 QUEUE_DEL(emitter, emitter->events);
00397 STACK_DEL(emitter, emitter->indents);
00398 while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
00399 yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
00400 yaml_free(tag_directive.handle);
00401 yaml_free(tag_directive.prefix);
00402 }
00403 STACK_DEL(emitter, emitter->tag_directives);
00404 yaml_free(emitter->anchors);
00405
00406 memset(emitter, 0, sizeof(yaml_emitter_t));
00407 }
00408
00409
00410
00411
00412
00413 static int
00414 yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
00415 {
00416 yaml_emitter_t *emitter = data;
00417
00418 if (emitter->output.string.size + *emitter->output.string.size_written
00419 < size) {
00420 memcpy(emitter->output.string.buffer
00421 + *emitter->output.string.size_written,
00422 buffer,
00423 emitter->output.string.size
00424 - *emitter->output.string.size_written);
00425 *emitter->output.string.size_written = emitter->output.string.size;
00426 return 0;
00427 }
00428
00429 memcpy(emitter->output.string.buffer
00430 + *emitter->output.string.size_written, buffer, size);
00431 *emitter->output.string.size_written += size;
00432 return 1;
00433 }
00434
00435
00436
00437
00438
00439 static int
00440 yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
00441 {
00442 yaml_emitter_t *emitter = data;
00443
00444 return (fwrite(buffer, 1, size, emitter->output.file) == size);
00445 }
00446
00447
00448
00449
00450 YAML_DECLARE(void)
00451 yaml_emitter_set_output_string(yaml_emitter_t *emitter,
00452 unsigned char *output, size_t size, size_t *size_written)
00453 {
00454 assert(emitter);
00455 assert(!emitter->write_handler);
00456 assert(output);
00457
00458 emitter->write_handler = yaml_string_write_handler;
00459 emitter->write_handler_data = emitter;
00460
00461 emitter->output.string.buffer = output;
00462 emitter->output.string.size = size;
00463 emitter->output.string.size_written = size_written;
00464 *size_written = 0;
00465 }
00466
00467
00468
00469
00470
00471 YAML_DECLARE(void)
00472 yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
00473 {
00474 assert(emitter);
00475 assert(!emitter->write_handler);
00476 assert(file);
00477
00478 emitter->write_handler = yaml_file_write_handler;
00479 emitter->write_handler_data = emitter;
00480
00481 emitter->output.file = file;
00482 }
00483
00484
00485
00486
00487
00488 YAML_DECLARE(void)
00489 yaml_emitter_set_output(yaml_emitter_t *emitter,
00490 yaml_write_handler_t *handler, void *data)
00491 {
00492 assert(emitter);
00493 assert(!emitter->write_handler);
00494 assert(handler);
00495
00496 emitter->write_handler = handler;
00497 emitter->write_handler_data = data;
00498 }
00499
00500
00501
00502
00503
00504 YAML_DECLARE(void)
00505 yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
00506 {
00507 assert(emitter);
00508 assert(!emitter->encoding);
00509
00510 emitter->encoding = encoding;
00511 }
00512
00513
00514
00515
00516
00517 YAML_DECLARE(void)
00518 yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
00519 {
00520 assert(emitter);
00521
00522 emitter->canonical = (canonical != 0);
00523 }
00524
00525
00526
00527
00528
00529 YAML_DECLARE(void)
00530 yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
00531 {
00532 assert(emitter);
00533
00534 emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
00535 }
00536
00537
00538
00539
00540
00541 YAML_DECLARE(void)
00542 yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
00543 {
00544 assert(emitter);
00545
00546 emitter->best_width = (width >= 0) ? width : -1;
00547 }
00548
00549
00550
00551
00552
00553 YAML_DECLARE(void)
00554 yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
00555 {
00556 assert(emitter);
00557
00558 emitter->unicode = (unicode != 0);
00559 }
00560
00561
00562
00563
00564
00565 YAML_DECLARE(void)
00566 yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
00567 {
00568 assert(emitter);
00569
00570 emitter->line_break = line_break;
00571 }
00572
00573
00574
00575
00576
00577 YAML_DECLARE(void)
00578 yaml_token_delete(yaml_token_t *token)
00579 {
00580 assert(token);
00581
00582 switch (token->type)
00583 {
00584 case YAML_TAG_DIRECTIVE_TOKEN:
00585 yaml_free(token->data.tag_directive.handle);
00586 yaml_free(token->data.tag_directive.prefix);
00587 break;
00588
00589 case YAML_ALIAS_TOKEN:
00590 yaml_free(token->data.alias.value);
00591 break;
00592
00593 case YAML_ANCHOR_TOKEN:
00594 yaml_free(token->data.anchor.value);
00595 break;
00596
00597 case YAML_TAG_TOKEN:
00598 yaml_free(token->data.tag.handle);
00599 yaml_free(token->data.tag.suffix);
00600 break;
00601
00602 case YAML_SCALAR_TOKEN:
00603 yaml_free(token->data.scalar.value);
00604 break;
00605
00606 default:
00607 break;
00608 }
00609
00610 memset(token, 0, sizeof(yaml_token_t));
00611 }
00612
00613
00614
00615
00616
00617
00618
00619 static int
00620 yaml_check_utf8(yaml_char_t *start, size_t length)
00621 {
00622 yaml_char_t *end = start+length;
00623 yaml_char_t *pointer = start;
00624
00625 while (pointer < end) {
00626 unsigned char octet;
00627 unsigned int width;
00628 unsigned int value;
00629 size_t k;
00630
00631 octet = pointer[0];
00632 width = (octet & 0x80) == 0x00 ? 1 :
00633 (octet & 0xE0) == 0xC0 ? 2 :
00634 (octet & 0xF0) == 0xE0 ? 3 :
00635 (octet & 0xF8) == 0xF0 ? 4 : 0;
00636 value = (octet & 0x80) == 0x00 ? octet & 0x7F :
00637 (octet & 0xE0) == 0xC0 ? octet & 0x1F :
00638 (octet & 0xF0) == 0xE0 ? octet & 0x0F :
00639 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
00640 if (!width) return 0;
00641 if (pointer+width > end) return 0;
00642 for (k = 1; k < width; k ++) {
00643 octet = pointer[k];
00644 if ((octet & 0xC0) != 0x80) return 0;
00645 value = (value << 6) + (octet & 0x3F);
00646 }
00647 if (!((width == 1) ||
00648 (width == 2 && value >= 0x80) ||
00649 (width == 3 && value >= 0x800) ||
00650 (width == 4 && value >= 0x10000))) return 0;
00651
00652 pointer += width;
00653 }
00654
00655 return 1;
00656 }
00657
00658
00659
00660
00661
00662 YAML_DECLARE(int)
00663 yaml_stream_start_event_initialize(yaml_event_t *event,
00664 yaml_encoding_t encoding)
00665 {
00666 yaml_mark_t mark = { 0, 0, 0 };
00667
00668 assert(event);
00669
00670 STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
00671
00672 return 1;
00673 }
00674
00675
00676
00677
00678
00679 YAML_DECLARE(int)
00680 yaml_stream_end_event_initialize(yaml_event_t *event)
00681 {
00682 yaml_mark_t mark = { 0, 0, 0 };
00683
00684 assert(event);
00685
00686 STREAM_END_EVENT_INIT(*event, mark, mark);
00687
00688 return 1;
00689 }
00690
00691
00692
00693
00694
00695 YAML_DECLARE(int)
00696 yaml_document_start_event_initialize(yaml_event_t *event,
00697 yaml_version_directive_t *version_directive,
00698 yaml_tag_directive_t *tag_directives_start,
00699 yaml_tag_directive_t *tag_directives_end,
00700 int implicit)
00701 {
00702 struct {
00703 yaml_error_type_t error;
00704 } context;
00705 yaml_mark_t mark = { 0, 0, 0 };
00706 yaml_version_directive_t *version_directive_copy = NULL;
00707 struct {
00708 yaml_tag_directive_t *start;
00709 yaml_tag_directive_t *end;
00710 yaml_tag_directive_t *top;
00711 } tag_directives_copy = { NULL, NULL, NULL };
00712 yaml_tag_directive_t value = { NULL, NULL };
00713
00714 assert(event);
00715 assert((tag_directives_start && tag_directives_end) ||
00716 (tag_directives_start == tag_directives_end));
00717
00718
00719 if (version_directive) {
00720 version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
00721 if (!version_directive_copy) goto error;
00722 version_directive_copy->major = version_directive->major;
00723 version_directive_copy->minor = version_directive->minor;
00724 }
00725
00726 if (tag_directives_start != tag_directives_end) {
00727 yaml_tag_directive_t *tag_directive;
00728 if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
00729 goto error;
00730 for (tag_directive = tag_directives_start;
00731 tag_directive != tag_directives_end; tag_directive ++) {
00732 assert(tag_directive->handle);
00733 assert(tag_directive->prefix);
00734 if (!yaml_check_utf8(tag_directive->handle,
00735 strlen((char *)tag_directive->handle)))
00736 goto error;
00737 if (!yaml_check_utf8(tag_directive->prefix,
00738 strlen((char *)tag_directive->prefix)))
00739 goto error;
00740 value.handle = yaml_strdup(tag_directive->handle);
00741 value.prefix = yaml_strdup(tag_directive->prefix);
00742 if (!value.handle || !value.prefix) goto error;
00743 if (!PUSH(&context, tag_directives_copy, value))
00744 goto error;
00745 value.handle = NULL;
00746 value.prefix = NULL;
00747 }
00748 }
00749
00750 DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
00751 tag_directives_copy.start, tag_directives_copy.top,
00752 implicit, mark, mark);
00753
00754 return 1;
00755
00756 error:
00757 yaml_free(version_directive_copy);
00758 while (!STACK_EMPTY(context, tag_directives_copy)) {
00759 yaml_tag_directive_t value = POP(context, tag_directives_copy);
00760 yaml_free(value.handle);
00761 yaml_free(value.prefix);
00762 }
00763 STACK_DEL(context, tag_directives_copy);
00764 yaml_free(value.handle);
00765 yaml_free(value.prefix);
00766
00767 return 0;
00768 }
00769
00770
00771
00772
00773
00774 YAML_DECLARE(int)
00775 yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
00776 {
00777 yaml_mark_t mark = { 0, 0, 0 };
00778
00779 assert(event);
00780
00781 DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
00782
00783 return 1;
00784 }
00785
00786
00787
00788
00789
00790 YAML_DECLARE(int)
00791 yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
00792 {
00793 yaml_mark_t mark = { 0, 0, 0 };
00794 yaml_char_t *anchor_copy = NULL;
00795
00796 assert(event);
00797 assert(anchor);
00798
00799 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
00800
00801 anchor_copy = yaml_strdup(anchor);
00802 if (!anchor_copy)
00803 return 0;
00804
00805 ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
00806
00807 return 1;
00808 }
00809
00810
00811
00812
00813
00814 YAML_DECLARE(int)
00815 yaml_scalar_event_initialize(yaml_event_t *event,
00816 yaml_char_t *anchor, yaml_char_t *tag,
00817 yaml_char_t *value, int length,
00818 int plain_implicit, int quoted_implicit,
00819 yaml_scalar_style_t style)
00820 {
00821 yaml_mark_t mark = { 0, 0, 0 };
00822 yaml_char_t *anchor_copy = NULL;
00823 yaml_char_t *tag_copy = NULL;
00824 yaml_char_t *value_copy = NULL;
00825 size_t value_length;
00826
00827 assert(event);
00828 assert(value);
00829
00830 if (anchor) {
00831 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
00832 anchor_copy = yaml_strdup(anchor);
00833 if (!anchor_copy) goto error;
00834 }
00835
00836 if (tag) {
00837 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
00838 tag_copy = yaml_strdup(tag);
00839 if (!tag_copy) goto error;
00840 }
00841
00842 if (length < 0) {
00843 value_length = strlen((char *)value);
00844 }
00845 else {
00846 value_length = (size_t)length;
00847 }
00848
00849 if (!yaml_check_utf8(value, value_length)) goto error;
00850 value_copy = yaml_malloc(value_length+1);
00851 if (!value_copy) goto error;
00852 memcpy(value_copy, value, value_length);
00853 value_copy[value_length] = '\0';
00854
00855 SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, value_length,
00856 plain_implicit, quoted_implicit, style, mark, mark);
00857
00858 return 1;
00859
00860 error:
00861 yaml_free(anchor_copy);
00862 yaml_free(tag_copy);
00863 yaml_free(value_copy);
00864
00865 return 0;
00866 }
00867
00868
00869
00870
00871
00872 YAML_DECLARE(int)
00873 yaml_sequence_start_event_initialize(yaml_event_t *event,
00874 yaml_char_t *anchor, yaml_char_t *tag, int implicit,
00875 yaml_sequence_style_t style)
00876 {
00877 yaml_mark_t mark = { 0, 0, 0 };
00878 yaml_char_t *anchor_copy = NULL;
00879 yaml_char_t *tag_copy = NULL;
00880
00881 assert(event);
00882
00883 if (anchor) {
00884 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
00885 anchor_copy = yaml_strdup(anchor);
00886 if (!anchor_copy) goto error;
00887 }
00888
00889 if (tag) {
00890 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
00891 tag_copy = yaml_strdup(tag);
00892 if (!tag_copy) goto error;
00893 }
00894
00895 SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
00896 implicit, style, mark, mark);
00897
00898 return 1;
00899
00900 error:
00901 yaml_free(anchor_copy);
00902 yaml_free(tag_copy);
00903
00904 return 0;
00905 }
00906
00907
00908
00909
00910
00911 YAML_DECLARE(int)
00912 yaml_sequence_end_event_initialize(yaml_event_t *event)
00913 {
00914 yaml_mark_t mark = { 0, 0, 0 };
00915
00916 assert(event);
00917
00918 SEQUENCE_END_EVENT_INIT(*event, mark, mark);
00919
00920 return 1;
00921 }
00922
00923
00924
00925
00926
00927 YAML_DECLARE(int)
00928 yaml_mapping_start_event_initialize(yaml_event_t *event,
00929 yaml_char_t *anchor, yaml_char_t *tag, int implicit,
00930 yaml_mapping_style_t style)
00931 {
00932 yaml_mark_t mark = { 0, 0, 0 };
00933 yaml_char_t *anchor_copy = NULL;
00934 yaml_char_t *tag_copy = NULL;
00935
00936 assert(event);
00937
00938 if (anchor) {
00939 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
00940 anchor_copy = yaml_strdup(anchor);
00941 if (!anchor_copy) goto error;
00942 }
00943
00944 if (tag) {
00945 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
00946 tag_copy = yaml_strdup(tag);
00947 if (!tag_copy) goto error;
00948 }
00949
00950 MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
00951 implicit, style, mark, mark);
00952
00953 return 1;
00954
00955 error:
00956 yaml_free(anchor_copy);
00957 yaml_free(tag_copy);
00958
00959 return 0;
00960 }
00961
00962
00963
00964
00965
00966 YAML_DECLARE(int)
00967 yaml_mapping_end_event_initialize(yaml_event_t *event)
00968 {
00969 yaml_mark_t mark = { 0, 0, 0 };
00970
00971 assert(event);
00972
00973 MAPPING_END_EVENT_INIT(*event, mark, mark);
00974
00975 return 1;
00976 }
00977
00978
00979
00980
00981
00982 YAML_DECLARE(void)
00983 yaml_event_delete(yaml_event_t *event)
00984 {
00985 yaml_tag_directive_t *tag_directive;
00986
00987 assert(event);
00988
00989 switch (event->type)
00990 {
00991 case YAML_DOCUMENT_START_EVENT:
00992 yaml_free(event->data.document_start.version_directive);
00993 for (tag_directive = event->data.document_start.tag_directives.start;
00994 tag_directive != event->data.document_start.tag_directives.end;
00995 tag_directive++) {
00996 yaml_free(tag_directive->handle);
00997 yaml_free(tag_directive->prefix);
00998 }
00999 yaml_free(event->data.document_start.tag_directives.start);
01000 break;
01001
01002 case YAML_ALIAS_EVENT:
01003 yaml_free(event->data.alias.anchor);
01004 break;
01005
01006 case YAML_SCALAR_EVENT:
01007 yaml_free(event->data.scalar.anchor);
01008 yaml_free(event->data.scalar.tag);
01009 yaml_free(event->data.scalar.value);
01010 break;
01011
01012 case YAML_SEQUENCE_START_EVENT:
01013 yaml_free(event->data.sequence_start.anchor);
01014 yaml_free(event->data.sequence_start.tag);
01015 break;
01016
01017 case YAML_MAPPING_START_EVENT:
01018 yaml_free(event->data.mapping_start.anchor);
01019 yaml_free(event->data.mapping_start.tag);
01020 break;
01021
01022 default:
01023 break;
01024 }
01025
01026 memset(event, 0, sizeof(yaml_event_t));
01027 }
01028
01029
01030
01031
01032
01033 YAML_DECLARE(int)
01034 yaml_document_initialize(yaml_document_t *document,
01035 yaml_version_directive_t *version_directive,
01036 yaml_tag_directive_t *tag_directives_start,
01037 yaml_tag_directive_t *tag_directives_end,
01038 int start_implicit, int end_implicit)
01039 {
01040 struct {
01041 yaml_error_type_t error;
01042 } context;
01043 struct {
01044 yaml_node_t *start;
01045 yaml_node_t *end;
01046 yaml_node_t *top;
01047 } nodes = { NULL, NULL, NULL };
01048 yaml_version_directive_t *version_directive_copy = NULL;
01049 struct {
01050 yaml_tag_directive_t *start;
01051 yaml_tag_directive_t *end;
01052 yaml_tag_directive_t *top;
01053 } tag_directives_copy = { NULL, NULL, NULL };
01054 yaml_tag_directive_t value = { NULL, NULL };
01055 yaml_mark_t mark = { 0, 0, 0 };
01056
01057 assert(document);
01058 assert((tag_directives_start && tag_directives_end) ||
01059 (tag_directives_start == tag_directives_end));
01060
01061
01062 if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
01063
01064 if (version_directive) {
01065 version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
01066 if (!version_directive_copy) goto error;
01067 version_directive_copy->major = version_directive->major;
01068 version_directive_copy->minor = version_directive->minor;
01069 }
01070
01071 if (tag_directives_start != tag_directives_end) {
01072 yaml_tag_directive_t *tag_directive;
01073 if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
01074 goto error;
01075 for (tag_directive = tag_directives_start;
01076 tag_directive != tag_directives_end; tag_directive ++) {
01077 assert(tag_directive->handle);
01078 assert(tag_directive->prefix);
01079 if (!yaml_check_utf8(tag_directive->handle,
01080 strlen((char *)tag_directive->handle)))
01081 goto error;
01082 if (!yaml_check_utf8(tag_directive->prefix,
01083 strlen((char *)tag_directive->prefix)))
01084 goto error;
01085 value.handle = yaml_strdup(tag_directive->handle);
01086 value.prefix = yaml_strdup(tag_directive->prefix);
01087 if (!value.handle || !value.prefix) goto error;
01088 if (!PUSH(&context, tag_directives_copy, value))
01089 goto error;
01090 value.handle = NULL;
01091 value.prefix = NULL;
01092 }
01093 }
01094
01095 DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
01096 tag_directives_copy.start, tag_directives_copy.top,
01097 start_implicit, end_implicit, mark, mark);
01098
01099 return 1;
01100
01101 error:
01102 STACK_DEL(&context, nodes);
01103 yaml_free(version_directive_copy);
01104 while (!STACK_EMPTY(&context, tag_directives_copy)) {
01105 yaml_tag_directive_t value = POP(&context, tag_directives_copy);
01106 yaml_free(value.handle);
01107 yaml_free(value.prefix);
01108 }
01109 STACK_DEL(&context, tag_directives_copy);
01110 yaml_free(value.handle);
01111 yaml_free(value.prefix);
01112
01113 return 0;
01114 }
01115
01116
01117
01118
01119
01120 YAML_DECLARE(void)
01121 yaml_document_delete(yaml_document_t *document)
01122 {
01123 struct {
01124 yaml_error_type_t error;
01125 } context;
01126 yaml_tag_directive_t *tag_directive;
01127
01128 context.error = YAML_NO_ERROR;
01129
01130 assert(document);
01131
01132 while (!STACK_EMPTY(&context, document->nodes)) {
01133 yaml_node_t node = POP(&context, document->nodes);
01134 yaml_free(node.tag);
01135 switch (node.type) {
01136 case YAML_SCALAR_NODE:
01137 yaml_free(node.data.scalar.value);
01138 break;
01139 case YAML_SEQUENCE_NODE:
01140 STACK_DEL(&context, node.data.sequence.items);
01141 break;
01142 case YAML_MAPPING_NODE:
01143 STACK_DEL(&context, node.data.mapping.pairs);
01144 break;
01145 default:
01146 assert(0);
01147 }
01148 }
01149 STACK_DEL(&context, document->nodes);
01150
01151 yaml_free(document->version_directive);
01152 for (tag_directive = document->tag_directives.start;
01153 tag_directive != document->tag_directives.end;
01154 tag_directive++) {
01155 yaml_free(tag_directive->handle);
01156 yaml_free(tag_directive->prefix);
01157 }
01158 yaml_free(document->tag_directives.start);
01159
01160 memset(document, 0, sizeof(yaml_document_t));
01161 }
01162
01167 YAML_DECLARE(yaml_node_t *)
01168 yaml_document_get_node(yaml_document_t *document, int index)
01169 {
01170 assert(document);
01171
01172 if (index > 0 && document->nodes.start + index <= document->nodes.top) {
01173 return document->nodes.start + index - 1;
01174 }
01175 return NULL;
01176 }
01177
01182 YAML_DECLARE(yaml_node_t *)
01183 yaml_document_get_root_node(yaml_document_t *document)
01184 {
01185 assert(document);
01186
01187 if (document->nodes.top != document->nodes.start) {
01188 return document->nodes.start;
01189 }
01190 return NULL;
01191 }
01192
01193
01194
01195
01196
01197 YAML_DECLARE(int)
01198 yaml_document_add_scalar(yaml_document_t *document,
01199 yaml_char_t *tag, yaml_char_t *value, int length,
01200 yaml_scalar_style_t style)
01201 {
01202 struct {
01203 yaml_error_type_t error;
01204 } context;
01205 yaml_mark_t mark = { 0, 0, 0 };
01206 yaml_char_t *tag_copy = NULL;
01207 yaml_char_t *value_copy = NULL;
01208 yaml_node_t node;
01209 size_t value_length;
01210 ptrdiff_t ret;
01211
01212 assert(document);
01213 assert(value);
01214
01215 if (!tag) {
01216 tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
01217 }
01218
01219 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
01220 tag_copy = yaml_strdup(tag);
01221 if (!tag_copy) goto error;
01222
01223 if (length < 0) {
01224 value_length = strlen((char *)value);
01225 }
01226 else {
01227 value_length = (size_t)length;
01228 }
01229
01230 if (!yaml_check_utf8(value, value_length)) goto error;
01231 value_copy = yaml_malloc(value_length+1);
01232 if (!value_copy) goto error;
01233 memcpy(value_copy, value, value_length);
01234 value_copy[value_length] = '\0';
01235
01236 SCALAR_NODE_INIT(node, tag_copy, value_copy, value_length, style, mark, mark);
01237 if (!PUSH(&context, document->nodes, node)) goto error;
01238
01239 ret = document->nodes.top - document->nodes.start;
01240 #if PTRDIFF_MAX > INT_MAX
01241 if (ret > INT_MAX) goto error;
01242 #endif
01243 return (int)ret;
01244
01245 error:
01246 yaml_free(tag_copy);
01247 yaml_free(value_copy);
01248
01249 return 0;
01250 }
01251
01252
01253
01254
01255
01256 YAML_DECLARE(int)
01257 yaml_document_add_sequence(yaml_document_t *document,
01258 yaml_char_t *tag, yaml_sequence_style_t style)
01259 {
01260 struct {
01261 yaml_error_type_t error;
01262 } context;
01263 yaml_mark_t mark = { 0, 0, 0 };
01264 yaml_char_t *tag_copy = NULL;
01265 struct {
01266 yaml_node_item_t *start;
01267 yaml_node_item_t *end;
01268 yaml_node_item_t *top;
01269 } items = { NULL, NULL, NULL };
01270 yaml_node_t node;
01271 ptrdiff_t ret;
01272
01273 assert(document);
01274
01275 if (!tag) {
01276 tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
01277 }
01278
01279 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
01280 tag_copy = yaml_strdup(tag);
01281 if (!tag_copy) goto error;
01282
01283 if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
01284
01285 SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
01286 style, mark, mark);
01287 if (!PUSH(&context, document->nodes, node)) goto error;
01288
01289 ret = document->nodes.top - document->nodes.start;
01290 #if PTRDIFF_MAX > INT_MAX
01291 if (ret > INT_MAX) goto error;
01292 #endif
01293 return (int)ret;
01294
01295 error:
01296 STACK_DEL(&context, items);
01297 yaml_free(tag_copy);
01298
01299 return 0;
01300 }
01301
01302
01303
01304
01305
01306 YAML_DECLARE(int)
01307 yaml_document_add_mapping(yaml_document_t *document,
01308 yaml_char_t *tag, yaml_mapping_style_t style)
01309 {
01310 struct {
01311 yaml_error_type_t error;
01312 } context;
01313 yaml_mark_t mark = { 0, 0, 0 };
01314 yaml_char_t *tag_copy = NULL;
01315 struct {
01316 yaml_node_pair_t *start;
01317 yaml_node_pair_t *end;
01318 yaml_node_pair_t *top;
01319 } pairs = { NULL, NULL, NULL };
01320 yaml_node_t node;
01321 ptrdiff_t ret;
01322
01323 assert(document);
01324
01325 if (!tag) {
01326 tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
01327 }
01328
01329 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
01330 tag_copy = yaml_strdup(tag);
01331 if (!tag_copy) goto error;
01332
01333 if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
01334
01335 MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
01336 style, mark, mark);
01337 if (!PUSH(&context, document->nodes, node)) goto error;
01338
01339 ret = document->nodes.top - document->nodes.start;
01340 #if PTRDIFF_MAX > INT_MAX
01341 if (ret > INT_MAX) goto error;
01342 #endif
01343 return (int)ret;
01344
01345 error:
01346 STACK_DEL(&context, pairs);
01347 yaml_free(tag_copy);
01348
01349 return 0;
01350 }
01351
01352
01353
01354
01355
01356 YAML_DECLARE(int)
01357 yaml_document_append_sequence_item(yaml_document_t *document,
01358 int sequence, int item)
01359 {
01360 struct {
01361 yaml_error_type_t error;
01362 } context;
01363
01364 assert(document);
01365 assert(sequence > 0
01366 && document->nodes.start + sequence <= document->nodes.top);
01367
01368 assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
01369
01370 assert(item > 0 && document->nodes.start + item <= document->nodes.top);
01371
01372
01373 if (!PUSH(&context,
01374 document->nodes.start[sequence-1].data.sequence.items, item))
01375 return 0;
01376
01377 return 1;
01378 }
01379
01380
01381
01382
01383
01384 YAML_DECLARE(int)
01385 yaml_document_append_mapping_pair(yaml_document_t *document,
01386 int mapping, int key, int value)
01387 {
01388 struct {
01389 yaml_error_type_t error;
01390 } context;
01391
01392 yaml_node_pair_t pair;
01393
01394 assert(document);
01395 assert(mapping > 0
01396 && document->nodes.start + mapping <= document->nodes.top);
01397
01398 assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
01399
01400 assert(key > 0 && document->nodes.start + key <= document->nodes.top);
01401
01402 assert(value > 0 && document->nodes.start + value <= document->nodes.top);
01403
01404
01405 pair.key = key;
01406 pair.value = value;
01407
01408 if (!PUSH(&context,
01409 document->nodes.start[mapping-1].data.mapping.pairs, pair))
01410 return 0;
01411
01412 return 1;
01413 }
01414
01415
01416