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

Revision 199, 15.7 KB checked in by xi, 8 years ago (diff)

Add event constructors and destructors.

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