Changeset 208 for libyaml/trunk/src/api.c
- Timestamp:
- 07/21/06 09:50:32 (7 years ago)
- File:
-
- 1 edited
-
libyaml/trunk/src/api.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libyaml/trunk/src/api.c
r203 r208 1 1 2 #if HAVE_CONFIG_H 3 #include <config.h> 4 #endif 5 6 #include <yaml.h> 7 8 #include <assert.h> 2 #include "yaml_private.h" 3 4 /* 5 * Get the library version. 6 */ 9 7 10 8 YAML_DECLARE(const char *) … … 13 11 return YAML_VERSION_STRING; 14 12 } 13 14 /* 15 * Get the library version numbers. 16 */ 15 17 16 18 YAML_DECLARE(void) … … 53 55 54 56 /* 57 * Duplicate a string. 58 */ 59 60 YAML_DECLARE(char *) 61 yaml_strdup(const char *str) 62 { 63 return strdup(str); 64 } 65 66 /* 67 * Extend a string. 68 */ 69 70 YAML_DECLARE(int) 71 yaml_string_extend(yaml_char_t **start, 72 yaml_char_t **pointer, yaml_char_t **end) 73 { 74 void *new_start = yaml_realloc(*start, (*end - *start)*2); 75 76 if (!new_start) return 0; 77 78 memset(new_start + (*end - *start), 0, *end - *start); 79 80 *pointer = new_start + (*pointer - *start); 81 *end = new_start + (*end - *start)*2; 82 *start = new_start; 83 84 return 1; 85 } 86 87 /* 88 * Append a string B to a string A. 89 */ 90 91 YAML_DECLARE(int) 92 yaml_string_join( 93 yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, 94 yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end) 95 { 96 if (*b_start == *b_pointer) 97 return 1; 98 99 while (*a_end - *a_pointer <= *b_pointer - *b_start) { 100 if (!yaml_string_extend(a_start, a_pointer, a_end)) 101 return 0; 102 } 103 104 memcpy(*a_pointer, *b_start, *b_pointer - *b_start); 105 *a_pointer += *b_pointer - *b_start; 106 107 return 1; 108 } 109 110 /* 111 * Extend a stack. 112 */ 113 114 YAML_DECLARE(int) 115 yaml_stack_extend(void **start, void **top, void **end) 116 { 117 void *new_start = yaml_realloc(*start, (*end - *start)*2); 118 119 if (!new_start) return 0; 120 121 *top = new_start + (*top - *start); 122 *end = new_start + (*end - *start)*2; 123 *start = new_start; 124 125 return 1; 126 } 127 128 /* 129 * Extend or move a queue. 130 */ 131 132 YAML_DECLARE(int) 133 yaml_queue_extend(void **start, void **head, void **tail, void **end) 134 { 135 /* Check if we need to resize the queue. */ 136 137 if (*start == *head && *tail == *end) { 138 void *new_start = yaml_realloc(*start, (*end - *start)*2); 139 140 if (!new_start) return 0; 141 142 *head = new_start + (*head - *start); 143 *tail = new_start + (*tail - *start); 144 *end = new_start + (*end - *start)*2; 145 *start = new_start; 146 } 147 148 /* Check if we need to move the queue at the beginning of the buffer. */ 149 150 if (*tail == *end) { 151 if (*head != *tail) { 152 memmove(*start, *head, *tail - *head); 153 } 154 *tail -= *head - *start; 155 *head = *start; 156 } 157 158 return 1; 159 } 160 161 162 /* 55 163 * Create a new parser object. 56 164 */ 57 165 58 YAML_DECLARE(yaml_parser_t *) 59 yaml_parser_new(void) 60 { 61 yaml_parser_t *parser; 62 63 /* Allocate the parser structure. */ 64 65 parser = yaml_malloc(sizeof(yaml_parser_t)); 66 if (!parser) goto error; 166 YAML_DECLARE(int) 167 yaml_parser_initialize(yaml_parser_t *parser) 168 { 169 assert(parser); /* Non-NULL parser object expected. */ 67 170 68 171 memset(parser, 0, sizeof(yaml_parser_t)); 69 70 /* Allocate the raw buffer. */ 71 72 parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE); 73 if (!parser->raw_buffer) goto error; 74 memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE); 75 76 parser->raw_pointer = parser->raw_buffer; 77 parser->raw_unread = 0; 78 79 /* Allocate the character buffer. */ 80 81 parser->buffer = yaml_malloc(YAML_BUFFER_SIZE); 82 if (!parser->buffer) goto error; 83 memset(parser->buffer, 0, YAML_BUFFER_SIZE); 84 85 parser->buffer_end = parser->buffer; 86 parser->pointer = parser->buffer; 87 parser->unread = 0; 88 89 /* Allocate the tokens queue. */ 90 91 parser->tokens = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_token_t *)); 92 if (!parser->tokens) goto error; 93 memset(parser->tokens, 0, YAML_DEFAULT_SIZE*sizeof(yaml_token_t *)); 94 95 parser->tokens_size = YAML_DEFAULT_SIZE; 96 parser->tokens_head = 0; 97 parser->tokens_tail = 0; 98 parser->tokens_parsed = 0; 99 100 /* Allocate the indents stack. */ 101 102 parser->indents = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(int)); 103 if (!parser->indents) goto error; 104 memset(parser->indents, 0, YAML_DEFAULT_SIZE*sizeof(int)); 105 106 parser->indents_size = YAML_DEFAULT_SIZE; 107 parser->indents_length = 0; 108 109 /* Allocate the stack of potential simple keys. */ 110 111 parser->simple_keys = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_simple_key_t *)); 112 if (!parser->simple_keys) goto error; 113 memset(parser->simple_keys, 0, YAML_DEFAULT_SIZE*sizeof(yaml_simple_key_t *)); 114 115 parser->simple_keys_size = YAML_DEFAULT_SIZE; 116 117 /* Allocate the stack of parser states. */ 118 119 parser->states = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_parser_state_t)); 120 if (!parser->states) goto error; 121 memset(parser->states, 0, YAML_DEFAULT_SIZE*sizeof(yaml_parser_state_t)); 122 123 parser->states_size = YAML_DEFAULT_SIZE; 124 125 /* Set the initial state. */ 126 127 parser->state = YAML_PARSE_STREAM_START_STATE; 128 129 /* Allocate the stack of marks. */ 130 131 parser->marks = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_mark_t)); 132 if (!parser->marks) goto error; 133 memset(parser->marks, 0, YAML_DEFAULT_SIZE*sizeof(yaml_mark_t)); 134 135 parser->marks_size = YAML_DEFAULT_SIZE; 136 137 /* Allocate the list of TAG directives. */ 138 139 parser->tag_directives = yaml_malloc(YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *)); 140 if (!parser->tag_directives) goto error; 141 memset(parser->tag_directives, 0, YAML_DEFAULT_SIZE*sizeof(yaml_tag_directive_t *)); 142 143 parser->tag_directives_size = YAML_DEFAULT_SIZE; 144 145 /* Done. */ 146 147 return parser; 148 149 /* On error, free allocated buffers. */ 172 if (!BUFFER_INIT(parser, parser->raw_buffer, RAW_BUFFER_SIZE)) 173 goto error; 174 if (!BUFFER_INIT(parser, parser->buffer, BUFFER_SIZE)) 175 goto error; 176 if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE)) 177 goto error; 178 if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE)) 179 goto error; 180 if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE)) 181 goto error; 182 if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE)) 183 goto error; 184 if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE)) 185 goto error; 186 if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE)) 187 goto error; 188 189 return 1; 150 190 151 191 error: 152 192 153 if (!parser) return NULL; 154 155 yaml_free(parser->tag_directives); 156 yaml_free(parser->marks); 157 yaml_free(parser->states); 158 yaml_free(parser->simple_keys); 159 yaml_free(parser->indents); 160 yaml_free(parser->tokens); 161 yaml_free(parser->buffer); 162 yaml_free(parser->raw_buffer); 163 164 yaml_free(parser); 165 166 return NULL; 193 BUFFER_DEL(parser, parser->raw_buffer); 194 BUFFER_DEL(parser, parser->buffer); 195 QUEUE_DEL(parser, parser->tokens); 196 STACK_DEL(parser, parser->indents); 197 STACK_DEL(parser, parser->simple_keys); 198 STACK_DEL(parser, parser->states); 199 STACK_DEL(parser, parser->marks); 200 STACK_DEL(parser, parser->tag_directives); 201 202 return 0; 167 203 } 168 204 … … 176 212 assert(parser); /* Non-NULL parser object expected. */ 177 213 178 /*yaml_free(parser->tag_directives);*/ 179 yaml_free(parser->marks); 180 yaml_free(parser->states); 181 yaml_free(parser->simple_keys); 182 yaml_free(parser->indents); 183 yaml_free(parser->tokens); 184 yaml_free(parser->buffer); 185 yaml_free(parser->raw_buffer); 214 BUFFER_DEL(parser, parser->raw_buffer); 215 BUFFER_DEL(parser, parser->buffer); 216 while (!QUEUE_EMPTY(parser, parser->tokens)) { 217 yaml_token_delete(&DEQUEUE(parser, parser->tokens)); 218 } 219 QUEUE_DEL(parser, parser->tokens); 220 STACK_DEL(parser, parser->indents); 221 STACK_DEL(parser, parser->simple_keys); 222 STACK_DEL(parser, parser->states); 223 STACK_DEL(parser, parser->marks); 224 while (!STACK_EMPTY(parser, parser->tag_directives)) { 225 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); 226 yaml_free(tag_directive.handle); 227 yaml_free(tag_directive.prefix); 228 } 229 STACK_DEL(parser, parser->tag_directives); 186 230 187 231 memset(parser, 0, sizeof(yaml_parser_t)); 188 189 yaml_free(parser);190 232 } 191 233 … … 198 240 size_t *size_read) 199 241 { 200 yaml_ string_input_t *input= data;201 202 if ( input->current == input->end) {242 yaml_parser_t *parser = data; 243 244 if (parser->input.string.current == parser->input.string.end) { 203 245 *size_read = 0; 204 246 return 1; 205 247 } 206 248 207 if (size > ( input->end - input->current)) {208 size = input->end - input->current;209 } 210 211 memcpy(buffer, input->current, size);212 input->current += size;249 if (size > (parser->input.string.end - parser->input.string.current)) { 250 size = parser->input.string.end - parser->input.string.current; 251 } 252 253 memcpy(buffer, parser->input.string.current, size); 254 parser->input.string.current += size; 213 255 *size_read = size; 214 256 return 1; … … 223 265 size_t *size_read) 224 266 { 225 *size_read = fread(buffer, 1, size, (FILE *)data); 226 return !ferror((FILE *)data); 267 yaml_parser_t *parser = data; 268 269 *size_read = fread(buffer, 1, size, parser->input.file); 270 return !ferror(parser->input.file); 227 271 } 228 272 … … 239 283 assert(input); /* Non-NULL input string expected. */ 240 284 241 parser->string_input.start = input;242 parser->string_input.current = input;243 parser->string_input.end = input+size;244 245 285 parser->read_handler = yaml_string_read_handler; 246 parser->read_handler_data = &parser->string_input; 286 parser->read_handler_data = parser; 287 288 parser->input.string.start = input; 289 parser->input.string.current = input; 290 parser->input.string.end = input+size; 247 291 } 248 292 … … 259 303 260 304 parser->read_handler = yaml_file_read_handler; 261 parser->read_handler_data = file; 305 parser->read_handler_data = parser; 306 307 parser->input.file = file; 262 308 } 263 309 … … 289 335 290 336 parser->encoding = encoding; 291 }292 293 /*294 * Create a token.295 */296 297 YAML_DECLARE(yaml_token_t *)298 yaml_token_new(yaml_token_type_t type,299 yaml_mark_t start_mark, yaml_mark_t end_mark)300 {301 yaml_token_t *token = yaml_malloc(sizeof(yaml_token_t));302 303 if (!token) return NULL;304 305 memset(token, 0, sizeof(yaml_token_t));306 307 token->type = type;308 token->start_mark = start_mark;309 token->end_mark = end_mark;310 311 return token;312 }313 314 /*315 * Create a STREAM-START token.316 */317 318 YAML_DECLARE(yaml_token_t *)319 yaml_stream_start_token_new(yaml_encoding_t encoding,320 yaml_mark_t start_mark, yaml_mark_t end_mark)321 {322 yaml_token_t *token = yaml_token_new(YAML_STREAM_START_TOKEN,323 start_mark, end_mark);324 325 if (!token) return NULL;326 327 token->data.stream_start.encoding = encoding;328 329 return token;330 }331 332 /*333 * Create a STREAM-END token.334 */335 336 YAML_DECLARE(yaml_token_t *)337 yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)338 {339 yaml_token_t *token = yaml_token_new(YAML_STREAM_END_TOKEN,340 start_mark, end_mark);341 342 if (!token) return NULL;343 344 return token;345 }346 347 /*348 * Create a VERSION-DIRECTIVE token.349 */350 351 YAML_DECLARE(yaml_token_t *)352 yaml_version_directive_token_new(int major, int minor,353 yaml_mark_t start_mark, yaml_mark_t end_mark)354 {355 yaml_token_t *token = yaml_token_new(YAML_VERSION_DIRECTIVE_TOKEN,356 start_mark, end_mark);357 358 if (!token) return NULL;359 360 token->data.version_directive.major = major;361 token->data.version_directive.minor = minor;362 363 return token;364 }365 366 /*367 * Create a TAG-DIRECTIVE token.368 */369 370 YAML_DECLARE(yaml_token_t *)371 yaml_tag_directive_token_new(yaml_char_t *handle, yaml_char_t *prefix,372 yaml_mark_t start_mark, yaml_mark_t end_mark)373 {374 yaml_token_t *token = yaml_token_new(YAML_TAG_DIRECTIVE_TOKEN,375 start_mark, end_mark);376 377 if (!token) return NULL;378 379 token->data.tag_directive.handle = handle;380 token->data.tag_directive.prefix = prefix;381 382 return token;383 }384 385 /*386 * Create an ALIAS token.387 */388 389 YAML_DECLARE(yaml_token_t *)390 yaml_alias_token_new(yaml_char_t *anchor,391 yaml_mark_t start_mark, yaml_mark_t end_mark)392 {393 yaml_token_t *token = yaml_token_new(YAML_ALIAS_TOKEN,394 start_mark, end_mark);395 396 if (!token) return NULL;397 398 token->data.alias.value = anchor;399 400 return token;401 }402 403 /*404 * Create an ANCHOR token.405 */406 407 YAML_DECLARE(yaml_token_t *)408 yaml_anchor_token_new(yaml_char_t *anchor,409 yaml_mark_t start_mark, yaml_mark_t end_mark)410 {411 yaml_token_t *token = yaml_token_new(YAML_ANCHOR_TOKEN,412 start_mark, end_mark);413 414 if (!token) return NULL;415 416 token->data.anchor.value = anchor;417 418 return token;419 }420 421 /*422 * Create a TAG token.423 */424 425 YAML_DECLARE(yaml_token_t *)426 yaml_tag_token_new(yaml_char_t *handle, yaml_char_t *suffix,427 yaml_mark_t start_mark, yaml_mark_t end_mark)428 {429 yaml_token_t *token = yaml_token_new(YAML_TAG_TOKEN,430 start_mark, end_mark);431 432 if (!token) return NULL;433 434 token->data.tag.handle = handle;435 token->data.tag.suffix = suffix;436 437 return token;438 }439 440 /*441 * Create a SCALAR token.442 */443 444 YAML_DECLARE(yaml_token_t *)445 yaml_scalar_token_new(yaml_char_t *value, size_t length,446 yaml_scalar_style_t style,447 yaml_mark_t start_mark, yaml_mark_t end_mark)448 {449 yaml_token_t *token = yaml_token_new(YAML_SCALAR_TOKEN,450 start_mark, end_mark);451 452 if (!token) return NULL;453 454 token->data.scalar.value = value;455 token->data.scalar.length = length;456 token->data.scalar.style = style;457 458 return token;459 337 } 460 338 … … 494 372 495 373 memset(token, 0, sizeof(yaml_token_t)); 496 497 yaml_free(token);498 }499 500 /*501 * Create an event.502 */503 504 static yaml_event_t *505 yaml_event_new(yaml_event_type_t type,506 yaml_mark_t start_mark, yaml_mark_t end_mark)507 {508 yaml_event_t *event = yaml_malloc(sizeof(yaml_event_t));509 510 if (!event) return NULL;511 512 memset(event, 0, sizeof(yaml_event_t));513 514 event->type = type;515 event->start_mark = start_mark;516 event->end_mark = end_mark;517 518 return event;519 }520 521 /*522 * Create a STREAM-START event.523 */524 525 YAML_DECLARE(yaml_event_t *)526 yaml_stream_start_event_new(yaml_encoding_t encoding,527 yaml_mark_t start_mark, yaml_mark_t end_mark)528 {529 yaml_event_t *event = yaml_event_new(YAML_STREAM_START_EVENT,530 start_mark, end_mark);531 532 if (!event) return NULL;533 534 event->data.stream_start.encoding = encoding;535 536 return event;537 }538 539 /*540 * Create a STREAM-END event.541 */542 543 YAML_DECLARE(yaml_event_t *)544 yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)545 {546 return yaml_event_new(YAML_STREAM_END_EVENT, start_mark, end_mark);547 }548 549 /*550 * Create a DOCUMENT-START event.551 */552 553 YAML_DECLARE(yaml_event_t *)554 yaml_document_start_event_new(yaml_version_directive_t *version_directive,555 yaml_tag_directive_t **tag_directives, int implicit,556 yaml_mark_t start_mark, yaml_mark_t end_mark)557 {558 yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_START_EVENT,559 start_mark, end_mark);560 561 if (!event) return NULL;562 563 event->data.document_start.version_directive = version_directive;564 event->data.document_start.tag_directives = tag_directives;565 event->data.document_start.implicit = implicit;566 567 return event;568 }569 570 /*571 * Create a DOCUMENT-END event.572 */573 574 YAML_DECLARE(yaml_event_t *)575 yaml_document_end_event_new(int implicit,576 yaml_mark_t start_mark, yaml_mark_t end_mark)577 {578 yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_END_EVENT,579 start_mark, end_mark);580 581 if (!event) return NULL;582 583 event->data.document_end.implicit = implicit;584 585 return event;586 }587 588 /*589 * Create an ALIAS event.590 */591 592 YAML_DECLARE(yaml_event_t *)593 yaml_alias_event_new(yaml_char_t *anchor,594 yaml_mark_t start_mark, yaml_mark_t end_mark)595 {596 yaml_event_t *event = yaml_event_new(YAML_ALIAS_EVENT,597 start_mark, end_mark);598 599 if (!event) return NULL;600 601 event->data.alias.anchor = anchor;602 603 return event;604 }605 606 /*607 * Create a SCALAR event.608 */609 610 YAML_DECLARE(yaml_event_t *)611 yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag,612 yaml_char_t *value, size_t length,613 int plain_implicit, int quoted_implicit,614 yaml_scalar_style_t style,615 yaml_mark_t start_mark, yaml_mark_t end_mark)616 {617 yaml_event_t *event = yaml_event_new(YAML_SCALAR_EVENT,618 start_mark, end_mark);619 620 if (!event) return NULL;621 622 event->data.scalar.anchor = anchor;623 event->data.scalar.tag = tag;624 event->data.scalar.value = value;625 event->data.scalar.length = length;626 event->data.scalar.plain_implicit = plain_implicit;627 event->data.scalar.quoted_implicit = quoted_implicit;628 event->data.scalar.style = style;629 630 return event;631 }632 633 /*634 * Create a SEQUENCE-START event.635 */636 637 YAML_DECLARE(yaml_event_t *)638 yaml_sequence_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,639 int implicit, yaml_sequence_style_t style,640 yaml_mark_t start_mark, yaml_mark_t end_mark)641 {642 yaml_event_t *event = yaml_event_new(YAML_SEQUENCE_START_EVENT,643 start_mark, end_mark);644 645 if (!event) return NULL;646 647 event->data.sequence_start.anchor = anchor;648 event->data.sequence_start.tag = tag;649 event->data.sequence_start.implicit = implicit;650 event->data.sequence_start.style = style;651 652 return event;653 }654 655 /*656 * Create a SEQUENCE-END event.657 */658 659 YAML_DECLARE(yaml_event_t *)660 yaml_sequence_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)661 {662 return yaml_event_new(YAML_SEQUENCE_END_EVENT, start_mark, end_mark);663 }664 665 /*666 * Create a MAPPING-START event.667 */668 669 YAML_DECLARE(yaml_event_t *)670 yaml_mapping_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,671 int implicit, yaml_mapping_style_t style,672 yaml_mark_t start_mark, yaml_mark_t end_mark)673 {674 yaml_event_t *event = yaml_event_new(YAML_MAPPING_START_EVENT,675 start_mark, end_mark);676 677 if (!event) return NULL;678 679 event->data.mapping_start.anchor = anchor;680 event->data.mapping_start.tag = tag;681 event->data.mapping_start.implicit = implicit;682 event->data.mapping_start.style = style;683 684 return event;685 }686 687 /*688 * Create a MAPPING-END event.689 */690 691 YAML_DECLARE(yaml_event_t *)692 yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)693 {694 return yaml_event_new(YAML_MAPPING_END_EVENT, start_mark, end_mark);695 374 } 696 375 … … 702 381 yaml_event_delete(yaml_event_t *event) 703 382 { 383 yaml_tag_directive_t *tag_directive; 384 704 385 assert(event); /* Non-NULL event object expected. */ 705 386 … … 707 388 { 708 389 case YAML_DOCUMENT_START_EVENT: 709 /*yaml_free(event->data.document_start.version_directive); 710 if (event->data.document_start.tag_directives) { 711 yaml_tag_directive_t **tag_directive; 712 for (tag_directive = event->data.document_start.tag_directives; 713 *tag_directive; tag_directive++) { 714 yaml_free((*tag_directive)->handle); 715 yaml_free((*tag_directive)->prefix); 716 yaml_free(*tag_directive); 717 } 718 yaml_free(event->data.document_start.tag_directives); 719 }*/ 390 yaml_free(event->data.document_start.version_directive); 391 for (tag_directive = event->data.document_start.tag_directives.start; 392 tag_directive != event->data.document_start.tag_directives.end; 393 tag_directive++) { 394 yaml_free(tag_directive->handle); 395 yaml_free(tag_directive->prefix); 396 } 397 yaml_free(event->data.document_start.tag_directives.start); 720 398 break; 721 399 … … 742 420 743 421 memset(event, 0, sizeof(yaml_event_t)); 744 745 yaml_free(event); 746 } 747 422 } 423
Note: See TracChangeset
for help on using the changeset viewer.
