Show
Ignore:
Timestamp:
01/19/08 08:54:22 (4 years ago)
Author:
xi
Message:

Minor API updates.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • libyaml/trunk/src/api.c

    r265 r267  
     1/***************************************************************************** 
     2 * LibYAML API Implementation 
     3 * 
     4 * Copyright (c) 2006 Kirill Simonov 
     5 * 
     6 * LibYAML is free software; you can use, modify and/or redistribute it under 
     7 * the terms of the MIT license; see the file LICENCE for more details. 
     8 *****************************************************************************/ 
    19 
    210#include "yaml_private.h" 
    311 
    4 /* 
    5  * Get the library version. 
     12/***************************************************************************** 
     13 * Version Information 
     14 *****************************************************************************/ 
     15 
     16/* 
     17 * Get the library version as a static string. 
    618 */ 
    719 
     
    2436} 
    2537 
     38/***************************************************************************** 
     39 * Memory Management 
     40 *****************************************************************************/ 
     41 
    2642/* 
    2743 * Allocate a dynamic memory block. 
     
    6682    return (yaml_char_t *)strdup((char *)str); 
    6783} 
     84 
     85/***************************************************************************** 
     86 * Error Handling 
     87 *****************************************************************************/ 
    6888 
    6989/* 
     
    171191} 
    172192 
     193/***************************************************************************** 
     194 * String, Stack and Queue Management 
     195 *****************************************************************************/ 
    173196 
    174197/* 
     
    264287} 
    265288 
    266  
    267 /* 
    268  * Create a new parser object. 
    269  */ 
    270  
    271 YAML_DECLARE(yaml_parser_t *) 
    272 yaml_parser_new(void) 
    273 { 
    274     yaml_parser_t *parser = yaml_malloc(sizeof(yaml_parser_t)); 
    275  
    276     if (!parser) 
    277         return NULL; 
    278  
    279     memset(parser, 0, sizeof(yaml_parser_t)); 
    280     if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY)) 
    281         goto error; 
    282     if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY)) 
    283         goto error; 
    284     if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY)) 
    285         goto error; 
    286     if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_CAPACITY)) 
    287         goto error; 
    288     if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_CAPACITY)) 
    289         goto error; 
    290     if (!STACK_INIT(parser, parser->states, INITIAL_STACK_CAPACITY)) 
    291         goto error; 
    292     if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_CAPACITY)) 
    293         goto error; 
    294     if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_CAPACITY)) 
    295         goto error; 
    296  
    297     return parser; 
    298  
    299 error: 
    300     yaml_parser_delete(parser); 
    301  
    302     return NULL; 
    303 } 
    304  
    305 /* 
    306  * Destroy a parser object. 
    307  */ 
    308  
    309 YAML_DECLARE(void) 
    310 yaml_parser_delete(yaml_parser_t *parser) 
    311 { 
    312     assert(parser); /* Non-NULL parser object expected. */ 
    313  
    314     IOSTRING_DEL(parser, parser->raw_input); 
    315     IOSTRING_DEL(parser, parser->input); 
    316     while (!QUEUE_EMPTY(parser, parser->tokens)) { 
    317         yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
    318     } 
    319     QUEUE_DEL(parser, parser->tokens); 
    320     STACK_DEL(parser, parser->indents); 
    321     STACK_DEL(parser, parser->simple_keys); 
    322     STACK_DEL(parser, parser->states); 
    323     STACK_DEL(parser, parser->marks); 
    324     while (!STACK_EMPTY(parser, parser->tag_directives)) { 
    325         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
    326         yaml_free(tag_directive.handle); 
    327         yaml_free(tag_directive.prefix); 
    328     } 
    329     STACK_DEL(parser, parser->tag_directives); 
    330  
    331     memset(parser, 0, sizeof(yaml_parser_t)); 
    332     yaml_free(parser); 
    333 } 
    334  
    335 /* 
    336  * Get the current parser error. 
    337  */ 
    338  
    339 YAML_DECLARE(void) 
    340 yaml_parser_get_error(yaml_parser_t *parser, yaml_error_t *error) 
    341 { 
    342     assert(parser); /* Non-NULL parser object expected. */ 
    343  
    344     *error = parser->error; 
    345 } 
    346  
    347 /* 
    348  * Standard string read handler. 
    349  */ 
    350  
    351 static int 
    352 yaml_string_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
    353         size_t *length) 
    354 { 
    355     yaml_standard_reader_data_t *data = untyped_data; 
    356  
    357     if (data->string.pointer == data->string.length) { 
    358         *length = 0; 
    359         return 1; 
    360     } 
    361  
    362     if (capacity > (size_t)(data->string.length - data->string.pointer)) { 
    363         capacity = data->string.length - data->string.pointer; 
    364     } 
    365  
    366     memcpy(buffer, data->string.buffer + data->string.pointer, capacity); 
    367     data->string.pointer += capacity; 
    368     *length = capacity; 
    369     return 1; 
    370 } 
    371  
    372 /* 
    373  * Standard file read handler. 
    374  */ 
    375  
    376 static int 
    377 yaml_file_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
    378         size_t *length) 
    379 { 
    380     yaml_standard_reader_data_t *data = untyped_data; 
    381  
    382     *length = fread(buffer, 1, capacity, data->file); 
    383     return !ferror(data->file); 
    384 } 
    385  
    386 /* 
    387  * Set a string input. 
    388  */ 
    389  
    390 YAML_DECLARE(void) 
    391 yaml_parser_set_string_reader(yaml_parser_t *parser, 
    392         const unsigned char *buffer, size_t length) 
    393 { 
    394     assert(parser); /* Non-NULL parser object expected. */ 
    395     assert(!parser->reader);    /* You can set the input handler only once. */ 
    396     assert(buffer); /* Non-NULL input string expected. */ 
    397  
    398     parser->reader = yaml_string_reader; 
    399     parser->reader_data = &(parser->standard_reader_data); 
    400  
    401     parser->standard_reader_data.string.buffer = buffer; 
    402     parser->standard_reader_data.string.pointer = 0; 
    403     parser->standard_reader_data.string.length = length; 
    404 } 
    405  
    406 /* 
    407  * Set a file input. 
    408  */ 
    409  
    410 YAML_DECLARE(void) 
    411 yaml_parser_set_file_reader(yaml_parser_t *parser, FILE *file) 
    412 { 
    413     assert(parser); /* Non-NULL parser object expected. */ 
    414     assert(!parser->reader);    /* You can set the input handler only once. */ 
    415     assert(file);   /* Non-NULL file object expected. */ 
    416  
    417     parser->reader = yaml_file_reader; 
    418     parser->reader_data = &(parser->standard_reader_data); 
    419  
    420     parser->standard_reader_data.file = file; 
    421 } 
    422  
    423 /* 
    424  * Set a generic input. 
    425  */ 
    426  
    427 YAML_DECLARE(void) 
    428 yaml_parser_set_reader(yaml_parser_t *parser, 
    429         yaml_reader_t *reader, void *data) 
    430 { 
    431     assert(parser); /* Non-NULL parser object expected. */ 
    432     assert(!parser->reader);    /* You can set the input handler only once. */ 
    433     assert(reader); /* Non-NULL read handler expected. */ 
    434  
    435     parser->reader = reader; 
    436     parser->reader_data = data; 
    437 } 
    438  
    439 /* 
    440  * Set the source encoding. 
    441  */ 
    442  
    443 YAML_DECLARE(void) 
    444 yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) 
    445 { 
    446     assert(parser); /* Non-NULL parser object expected. */ 
    447     assert(!parser->encoding);  /* Encoding is already set or detected. */ 
    448  
    449     parser->encoding = encoding; 
    450 } 
    451  
    452 /* 
    453  * Create a new emitter object. 
    454  */ 
    455  
    456 YAML_DECLARE(yaml_emitter_t *) 
    457 yaml_emitter_new(void) 
    458 { 
    459     yaml_emitter_t *emitter = yaml_malloc(sizeof(yaml_emitter_t)); 
    460  
    461     if (!emitter) 
    462         return NULL; 
    463  
    464     memset(emitter, 0, sizeof(yaml_emitter_t)); 
    465     if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY)) 
    466         goto error; 
    467     if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY)) 
    468         goto error; 
    469     if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY)) 
    470         goto error; 
    471     if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_CAPACITY)) 
    472         goto error; 
    473     if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_CAPACITY)) 
    474         goto error; 
    475     if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_CAPACITY)) 
    476         goto error; 
    477  
    478     return emitter; 
    479  
    480 error: 
    481     yaml_emitter_delete(emitter); 
    482  
    483     return NULL; 
    484 } 
    485  
    486 /* 
    487  * Destroy an emitter object. 
    488  */ 
    489  
    490 YAML_DECLARE(void) 
    491 yaml_emitter_delete(yaml_emitter_t *emitter) 
    492 { 
    493     assert(emitter);    /* Non-NULL emitter object expected. */ 
    494  
    495     IOSTRING_DEL(emitter, emitter->output); 
    496     IOSTRING_DEL(emitter, emitter->raw_output); 
    497     STACK_DEL(emitter, emitter->states); 
    498     while (!QUEUE_EMPTY(emitter, emitter->events)) { 
    499         yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
    500     } 
    501     QUEUE_DEL(emitter, emitter->events); 
    502     STACK_DEL(emitter, emitter->indents); 
    503     while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
    504         yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
    505         yaml_free(tag_directive.handle); 
    506         yaml_free(tag_directive.prefix); 
    507     } 
    508     STACK_DEL(emitter, emitter->tag_directives); 
    509     yaml_free(emitter->anchors); 
    510  
    511     memset(emitter, 0, sizeof(yaml_emitter_t)); 
    512     yaml_free(emitter); 
    513 } 
    514  
    515 /* 
    516  * Get the current emitter error. 
    517  */ 
    518  
    519 YAML_DECLARE(void) 
    520 yaml_emitter_get_error(yaml_emitter_t *emitter, yaml_error_t *error) 
    521 { 
    522     assert(emitter);    /* Non-NULL emitter object expected. */ 
    523  
    524     *error = emitter->error; 
    525 } 
    526  
    527 /* 
    528  * String write handler. 
    529  */ 
    530  
    531 static int 
    532 yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
    533 { 
    534     yaml_standard_writer_data_t *data = untyped_data; 
    535     int result = 1; 
    536  
    537     if (data->string.capacity - data->string.pointer < length) { 
    538         length = data->string.capacity - data->string.pointer; 
    539         result = 0; 
    540     } 
    541  
    542     memcpy(data->string.buffer + data->string.pointer, buffer, length); 
    543     data->string.pointer += length; 
    544     *data->length += length; 
    545  
    546     return result; 
    547 } 
    548  
    549 /* 
    550  * File write handler. 
    551  */ 
    552  
    553 static int 
    554 yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
    555 { 
    556     yaml_standard_writer_data_t *data = untyped_data; 
    557  
    558     return (fwrite(buffer, 1, length, data->file) == length); 
    559 } 
    560 /* 
    561  * Set a string output. 
    562  */ 
    563  
    564 YAML_DECLARE(void) 
    565 yaml_emitter_set_string_writer(yaml_emitter_t *emitter, 
    566         unsigned char *buffer, size_t capacity, size_t *length) 
    567 { 
    568     assert(emitter);    /* Non-NULL emitter object expected. */ 
    569     assert(!emitter->writer);   /* You can set the output only once. */ 
    570     assert(buffer);     /* Non-NULL output string expected. */ 
    571  
    572     emitter->writer = yaml_string_writer; 
    573     emitter->writer_data = &(emitter->standard_writer_data); 
    574  
    575     emitter->standard_writer_data.string.buffer = buffer; 
    576     emitter->standard_writer_data.string.pointer = 0; 
    577     emitter->standard_writer_data.string.capacity = capacity; 
    578     emitter->standard_writer_data.length = length; 
    579  
    580     *length = 0; 
    581 } 
    582  
    583 /* 
    584  * Set a file output. 
    585  */ 
    586  
    587 YAML_DECLARE(void) 
    588 yaml_emitter_set_file_writer(yaml_emitter_t *emitter, FILE *file) 
    589 { 
    590     assert(emitter);    /* Non-NULL emitter object expected. */ 
    591     assert(!emitter->writer);   /* You can set the output only once. */ 
    592     assert(file);       /* Non-NULL file object expected. */ 
    593  
    594     emitter->writer = yaml_string_writer; 
    595     emitter->writer_data = &(emitter->standard_writer_data); 
    596  
    597     emitter->standard_writer_data.file = file; 
    598 } 
    599  
    600 /* 
    601  * Set a generic output handler. 
    602  */ 
    603  
    604 YAML_DECLARE(void) 
    605 yaml_emitter_set_writer(yaml_emitter_t *emitter, 
    606         yaml_writer_t *writer, void *data) 
    607 { 
    608     assert(emitter);    /* Non-NULL emitter object expected. */ 
    609     assert(!emitter->writer);   /* You can set the output only once. */ 
    610     assert(writer); /* Non-NULL handler object expected. */ 
    611  
    612     emitter->writer = writer; 
    613     emitter->writer_data = data; 
    614 } 
    615  
    616 /* 
    617  * Set the output encoding. 
    618  */ 
    619  
    620 YAML_DECLARE(void) 
    621 yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) 
    622 { 
    623     assert(emitter);    /* Non-NULL emitter object expected. */ 
    624     assert(!emitter->encoding);     /* You can set encoding only once. */ 
    625  
    626     emitter->encoding = encoding; 
    627 } 
    628  
    629 /* 
    630  * Set the canonical output style. 
    631  */ 
    632  
    633 YAML_DECLARE(void) 
    634 yaml_emitter_set_canonical(yaml_emitter_t *emitter, int is_canonical) 
    635 { 
    636     assert(emitter);    /* Non-NULL emitter object expected. */ 
    637  
    638     emitter->is_canonical = (is_canonical != 0); 
    639 } 
    640  
    641 /* 
    642  * Set the indentation increment. 
    643  */ 
    644  
    645 YAML_DECLARE(void) 
    646 yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) 
    647 { 
    648     assert(emitter);    /* Non-NULL emitter object expected. */ 
    649  
    650     emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; 
    651 } 
    652  
    653 /* 
    654  * Set the preferred line width. 
    655  */ 
    656  
    657 YAML_DECLARE(void) 
    658 yaml_emitter_set_width(yaml_emitter_t *emitter, int width) 
    659 { 
    660     assert(emitter);    /* Non-NULL emitter object expected. */ 
    661  
    662     emitter->best_width = (width >= 0) ? width : -1; 
    663 } 
    664  
    665 /* 
    666  * Set if unescaped non-ASCII characters are allowed. 
    667  */ 
    668  
    669 YAML_DECLARE(void) 
    670 yaml_emitter_set_unicode(yaml_emitter_t *emitter, int is_unicode) 
    671 { 
    672     assert(emitter);    /* Non-NULL emitter object expected. */ 
    673  
    674     emitter->is_unicode = (is_unicode != 0); 
    675 } 
    676  
    677 /* 
    678  * Set the preferred line break character. 
    679  */ 
    680  
    681 YAML_DECLARE(void) 
    682 yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) 
    683 { 
    684     assert(emitter);    /* Non-NULL emitter object expected. */ 
    685  
    686     emitter->line_break = line_break; 
    687 } 
     289/***************************************************************************** 
     290 * Token API 
     291 *****************************************************************************/ 
    688292 
    689293/* 
     
    713317    assert(token);  /* Non-NULL token object expected. */ 
    714318 
    715     yaml_token_destroy(token); 
     319    yaml_token_clear(token); 
    716320    yaml_free(token); 
    717321} 
     
    726330    assert(token);  /* Non-NULL token object is expected. */ 
    727331    assert(model);  /* Non-NULL model token object is expected. */ 
     332    assert(!token->type);   /* The token must be empty. */ 
    728333 
    729334    memset(token, 0, sizeof(yaml_token_t)); 
    730335 
    731336    token->type = model->type; 
     337    token->start_mark = model->start_mark; 
     338    token->end_mark = model->end_mark; 
    732339 
    733340    switch (token->type) 
     
    790397 
    791398error: 
    792     yaml_token_destroy(token); 
     399    yaml_token_clear(token); 
    793400 
    794401    return 0; 
     
    796403 
    797404/* 
    798  * Destroy a token object. 
    799  */ 
    800  
    801 YAML_DECLARE(void) 
    802 yaml_token_destroy(yaml_token_t *token) 
     405 * Clear a token object. 
     406 */ 
     407 
     408YAML_DECLARE(void) 
     409yaml_token_clear(yaml_token_t *token) 
    803410{ 
    804411    assert(token);  /* Non-NULL token object expected. */ 
     
    835442} 
    836443 
    837 /* 
    838  * Check if a string is a valid UTF-8 sequence. 
    839  * 
    840  * Check 'reader.c' for more details on UTF-8 encoding. 
    841  */ 
    842  
    843 static int 
    844 yaml_valid_utf8(const yaml_char_t *buffer, size_t length) 
    845 { 
    846     size_t pointer = 0; 
    847  
    848     while (pointer < length) { 
    849         unsigned char octet; 
    850         unsigned int width; 
    851         unsigned int value; 
    852         size_t k; 
    853  
    854         octet = buffer[pointer]; 
    855         width = (octet & 0x80) == 0x00 ? 1 : 
    856                 (octet & 0xE0) == 0xC0 ? 2 : 
    857                 (octet & 0xF0) == 0xE0 ? 3 : 
    858                 (octet & 0xF8) == 0xF0 ? 4 : 0; 
    859         value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
    860                 (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
    861                 (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
    862                 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
    863         if (!width) return 0; 
    864         if (pointer+width > length) return 0; 
    865         for (k = 1; k < width; k ++) { 
    866             octet = buffer[pointer+k]; 
    867             if ((octet & 0xC0) != 0x80) return 0; 
    868             value = (value << 6) + (octet & 0x3F); 
    869         } 
    870         if (!((width == 1) || 
    871             (width == 2 && value >= 0x80) || 
    872             (width == 3 && value >= 0x800) || 
    873             (width == 4 && value >= 0x10000))) return 0; 
    874  
    875         pointer += width; 
    876     } 
    877  
    878     return 1; 
    879 } 
     444/***************************************************************************** 
     445 * Event API 
     446 *****************************************************************************/ 
    880447 
    881448/* 
     
    905472    assert(event);  /* Non-NULL event object expected. */ 
    906473 
    907     yaml_event_destroy(event); 
     474    yaml_event_clear(event); 
    908475    yaml_free(event); 
    909476} 
     
    922489    assert(event);  /* Non-NULL event object is expected. */ 
    923490    assert(model);  /* Non-NULL model event object is expected. */ 
     491    assert(!event->type);   /* The event must be empty. */ 
    924492 
    925493    memset(event, 0, sizeof(yaml_event_t)); 
    926494 
    927495    event->type = model->type; 
     496    event->start_mark = model->start_mark; 
     497    event->end_mark = model->end_mark; 
    928498 
    929499    switch (event->type) 
     
    989559                    model->data.scalar.length+1); 
    990560            event->data.scalar.length = model->data.scalar.length; 
    991             event->data.scalar.is_plain_implicit = 
    992                 model->data.scalar.is_plain_implicit; 
    993             event->data.scalar.is_quoted_implicit = 
    994                 model->data.scalar.is_quoted_implicit; 
     561            event->data.scalar.is_plain_nonspecific = 
     562                model->data.scalar.is_plain_nonspecific; 
     563            event->data.scalar.is_quoted_nonspecific = 
     564                model->data.scalar.is_quoted_nonspecific; 
    995565            event->data.scalar.style = model->data.scalar.style; 
    996566            break; 
     
    1005575                        yaml_strdup(model->data.sequence_start.tag))) 
    1006576                goto error; 
    1007             event->data.sequence_start.is_implicit = 
    1008                 model->data.sequence_start.is_implicit; 
     577            event->data.sequence_start.is_nonspecific = 
     578                model->data.sequence_start.is_nonspecific; 
    1009579            event->data.sequence_start.style = 
    1010580                model->data.sequence_start.style; 
     
    1020590                        yaml_strdup(model->data.mapping_start.tag))) 
    1021591                goto error; 
    1022             event->data.mapping_start.is_implicit = 
    1023                 model->data.mapping_start.is_implicit; 
     592            event->data.mapping_start.is_nonspecific = 
     593                model->data.mapping_start.is_nonspecific; 
    1024594            event->data.mapping_start.style = 
    1025595                model->data.mapping_start.style; 
     
    1033603 
    1034604error: 
    1035     yaml_event_destroy(event); 
     605    yaml_event_clear(event); 
    1036606 
    1037607    return 0; 
     
    1039609 
    1040610/* 
    1041  * Create STREAM-START. 
    1042  */ 
    1043  
    1044 YAML_DECLARE(int) 
    1045 yaml_event_create_stream_start(yaml_event_t *event, 
    1046         yaml_encoding_t encoding) 
    1047 { 
    1048     yaml_mark_t mark = { 0, 0, 0 }; 
    1049  
    1050     assert(event);  /* Non-NULL event object is expected. */ 
    1051  
    1052     STREAM_START_EVENT_INIT(*event, encoding, mark, mark); 
    1053  
    1054     return 1; 
    1055 } 
    1056  
    1057 /* 
    1058  * Create STREAM-END. 
    1059  */ 
    1060  
    1061 YAML_DECLARE(int) 
    1062 yaml_event_create_stream_end(yaml_event_t *event) 
    1063 { 
    1064     yaml_mark_t mark = { 0, 0, 0 }; 
    1065  
    1066     assert(event);  /* Non-NULL event object is expected. */ 
    1067  
    1068     STREAM_END_EVENT_INIT(*event, mark, mark); 
    1069  
    1070     return 1; 
    1071 } 
    1072  
    1073 /* 
    1074  * Create DOCUMENT-START. 
    1075  */ 
    1076  
    1077 YAML_DECLARE(int) 
    1078 yaml_event_create_document_start(yaml_event_t *event, 
    1079         const yaml_version_directive_t *version_directive, 
    1080         const yaml_tag_directive_t *tag_directives, 
    1081         int is_implicit) 
    1082 { 
    1083     struct { 
    1084         yaml_error_t error; 
    1085     } self; 
    1086     yaml_mark_t mark = { 0, 0, 0 }; 
    1087     yaml_version_directive_t *version_directive_copy = NULL; 
    1088     struct { 
    1089         yaml_tag_directive_t *list; 
    1090         size_t length; 
    1091         size_t capacity; 
    1092     } tag_directives_copy = { NULL, 0, 0 }; 
    1093  
    1094     assert(event);          /* Non-NULL event object is expected. */ 
    1095  
    1096     if (version_directive) { 
    1097         version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
    1098         if (!version_directive_copy) goto error; 
    1099         *version_directive_copy = *version_directive; 
    1100     } 
    1101  
    1102     if (tag_directives && (tag_directives->handle || tag_directives->prefix)) { 
    1103         if (!STACK_INIT(&self, tag_directives_copy, INITIAL_STACK_CAPACITY)) 
    1104             goto error; 
    1105         while (tag_directives->handle || tag_directives->prefix) { 
    1106             yaml_tag_directive_t value = *tag_directives; 
    1107             assert(value.handle); 
    1108             assert(value.prefix); 
    1109             if (!yaml_valid_utf8(value.handle, strlen((char *)value.handle))) 
    1110                 goto error; 
    1111             if (!yaml_valid_utf8(value.prefix, strlen((char *)value.prefix))) 
    1112                 goto error; 
    1113             if (!PUSH(&self, tag_directives_copy, value)) 
    1114                 goto error; 
    1115             value.handle = yaml_strdup(value.handle); 
    1116             value.prefix = yaml_strdup(value.prefix); 
    1117             tag_directives_copy.list[tag_directives_copy.length-1] = value; 
    1118             if (!value.handle || !value.prefix) 
    1119                 goto error; 
    1120         } 
    1121     } 
    1122  
    1123     DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, 
    1124             tag_directives_copy.list, tag_directives_copy.length, 
    1125             tag_directives_copy.capacity, is_implicit, mark, mark); 
    1126  
    1127     return 1; 
    1128  
    1129 error: 
    1130     yaml_free(version_directive_copy); 
    1131     while (!STACK_EMPTY(&self, tag_directives_copy)) { 
    1132         yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
    1133         yaml_free(value.handle); 
    1134         yaml_free(value.prefix); 
    1135     } 
    1136     STACK_DEL(&self, tag_directives_copy); 
    1137  
    1138     return 0; 
    1139 } 
    1140  
    1141 /* 
    1142  * Create DOCUMENT-END. 
    1143  */ 
    1144  
    1145 YAML_DECLARE(int) 
    1146 yaml_event_create_document_end(yaml_event_t *event, int is_implicit) 
    1147 { 
    1148     yaml_mark_t mark = { 0, 0, 0 }; 
    1149  
    1150     assert(event);      /* Non-NULL emitter object is expected. */ 
    1151  
    1152     DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark); 
    1153  
    1154     return 1; 
    1155 } 
    1156  
    1157 /* 
    1158  * Create ALIAS. 
    1159  */ 
    1160  
    1161 YAML_DECLARE(int) 
    1162 yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor) 
    1163 { 
    1164     yaml_mark_t mark = { 0, 0, 0 }; 
    1165     yaml_char_t *anchor_copy = NULL; 
    1166  
    1167     assert(event);      /* Non-NULL event object is expected. */ 
    1168     assert(anchor);     /* Non-NULL anchor is expected. */ 
    1169  
    1170     if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) return 0; 
    1171  
    1172     anchor_copy = yaml_strdup(anchor); 
    1173     if (!anchor_copy) 
    1174         return 0; 
    1175  
    1176     ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); 
    1177  
    1178     return 1; 
    1179 } 
    1180  
    1181 /* 
    1182  * Create SCALAR. 
    1183  */ 
    1184  
    1185 YAML_DECLARE(int) 
    1186 yaml_event_create_scalar(yaml_event_t *event, 
    1187         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1188         const yaml_char_t *value, size_t length, 
    1189         int is_plain_implicit, int is_quoted_implicit, 
    1190         yaml_scalar_style_t style) 
    1191 { 
    1192     yaml_mark_t mark = { 0, 0, 0 }; 
    1193     yaml_char_t *anchor_copy = NULL; 
    1194     yaml_char_t *tag_copy = NULL; 
    1195     yaml_char_t *value_copy = NULL; 
    1196  
    1197     assert(event);      /* Non-NULL event object is expected. */ 
    1198     assert(value);      /* Non-NULL anchor is expected. */ 
    1199  
    1200     if (anchor) { 
    1201         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1202             goto error; 
    1203         anchor_copy = yaml_strdup(anchor); 
    1204         if (!anchor_copy) 
    1205             goto error; 
    1206     } 
    1207  
    1208     if (tag) { 
    1209         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1210             goto error; 
    1211         tag_copy = yaml_strdup(tag); 
    1212         if (!tag_copy) 
    1213             goto error; 
    1214     } 
    1215  
    1216     if (length < 0) { 
    1217         length = strlen((char *)value); 
    1218     } 
    1219  
    1220     if (!yaml_valid_utf8(value, length)) 
    1221         goto error; 
    1222     value_copy = yaml_malloc(length+1); 
    1223     if (!value_copy) 
    1224         goto error; 
    1225     memcpy(value_copy, value, length); 
    1226     value_copy[length] = '\0'; 
    1227  
    1228     SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, 
    1229             is_plain_implicit, is_quoted_implicit, style, mark, mark); 
    1230  
    1231     return 1; 
    1232  
    1233 error: 
    1234     yaml_free(anchor_copy); 
    1235     yaml_free(tag_copy); 
    1236     yaml_free(value_copy); 
    1237  
    1238     return 0; 
    1239 } 
    1240  
    1241 /* 
    1242  * Create SEQUENCE-START. 
    1243  */ 
    1244  
    1245 YAML_DECLARE(int) 
    1246 yaml_event_create_sequence_start(yaml_event_t *event, 
    1247         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1248         int is_implicit, yaml_sequence_style_t style) 
    1249 { 
    1250     yaml_mark_t mark = { 0, 0, 0 }; 
    1251     yaml_char_t *anchor_copy = NULL; 
    1252     yaml_char_t *tag_copy = NULL; 
    1253  
    1254     assert(event);      /* Non-NULL event object is expected. */ 
    1255  
    1256     if (anchor) { 
    1257         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1258             goto error; 
    1259         anchor_copy = yaml_strdup(anchor); 
    1260         if (!anchor_copy) 
    1261             goto error; 
    1262     } 
    1263  
    1264     if (tag) { 
    1265         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1266             goto error; 
    1267         tag_copy = yaml_strdup(tag); 
    1268         if (!tag_copy) 
    1269             goto error; 
    1270     } 
    1271  
    1272     SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
    1273             is_implicit, style, mark, mark); 
    1274  
    1275     return 1; 
    1276  
    1277 error: 
    1278     yaml_free(anchor_copy); 
    1279     yaml_free(tag_copy); 
    1280  
    1281     return 0; 
    1282 } 
    1283  
    1284 /* 
    1285  * Create SEQUENCE-END. 
    1286  */ 
    1287  
    1288 YAML_DECLARE(int) 
    1289 yaml_event_create_sequence_end(yaml_event_t *event) 
    1290 { 
    1291     yaml_mark_t mark = { 0, 0, 0 }; 
    1292  
    1293     assert(event);      /* Non-NULL event object is expected. */ 
    1294  
    1295     SEQUENCE_END_EVENT_INIT(*event, mark, mark); 
    1296  
    1297     return 1; 
    1298 } 
    1299  
    1300 /* 
    1301  * Create MAPPING-START. 
    1302  */ 
    1303  
    1304 YAML_DECLARE(int) 
    1305 yaml_event_create_mapping_start(yaml_event_t *event, 
    1306         const yaml_char_t *anchor, const yaml_char_t *tag, 
    1307         int is_implicit, yaml_mapping_style_t style) 
    1308 { 
    1309     yaml_mark_t mark = { 0, 0, 0 }; 
    1310     yaml_char_t *anchor_copy = NULL; 
    1311     yaml_char_t *tag_copy = NULL; 
    1312  
    1313     assert(event);      /* Non-NULL event object is expected. */ 
    1314  
    1315     if (anchor) { 
    1316         if (!yaml_valid_utf8(anchor, strlen((char *)anchor))) 
    1317             goto error; 
    1318         anchor_copy = yaml_strdup(anchor); 
    1319         if (!anchor_copy) 
    1320             goto error; 
    1321     } 
    1322  
    1323     if (tag) { 
    1324         if (!yaml_valid_utf8(tag, strlen((char *)tag))) 
    1325             goto error; 
    1326         tag_copy = yaml_strdup(tag); 
    1327         if (!tag_copy) 
    1328             goto error; 
    1329     } 
    1330  
    1331     MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
    1332             is_implicit, style, mark, mark); 
    1333  
    1334     return 1; 
    1335  
    1336 error: 
    1337     yaml_free(anchor_copy); 
    1338     yaml_free(tag_copy); 
    1339  
    1340     return 0; 
    1341 } 
    1342  
    1343 /* 
    1344  * Create MAPPING-END. 
    1345  */ 
    1346  
    1347 YAML_DECLARE(int) 
    1348 yaml_event_create_mapping_end(yaml_event_t *event) 
    1349 { 
    1350     yaml_mark_t mark = { 0, 0, 0 }; 
    1351  
    1352     assert(event);      /* Non-NULL event object is expected. */ 
    1353  
    1354     MAPPING_END_EVENT_INIT(*event, mark, mark); 
    1355  
    1356     return 1; 
    1357 } 
    1358  
    1359 /* 
    1360  * Destroy an event object. 
    1361  */ 
    1362  
    1363 YAML_DECLARE(void) 
    1364 yaml_event_destroy(yaml_event_t *event) 
     611 * Clear an event object. 
     612 */ 
     613 
     614YAML_DECLARE(void) 
     615yaml_event_clear(yaml_event_t *event) 
    1365616{ 
    1366617    struct { 
     
    1410661} 
    1411662 
    1412 #if 0 
    1413  
    1414 /* 
    1415  * Create a document object. 
    1416  */ 
    1417  
    1418 YAML_DECLARE(int) 
    1419 yaml_document_initialize(yaml_document_t *document, 
    1420         yaml_version_directive_t *version_directive, 
    1421         yaml_tag_directive_t *tag_directives_start, 
    1422         yaml_tag_directive_t *tag_directives_end, 
    1423         int start_implicit, int end_implicit) 
     663/* 
     664 * Create STREAM-START. 
     665 */ 
     666 
     667YAML_DECLARE(int) 
     668yaml_event_create_stream_start(yaml_event_t *event, 
     669        yaml_encoding_t encoding) 
     670{ 
     671    yaml_mark_t mark = { 0, 0, 0 }; 
     672 
     673    assert(event);  /* Non-NULL event object is expected. */ 
     674    assert(!event->type);   /* The event must be empty. */ 
     675 
     676    STREAM_START_EVENT_INIT(*event, encoding, mark, mark); 
     677 
     678    return 1; 
     679} 
     680 
     681/* 
     682 * Create STREAM-END. 
     683 */ 
     684 
     685YAML_DECLARE(int) 
     686yaml_event_create_stream_end(yaml_event_t *event) 
     687{ 
     688    yaml_mark_t mark = { 0, 0, 0 }; 
     689 
     690    assert(event);  /* Non-NULL event object is expected. */ 
     691    assert(!event->type);   /* The event must be empty. */ 
     692 
     693    STREAM_END_EVENT_INIT(*event, mark, mark); 
     694 
     695    return 1; 
     696} 
     697 
     698/* 
     699 * Create DOCUMENT-START. 
     700 */ 
     701 
     702YAML_DECLARE(int) 
     703yaml_event_create_document_start(yaml_event_t *event, 
     704        const yaml_version_directive_t *version_directive, 
     705        const yaml_tag_directive_t *tag_directives_list, 
     706        size_t tag_directives_length, int is_implicit) 
    1424707{ 
    1425708    struct { 
    1426         yaml_error_type_t error; 
    1427     } context; 
    1428     struct { 
    1429         yaml_node_t *start; 
    1430         yaml_node_t *end; 
    1431         yaml_node_t *top; 
    1432     } nodes = { NULL, NULL, NULL }; 
     709        yaml_error_t error; 
     710    } self; 
     711    yaml_mark_t mark = { 0, 0, 0 }; 
    1433712    yaml_version_directive_t *version_directive_copy = NULL; 
    1434713    struct { 
    1435         yaml_tag_directive_t *start; 
    1436         yaml_tag_directive_t *end; 
    1437         yaml_tag_directive_t *top; 
    1438     } tag_directives_copy = { NULL, NULL, NULL }; 
    1439     yaml_tag_directive_t value = { NULL, NULL }; 
    1440     yaml_mark_t mark = { 0, 0, 0 }; 
    1441  
    1442     assert(document);       /* Non-NULL document object is expected. */ 
    1443     assert((tag_directives_start && tag_directives_end) || 
    1444             (tag_directives_start == tag_directives_end)); 
    1445                             /* Valid tag directives are expected. */ 
    1446  
    1447     if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error; 
     714        yaml_tag_directive_t *list; 
     715        size_t length; 
     716        size_t capacity; 
     717    } tag_directives_copy = { NULL, 0, 0 }; 
     718    int idx; 
     719 
     720    assert(event);          /* Non-NULL event object is expected. */ 
     721    assert(!event->type);   /* The event must be empty. */ 
    1448722 
    1449723    if (version_directive) { 
    1450724        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
    1451725        if (!version_directive_copy) goto error; 
    1452         version_directive_copy->major = version_directive->major; 
    1453         version_directive_copy->minor = version_directive->minor; 
    1454     } 
    1455  
    1456     if (tag_directives_start != tag_directives_end) { 
    1457         yaml_tag_directive_t *tag_directive; 
    1458         if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) 
     726        *version_directive_copy = *version_directive; 
     727    } 
     728 
     729    if (tag_directives_list && tag_directives_length) { 
     730        if (!STACK_INIT(&self, tag_directives_copy, tag_directives_length)) 
    1459731            goto error; 
    1460         for (tag_directive = tag_directives_start; 
    1461                 tag_directive != tag_directives_end; tag_directive ++) { 
    1462             assert(tag_directive->handle); 
    1463             assert(tag_directive->prefix); 
    1464             if (!yaml_valid_utf8(tag_directive->handle, 
    1465                         strlen((char *)tag_directive->handle))) 
     732        for (idx = 0; idx < tag_directives_length; idx++) { 
     733            yaml_tag_directive_t value = tag_directives_list[idx]; 
     734            assert(value.handle); 
     735            assert(value.prefix); 
     736            value.handle = yaml_strdup(value.handle); 
     737            value.prefix = yaml_strdup(value.prefix); 
     738            PUSH(&self, tag_directives_copy, value); 
     739            if (!value.handle || !value.prefix) 
    1466740                goto error; 
    1467             if (!yaml_valid_utf8(tag_directive->prefix, 
    1468                         strlen((char *)tag_directive->prefix))) 
    1469                 goto error; 
    1470             value.handle = yaml_strdup(tag_directive->handle); 
    1471             value.prefix = yaml_strdup(tag_directive->prefix); 
    1472             if (!value.handle || !value.prefix) goto error; 
    1473             if (!PUSH(&context, tag_directives_copy, value)) 
    1474                 goto error; 
    1475             value.handle = NULL; 
    1476             value.prefix = NULL; 
    1477741        } 
    1478742    } 
    1479743 
    1480     DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, 
    1481             tag_directives_copy.start, tag_directives_copy.top, 
    1482             start_implicit, end_implicit, mark, mark); 
     744    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, 
     745            tag_directives_copy.list, tag_directives_copy.length, 
     746            tag_directives_copy.capacity, is_implicit, mark, mark); 
    1483747 
    1484748    return 1; 
    1485749 
    1486750error: 
    1487     STACK_DEL(&context, nodes); 
    1488751    yaml_free(version_directive_copy); 
    1489     while (!STACK_EMPTY(&context, tag_directives_copy)) { 
    1490         yaml_tag_directive_t value = POP(&context, tag_directives_copy); 
     752    while (!STACK_EMPTY(&self, tag_directives_copy)) { 
     753        yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
    1491754        yaml_free(value.handle); 
    1492755        yaml_free(value.prefix); 
    1493756    } 
    1494     STACK_DEL(&context, tag_directives_copy); 
    1495     yaml_free(value.handle); 
    1496     yaml_free(value.prefix); 
     757    STACK_DEL(&self, tag_directives_copy); 
    1497758 
    1498759    return 0; 
     
    1500761 
    1501762/* 
    1502  * Destroy a document object. 
     763 * Create DOCUMENT-END. 
     764 */ 
     765 
     766YAML_DECLARE(int) 
     767yaml_event_create_document_end(yaml_event_t *event, int is_implicit) 
     768{ 
     769    yaml_mark_t mark = { 0, 0, 0 }; 
     770 
     771    assert(event);      /* Non-NULL emitter object is expected. */ 
     772    assert(!event->type);   /* The event must be empty. */ 
     773 
     774    DOCUMENT_END_EVENT_INIT(*event, is_implicit, mark, mark); 
     775 
     776    return 1; 
     777} 
     778 
     779/* 
     780 * Create ALIAS. 
     781 */ 
     782 
     783YAML_DECLARE(int) 
     784yaml_event_create_alias(yaml_event_t *event, const yaml_char_t *anchor) 
     785{ 
     786    yaml_mark_t mark = { 0, 0, 0 }; 
     787    yaml_char_t *anchor_copy = NULL; 
     788 
     789    assert(event);      /* Non-NULL event object is expected. */ 
     790    assert(!event->type);   /* The event must be empty. */ 
     791    assert(anchor);     /* Non-NULL anchor is expected. */ 
     792 
     793    anchor_copy = yaml_strdup(anchor); 
     794    if (!anchor_copy) 
     795        return 0; 
     796 
     797    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); 
     798 
     799    return 1; 
     800} 
     801 
     802/* 
     803 * Create SCALAR. 
     804 */ 
     805 
     806YAML_DECLARE(int) 
     807yaml_event_create_scalar(yaml_event_t *event, 
     808        const yaml_char_t *anchor, const yaml_char_t *tag, 
     809        const yaml_char_t *value, int length, 
     810        int is_plain_nonspecific, int is_quoted_nonspecific, 
     811        yaml_scalar_style_t style) 
     812{ 
     813    yaml_mark_t mark = { 0, 0, 0 }; 
     814    yaml_char_t *anchor_copy = NULL; 
     815    yaml_char_t *tag_copy = NULL; 
     816    yaml_char_t *value_copy = NULL; 
     817 
     818    assert(event);      /* Non-NULL event object is expected. */ 
     819    assert(!event->type);   /* The event must be empty. */ 
     820    assert(value);      /* Non-NULL anchor is expected. */ 
     821 
     822    if (anchor) { 
     823        anchor_copy = yaml_strdup(anchor); 
     824        if (!anchor_copy) 
     825            goto error; 
     826    } 
     827 
     828    if (tag) { 
     829        tag_copy = yaml_strdup(tag); 
     830        if (!tag_copy) 
     831            goto error; 
     832    } 
     833 
     834    if (length < 0) { 
     835        length = strlen((char *)value); 
     836    } 
     837 
     838    value_copy = yaml_malloc(length+1); 
     839    if (!value_copy) 
     840        goto error; 
     841    memcpy(value_copy, value, length); 
     842    value_copy[length] = '\0'; 
     843 
     844    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, 
     845            is_plain_nonspecific, is_quoted_nonspecific, style, mark, mark); 
     846 
     847    return 1; 
     848 
     849error: 
     850    yaml_free(anchor_copy); 
     851    yaml_free(tag_copy); 
     852    yaml_free(value_copy); 
     853 
     854    return 0; 
     855} 
     856 
     857/* 
     858 * Create SEQUENCE-START. 
     859 */ 
     860 
     861YAML_DECLARE(int) 
     862yaml_event_create_sequence_start(yaml_event_t *event, 
     863        const yaml_char_t *anchor, const yaml_char_t *tag, 
     864        int is_nonspecific, yaml_sequence_style_t style) 
     865{ 
     866    yaml_mark_t mark = { 0, 0, 0 }; 
     867    yaml_char_t *anchor_copy = NULL; 
     868    yaml_char_t *tag_copy = NULL; 
     869 
     870    assert(event);      /* Non-NULL event object is expected. */ 
     871    assert(!event->type);   /* The event must be empty. */ 
     872 
     873    if (anchor) { 
     874        anchor_copy = yaml_strdup(anchor); 
     875        if (!anchor_copy) 
     876            goto error; 
     877    } 
     878 
     879    if (tag) { 
     880        tag_copy = yaml_strdup(tag); 
     881        if (!tag_copy) 
     882            goto error; 
     883    } 
     884 
     885    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     886            is_nonspecific, style, mark, mark); 
     887 
     888    return 1; 
     889 
     890error: 
     891    yaml_free(anchor_copy); 
     892    yaml_free(tag_copy); 
     893 
     894    return 0; 
     895} 
     896 
     897/* 
     898 * Create SEQUENCE-END. 
     899 */ 
     900 
     901YAML_DECLARE(int) 
     902yaml_event_create_sequence_end(yaml_event_t *event) 
     903{ 
     904    yaml_mark_t mark = { 0, 0, 0 }; 
     905 
     906    assert(event);      /* Non-NULL event object is expected. */ 
     907    assert(!event->type);   /* The event must be empty. */ 
     908 
     909    SEQUENCE_END_EVENT_INIT(*event, mark, mark); 
     910 
     911    return 1; 
     912} 
     913 
     914/* 
     915 * Create MAPPING-START. 
     916 */ 
     917 
     918YAML_DECLARE(int) 
     919yaml_event_create_mapping_start(yaml_event_t *event, 
     920        const yaml_char_t *anchor, const yaml_char_t *tag, 
     921        int is_nonspecific, yaml_mapping_style_t style) 
     922{ 
     923    yaml_mark_t mark = { 0, 0, 0 }; 
     924    yaml_char_t *anchor_copy = NULL; 
     925    yaml_char_t *tag_copy = NULL; 
     926 
     927    assert(event);      /* Non-NULL event object is expected. */ 
     928    assert(!event->type);   /* The event must be empty. */ 
     929 
     930    if (anchor) { 
     931        anchor_copy = yaml_strdup(anchor); 
     932        if (!anchor_copy) 
     933            goto error; 
     934    } 
     935 
     936    if (tag) { 
     937        tag_copy = yaml_strdup(tag); 
     938        if (!tag_copy) 
     939            goto error; 
     940    } 
     941 
     942    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     943            is_nonspecific, style, mark, mark); 
     944 
     945    return 1; 
     946 
     947error: 
     948    yaml_free(anchor_copy); 
     949    yaml_free(tag_copy); 
     950 
     951    return 0; 
     952} 
     953 
     954/* 
     955 * Create MAPPING-END. 
     956 */ 
     957 
     958YAML_DECLARE(int) 
     959yaml_event_create_mapping_end(yaml_event_t *event) 
     960{ 
     961    yaml_mark_t mark = { 0, 0, 0 }; 
     962 
     963    assert(event);      /* Non-NULL event object is expected. */ 
     964    assert(!event->type);   /* The event must be empty. */ 
     965 
     966    MAPPING_END_EVENT_INIT(*event, mark, mark); 
     967 
     968    return 1; 
     969} 
     970 
     971/***************************************************************************** 
     972 * Document API 
     973 *****************************************************************************/ 
     974 
     975/* 
     976 * Allocate a document object. 
     977 */ 
     978 
     979YAML_DECLARE(yaml_document_t *) 
     980yaml_document_new(void) 
     981{ 
     982    yaml_document_t *document = yaml_malloc(sizeof(yaml_document_t)); 
     983 
     984    if (!document) 
     985        return NULL; 
     986 
     987    memset(document, 0, sizeof(yaml_document_t)); 
     988 
     989    return document; 
     990} 
     991 
     992/* 
     993 * Deallocate a document object. 
    1503994 */ 
    1504995 
    1505996YAML_DECLARE(void) 
    1506997yaml_document_delete(yaml_document_t *document) 
     998{ 
     999    assert(document);   /* Non-NULL document object is expected. */ 
     1000 
     1001    yaml_document_clear(document); 
     1002    yaml_free(document); 
     1003} 
     1004 
     1005/* 
     1006 * Duplicate a document object. 
     1007 */ 
     1008 
     1009YAML_DECLARE(int) 
     1010yaml_document_duplicate(yaml_document_t *document, yaml_document_t *model) 
     1011{ 
     1012    struct { 
     1013        yaml_error_t error; 
     1014    } self; 
     1015    yaml_char_t *anchor = NULL; 
     1016    yaml_char_t *tag = NULL; 
     1017    yaml_char_t *value = NULL; 
     1018    yaml_node_item_t *item_list = NULL; 
     1019    yaml_node_pair_t *pair_list = NULL; 
     1020    int idx; 
     1021 
     1022    assert(document);   /* Non-NULL document object is expected. */ 
     1023    assert(!document->type);    /* The document must be empty. */ 
     1024    assert(model);      /* Non-NULL model object is expected. */ 
     1025 
     1026    if (model->type != YAML_DOCUMENT) 
     1027        return 1; 
     1028 
     1029    if (!yaml_document_create(document, model->version_directive, 
     1030                model->tag_directives.list, model->tag_directives.length, 
     1031                model->is_start_implicit, model->is_end_implicit)) 
     1032        return 0; 
     1033 
     1034    document->start_mark = model->start_mark; 
     1035    document->end_mark = model->end_mark; 
     1036 
     1037    for (idx = 0; idx < model->nodes.length; idx++) 
     1038    { 
     1039        yaml_node_t *node = STACK_ITER(&self, model->nodes, idx); 
     1040        yaml_node_t copy; 
     1041        if (node->anchor) { 
     1042            anchor = yaml_strdup(node->anchor); 
     1043            if (!anchor) goto error; 
     1044        } 
     1045        tag = yaml_strdup(node->tag); 
     1046        if (!tag) goto error; 
     1047        switch (node->type) 
     1048        { 
     1049            case YAML_SCALAR_NODE: 
     1050                value = yaml_malloc(node->data.scalar.length+1); 
     1051                if (!value) 
     1052                    goto error; 
     1053                memcpy(value, node->data.scalar.value, 
     1054                        node->data.scalar.length); 
     1055                value[node->data.scalar.length] = '\0'; 
     1056                SCALAR_NODE_INIT(copy, anchor, tag, value, 
     1057                        node->data.scalar.length, node->data.scalar.style, 
     1058                        node->start_mark, node->end_mark); 
     1059                break; 
     1060 
     1061            case YAML_SEQUENCE_NODE: 
     1062                item_list = yaml_malloc(node->data.sequence.items.capacity 
     1063                        * sizeof(yaml_node_item_t)); 
     1064                if (!item_list) goto error; 
     1065                memcpy(item_list, node->data.sequence.items.list, 
     1066                        node->data.sequence.items.capacity 
     1067                        * sizeof(yaml_node_item_t)); 
     1068                SEQUENCE_NODE_INIT(copy, anchor, tag, item_list, 
     1069                        node->data.sequence.items.length, 
     1070                        node->data.sequence.items.capacity, 
     1071                        node->data.sequence.style, 
     1072                        node->start_mark, node->end_mark); 
     1073                break; 
     1074 
     1075            case YAML_MAPPING_NODE: 
     1076                pair_list = yaml_malloc(node->data.mapping.pairs.capacity 
     1077                        * sizeof(yaml_node_pair_t)); 
     1078                if (!pair_list) goto error; 
     1079                memcpy(pair_list, node->data.mapping.pairs.list, 
     1080                        node->data.mapping.pairs.capacity 
     1081                        * sizeof(yaml_node_pair_t)); 
     1082                MAPPING_NODE_INIT(copy, anchor, tag, pair_list, 
     1083                        node->data.mapping.pairs.length, 
     1084                        node->data.mapping.pairs.capacity, 
     1085                        node->data.mapping.style, 
     1086                        node->start_mark, node->end_mark); 
     1087                break; 
     1088 
     1089            default: 
     1090                assert(0);  /* Should never happen. */ 
     1091        } 
     1092 
     1093        if (!PUSH(&self, document->nodes, copy)) 
     1094            goto error; 
     1095 
     1096        anchor = NULL; 
     1097        tag = NULL; 
     1098        value = NULL; 
     1099        item_list = NULL; 
     1100        pair_list = NULL; 
     1101    } 
     1102 
     1103error: 
     1104    yaml_free(anchor); 
     1105    yaml_free(tag); 
     1106    yaml_free(value); 
     1107    yaml_free(item_list); 
     1108    yaml_free(pair_list); 
     1109 
     1110    yaml_document_clear(document); 
     1111 
     1112    return 0; 
     1113} 
     1114 
     1115/* 
     1116 * Clear a document object. 
     1117 */ 
     1118 
     1119YAML_DECLARE(void) 
     1120yaml_document_clear(yaml_document_t *document) 
    15071121{ 
    15081122    struct { 
    15091123        yaml_error_type_t error; 
    1510     } context; 
     1124    } self; 
    15111125    yaml_tag_directive_t *tag_directive; 
    15121126 
    1513     context.error = YAML_NO_ERROR;  /* Eliminate a compliler warning. */ 
     1127    self.error = YAML_NO_ERROR;  /* Eliminate a compliler warning. */ 
    15141128 
    15151129    assert(document);   /* Non-NULL document object is expected. */ 
     1130 
     1131    if (!document->type) 
     1132        return; 
    15161133 
    15171134    while (!STACK_EMPTY(&context, document->nodes)) { 
     
    15321149        } 
    15331150    } 
    1534     STACK_DEL(&context, document->nodes); 
     1151    STACK_DEL(&self, document->nodes); 
    15351152 
    15361153    yaml_free(document->version_directive); 
    1537     for (tag_directive = document->tag_directives.start; 
    1538             tag_directive != document->tag_directives.end; 
    1539             tag_directive++) { 
    1540         yaml_free(tag_directive->handle); 
    1541         yaml_free(tag_directive->prefix); 
    1542     } 
    1543     yaml_free(document->tag_directives.start); 
     1154    while (!STACK_EMPTY(&self, document->tag_directives)) { 
     1155        yaml_tag_directive_t tag_directive = POP(&self, document->tag_directives); 
     1156        yaml_free(tag_directive.handle); 
     1157        yaml_free(tag_directive.prefix); 
     1158    } 
     1159    STACK_DEL(&self, document->tag_directives); 
    15441160 
    15451161    memset(document, 0, sizeof(yaml_document_t)); 
    15461162} 
    15471163 
    1548 /** 
     1164/* 
     1165 * Create a document. 
     1166 */ 
     1167 
     1168YAML_DECLARE(int) 
     1169yaml_document_create(yaml_document_t *document, 
     1170        const yaml_version_directive_t *version_directive, 
     1171        const yaml_tag_directive_t *tag_directives_list, 
     1172        size_t tag_directives_length, 
     1173        int is_start_implicit, int is_end_implicit) 
     1174{ 
     1175    struct { 
     1176        yaml_error_t error; 
     1177    } self; 
     1178    yaml_mark_t mark = { 0, 0, 0 }; 
     1179    struct { 
     1180        yaml_node_t *list; 
     1181        size_t length; 
     1182        size_t capacity; 
     1183    } nodes; 
     1184    yaml_version_directive_t *version_directive_copy = NULL; 
     1185    struct { 
     1186        yaml_tag_directive_t *list; 
     1187        size_t length; 
     1188        size_t capacity; 
     1189    } tag_directives_copy = { NULL, 0, 0 }; 
     1190    int idx; 
     1191 
     1192    assert(document);           /* Non-NULL event object is expected. */ 
     1193    assert(!document->type);    /* The document must be empty. */ 
     1194     
     1195    if (!STACK_INIT(&self, nodes, INITIAL_STACK_CAPACITY)) 
     1196        goto error; 
     1197 
     1198    if (version_directive) { 
     1199        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
     1200        if (!version_directive_copy) goto error; 
     1201        *version_directive_copy = *version_directive; 
     1202    } 
     1203 
     1204    if (tag_directives_list && tag_directives_length) { 
     1205        if (!STACK_INIT(&self, tag_directives_copy, tag_directives_length)) 
     1206            goto error; 
     1207        for (idx = 0; idx < tag_directives_length; idx++) { 
     1208            yaml_tag_directive_t value = tag_directives_list[idx]; 
     1209            assert(value.handle); 
     1210            assert(value.prefix); 
     1211            value.handle = yaml_strdup(value.handle); 
     1212            value.prefix = yaml_strdup(value.prefix); 
     1213            PUSH(&self, tag_directives_copy, value); 
     1214            if (!value.handle || !value.prefix) 
     1215                goto error; 
     1216        } 
     1217    } 
     1218 
     1219    DOCUMENT_INIT(*document, nodes.list, nodes.length, nodes.capacity, 
     1220            version_directive_copy, tag_directives_copy.list, 
     1221            tag_directives_copy.length, tag_directives_copy.capacity, 
     1222            is_start_implicit, is_end_implicit, mark, mark); 
     1223 
     1224    return 1; 
     1225 
     1226error: 
     1227    STACK_DEL(&self, nodes); 
     1228 
     1229    yaml_free(version_directive_copy); 
     1230 
     1231    while (!STACK_EMPTY(&self, tag_directives_copy)) { 
     1232        yaml_tag_directive_t value = POP(&self, tag_directives_copy); 
     1233        yaml_free(value.handle); 
     1234        yaml_free(value.prefix); 
     1235    } 
     1236    STACK_DEL(&self, tag_directives_copy); 
     1237 
     1238    return 0; 
     1239} 
     1240 
     1241/* 
    15491242 * Get a document node. 
    15501243 */ 
    15511244 
    15521245YAML_DECLARE(yaml_node_t *) 
    1553 yaml_document_get_node(yaml_document_t *document, int index) 
     1246yaml_document_get_node(yaml_document_t *document, int node_id) 
    15541247{ 
    15551248    assert(document);   /* Non-NULL document object is expected. */ 
    1556  
    1557     if (index > 0 && document->nodes.start + index <= document->nodes.top) { 
    1558         return document->nodes.start + index - 1; 
     1249    assert(document->type); /* Initialized document is expected. */ 
     1250 
     1251    if (node_id < 0) { 
     1252        node_id += document->nodes.length; 
     1253    } 
     1254 
     1255    if (node_id >= 0 && node_id < document->nodes.length) { 
     1256        return document->nodes.list + node_id; 
    15591257    } 
    15601258    return NULL; 
    15611259} 
    15621260 
    1563 /** 
    1564  * Get the root object. 
    1565  */ 
    1566  
    1567 YAML_DECLARE(yaml_node_t *) 
    1568 yaml_document_get_root_node(yaml_document_t *document) 
    1569 { 
    1570     assert(document);   /* Non-NULL document object is expected. */ 
    1571  
    1572     if (document->nodes.top != document->nodes.start) { 
    1573         return document->nodes.start; 
    1574     } 
    1575     return NULL; 
    1576 } 
    1577  
    15781261/* 
    15791262 * Add a scalar node to a document. 
     
    15811264 
    15821265YAML_DECLARE(int) 
    1583 yaml_document_add_scalar(yaml_document_t *document, 
    1584         yaml_char_t *tag, yaml_char_t *value, int length, 
     1266yaml_document_add_scalar(yaml_document_t *document, int *node_id, 
     1267        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1268        const yaml_char_t *value, int length, 
    15851269        yaml_scalar_style_t style) 
    15861270{ 
    15871271    struct { 
    1588         yaml_error_type_t error; 
    1589     } context; 
     1272        yaml_error_t error; 
     1273    } self; 
    15901274    yaml_mark_t mark = { 0, 0, 0 }; 
     1275    yaml_char_t *anchor_copy = NULL; 
    15911276    yaml_char_t *tag_copy = NULL; 
    15921277    yaml_char_t *value_copy = NULL; 
     
    15941279 
    15951280    assert(document);   /* Non-NULL document object is expected. */ 
     1281    assert(document->type); /* Initialized document is required. */ 
     1282    assert(tag);        /* Non-NULL tag is expected. */ 
    15961283    assert(value);      /* Non-NULL value is expected. */ 
    15971284 
    1598     if (!tag) { 
    1599         tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; 
    1600     } 
    1601  
    1602     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1285    if (anchor) { 
     1286        anchor_copy = yaml_strdup(anchor); 
     1287        if (!anchor_copy) goto error; 
     1288    } 
     1289 
    16031290    tag_copy = yaml_strdup(tag); 
    16041291    if (!tag_copy) goto error; 
     
    16081295    } 
    16091296 
    1610     if (!yaml_valid_utf8(value, length)) goto error; 
    16111297    value_copy = yaml_malloc(length+1); 
    16121298    if (!value_copy) goto error; 
     
    16141300    value_copy[length] = '\0'; 
    16151301 
    1616     SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); 
    1617     if (!PUSH(&context, document->nodes, node)) goto error; 
    1618  
    1619     return document->nodes.top - document->nodes.start; 
     1302    SCALAR_NODE_INIT(node, anchor_copy, tag_copy, value_copy, length, 
     1303            style, mark, mark); 
     1304    if (!PUSH(&self, document->nodes, node)) goto error; 
     1305 
     1306    if (node_id) { 
     1307        *node_id = document->nodes.length-1; 
     1308    } 
     1309 
     1310    return 1; 
    16201311 
    16211312error: 
     1313    yaml_free(anchor_copy); 
    16221314    yaml_free(tag_copy); 
    16231315    yaml_free(value_copy); 
     
    16311323 
    16321324YAML_DECLARE(int) 
    1633 yaml_document_add_sequence(yaml_document_t *document, 
    1634         yaml_char_t *tag, yaml_sequence_style_t style) 
     1325yaml_document_add_sequence(yaml_document_t *document, int *node_id, 
     1326        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1327        yaml_sequence_style_t style) 
    16351328{ 
    16361329    struct { 
    1637         yaml_error_type_t error; 
    1638     } context; 
     1330        yaml_error_t error; 
     1331    } self; 
    16391332    yaml_mark_t mark = { 0, 0, 0 }; 
     1333    yaml_char_t *anchor_copy = NULL; 
    16401334    yaml_char_t *tag_copy = NULL; 
    16411335    struct { 
    1642         yaml_node_item_t *start; 
    1643         yaml_node_item_t *end; 
    1644         yaml_node_item_t *top; 
    1645     } items = { NULL, NULL, NULL }; 
     1336        yaml_node_item_t *list; 
     1337        size_t length; 
     1338        size_t capacity; 
     1339    } items = { NULL, 0, 0 }; 
    16461340    yaml_node_t node; 
    16471341 
    16481342    assert(document);   /* Non-NULL document object is expected. */ 
    1649  
    1650     if (!tag) { 
    1651         tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; 
    1652     } 
    1653  
    1654     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1343    assert(document->type); /* Initialized document is required. */ 
     1344    assert(tag);        /* Non-NULL tag is expected. */ 
     1345 
     1346    if (anchor) { 
     1347        anchor_copy = yaml_strdup(anchor); 
     1348        if (!anchor_copy) goto error; 
     1349    } 
     1350 
    16551351    tag_copy = yaml_strdup(tag); 
    16561352    if (!tag_copy) goto error; 
    16571353 
    1658     if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error; 
    1659  
    1660     SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, 
    1661             style, mark, mark); 
    1662     if (!PUSH(&context, document->nodes, node)) goto error; 
    1663  
    1664     return document->nodes.top - document->nodes.start; 
     1354    if (!STACK_INIT(&self, items, INITIAL_STACK_CAPACITY)) goto error; 
     1355 
     1356    SEQUENCE_NODE_INIT(node, anchor_copy, tag_copy, 
     1357            items.list, items.length, items.capacity, style, mark, mark); 
     1358    if (!PUSH(&self, document->nodes, node)) goto error; 
     1359 
     1360    if (node_id) { 
     1361        *node_id = document->nodes.length-1; 
     1362    } 
     1363 
     1364    return 1; 
    16651365 
    16661366error: 
    1667     STACK_DEL(&context, items); 
     1367    STACK_DEL(&self, items); 
     1368    yaml_free(anchor_copy); 
    16681369    yaml_free(tag_copy); 
    16691370 
     
    16761377 
    16771378YAML_DECLARE(int) 
    1678 yaml_document_add_mapping(yaml_document_t *document, 
    1679         yaml_char_t *tag, yaml_mapping_style_t style) 
     1379yaml_document_add_mapping(yaml_document_t *document, int *node_id, 
     1380        const yaml_char_t *anchor, const yaml_char_t *tag, 
     1381        yaml_mapping_style_t style) 
    16801382{ 
    16811383    struct { 
    1682         yaml_error_type_t error; 
    1683     } context; 
     1384        yaml_error_t error; 
     1385    } self; 
    16841386    yaml_mark_t mark = { 0, 0, 0 }; 
     1387    yaml_char_t *anchor_copy = NULL; 
    16851388    yaml_char_t *tag_copy = NULL; 
    16861389    struct { 
    1687         yaml_node_pair_t *start; 
    1688         yaml_node_pair_t *end; 
    1689         yaml_node_pair_t *top; 
    1690     } pairs = { NULL, NULL, NULL }; 
     1390        yaml_node_pair_t *list; 
     1391        size_t length; 
     1392        size_t capacity; 
     1393    } pairs = { NULL, 0, 0 }; 
    16911394    yaml_node_t node; 
    16921395 
    16931396    assert(document);   /* Non-NULL document object is expected. */ 
    1694  
    1695     if (!tag) { 
    1696         tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; 
    1697     } 
    1698  
    1699     if (!yaml_valid_utf8(tag, strlen((char *)tag))) goto error; 
     1397    assert(document->type); /* Initialized document is required. */ 
     1398    assert(tag);        /* Non-NULL tag is expected. */ 
     1399 
     1400    if (anchor) { 
     1401        anchor_copy = yaml_strdup(anchor); 
     1402        if (!anchor_copy) goto error; 
     1403    } 
     1404 
    17001405    tag_copy = yaml_strdup(tag); 
    17011406    if (!tag_copy) goto error; 
    17021407 
    1703     if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error; 
    1704  
    1705     MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, 
    1706             style, mark, mark); 
    1707     if (!PUSH(&context, document->nodes, node)) goto error; 
    1708  
    1709     return document->nodes.top - document->nodes.start; 
     1408    if (!STACK_INIT(&self, pairs, INITIAL_STACK_CAPACITY)) goto error; 
     1409 
     1410    MAPPING_NODE_INIT(node, anchor_copy, tag_copy, 
     1411            pairs.list, pairs.length, pairs.capacity, style, mark, mark); 
     1412    if (!PUSH(&self, document->nodes, node)) goto error; 
     1413 
     1414    if (node_id) { 
     1415        *node_id = document->nodes.length-1; 
     1416    } 
     1417 
     1418    return 1; 
    17101419 
    17111420error: 
    1712     STACK_DEL(&context, pairs); 
     1421    STACK_DEL(&self, pairs); 
     1422    yaml_free(anchor_copy); 
    17131423    yaml_free(tag_copy); 
    17141424 
     
    17221432YAML_DECLARE(int) 
    17231433yaml_document_append_sequence_item(yaml_document_t *document, 
    1724         int sequence, int item) 
     1434        int sequence_id, int item_id) 
    17251435{ 
    17261436    struct { 
    1727         yaml_error_type_t error; 
    1728     } context; 
     1437        yaml_error_t error; 
     1438    } self; 
    17291439 
    17301440    assert(document);       /* Non-NULL document is required. */ 
    1731     assert(sequence > 0 
    1732             && document->nodes.start + sequence <= document->nodes.top); 
     1441    assert(document->type); /* Initialized document is expected. */ 
     1442 
     1443    if (sequence_id) { 
     1444        sequence_id += document->nodes.length; 
     1445    } 
     1446    if (item_id) { 
     1447        item_id += document->nodes.length; 
     1448    } 
     1449 
     1450    assert(sequence_id >= 0 && sequence_id < document->nodes.length); 
    17331451                            /* Valid sequence id is required. */ 
    1734     assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); 
    1735                             /* A sequence node is required. */ 
    1736     assert(item > 0 && document->nodes.start + item <= document->nodes.top); 
     1452    assert(item_id >= 0 && item_id < document->nodes.length); 
    17371453                            /* Valid item id is required. */ 
    1738  
    1739     if (!PUSH(&context, 
    1740                 document->nodes.start[sequence-1].data.sequence.items, item)) 
     1454    assert(document->nodes.list[sequence_id].type == YAML_SEQUENCE_NODE); 
     1455                            /* A sequence node is expected. */ 
     1456 
     1457    if (!PUSH(&self, 
     1458                document->nodes.list[sequence_id].data.sequence.items, item_id)) 
    17411459        return 0; 
    17421460 
     
    17501468YAML_DECLARE(int) 
    17511469yaml_document_append_mapping_pair(yaml_document_t *document, 
    1752         int mapping, int key, int value) 
     1470        int mapping_id, int key_id, int value_id) 
    17531471{ 
    17541472    struct { 
    1755         yaml_error_type_t error; 
    1756     } context; 
    1757     yaml_node_pair_t pair = { key, value }; 
     1473        yaml_error_t error; 
     1474    } self; 
     1475    yaml_node_pair_t pair = { key_id, value_id }; 
    17581476 
    17591477    assert(document);       /* Non-NULL document is required. */ 
    1760     assert(mapping > 0 
    1761             && document->nodes.start + mapping <= document->nodes.top); 
     1478    assert(document->type); /* Initialized document is expected. */ 
     1479 
     1480    if (mapping_id < 0) { 
     1481        mapping_id += document->nodes.length; 
     1482    } 
     1483    if (key_id < 0) { 
     1484        key_id += document->nodes.length; 
     1485    } 
     1486    if (value_id < 0) { 
     1487        value_id += document->nodes.length; 
     1488    } 
     1489 
     1490    assert(mapping_id >= 0 && mapping_id < document->nodes.length); 
    17621491                            /* Valid mapping id is required. */ 
    1763     assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); 
    1764                             /* A mapping node is required. */ 
    1765     assert(key > 0 && document->nodes.start + key <= document->nodes.top); 
     1492    assert(key_id >= 0 && key_id < document->nodes.length); 
    17661493                            /* Valid key id is required. */ 
    1767     assert(value > 0 && document->nodes.start + value <= document->nodes.top); 
     1494    assert(value_id >= 0 && value_id < document->nodes.length); 
    17681495                            /* Valid value id is required. */ 
    1769  
    1770     if (!PUSH(&context, 
    1771                 document->nodes.start[mapping-1].data.mapping.pairs, pair)) 
    1772         return 0; 
    1773  
    1774     return 1; 
    1775 } 
    1776  
    1777 #endif 
    1778  
     1496    assert(document->nodes.list[mapping_id].type == YAML_MAPPING_NODE); 
     1497                            /* A mapping node is expected. */ 
     1498 
     1499    if (!PUSH(&self, 
     1500                document->nodes.list[mapping_id].data.mapping.pairs, pair)) 
     1501        return 0; 
     1502 
     1503    return 1; 
     1504} 
     1505 
     1506/* 
     1507 * Ensure that the node is a `!!null` SCALAR node. 
     1508 */ 
     1509 
     1510YAML_DECLARE(int) 
     1511yaml_document_get_null_node(yaml_document_t *document, int node_id) 
     1512{ 
     1513    yaml_node_t *node; 
     1514    yaml_char_t *scalar; 
     1515 
     1516    assert(document);       /* Non-NULL document is required. */ 
     1517    assert(document->type); /* Initialized document is expected. */ 
     1518 
     1519    if (node_id < 0) { 
     1520        node_id += document->nodes.length; 
     1521    } 
     1522 
     1523    assert(node_id >= 0 && node_id < document->nodes.length); 
     1524                            /* Valid node id is required. */ 
     1525 
     1526    node = document->nodes.list + node_id; 
     1527 
     1528    if (node->type != YAML_SCALAR_NODE) 
     1529        return 0; 
     1530 
     1531    if (strcmp(node->tag, YAML_NULL_TAG)) 
     1532        return 0; 
     1533 
     1534    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1535        return 0; 
     1536 
     1537    scalar = node->data.scalar.value; 
     1538 
     1539    if (!strcmp(scalar, "") || !strcmp(scalar, "~") || !strcmp(scalar, "null") 
     1540            || !strcmp(scalar, "Null") || !strcmp(scalar, "NULL")) 
     1541        return 1; 
     1542 
     1543    return 0; 
     1544} 
     1545 
     1546/* 
     1547 * Ensure that the node is a `!!bool` SCALAR node. 
     1548 */ 
     1549 
     1550YAML_DECLARE(int) 
     1551yaml_document_get_bool_node(yaml_document_t *document, int node_id, int *value) 
     1552{ 
     1553    yaml_node_t *node; 
     1554    yaml_char_t *scalar; 
     1555 
     1556    assert(document);       /* Non-NULL document is required. */ 
     1557    assert(document->type); /* Initialized document is expected. */ 
     1558 
     1559    if (node_id < 0) { 
     1560        node_id += document->nodes.length; 
     1561    } 
     1562 
     1563    assert(node_id >= 0 && node_id < document->nodes.length); 
     1564                            /* Valid node id is required. */ 
     1565 
     1566    node = document->nodes.list + node_id; 
     1567 
     1568    if (node->type != YAML_SCALAR_NODE) 
     1569        return 0; 
     1570 
     1571    if (strcmp(node->tag, YAML_BOOL_TAG)) 
     1572        return 0; 
     1573 
     1574    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1575        return 0; 
     1576 
     1577    scalar = node->data.scalar.value; 
     1578 
     1579    if (!strcmp(scalar, "yes") || !strcmp(scalar, "Yes") || !strcmp(scalar, "YES") || 
     1580            !strcmp(scalar, "true") || !strcmp(scalar, "True") || !strcmp(scalar, "TRUE") || 
     1581            !strcmp(scalar, "on") || !strcmp(scalar, "On") || !strcmp(scalar, "ON")) { 
     1582        if (value) { 
     1583            *value = 1; 
     1584        } 
     1585        return 1; 
     1586    } 
     1587 
     1588    if (!strcmp(scalar, "no") || !strcmp(scalar, "No") || !strcmp(scalar, "NO") || 
     1589            !strcmp(scalar, "false") || !strcmp(scalar, "False") || !strcmp(scalar, "FALSE") || 
     1590            !strcmp(scalar, "off") || !strcmp(scalar, "Off") || !strcmp(scalar, "OFF")) { 
     1591        if (value) { 
     1592            *value = 0; 
     1593        } 
     1594        return 1; 
     1595    } 
     1596 
     1597    return 0; 
     1598} 
     1599 
     1600/* 
     1601 * Ensure that the node is a `!!str` SCALAR node. 
     1602 */ 
     1603 
     1604YAML_DECLARE(int) 
     1605yaml_document_get_str_node(yaml_document_t *document, int node_id, 
     1606        char **value) 
     1607{ 
     1608    yaml_node_t *node; 
     1609 
     1610    assert(document);       /* Non-NULL document is required. */ 
     1611    assert(document->type); /* Initialized document is expected. */ 
     1612 
     1613    if (node_id < 0) { 
     1614        node_id += document->nodes.length; 
     1615    } 
     1616 
     1617    assert(node_id >= 0 && node_id < document->nodes.length); 
     1618                            /* Valid node id is required. */ 
     1619 
     1620    node = document->nodes.list + node_id; 
     1621 
     1622    if (node->type != YAML_SCALAR_NODE) 
     1623        return 0; 
     1624 
     1625    if (strcmp(node->tag, YAML_STR_TAG)) 
     1626        return 0; 
     1627 
     1628    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1629        return 0; 
     1630 
     1631    if (value) { 
     1632        *value = node->data.scalar.value; 
     1633    } 
     1634 
     1635    return 1; 
     1636} 
     1637 
     1638/* 
     1639 * Ensure that the node is an `!!int` SCALAR node. 
     1640 */ 
     1641 
     1642YAML_DECLARE(int) 
     1643yaml_document_get_int_node(yaml_document_t *document, int node_id, 
     1644        long *value) 
     1645{ 
     1646    yaml_node_t *node; 
     1647    yaml_char_t *scalar; 
     1648    char *tail; 
     1649    long integer; 
     1650    int old_errno = errno, new_errno; 
     1651 
     1652    assert(document);       /* Non-NULL document is required. */ 
     1653    assert(document->type); /* Initialized document is expected. */ 
     1654 
     1655    if (node_id < 0) { 
     1656        node_id += document->nodes.length; 
     1657    } 
     1658 
     1659    assert(node_id >= 0 && node_id < document->nodes.length); 
     1660                            /* Valid node id is required. */ 
     1661 
     1662    node = document->nodes.list + node_id; 
     1663 
     1664    if (node->type != YAML_SCALAR_NODE) 
     1665        return 0; 
     1666 
     1667    if (strcmp(node->tag, YAML_INT_TAG)) 
     1668        return 0; 
     1669 
     1670    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1671        return 0; 
     1672 
     1673    if (!node->data.scalar.length) 
     1674        return 0; 
     1675 
     1676    scalar = node->data.scalar.value; 
     1677 
     1678    errno = 0; 
     1679 
     1680    integer = strtol((char *)scalar, &tail, 0); 
     1681 
     1682    new_errno = errno; 
     1683    errno = old_errno; 
     1684 
     1685    if (new_errno || *tail) { 
     1686        return 0; 
     1687    } 
     1688 
     1689    if (value) { 
     1690        *value = integer; 
     1691    } 
     1692 
     1693    return 1; 
     1694} 
     1695 
     1696/* 
     1697 * Ensure that the node is a `!!float` SCALAR node. 
     1698 */ 
     1699 
     1700YAML_DECLARE(int) 
     1701yaml_document_get_float_node(yaml_document_t *document, int node_id, 
     1702        double *value) 
     1703{ 
     1704    yaml_node_t *node; 
     1705    yaml_char_t *scalar; 
     1706    char buffer[128]; 
     1707    char *pointer; 
     1708    char *tail; 
     1709    double real; 
     1710    int old_errno = errno, new_errno; 
     1711    char decimal_point = localeconv()->decimal_point[0]; 
     1712 
     1713    assert(document);       /* Non-NULL document is required. */ 
     1714    assert(document->type); /* Initialized document is expected. */ 
     1715 
     1716    if (node_id < 0) { 
     1717        node_id += document->nodes.length; 
     1718    } 
     1719 
     1720    assert(node_id >= 0 && node_id < document->nodes.length); 
     1721                            /* Valid node id is required. */ 
     1722 
     1723    node = document->nodes.list + node_id; 
     1724 
     1725    if (node->type != YAML_SCALAR_NODE) 
     1726        return 0; 
     1727 
     1728    if (strcmp(node->tag, YAML_FLOAT_TAG) && strcmp(node->tag, YAML_INT_TAG)) 
     1729        return 0; 
     1730 
     1731    if (node->data.scalar.length != strlen(node->data.scalar.value)) 
     1732        return 0; 
     1733 
     1734    if (!node->data.scalar.length) 
     1735        return 0; 
     1736 
     1737    scalar = node->data.scalar.value; 
     1738 
     1739    if (!strcmp(scalar, ".nan") || !strcmp(scalar, ".NaN") || !strcmp(scalar, ".NAN")) { 
     1740        if (value) { 
     1741            *value = 0.0/0.0; 
     1742        } 
     1743        return 1; 
     1744    } 
     1745 
     1746    if (!strcmp(scalar, ".inf") || !strcmp(scalar, ".Inf") || !strcmp(scalar, ".INF") || 
     1747            !strcmp(scalar, "+.inf") || !strcmp(scalar, "+.Inf") || !strcmp(scalar, "+.INF")) { 
     1748        if (value) { 
     1749            *value = 1.0/0.0; 
     1750        } 
     1751        return 1; 
     1752    } 
     1753 
     1754    if (!strcmp(scalar, "-.inf") || !strcmp(scalar, "-.Inf") || !strcmp(scalar, "-.INF")) { 
     1755        if (value) { 
     1756            *value = -1.0/0.0; 
     1757        } 
     1758        return 1; 
     1759    } 
     1760 
     1761    if (strlen(scalar) >= sizeof(buffer)) 
     1762        return 0; 
     1763 
     1764    strcpy(buffer, (const char *)scalar); 
     1765 
     1766    /* Replace a locale-dependent decimal point with a dot. */ 
     1767 
     1768    for (pointer = buffer; *pointer; pointer++) { 
     1769        if (*pointer == decimal_point) { 
     1770            *pointer = '.'; 
     1771            break; 
     1772        } 
     1773    } 
     1774 
     1775    errno = 0; 
     1776 
     1777    real = strtod(buffer, &tail); 
     1778 
     1779    new_errno = errno; 
     1780    errno = old_errno; 
     1781 
     1782    if (new_errno || *tail) { 
     1783        return 0; 
     1784    } 
     1785 
     1786    if (value) { 
     1787        *value = real; 
     1788    } 
     1789 
     1790    return 1; 
     1791} 
     1792 
     1793/* 
     1794 * Ensure that the node is a `!!seq` SEQUENCE node. 
     1795 */ 
     1796 
     1797YAML_DECLARE(int) 
     1798yaml_document_get_seq_node(yaml_document_t *document, int node_id, 
     1799        yaml_node_item_t **items, size_t *length) 
     1800{ 
     1801    yaml_node_t *node; 
     1802 
     1803    assert(document);       /* Non-NULL document is required. */ 
     1804    assert(document->type); /* Initialized document is expected. */ 
     1805 
     1806    assert((items && length) || (!items && !length)); 
     1807                /* items and length must be equal to NULL simultaneously. */ 
     1808 
     1809    if (node_id < 0) { 
     1810        node_id += document->nodes.length; 
     1811    } 
     1812 
     1813    assert(node_id >= 0 && node_id < document->nodes.length); 
     1814                            /* Valid node id is required. */ 
     1815 
     1816    node = document->nodes.list + node_id; 
     1817 
     1818    if (node->type != YAML_SEQUENCE_NODE) 
     1819        return 0; 
     1820 
     1821    if (strcmp(node->tag, YAML_SEQ_TAG)) 
     1822        return 0; 
     1823 
     1824    if (items && length) { 
     1825        *items = node->data.sequence.items.list; 
     1826        *length = node->data.sequence.items.length; 
     1827    } 
     1828 
     1829    return 1; 
     1830} 
     1831 
     1832/* 
     1833 * Ensure that the node is a `!!map` MAPPING node. 
     1834 */ 
     1835 
     1836YAML_DECLARE(int) 
     1837yaml_document_get_map_node(yaml_document_t *document, int node_id, 
     1838        yaml_node_pair_t **pairs, size_t *length) 
     1839{ 
     1840    yaml_node_t *node; 
     1841 
     1842    assert(document);       /* Non-NULL document is required. */ 
     1843    assert(document->type); /* Initialized document is expected. */ 
     1844 
     1845    assert((pairs && length) || (!pairs && !length)); 
     1846                /* pairs and length must be equal to NULL simultaneously. */ 
     1847 
     1848    if (node_id < 0) { 
     1849        node_id += document->nodes.length; 
     1850    } 
     1851 
     1852    assert(node_id >= 0 && node_id < document->nodes.length); 
     1853                            /* Valid node id is required. */ 
     1854 
     1855    node = document->nodes.list + node_id; 
     1856 
     1857    if (node->type != YAML_MAPPING_NODE) 
     1858        return 0; 
     1859 
     1860    if (strcmp(node->tag, YAML_MAP_TAG)) 
     1861        return 0; 
     1862 
     1863    if (pairs && length) { 
     1864        *pairs = node->data.mapping.pairs.list; 
     1865        *length = node->data.mapping.pairs.length; 
     1866    } 
     1867 
     1868    return 1; 
     1869} 
     1870 
     1871/* 
     1872 * Add a `!!null` SCALAR node. 
     1873 */ 
     1874 
     1875YAML_DECLARE(int) 
     1876yaml_document_add_null_node(yaml_document_t *document, int *node_id) 
     1877{ 
     1878    return yaml_document_add_scalar(document, node_id, NULL, 
     1879            YAML_NULL_TAG, "null", -1, YAML_ANY_SCALAR_STYLE); 
     1880} 
     1881 
     1882/* 
     1883 * Add a `!!bool` SCALAR node. 
     1884 */ 
     1885 
     1886YAML_DECLARE(int) 
     1887yaml_document_add_bool_node(yaml_document_t *document, int *node_id, 
     1888        int value) 
     1889{ 
     1890    return yaml_document_add_scalar(document, node_id, NULL, YAML_BOOL_TAG, 
     1891            (value ? "true" : "false"), -1, YAML_ANY_SCALAR_STYLE); 
     1892} 
     1893 
     1894/* 
     1895 * Add a `!!str` SCALAR node. 
     1896 */ 
     1897 
     1898YAML_DECLARE(int) 
     1899yaml_document_add_str_node(yaml_document_t *document, int *node_id, 
     1900        const char *value) 
     1901{ 
     1902    return yaml_document_add_scalar(document, node_id, NULL, YAML_STR_TAG, 
     1903            (const yaml_char_t *) value, -1, YAML_ANY_SCALAR_STYLE); 
     1904} 
     1905 
     1906/* 
     1907 * Add an `!!int` SCALAR node. 
     1908 */ 
     1909 
     1910YAML_DECLARE(int) 
     1911yaml_document_add_int_node(yaml_document_t *document, int *node_id, 
     1912        long value) 
     1913{ 
     1914    char buffer[128];   /* 128 bytes should be enough for everybody. */ 
     1915    int length; 
     1916 
     1917    length = snprintf(buffer, sizeof(buffer), "%ld", value); 
     1918    if (length < 0 || length >= sizeof(buffer)) return 0; 
     1919 
     1920    return yaml_document_add_scalar(document, node_id, NULL, YAML_INT_TAG, 
     1921            (const yaml_char_t *) buffer, -1, YAML_ANY_SCALAR_STYLE); 
     1922} 
     1923 
     1924/* 
     1925 * Add a `!!float` SCALAR node. 
     1926 */ 
     1927 
     1928YAML_DECLARE(int) 
     1929yaml_document_add_float_node(yaml_document_t *document, int *node_id, 
     1930        double value) 
     1931{ 
     1932    char buffer[128];   /* 128 bytes should be enough for everybody. */ 
     1933    char *pointer; 
     1934    int length; 
     1935    char decimal_point = *localeconv()->decimal_point; 
     1936 
     1937    length = snprintf(buffer, sizeof(buffer), "%.12g", value); 
     1938        /* .12 is a reasonable precision; it is used by str(float) in Python. */ 
     1939    if (length < 0 || length >= sizeof(buffer)-3) return 0; 
     1940 
     1941    /* Replace a locale-dependent decimal point with a dot. */ 
     1942 
     1943    for (pointer = buffer; *pointer; pointer++) { 
     1944        if (*pointer == decimal_point) { 
     1945            *pointer = '.'; 
     1946            break; 
     1947        } 
     1948    } 
     1949 
     1950    /* Check if the formatted number contains a decimal dot. */ 
     1951 
     1952    for (pointer = buffer; *pointer; pointer++) { 
     1953        if (*pointer != '+' && *pointer != '-' && !isdigit(*pointer)) { 
     1954            break; 
     1955        } 
     1956    } 
     1957 
     1958    /* Add .0 at the end of the buffer if needed. */ 
     1959 
     1960    if (!*pointer) { 
     1961        *(pointer++) = '.'; 
     1962        *(pointer++) = '0'; 
     1963        *(pointer++) = '\0'; 
     1964    } 
     1965 
     1966    return yaml_document_add_scalar(document, node_id, NULL, YAML_FLOAT_TAG, 
     1967            (const yaml_char_t *) buffer, -1, YAML_ANY_SCALAR_STYLE); 
     1968} 
     1969 
     1970/* 
     1971 * Add a `!!seq` SEQUENCE node. 
     1972 */ 
     1973 
     1974YAML_DECLARE(int) 
     1975yaml_document_add_seq_node(yaml_document_t *document, int *node_id) 
     1976{ 
     1977    return yaml_document_add_sequence(document, node_id, NULL, 
     1978            YAML_SEQ_TAG, YAML_ANY_SEQUENCE_STYLE); 
     1979} 
     1980 
     1981/* 
     1982 * Add a `!!map` MAPPING node. 
     1983 */ 
     1984 
     1985YAML_DECLARE(int) 
     1986yaml_document_add_map_node(yaml_document_t *document, int *node_id) 
     1987{ 
     1988    return yaml_document_add_mapping(document, node_id, NULL, 
     1989            YAML_MAP_TAG, YAML_ANY_MAPPING_STYLE); 
     1990} 
     1991 
     1992/***************************************************************************** 
     1993 * Standard Handlers 
     1994 *****************************************************************************/ 
     1995 
     1996/* 
     1997 * Standard string read handler. 
     1998 */ 
     1999 
     2000static int 
     2001yaml_string_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
     2002        size_t *length) 
     2003{ 
     2004    yaml_standard_reader_data_t *data = untyped_data; 
     2005 
     2006    if (data->string.pointer == data->string.length) { 
     2007        *length = 0; 
     2008        return 1; 
     2009    } 
     2010 
     2011    if (capacity > (size_t)(data->string.length - data->string.pointer)) { 
     2012        capacity = data->string.length - data->string.pointer; 
     2013    } 
     2014 
     2015    memcpy(buffer, data->string.buffer + data->string.pointer, capacity); 
     2016    data->string.pointer += capacity; 
     2017    *length = capacity; 
     2018    return 1; 
     2019} 
     2020 
     2021/* 
     2022 * Standard file read handler. 
     2023 */ 
     2024 
     2025static int 
     2026yaml_file_reader(void *untyped_data, unsigned char *buffer, size_t capacity, 
     2027        size_t *length) 
     2028{ 
     2029    yaml_standard_reader_data_t *data = untyped_data; 
     2030 
     2031    *length = fread(buffer, 1, capacity, data->file); 
     2032    return !ferror(data->file); 
     2033} 
     2034 
     2035/* 
     2036 * String write handler. 
     2037 */ 
     2038 
     2039static int 
     2040yaml_string_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
     2041{ 
     2042    yaml_standard_writer_data_t *data = untyped_data; 
     2043    int result = 1; 
     2044 
     2045    if (data->string.capacity - data->string.pointer < length) { 
     2046        length = data->string.capacity - data->string.pointer; 
     2047        result = 0; 
     2048    } 
     2049 
     2050    memcpy(data->string.buffer + data->string.pointer, buffer, length); 
     2051    data->string.pointer += length; 
     2052    *data->length += length; 
     2053 
     2054    return result; 
     2055} 
     2056 
     2057/* 
     2058 * File write handler. 
     2059 */ 
     2060 
     2061static int 
     2062yaml_file_writer(void *untyped_data, const unsigned char *buffer, size_t length) 
     2063{ 
     2064    yaml_standard_writer_data_t *data = untyped_data; 
     2065 
     2066    return (fwrite(buffer, 1, length, data->file) == length); 
     2067} 
     2068 
     2069/* 
     2070 * Standard resolve handler. 
     2071 * 
     2072 * The standard resolve handler recognizes the following scalars: 
     2073 * 
     2074 * - `!!null`: `~|null|Null|NULL|<empty string>`. 
     2075 * 
     2076 * - `!!bool`: `yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE| 
     2077 *              on|On|ON|off|Off|OFF` 
     2078 * 
     2079 * - `!!int`: any string that is successfully converted using `strtol()`. 
     2080 * 
     2081 * - `!!float`: `[+-]?(.inf|.Inf|.INF)|.nan|.NaN|.NAN` or any string 
     2082 *   successfully converted using `strtod()`. 
     2083 */ 
     2084 
     2085static int 
     2086yaml_standard_resolver(void *untyped_data, yaml_incomplete_node_t *node, 
     2087        const yaml_char_t **tag) 
     2088{ 
     2089    if (node->type == YAML_SCALAR_NODE && node->data.scalar.is_plain) 
     2090    { 
     2091        yaml_char_t *value = node->data.scalar.value; 
     2092        char buffer[128]; 
     2093        char *pointer; 
     2094        char *tail; 
     2095        int old_errno, new_errno; 
     2096        char decimal_point = *(localeconv()->decimal_point); 
     2097 
     2098        if (strlen(value) != node->data.scalar.length) { 
     2099            *tag = YAML_STR_TAG; 
     2100            return 1; 
     2101        } 
     2102 
     2103        if (!strcmp(value, "") || !strcmp(value, "~") || 
     2104                !strcmp(value, "null") || !strcmp(value, "Null") || !strcmp(value, "NULL")) { 
     2105            *tag = YAML_NULL_TAG; 
     2106            return 1; 
     2107        } 
     2108 
     2109        if (!strcmp(value, "yes") || !strcmp(value, "Yes") || !strcmp(value, "YES") || 
     2110                !strcmp(value, "no") || !strcmp(value, "No") || !strcmp(value, "NO") || 
     2111                !strcmp(value, "true") || !strcmp(value, "True") || !strcmp(value, "TRUE") || 
     2112                !strcmp(value, "false") || !strcmp(value, "False") || !strcmp(value, "FALSE") || 
     2113                !strcmp(value, "on") || !strcmp(value, "On") || !strcmp(value, "ON") || 
     2114                !strcmp(value, "off") || !strcmp(value, "Off") || !strcmp(value, "OFF")) { 
     2115            *tag = YAML_BOOL_TAG; 
     2116            return 1; 
     2117        } 
     2118 
     2119        if (!strcmp(value, ".inf") || !strcmp(value, ".Inf") || !strcmp(value, ".INF") || 
     2120                !strcmp(value, "+.inf") || !strcmp(value, "+.Inf") || !strcmp(value, "+.INF") || 
     2121                !strcmp(value, "-.inf") || !strcmp(value, "-.Inf") || !strcmp(value, "-.INF") || 
     2122                !strcmp(value, ".nan") || !strcmp(value, ".NaN") || !strcmp(value, ".NAN")) { 
     2123            *tag = YAML_FLOAT_TAG; 
     2124            return 1; 
     2125        } 
     2126 
     2127        old_errno = errno; 
     2128        errno = 0; 
     2129 
     2130        strtol((const char *)value, &tail, 0); 
     2131 
     2132        new_errno = errno; 
     2133        errno = old_errno; 
     2134 
     2135        if (!new_errno && !*tail) { 
     2136            *tag = YAML_INT_TAG; 
     2137            return 1; 
     2138        } 
     2139 
     2140        if (strlen(value) < sizeof(buffer)) 
     2141        { 
     2142            strcpy(buffer, (const char *)value); 
     2143 
     2144            /* Replace a locale-dependent decimal point with a dot. */ 
     2145 
     2146            for (pointer = buffer; *pointer; pointer++) { 
     2147                if (*pointer == decimal_point) { 
     2148                    *pointer = '.'; 
     2149                    break; 
     2150                } 
     2151            } 
     2152 
     2153            old_errno = errno; 
     2154            errno = 0; 
     2155 
     2156            strtod(buffer, &tail); 
     2157 
     2158            new_errno = errno; 
     2159            errno = old_errno; 
     2160 
     2161            if (!new_errno && !*tail) { 
     2162                *tag = YAML_FLOAT_TAG; 
     2163                return 1; 
     2164            } 
     2165        } 
     2166    } 
     2167 
     2168    switch (node->type) 
     2169    { 
     2170        case YAML_SCALAR_NODE: 
     2171            *tag = YAML_STR_TAG; 
     2172            break; 
     2173        case YAML_SEQUENCE_NODE: 
     2174            *tag = YAML_SEQ_TAG; 
     2175            break; 
     2176        case YAML_MAPPING_NODE: 
     2177            *tag = YAML_MAP_TAG; 
     2178            break; 
     2179        default: 
     2180            assert(0);      /* Should never happen. */ 
     2181    } 
     2182 
     2183    return 1; 
     2184} 
     2185 
     2186 
     2187/***************************************************************************** 
     2188 * Parser API 
     2189 *****************************************************************************/ 
     2190 
     2191/* 
     2192 * Allocate a new parser object. 
     2193 */ 
     2194 
     2195YAML_DECLARE(yaml_parser_t *) 
     2196yaml_parser_new(void) 
     2197{ 
     2198    yaml_parser_t *parser = yaml_malloc(sizeof(yaml_parser_t)); 
     2199 
     2200    if (!parser) 
     2201        return NULL; 
     2202 
     2203    memset(parser, 0, sizeof(yaml_parser_t)); 
     2204 
     2205    if (!IOSTRING_INIT(parser, parser->raw_input, RAW_INPUT_BUFFER_CAPACITY)) 
     2206        goto error; 
     2207    if (!IOSTRING_INIT(parser, parser->input, INPUT_BUFFER_CAPACITY)) 
     2208        goto error; 
     2209    if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_CAPACITY)) 
     2210        goto error; 
     2211    if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_CAPACITY)) 
     2212        goto error; 
     2213    if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_CAPACITY)) 
     2214        goto error; 
     2215    if (!STACK_INIT(parser, parser->states, INITIAL_STACK_CAPACITY)) 
     2216        goto error; 
     2217    if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_CAPACITY)) 
     2218        goto error; 
     2219    if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_CAPACITY)) 
     2220        goto error; 
     2221 
     2222    return parser; 
     2223 
     2224error: 
     2225    yaml_parser_delete(parser); 
     2226 
     2227    return NULL; 
     2228} 
     2229 
     2230/* 
     2231 * Deallocate a parser object. 
     2232 */ 
     2233 
     2234YAML_DECLARE(void) 
     2235yaml_parser_delete(yaml_parser_t *parser) 
     2236{ 
     2237    assert(parser); /* Non-NULL parser object expected. */ 
     2238 
     2239    IOSTRING_DEL(parser, parser->raw_input); 
     2240    IOSTRING_DEL(parser, parser->input); 
     2241    while (!QUEUE_EMPTY(parser, parser->tokens)) { 
     2242        yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
     2243    } 
     2244    QUEUE_DEL(parser, parser->tokens); 
     2245    STACK_DEL(parser, parser->indents); 
     2246    STACK_DEL(parser, parser->simple_keys); 
     2247    STACK_DEL(parser, parser->states); 
     2248    STACK_DEL(parser, parser->marks); 
     2249    while (!STACK_EMPTY(parser, parser->tag_directives)) { 
     2250        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
     2251        yaml_free(tag_directive.handle); 
     2252        yaml_free(tag_directive.prefix); 
     2253    } 
     2254    STACK_DEL(parser, parser->tag_directives); 
     2255 
     2256    memset(parser, 0, sizeof(yaml_parser_t)); 
     2257 
     2258    yaml_free(parser); 
     2259} 
     2260 
     2261/* 
     2262 * Reset a parser object. 
     2263 */ 
     2264 
     2265YAML_DECLARE(void) 
     2266yaml_parser_reset(yaml_parser_t *parser) 
     2267{ 
     2268    yaml_parser_t copy = *parser; 
     2269 
     2270    assert(parser); /* Non-NULL parser object expected. */ 
     2271 
     2272    while (!QUEUE_EMPTY(parser, parser->tokens)) { 
     2273        yaml_token_destroy(&DEQUEUE(parser, parser->tokens)); 
     2274    } 
     2275    while (!STACK_EMPTY(parser, parser->tag_directives)) { 
     2276        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 
     2277        yaml_free(tag_directive.handle); 
     2278        yaml_free(tag_directive.prefix); 
     2279    } 
     2280 
     2281    memset(parser, 0, sizeof(yaml_parser_t)); 
     2282 
     2283    IOSTRING_SET(parser, parser->raw_input, 
     2284            copy.raw_input.buffer, copy.raw_input.capacity); 
     2285    IOSTRING_SET(parser, parser->input, 
     2286            copy.input.buffer, copy.input.capacity); 
     2287    QUEUE_SET(parser, parser->tokens, 
     2288            copy.tokens.list, copy.tokens.capacity); 
     2289    STACK_SET(parser, parser->indents, 
     2290            copy.indents.list, copy.indents.capacity); 
     2291    STACK_SET(parser, parser->simple_keys, 
     2292            copy.simple_keys.list, copy.simple_keys.capacity); 
     2293    STACK_SET(parser, parser->states, 
     2294            copy.states.list, copy.states.capacity); 
     2295    STACK_SET(parser, parser->marks, 
     2296            copy.marks.list, copy.marks.capacity); 
     2297    STACK_SET(parse, parser->tag_directives, 
     2298            copy.tag_directives.list, copy.tag_directives.capacity); 
     2299} 
     2300 
     2301/* 
     2302 * Get the current parser error. 
     2303 */ 
     2304 
     2305YAML_DECLARE(yaml_error_t *) 
     2306yaml_parser_get_error(yaml_parser_t *parser) 
     2307{ 
     2308    assert(parser); /* Non-NULL parser object expected. */ 
     2309 
     2310    return &(parser->error); 
     2311} 
     2312 
     2313/* 
     2314 * Set a string input. 
     2315 */ 
     2316 
     2317YAML_DECLARE(void) 
     2318yaml_parser_set_string_reader(yaml_parser_t *parser, 
     2319        const unsigned char *buffer, size_t length) 
     2320{ 
     2321    assert(parser); /* Non-NULL parser object expected. */ 
     2322    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2323    assert(buffer); /* Non-NULL input string expected. */ 
     2324 
     2325    parser->reader = yaml_string_reader; 
     2326    parser->reader_data = &(parser->standard_reader_data); 
     2327 
     2328    parser->standard_reader_data.string.buffer = buffer; 
     2329    parser->standard_reader_data.string.pointer = 0; 
     2330    parser->standard_reader_data.string.length = length; 
     2331} 
     2332 
     2333/* 
     2334 * Set a file input. 
     2335 */ 
     2336 
     2337YAML_DECLARE(void) 
     2338yaml_parser_set_file_reader(yaml_parser_t *parser, FILE *file) 
     2339{ 
     2340    assert(parser); /* Non-NULL parser object expected. */ 
     2341    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2342    assert(file);   /* Non-NULL file object expected. */ 
     2343 
     2344    parser->reader = yaml_file_reader; 
     2345    parser->reader_data = &(parser->standard_reader_data); 
     2346 
     2347    parser->standard_reader_data.file = file; 
     2348} 
     2349 
     2350/* 
     2351 * Set a generic input. 
     2352 */ 
     2353 
     2354YAML_DECLARE(void) 
     2355yaml_parser_set_reader(yaml_parser_t *parser, 
     2356        yaml_reader_t *reader, void *data) 
     2357{ 
     2358    assert(parser); /* Non-NULL parser object expected. */ 
     2359    assert(!parser->reader);    /* You can set the input handler only once. */ 
     2360    assert(reader); /* Non-NULL read handler expected. */ 
     2361 
     2362    parser->reader = reader; 
     2363    parser->reader_data = data; 
     2364} 
     2365 
     2366/* 
     2367 * Set a standard tag resolver. 
     2368 */ 
     2369 
     2370YAML_DECLARE(void) 
     2371yaml_parser_set_standard_resolver(yaml_parser_t *parser) 
     2372{ 
     2373    assert(parser); /* Non-NULL parser object expected. */ 
     2374    assert(!parser->resolver);  /* You can set the tag resolver only once. */ 
     2375 
     2376    parser->resolver = yaml_standard_resolver; 
     2377    parser->resolver_data = NULL; 
     2378} 
     2379 
     2380/* 
     2381 * Set a generic tag resolver. 
     2382 */ 
     2383 
     2384YAML_DECLARE(void) 
     2385yaml_parser_set_resolver(yaml_parser_t *parser, 
     2386        yaml_resolver_t *resolver, void *data) 
     2387{ 
     2388    assert(parser);     /* Non-NULL parser object expected. */ 
     2389    assert(!parser->resolver);  /* You can set the tag resolver only once. */ 
     2390    assert(resolver);   /* Non-NULL resolver is expected. */ 
     2391 
     2392    parser->resolver = resolver; 
     2393    parser->resolver_data = data; 
     2394} 
     2395 
     2396/* 
     2397 * Set the source encoding. 
     2398 */ 
     2399 
     2400YAML_DECLARE(void) 
     2401yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) 
     2402{ 
     2403    assert(parser); /* Non-NULL parser object expected. */ 
     2404    assert(!parser->encoding);  /* Encoding is already set or detected. */ 
     2405 
     2406    parser->encoding = encoding; 
     2407} 
     2408 
     2409/***************************************************************************** 
     2410 * Parser API 
     2411 *****************************************************************************/ 
     2412 
     2413/* 
     2414 * Create a new emitter object. 
     2415 */ 
     2416 
     2417YAML_DECLARE(yaml_emitter_t *) 
     2418yaml_emitter_new(void) 
     2419{ 
     2420    yaml_emitter_t *emitter = yaml_malloc(sizeof(yaml_emitter_t)); 
     2421 
     2422    if (!emitter) 
     2423        return NULL; 
     2424 
     2425    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2426    if (!IOSTRING_INIT(emitter, emitter->output, OUTPUT_BUFFER_CAPACITY)) 
     2427        goto error; 
     2428    if (!IOSTRING_INIT(emitter, emitter->raw_output, RAW_OUTPUT_BUFFER_CAPACITY)) 
     2429        goto error; 
     2430    if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_CAPACITY)) 
     2431        goto error; 
     2432    if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_CAPACITY)) 
     2433        goto error; 
     2434    if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_CAPACITY)) 
     2435        goto error; 
     2436    if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_CAPACITY)) 
     2437        goto error; 
     2438 
     2439    return emitter; 
     2440 
     2441error: 
     2442    yaml_emitter_delete(emitter); 
     2443 
     2444    return NULL; 
     2445} 
     2446 
     2447/* 
     2448 * Destroy an emitter object. 
     2449 */ 
     2450 
     2451YAML_DECLARE(void) 
     2452yaml_emitter_delete(yaml_emitter_t *emitter) 
     2453{ 
     2454    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2455 
     2456    IOSTRING_DEL(emitter, emitter->output); 
     2457    IOSTRING_DEL(emitter, emitter->raw_output); 
     2458    STACK_DEL(emitter, emitter->states); 
     2459    while (!QUEUE_EMPTY(emitter, emitter->events)) { 
     2460        yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
     2461    } 
     2462    QUEUE_DEL(emitter, emitter->events); 
     2463    STACK_DEL(emitter, emitter->indents); 
     2464    while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
     2465        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
     2466        yaml_free(tag_directive.handle); 
     2467        yaml_free(tag_directive.prefix); 
     2468    } 
     2469    STACK_DEL(emitter, emitter->tag_directives); 
     2470    yaml_free(emitter->anchors); 
     2471 
     2472    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2473    yaml_free(emitter); 
     2474} 
     2475 
     2476/* 
     2477 * Reset an emitter object. 
     2478 */ 
     2479 
     2480YAML_DECLARE(void) 
     2481yaml_emitter_reset(yaml_emitter_t *emitter) 
     2482{ 
     2483    yaml_emitter_t copy = *emitter; 
     2484 
     2485    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2486 
     2487    while (!QUEUE_EMPTY(emitter, emitter->events)) { 
     2488        yaml_event_destroy(&DEQUEUE(emitter, emitter->events)); 
     2489    } 
     2490    while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
     2491        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
     2492        yaml_free(tag_directive.handle); 
     2493        yaml_free(tag_directive.prefix); 
     2494    } 
     2495 
     2496    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     2497 
     2498    IOSTRING_SET(emitter, emitter->output, 
     2499            copy.output.buffer, copy.output.capacity); 
     2500    IOSTRING_SET(emitter, emitter->raw_output, 
     2501            copy.raw_output.buffer, copy.raw_output.capacity); 
     2502    STACK_SET(emitter, emitter->states, 
     2503            copy.states.list, copy.states.capacity); 
     2504    QUEUE_SET(emitter, emitter->events, 
     2505            copy.events.list, copy.events.capacity); 
     2506    STACK_SET(emitter, emitter->indents, 
     2507            copy.indents.list, copy.indents.capacity); 
     2508    STACK_SET(emitter, emitter->tag_directives, 
     2509            copy.tag_directives.list, copy.tag_directives.capacity); 
     2510} 
     2511 
     2512/* 
     2513 * Get the current emitter error. 
     2514 */ 
     2515 
     2516YAML_DECLARE(yaml_error_t *) 
     2517yaml_emitter_get_error(yaml_emitter_t *emitter) 
     2518{ 
     2519    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2520 
     2521    return &(emitter->error); 
     2522} 
     2523 
     2524/* 
     2525 * Set a string output. 
     2526 */ 
     2527 
     2528YAML_DECLARE(void) 
     2529yaml_emitter_set_string_writer(yaml_emitter_t *emitter, 
     2530        unsigned char *buffer, size_t capacity, size_t *length) 
     2531{ 
     2532    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2533    assert(!emitter->writer);   /* You can set the output only once. */ 
     2534    assert(buffer);     /* Non-NULL output string expected. */ 
     2535 
     2536    emitter->writer = yaml_string_writer; 
     2537    emitter->writer_data = &(emitter->standard_writer_data); 
     2538 
     2539    emitter->standard_writer_data.string.buffer = buffer; 
     2540    emitter->standard_writer_data.string.pointer = 0; 
     2541    emitter->standard_writer_data.string.capacity = capacity; 
     2542    emitter->standard_writer_data.length = length; 
     2543 
     2544    *length = 0; 
     2545} 
     2546 
     2547/* 
     2548 * Set a file output. 
     2549 */ 
     2550 
     2551YAML_DECLARE(void) 
     2552yaml_emitter_set_file_writer(yaml_emitter_t *emitter, FILE *file) 
     2553{ 
     2554    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2555    assert(!emitter->writer);   /* You can set the output only once. */ 
     2556    assert(file);       /* Non-NULL file object expected. */ 
     2557 
     2558    emitter->writer = yaml_string_writer; 
     2559    emitter->writer_data = &(emitter->standard_writer_data); 
     2560 
     2561    emitter->standard_writer_data.file = file; 
     2562} 
     2563 
     2564/* 
     2565 * Set a generic output handler. 
     2566 */ 
     2567 
     2568YAML_DECLARE(void) 
     2569yaml_emitter_set_writer(yaml_emitter_t *emitter, 
     2570        yaml_writer_t *writer, void *data) 
     2571{ 
     2572    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2573    assert(!emitter->writer);   /* You can set the output only once. */ 
     2574    assert(writer); /* Non-NULL handler object expected. */ 
     2575 
     2576    emitter->writer = writer; 
     2577    emitter->writer_data = data; 
     2578} 
     2579 
     2580/* 
     2581 * Set a standard tag resolver. 
     2582 */ 
     2583 
     2584YAML_DECLARE(void) 
     2585yaml_emitter_set_standard_resolver(yaml_emitter_t *emitter) 
     2586{ 
     2587    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2588    assert(!emitter->resolver); /* You can set the tag resolver only once. */ 
     2589 
     2590    emitter->resolver = yaml_standard_resolver; 
     2591    emitter->resolver_data = NULL; 
     2592} 
     2593 
     2594/* 
     2595 * Set a generic tag resolver. 
     2596 */ 
     2597 
     2598YAML_DECLARE(void) 
     2599yaml_emitter_set_resolver(yaml_emitter_t *emitter, 
     2600        yaml_resolver_t *resolver, void *data) 
     2601{ 
     2602    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2603    assert(!emitter->resolver); /* You can set the tag resolver only once. */ 
     2604    assert(resolver);   /* Non-NULL resolver is expected. */ 
     2605 
     2606    emitter->resolver = resolver; 
     2607    emitter->resolver_data = data; 
     2608} 
     2609 
     2610/* 
     2611 * Set the output encoding. 
     2612 */ 
     2613 
     2614YAML_DECLARE(void) 
     2615yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) 
     2616{ 
     2617    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2618    assert(!emitter->encoding);     /* You can set encoding only once. */ 
     2619 
     2620    emitter->encoding = encoding; 
     2621} 
     2622 
     2623/* 
     2624 * Set the canonical output style. 
     2625 */ 
     2626 
     2627YAML_DECLARE(void) 
     2628yaml_emitter_set_canonical(yaml_emitter_t *emitter, int is_canonical) 
     2629{ 
     2630    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2631 
     2632    emitter->is_canonical = (is_canonical != 0); 
     2633} 
     2634 
     2635/* 
     2636 * Set the indentation increment. 
     2637 */ 
     2638 
     2639YAML_DECLARE(void) 
     2640yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) 
     2641{ 
     2642    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2643 
     2644    emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; 
     2645} 
     2646 
     2647/* 
     2648 * Set the preferred line width. 
     2649 */ 
     2650 
     2651YAML_DECLARE(void) 
     2652yaml_emitter_set_width(yaml_emitter_t *emitter, int width) 
     2653{ 
     2654    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2655 
     2656    emitter->best_width = (width >= 0) ? width : -1; 
     2657} 
     2658 
     2659/* 
     2660 * Set if unescaped non-ASCII characters are allowed. 
     2661 */ 
     2662 
     2663YAML_DECLARE(void) 
     2664yaml_emitter_set_unicode(yaml_emitter_t *emitter, int is_unicode) 
     2665{ 
     2666    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2667 
     2668    emitter->is_unicode = (is_unicode != 0); 
     2669} 
     2670 
     2671/* 
     2672 * Set the preferred line break character. 
     2673 */ 
     2674 
     2675YAML_DECLARE(void) 
     2676yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) 
     2677{ 
     2678    assert(emitter);    /* Non-NULL emitter object expected. */ 
     2679 
     2680    emitter->line_break = line_break; 
     2681} 
     2682