]> andersk Git - libyaml.git/blame - src/api.c
Complete the Parser (it requires refactoring though) and fix some bugs.
[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
1eb01be7
KS
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
ab01bac8
KS
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
1eb01be7
KS
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
f2b59d4d
KS
145 /* Done. */
146
a51447c9 147 return parser;
f2b59d4d
KS
148
149 /* On error, free allocated buffers. */
150
151error:
152
153 if (!parser) return NULL;
154
1eb01be7 155 yaml_free(parser->tag_directives);
ab01bac8 156 yaml_free(parser->marks);
1eb01be7 157 yaml_free(parser->states);
f2b59d4d
KS
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;
a51447c9
KS
167}
168
169/*
170 * Destroy a parser object.
171 */
172
f642fd11 173YAML_DECLARE(void)
a51447c9
KS
174yaml_parser_delete(yaml_parser_t *parser)
175{
95b98ba9
KS
176 assert(parser); /* Non-NULL parser object expected. */
177
ab01bac8
KS
178 /*yaml_free(parser->tag_directives);*/
179 yaml_free(parser->marks);
1eb01be7 180 yaml_free(parser->states);
f2b59d4d
KS
181 yaml_free(parser->simple_keys);
182 yaml_free(parser->indents);
183 yaml_free(parser->tokens);
95b98ba9 184 yaml_free(parser->buffer);
6eb1ded4 185 yaml_free(parser->raw_buffer);
95b98ba9
KS
186
187 memset(parser, 0, sizeof(yaml_parser_t));
188
189 yaml_free(parser);
190}
191
192/*
6eb1ded4 193 * String read handler.
95b98ba9
KS
194 */
195
196static int
197yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
198 size_t *size_read)
199{
6eb1ded4
KS
200 yaml_string_input_t *input = data;
201
202 if (input->current == input->end) {
203 *size_read = 0;
204 return 1;
205 }
206
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;
213 *size_read = size;
95b98ba9
KS
214 return 1;
215}
216
217/*
218 * File read handler.
219 */
220
221static int
222yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
223 size_t *size_read)
224{
6eb1ded4
KS
225 *size_read = fread(buffer, 1, size, (FILE *)data);
226 return !ferror((FILE *)data);
95b98ba9
KS
227}
228
229/*
230 * Set a string input.
231 */
232
f642fd11 233YAML_DECLARE(void)
95b98ba9
KS
234yaml_parser_set_input_string(yaml_parser_t *parser,
235 unsigned char *input, size_t size)
236{
237 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 238 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
239 assert(input); /* Non-NULL input string expected. */
240
6eb1ded4
KS
241 parser->string_input.start = input;
242 parser->string_input.current = input;
243 parser->string_input.end = input+size;
95b98ba9 244
6eb1ded4
KS
245 parser->read_handler = yaml_string_read_handler;
246 parser->read_handler_data = &parser->string_input;
95b98ba9
KS
247}
248
249/*
250 * Set a file input.
251 */
252
f642fd11 253YAML_DECLARE(void)
95b98ba9
KS
254yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
255{
256 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 257 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
258 assert(file); /* Non-NULL file object expected. */
259
260 parser->read_handler = yaml_file_read_handler;
261 parser->read_handler_data = file;
262}
263
264/*
265 * Set a generic input.
266 */
267
f642fd11 268YAML_DECLARE(void)
95b98ba9
KS
269yaml_parser_set_input(yaml_parser_t *parser,
270 yaml_read_handler_t *handler, void *data)
271{
272 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 273 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
274 assert(handler); /* Non-NULL read handler expected. */
275
276 parser->read_handler = handler;
6eb1ded4 277 parser->read_handler_data = data;
95b98ba9
KS
278}
279
280/*
281 * Set the source encoding.
282 */
283
f642fd11 284YAML_DECLARE(void)
95b98ba9
KS
285yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
286{
287 assert(parser); /* Non-NULL parser object expected. */
288 assert(!parser->encoding); /* Encoding is already set or detected. */
289
290 parser->encoding = encoding;
a51447c9
KS
291}
292
f642fd11
KS
293/*
294 * Create a token.
295 */
296
297YAML_DECLARE(yaml_token_t *)
298yaml_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
318YAML_DECLARE(yaml_token_t *)
21fbedd4 319yaml_stream_start_token_new(yaml_encoding_t encoding,
f642fd11
KS
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
26687d7d 327 token->data.stream_start.encoding = encoding;
f642fd11
KS
328
329 return token;
330}
331
332/*
333 * Create a STREAM-END token.
334 */
335
336YAML_DECLARE(yaml_token_t *)
21fbedd4 337yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
f642fd11
KS
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
351YAML_DECLARE(yaml_token_t *)
352yaml_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
370YAML_DECLARE(yaml_token_t *)
371yaml_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
389YAML_DECLARE(yaml_token_t *)
390yaml_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
26687d7d 398 token->data.alias.value = anchor;
f642fd11
KS
399
400 return token;
401}
402
403/*
404 * Create an ANCHOR token.
405 */
406
407YAML_DECLARE(yaml_token_t *)
408yaml_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
26687d7d 416 token->data.anchor.value = anchor;
f642fd11
KS
417
418 return token;
419}
420
421/*
422 * Create a TAG token.
423 */
424
425YAML_DECLARE(yaml_token_t *)
426yaml_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
444YAML_DECLARE(yaml_token_t *)
445yaml_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}
460
461/*
462 * Destroy a token object.
463 */
464
465YAML_DECLARE(void)
466yaml_token_delete(yaml_token_t *token)
467{
468 assert(token); /* Non-NULL token object expected. */
469
470 switch (token->type)
471 {
472 case YAML_TAG_DIRECTIVE_TOKEN:
473 yaml_free(token->data.tag_directive.handle);
474 yaml_free(token->data.tag_directive.prefix);
475 break;
476
477 case YAML_ALIAS_TOKEN:
26687d7d
KS
478 yaml_free(token->data.alias.value);
479 break;
480
f642fd11 481 case YAML_ANCHOR_TOKEN:
26687d7d 482 yaml_free(token->data.anchor.value);
f642fd11
KS
483 break;
484
485 case YAML_TAG_TOKEN:
486 yaml_free(token->data.tag.handle);
487 yaml_free(token->data.tag.suffix);
488 break;
489
490 case YAML_SCALAR_TOKEN:
491 yaml_free(token->data.scalar.value);
492 break;
493 }
494
495 memset(token, 0, sizeof(yaml_token_t));
496
497 yaml_free(token);
498}
499
26687d7d
KS
500/*
501 * Create an event.
502 */
503
504static yaml_event_t *
505yaml_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
525YAML_DECLARE(yaml_event_t *)
526yaml_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
543YAML_DECLARE(yaml_event_t *)
544yaml_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
553YAML_DECLARE(yaml_event_t *)
554yaml_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
574YAML_DECLARE(yaml_event_t *)
575yaml_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
592YAML_DECLARE(yaml_event_t *)
593yaml_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
610YAML_DECLARE(yaml_event_t *)
611yaml_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
637YAML_DECLARE(yaml_event_t *)
52fba2c6 638yaml_sequence_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
26687d7d
KS
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
659YAML_DECLARE(yaml_event_t *)
660yaml_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
669YAML_DECLARE(yaml_event_t *)
52fba2c6 670yaml_mapping_start_event_new(yaml_char_t *anchor, yaml_char_t *tag,
26687d7d
KS
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
691YAML_DECLARE(yaml_event_t *)
692yaml_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}
696
697/*
698 * Destroy an event object.
699 */
700
701YAML_DECLARE(void)
702yaml_event_delete(yaml_event_t *event)
703{
704 assert(event); /* Non-NULL event object expected. */
705
706 switch (event->type)
707 {
708 case YAML_DOCUMENT_START_EVENT:
ab01bac8 709 /*yaml_free(event->data.document_start.version_directive);
26687d7d
KS
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);
ab01bac8 719 }*/
26687d7d
KS
720 break;
721
722 case YAML_ALIAS_EVENT:
723 yaml_free(event->data.alias.anchor);
724 break;
725
726 case YAML_SCALAR_EVENT:
727 yaml_free(event->data.scalar.anchor);
728 yaml_free(event->data.scalar.tag);
729 yaml_free(event->data.scalar.value);
730 break;
731
732 case YAML_SEQUENCE_START_EVENT:
733 yaml_free(event->data.sequence_start.anchor);
734 yaml_free(event->data.sequence_start.tag);
735 break;
736
737 case YAML_MAPPING_START_EVENT:
738 yaml_free(event->data.mapping_start.anchor);
739 yaml_free(event->data.mapping_start.tag);
740 break;
741 }
742
743 memset(event, 0, sizeof(yaml_event_t));
744
745 yaml_free(event);
746}
747
This page took 1.290796 seconds and 5 git commands to generate.