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