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