]> andersk Git - libyaml.git/blob - src/api.c
Add event constructors and destructors.
[libyaml.git] / src / api.c
1
2 #if HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include <yaml/yaml.h>
7
8 #include <assert.h>
9
10 /*
11  * Allocate a dynamic memory block.
12  */
13
14 YAML_DECLARE(void *)
15 yaml_malloc(size_t size)
16 {
17     return malloc(size ? size : 1);
18 }
19
20 /*
21  * Reallocate a dynamic memory block.
22  */
23
24 YAML_DECLARE(void *)
25 yaml_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
34 YAML_DECLARE(void)
35 yaml_free(void *ptr)
36 {
37     if (ptr) free(ptr);
38 }
39
40 /*
41  * Create a new parser object.
42  */
43
44 YAML_DECLARE(yaml_parser_t *)
45 yaml_parser_new(void)
46 {
47     yaml_parser_t *parser;
48
49     /* Allocate the parser structure. */
50
51     parser = yaml_malloc(sizeof(yaml_parser_t));
52     if (!parser) goto error;
53
54     memset(parser, 0, sizeof(yaml_parser_t));
55
56     /* Allocate the raw buffer. */
57
58     parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
59     if (!parser->raw_buffer) goto error;
60     memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE);
61
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);
68     if (!parser->buffer) goto error;
69     memset(parser->buffer, 0, YAML_BUFFER_SIZE);
70
71     parser->buffer_end = parser->buffer;
72     parser->pointer = parser->buffer;
73     parser->unread = 0;
74
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
105     return parser;
106
107     /* On error, free allocated buffers. */
108
109 error:
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;
122 }
123
124 /*
125  * Destroy a parser object.
126  */
127
128 YAML_DECLARE(void)
129 yaml_parser_delete(yaml_parser_t *parser)
130 {
131     assert(parser); /* Non-NULL parser object expected. */
132
133     yaml_free(parser->simple_keys);
134     yaml_free(parser->indents);
135     yaml_free(parser->tokens);
136     yaml_free(parser->buffer);
137     yaml_free(parser->raw_buffer);
138
139     memset(parser, 0, sizeof(yaml_parser_t));
140
141     yaml_free(parser);
142 }
143
144 /*
145  * String read handler.
146  */
147
148 static int
149 yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
150         size_t *size_read)
151 {
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;
166     return 1;
167 }
168
169 /*
170  * File read handler.
171  */
172
173 static int
174 yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
175         size_t *size_read)
176 {
177     *size_read = fread(buffer, 1, size, (FILE *)data);
178     return !ferror((FILE *)data);
179 }
180
181 /*
182  * Set a string input.
183  */
184
185 YAML_DECLARE(void)
186 yaml_parser_set_input_string(yaml_parser_t *parser,
187         unsigned char *input, size_t size)
188 {
189     assert(parser); /* Non-NULL parser object expected. */
190     assert(!parser->read_handler);  /* You can set the source only once. */
191     assert(input);  /* Non-NULL input string expected. */
192
193     parser->string_input.start = input;
194     parser->string_input.current = input;
195     parser->string_input.end = input+size;
196
197     parser->read_handler = yaml_string_read_handler;
198     parser->read_handler_data = &parser->string_input;
199 }
200
201 /*
202  * Set a file input.
203  */
204
205 YAML_DECLARE(void)
206 yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
207 {
208     assert(parser); /* Non-NULL parser object expected. */
209     assert(!parser->read_handler);  /* You can set the source only once. */
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
220 YAML_DECLARE(void)
221 yaml_parser_set_input(yaml_parser_t *parser,
222         yaml_read_handler_t *handler, void *data)
223 {
224     assert(parser); /* Non-NULL parser object expected. */
225     assert(!parser->read_handler);  /* You can set the source only once. */
226     assert(handler);    /* Non-NULL read handler expected. */
227
228     parser->read_handler = handler;
229     parser->read_handler_data = data;
230 }
231
232 /*
233  * Set the source encoding.
234  */
235
236 YAML_DECLARE(void)
237 yaml_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
245 /*
246  * Create a token.
247  */
248
249 YAML_DECLARE(yaml_token_t *)
250 yaml_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
270 YAML_DECLARE(yaml_token_t *)
271 yaml_stream_start_token_new(yaml_encoding_t encoding,
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
279     token->data.stream_start.encoding = encoding;
280
281     return token;
282 }
283
284 /*
285  * Create a STREAM-END token.
286  */
287
288 YAML_DECLARE(yaml_token_t *)
289 yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
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
303 YAML_DECLARE(yaml_token_t *)
304 yaml_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
322 YAML_DECLARE(yaml_token_t *)
323 yaml_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
341 YAML_DECLARE(yaml_token_t *)
342 yaml_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
350     token->data.alias.value = anchor;
351
352     return token;
353 }
354
355 /*
356  * Create an ANCHOR token.
357  */
358
359 YAML_DECLARE(yaml_token_t *)
360 yaml_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
368     token->data.anchor.value = anchor;
369
370     return token;
371 }
372
373 /*
374  * Create a TAG token.
375  */
376
377 YAML_DECLARE(yaml_token_t *)
378 yaml_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
396 YAML_DECLARE(yaml_token_t *)
397 yaml_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
417 YAML_DECLARE(void)
418 yaml_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:
430             yaml_free(token->data.alias.value);
431             break;
432
433         case YAML_ANCHOR_TOKEN:
434             yaml_free(token->data.anchor.value);
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
452 /*
453  * Create an event.
454  */
455
456 static yaml_event_t *
457 yaml_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
477 YAML_DECLARE(yaml_event_t *)
478 yaml_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
495 YAML_DECLARE(yaml_event_t *)
496 yaml_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
505 YAML_DECLARE(yaml_event_t *)
506 yaml_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
526 YAML_DECLARE(yaml_event_t *)
527 yaml_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
544 YAML_DECLARE(yaml_event_t *)
545 yaml_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
562 YAML_DECLARE(yaml_event_t *)
563 yaml_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
589 YAML_DECLARE(yaml_event_t *)
590 yaml_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
611 YAML_DECLARE(yaml_event_t *)
612 yaml_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
621 YAML_DECLARE(yaml_event_t *)
622 yaml_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
643 YAML_DECLARE(yaml_event_t *)
644 yaml_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
653 YAML_DECLARE(void)
654 yaml_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
This page took 0.223442 seconds and 5 git commands to generate.