]> andersk Git - libyaml.git/blame - src/api.c
Move yaml/yaml.h to yaml.h and merge version.c to api.c.
[libyaml.git] / src / api.c
CommitLineData
a51447c9
KS
1
2#if HAVE_CONFIG_H
3#include <config.h>
4#endif
5
5eff53a4 6#include <yaml.h>
a51447c9 7
95b98ba9
KS
8#include <assert.h>
9
5eff53a4
KS
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
95b98ba9
KS
24/*
25 * Allocate a dynamic memory block.
26 */
27
f642fd11 28YAML_DECLARE(void *)
95b98ba9
KS
29yaml_malloc(size_t size)
30{
31 return malloc(size ? size : 1);
32}
33
34/*
35 * Reallocate a dynamic memory block.
36 */
37
f642fd11 38YAML_DECLARE(void *)
95b98ba9
KS
39yaml_realloc(void *ptr, size_t size)
40{
41 return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
42}
43
a51447c9 44/*
95b98ba9
KS
45 * Free a dynamic memory block.
46 */
47
f642fd11 48YAML_DECLARE(void)
95b98ba9
KS
49yaml_free(void *ptr)
50{
51 if (ptr) free(ptr);
52}
53
54/*
55 * Create a new parser object.
a51447c9
KS
56 */
57
f642fd11 58YAML_DECLARE(yaml_parser_t *)
a51447c9
KS
59yaml_parser_new(void)
60{
61 yaml_parser_t *parser;
62
6eb1ded4
KS
63 /* Allocate the parser structure. */
64
95b98ba9 65 parser = yaml_malloc(sizeof(yaml_parser_t));
f2b59d4d 66 if (!parser) goto error;
a51447c9
KS
67
68 memset(parser, 0, sizeof(yaml_parser_t));
69
6eb1ded4
KS
70 /* Allocate the raw buffer. */
71
72 parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
f2b59d4d
KS
73 if (!parser->raw_buffer) goto error;
74 memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE);
75
6eb1ded4
KS
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);
f2b59d4d
KS
82 if (!parser->buffer) goto error;
83 memset(parser->buffer, 0, YAML_BUFFER_SIZE);
84
6eb1ded4
KS
85 parser->buffer_end = parser->buffer;
86 parser->pointer = parser->buffer;
87 parser->unread = 0;
88
f2b59d4d
KS
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
a51447c9 119 return parser;
f2b59d4d
KS
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;
a51447c9
KS
136}
137
138/*
139 * Destroy a parser object.
140 */
141
f642fd11 142YAML_DECLARE(void)
a51447c9
KS
143yaml_parser_delete(yaml_parser_t *parser)
144{
95b98ba9
KS
145 assert(parser); /* Non-NULL parser object expected. */
146
f2b59d4d
KS
147 yaml_free(parser->simple_keys);
148 yaml_free(parser->indents);
149 yaml_free(parser->tokens);
95b98ba9 150 yaml_free(parser->buffer);
6eb1ded4 151 yaml_free(parser->raw_buffer);
95b98ba9
KS
152
153 memset(parser, 0, sizeof(yaml_parser_t));
154
155 yaml_free(parser);
156}
157
158/*
6eb1ded4 159 * String read handler.
95b98ba9
KS
160 */
161
162static int
163yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
164 size_t *size_read)
165{
6eb1ded4
KS
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;
95b98ba9
KS
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{
6eb1ded4
KS
191 *size_read = fread(buffer, 1, size, (FILE *)data);
192 return !ferror((FILE *)data);
95b98ba9
KS
193}
194
195/*
196 * Set a string input.
197 */
198
f642fd11 199YAML_DECLARE(void)
95b98ba9
KS
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. */
6eb1ded4 204 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
205 assert(input); /* Non-NULL input string expected. */
206
6eb1ded4
KS
207 parser->string_input.start = input;
208 parser->string_input.current = input;
209 parser->string_input.end = input+size;
95b98ba9 210
6eb1ded4
KS
211 parser->read_handler = yaml_string_read_handler;
212 parser->read_handler_data = &parser->string_input;
95b98ba9
KS
213}
214
215/*
216 * Set a file input.
217 */
218
f642fd11 219YAML_DECLARE(void)
95b98ba9
KS
220yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
221{
222 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 223 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
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
f642fd11 234YAML_DECLARE(void)
95b98ba9
KS
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. */
6eb1ded4 239 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
240 assert(handler); /* Non-NULL read handler expected. */
241
242 parser->read_handler = handler;
6eb1ded4 243 parser->read_handler_data = data;
95b98ba9
KS
244}
245
246/*
247 * Set the source encoding.
248 */
249
f642fd11 250YAML_DECLARE(void)
95b98ba9
KS
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;
a51447c9
KS
257}
258
f642fd11
KS
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 *)
21fbedd4 285yaml_stream_start_token_new(yaml_encoding_t encoding,
f642fd11
KS
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
26687d7d 293 token->data.stream_start.encoding = encoding;
f642fd11
KS
294
295 return token;
296}
297
298/*
299 * Create a STREAM-END token.
300 */
301
302YAML_DECLARE(yaml_token_t *)
21fbedd4 303yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
f642fd11
KS
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
26687d7d 364 token->data.alias.value = anchor;
f642fd11
KS
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
26687d7d 382 token->data.anchor.value = anchor;
f642fd11
KS
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:
26687d7d
KS
444 yaml_free(token->data.alias.value);
445 break;
446
f642fd11 447 case YAML_ANCHOR_TOKEN:
26687d7d 448 yaml_free(token->data.anchor.value);
f642fd11
KS
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
26687d7d
KS
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
This page took 0.153225 seconds and 5 git commands to generate.