source: libyaml/trunk/src/api.c @ 200

Revision 200, 16.0 KB checked in by xi, 8 years ago (diff)

Move yaml/yaml.h to yaml.h and merge version.c to api.c.

RevLine 
[178]1
2#if HAVE_CONFIG_H
3#include <config.h>
4#endif
5
[200]6#include <yaml.h>
[178]7
[179]8#include <assert.h>
9
[200]10YAML_DECLARE(const char *)
11yaml_get_version_string(void)
12{
13    return YAML_VERSION_STRING;
14}
15
16YAML_DECLARE(void)
17yaml_get_version(int *major, int *minor, int *patch)
18{
19    *major = YAML_VERSION_MAJOR;
20    *minor = YAML_VERSION_MINOR;
21    *patch = YAML_VERSION_PATCH;
22}
23
[178]24/*
[179]25 * Allocate a dynamic memory block.
[178]26 */
27
[183]28YAML_DECLARE(void *)
[179]29yaml_malloc(size_t size)
30{
31    return malloc(size ? size : 1);
32}
33
34/*
35 * Reallocate a dynamic memory block.
36 */
37
[183]38YAML_DECLARE(void *)
[179]39yaml_realloc(void *ptr, size_t size)
40{
41    return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
42}
43
44/*
45 * Free a dynamic memory block.
46 */
47
[183]48YAML_DECLARE(void)
[179]49yaml_free(void *ptr)
50{
51    if (ptr) free(ptr);
52}
53
54/*
55 * Create a new parser object.
56 */
57
[183]58YAML_DECLARE(yaml_parser_t *)
[178]59yaml_parser_new(void)
60{
61    yaml_parser_t *parser;
62
[180]63    /* Allocate the parser structure. */
64
[179]65    parser = yaml_malloc(sizeof(yaml_parser_t));
[185]66    if (!parser) goto error;
[178]67
68    memset(parser, 0, sizeof(yaml_parser_t));
69
[180]70    /* Allocate the raw buffer. */
71
72    parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
[185]73    if (!parser->raw_buffer) goto error;
74    memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE);
75
[180]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);
[185]82    if (!parser->buffer) goto error;
83    memset(parser->buffer, 0, YAML_BUFFER_SIZE);
84
[180]85    parser->buffer_end = parser->buffer;
86    parser->pointer = parser->buffer;
87    parser->unread = 0;
88
[185]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    /* Done. */
118
[178]119    return parser;
[185]120
121    /* On error, free allocated buffers. */
122
123error:
124
125    if (!parser) return NULL;
126
127    yaml_free(parser->simple_keys);
128    yaml_free(parser->indents);
129    yaml_free(parser->tokens);
130    yaml_free(parser->buffer);
131    yaml_free(parser->raw_buffer);
132
133    yaml_free(parser);
134
135    return NULL;
[178]136}
137
138/*
139 * Destroy a parser object.
140 */
141
[183]142YAML_DECLARE(void)
[178]143yaml_parser_delete(yaml_parser_t *parser)
144{
[179]145    assert(parser); /* Non-NULL parser object expected. */
146
[185]147    yaml_free(parser->simple_keys);
148    yaml_free(parser->indents);
149    yaml_free(parser->tokens);
[179]150    yaml_free(parser->buffer);
[180]151    yaml_free(parser->raw_buffer);
[179]152
153    memset(parser, 0, sizeof(yaml_parser_t));
154
155    yaml_free(parser);
[178]156}
157
[179]158/*
[180]159 * String read handler.
[179]160 */
161
162static int
163yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
164        size_t *size_read)
165{
[180]166    yaml_string_input_t *input = data;
167
168    if (input->current == input->end) {
169        *size_read = 0;
170        return 1;
171    }
172
173    if (size > (input->end - input->current)) {
174        size = input->end - input->current;
175    }
176
177    memcpy(buffer, input->current, size);
178    input->current += size;
179    *size_read = size;
[179]180    return 1;
181}
182
183/*
184 * File read handler.
185 */
186
187static int
188yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
189        size_t *size_read)
190{
[180]191    *size_read = fread(buffer, 1, size, (FILE *)data);
192    return !ferror((FILE *)data);
[179]193}
194
195/*
196 * Set a string input.
197 */
198
[183]199YAML_DECLARE(void)
[179]200yaml_parser_set_input_string(yaml_parser_t *parser,
201        unsigned char *input, size_t size)
202{
203    assert(parser); /* Non-NULL parser object expected. */
[180]204    assert(!parser->read_handler);  /* You can set the source only once. */
[179]205    assert(input);  /* Non-NULL input string expected. */
206
[180]207    parser->string_input.start = input;
208    parser->string_input.current = input;
209    parser->string_input.end = input+size;
210
[179]211    parser->read_handler = yaml_string_read_handler;
[180]212    parser->read_handler_data = &parser->string_input;
[179]213}
214
215/*
216 * Set a file input.
217 */
218
[183]219YAML_DECLARE(void)
[179]220yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
221{
222    assert(parser); /* Non-NULL parser object expected. */
[180]223    assert(!parser->read_handler);  /* You can set the source only once. */
[179]224    assert(file);   /* Non-NULL file object expected. */
225
226    parser->read_handler = yaml_file_read_handler;
227    parser->read_handler_data = file;
228}
229
230/*
231 * Set a generic input.
232 */
233
[183]234YAML_DECLARE(void)
[179]235yaml_parser_set_input(yaml_parser_t *parser,
236        yaml_read_handler_t *handler, void *data)
237{
238    assert(parser); /* Non-NULL parser object expected. */
[180]239    assert(!parser->read_handler);  /* You can set the source only once. */
[179]240    assert(handler);    /* Non-NULL read handler expected. */
241
242    parser->read_handler = handler;
[180]243    parser->read_handler_data = data;
[179]244}
245
246/*
247 * Set the source encoding.
248 */
249
[183]250YAML_DECLARE(void)
[179]251yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
252{
253    assert(parser); /* Non-NULL parser object expected. */
254    assert(!parser->encoding); /* Encoding is already set or detected. */
255
256    parser->encoding = encoding;
257}
258
[183]259/*
260 * Create a token.
261 */
262
263YAML_DECLARE(yaml_token_t *)
264yaml_token_new(yaml_token_type_t type,
265        yaml_mark_t start_mark, yaml_mark_t end_mark)
266{
267    yaml_token_t *token = yaml_malloc(sizeof(yaml_token_t));
268
269    if (!token) return NULL;
270
271    memset(token, 0, sizeof(yaml_token_t));
272
273    token->type = type;
274    token->start_mark = start_mark;
275    token->end_mark = end_mark;
276
277    return token;
278}
279
280/*
281 * Create a STREAM-START token.
282 */
283
284YAML_DECLARE(yaml_token_t *)
[190]285yaml_stream_start_token_new(yaml_encoding_t encoding,
[183]286        yaml_mark_t start_mark, yaml_mark_t end_mark)
287{
288    yaml_token_t *token = yaml_token_new(YAML_STREAM_START_TOKEN,
289            start_mark, end_mark);
290
291    if (!token) return NULL;
292
[199]293    token->data.stream_start.encoding = encoding;
[183]294
295    return token;
296}
297
298/*
299 * Create a STREAM-END token.
300 */
301
302YAML_DECLARE(yaml_token_t *)
[190]303yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
[183]304{
305    yaml_token_t *token = yaml_token_new(YAML_STREAM_END_TOKEN,
306            start_mark, end_mark);
307
308    if (!token) return NULL;
309
310    return token;
311}
312
313/*
314 * Create a VERSION-DIRECTIVE token.
315 */
316
317YAML_DECLARE(yaml_token_t *)
318yaml_version_directive_token_new(int major, int minor,
319        yaml_mark_t start_mark, yaml_mark_t end_mark)
320{
321    yaml_token_t *token = yaml_token_new(YAML_VERSION_DIRECTIVE_TOKEN,
322            start_mark, end_mark);
323
324    if (!token) return NULL;
325
326    token->data.version_directive.major = major;
327    token->data.version_directive.minor = minor;
328
329    return token;
330}
331
332/*
333 * Create a TAG-DIRECTIVE token.
334 */
335
336YAML_DECLARE(yaml_token_t *)
337yaml_tag_directive_token_new(yaml_char_t *handle, yaml_char_t *prefix,
338        yaml_mark_t start_mark, yaml_mark_t end_mark)
339{
340    yaml_token_t *token = yaml_token_new(YAML_TAG_DIRECTIVE_TOKEN,
341            start_mark, end_mark);
342
343    if (!token) return NULL;
344
345    token->data.tag_directive.handle = handle;
346    token->data.tag_directive.prefix = prefix;
347
348    return token;
349}
350
351/*
352 * Create an ALIAS token.
353 */
354
355YAML_DECLARE(yaml_token_t *)
356yaml_alias_token_new(yaml_char_t *anchor,
357        yaml_mark_t start_mark, yaml_mark_t end_mark)
358{
359    yaml_token_t *token = yaml_token_new(YAML_ALIAS_TOKEN,
360            start_mark, end_mark);
361
362    if (!token) return NULL;
363
[199]364    token->data.alias.value = anchor;
[183]365
366    return token;
367}
368
369/*
370 * Create an ANCHOR token.
371 */
372
373YAML_DECLARE(yaml_token_t *)
374yaml_anchor_token_new(yaml_char_t *anchor,
375        yaml_mark_t start_mark, yaml_mark_t end_mark)
376{
377    yaml_token_t *token = yaml_token_new(YAML_ANCHOR_TOKEN,
378            start_mark, end_mark);
379
380    if (!token) return NULL;
381
[199]382    token->data.anchor.value = anchor;
[183]383
384    return token;
385}
386
387/*
388 * Create a TAG token.
389 */
390
391YAML_DECLARE(yaml_token_t *)
392yaml_tag_token_new(yaml_char_t *handle, yaml_char_t *suffix,
393        yaml_mark_t start_mark, yaml_mark_t end_mark)
394{
395    yaml_token_t *token = yaml_token_new(YAML_TAG_TOKEN,
396            start_mark, end_mark);
397
398    if (!token) return NULL;
399
400    token->data.tag.handle = handle;
401    token->data.tag.suffix = suffix;
402
403    return token;
404}
405
406/*
407 * Create a SCALAR token.
408 */
409
410YAML_DECLARE(yaml_token_t *)
411yaml_scalar_token_new(yaml_char_t *value, size_t length,
412        yaml_scalar_style_t style,
413        yaml_mark_t start_mark, yaml_mark_t end_mark)
414{
415    yaml_token_t *token = yaml_token_new(YAML_SCALAR_TOKEN,
416            start_mark, end_mark);
417
418    if (!token) return NULL;
419
420    token->data.scalar.value = value;
421    token->data.scalar.length = length;
422    token->data.scalar.style = style;
423
424    return token;
425}
426
427/*
428 * Destroy a token object.
429 */
430
431YAML_DECLARE(void)
432yaml_token_delete(yaml_token_t *token)
433{
434    assert(token);  /* Non-NULL token object expected. */
435
436    switch (token->type)
437    {
438        case YAML_TAG_DIRECTIVE_TOKEN:
439            yaml_free(token->data.tag_directive.handle);
440            yaml_free(token->data.tag_directive.prefix);
441            break;
442
443        case YAML_ALIAS_TOKEN:
[199]444            yaml_free(token->data.alias.value);
445            break;
446
[183]447        case YAML_ANCHOR_TOKEN:
[199]448            yaml_free(token->data.anchor.value);
[183]449            break;
450
451        case YAML_TAG_TOKEN:
452            yaml_free(token->data.tag.handle);
453            yaml_free(token->data.tag.suffix);
454            break;
455
456        case YAML_SCALAR_TOKEN:
457            yaml_free(token->data.scalar.value);
458            break;
459    }
460
461    memset(token, 0, sizeof(yaml_token_t));
462
463    yaml_free(token);
464}
465
[199]466/*
467 * Create an event.
468 */
469
470static yaml_event_t *
471yaml_event_new(yaml_event_type_t type,
472        yaml_mark_t start_mark, yaml_mark_t end_mark)
473{
474    yaml_event_t *event = yaml_malloc(sizeof(yaml_event_t));
475
476    if (!event) return NULL;
477
478    memset(event, 0, sizeof(yaml_event_t));
479
480    event->type = type;
481    event->start_mark = start_mark;
482    event->end_mark = end_mark;
483
484    return event;
485}
486
487/*
488 * Create a STREAM-START event.
489 */
490
491YAML_DECLARE(yaml_event_t *)
492yaml_stream_start_event_new(yaml_encoding_t encoding,
493        yaml_mark_t start_mark, yaml_mark_t end_mark)
494{
495    yaml_event_t *event = yaml_event_new(YAML_STREAM_START_EVENT,
496            start_mark, end_mark);
497
498    if (!event) return NULL;
499
500    event->data.stream_start.encoding = encoding;
501
502    return event;
503}
504
505/*
506 * Create a STREAM-END event.
507 */
508
509YAML_DECLARE(yaml_event_t *)
510yaml_stream_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
511{
512    return yaml_event_new(YAML_STREAM_END_EVENT, start_mark, end_mark);
513}
514
515/*
516 * Create a DOCUMENT-START event.
517 */
518
519YAML_DECLARE(yaml_event_t *)
520yaml_document_start_event_new(yaml_version_directive_t *version_directive,
521        yaml_tag_directive_t **tag_directives, int implicit,
522        yaml_mark_t start_mark, yaml_mark_t end_mark)
523{
524    yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_START_EVENT,
525            start_mark, end_mark);
526
527    if (!event) return NULL;
528
529    event->data.document_start.version_directive = version_directive;
530    event->data.document_start.tag_directives = tag_directives;
531    event->data.document_start.implicit = implicit;
532
533    return event;
534}
535
536/*
537 * Create a DOCUMENT-END event.
538 */
539
540YAML_DECLARE(yaml_event_t *)
541yaml_document_end_event_new(int implicit,
542        yaml_mark_t start_mark, yaml_mark_t end_mark)
543{
544    yaml_event_t *event = yaml_event_new(YAML_DOCUMENT_END_EVENT,
545            start_mark, end_mark);
546
547    if (!event) return NULL;
548
549    event->data.document_end.implicit = implicit;
550
551    return event;
552}
553
554/*
555 * Create an ALIAS event.
556 */
557
558YAML_DECLARE(yaml_event_t *)
559yaml_alias_event_new(yaml_char_t *anchor,
560        yaml_mark_t start_mark, yaml_mark_t end_mark)
561{
562    yaml_event_t *event = yaml_event_new(YAML_ALIAS_EVENT,
563            start_mark, end_mark);
564
565    if (!event) return NULL;
566
567    event->data.alias.anchor = anchor;
568
569    return event;
570}
571
572/*
573 * Create a SCALAR event.
574 */
575
576YAML_DECLARE(yaml_event_t *)
577yaml_scalar_event_new(yaml_char_t *anchor, yaml_char_t *tag,
578        yaml_char_t *value, size_t length,
579        int plain_implicit, int quoted_implicit,
580        yaml_scalar_style_t style,
581        yaml_mark_t start_mark, yaml_mark_t end_mark)
582{
583    yaml_event_t *event = yaml_event_new(YAML_SCALAR_EVENT,
584            start_mark, end_mark);
585
586    if (!event) return NULL;
587
588    event->data.scalar.anchor = anchor;
589    event->data.scalar.tag = tag;
590    event->data.scalar.value = value;
591    event->data.scalar.length = length;
592    event->data.scalar.plain_implicit = plain_implicit;
593    event->data.scalar.quoted_implicit = quoted_implicit;
594    event->data.scalar.style = style;
595
596    return event;
597}
598
599/*
600 * Create a SEQUENCE-START event.
601 */
602
603YAML_DECLARE(yaml_event_t *)
604yaml_sequence_start_new(yaml_char_t *anchor, yaml_char_t *tag,
605        int implicit, yaml_sequence_style_t style,
606        yaml_mark_t start_mark, yaml_mark_t end_mark)
607{
608    yaml_event_t *event = yaml_event_new(YAML_SEQUENCE_START_EVENT,
609            start_mark, end_mark);
610
611    if (!event) return NULL;
612
613    event->data.sequence_start.anchor = anchor;
614    event->data.sequence_start.tag = tag;
615    event->data.sequence_start.implicit = implicit;
616    event->data.sequence_start.style = style;
617
618    return event;
619}
620
621/*
622 * Create a SEQUENCE-END event.
623 */
624
625YAML_DECLARE(yaml_event_t *)
626yaml_sequence_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
627{
628    return yaml_event_new(YAML_SEQUENCE_END_EVENT, start_mark, end_mark);
629}
630
631/*
632 * Create a MAPPING-START event.
633 */
634
635YAML_DECLARE(yaml_event_t *)
636yaml_mapping_start_new(yaml_char_t *anchor, yaml_char_t *tag,
637        int implicit, yaml_mapping_style_t style,
638        yaml_mark_t start_mark, yaml_mark_t end_mark)
639{
640    yaml_event_t *event = yaml_event_new(YAML_MAPPING_START_EVENT,
641            start_mark, end_mark);
642
643    if (!event) return NULL;
644
645    event->data.mapping_start.anchor = anchor;
646    event->data.mapping_start.tag = tag;
647    event->data.mapping_start.implicit = implicit;
648    event->data.mapping_start.style = style;
649
650    return event;
651}
652
653/*
654 * Create a MAPPING-END event.
655 */
656
657YAML_DECLARE(yaml_event_t *)
658yaml_mapping_end_event_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
659{
660    return yaml_event_new(YAML_MAPPING_END_EVENT, start_mark, end_mark);
661}
662
663/*
664 * Destroy an event object.
665 */
666
667YAML_DECLARE(void)
668yaml_event_delete(yaml_event_t *event)
669{
670    assert(event);  /* Non-NULL event object expected. */
671
672    switch (event->type)
673    {
674        case YAML_DOCUMENT_START_EVENT:
675            yaml_free(event->data.document_start.version_directive);
676            if (event->data.document_start.tag_directives) {
677                yaml_tag_directive_t **tag_directive;
678                for (tag_directive = event->data.document_start.tag_directives;
679                        *tag_directive; tag_directive++) {
680                    yaml_free((*tag_directive)->handle);
681                    yaml_free((*tag_directive)->prefix);
682                    yaml_free(*tag_directive);
683                }
684                yaml_free(event->data.document_start.tag_directives);
685            }
686            break;
687
688        case YAML_ALIAS_EVENT:
689            yaml_free(event->data.alias.anchor);
690            break;
691
692        case YAML_SCALAR_EVENT:
693            yaml_free(event->data.scalar.anchor);
694            yaml_free(event->data.scalar.tag);
695            yaml_free(event->data.scalar.value);
696            break;
697
698        case YAML_SEQUENCE_START_EVENT:
699            yaml_free(event->data.sequence_start.anchor);
700            yaml_free(event->data.sequence_start.tag);
701            break;
702
703        case YAML_MAPPING_START_EVENT:
704            yaml_free(event->data.mapping_start.anchor);
705            yaml_free(event->data.mapping_start.tag);
706            break;
707    }
708
709    memset(event, 0, sizeof(yaml_event_t));
710
711    yaml_free(event);
712}
713
Note: See TracBrowser for help on using the repository browser.