]> andersk Git - libyaml.git/blob - src/api.c
Start working on the parser.
[libyaml.git] / src / api.c
1
2 #if HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include <yaml.h>
7
8 #include <assert.h>
9
10 YAML_DECLARE(const char *)
11 yaml_get_version_string(void)
12 {
13     return YAML_VERSION_STRING;
14 }
15
16 YAML_DECLARE(void)
17 yaml_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
24 /*
25  * Allocate a dynamic memory block.
26  */
27
28 YAML_DECLARE(void *)
29 yaml_malloc(size_t size)
30 {
31     return malloc(size ? size : 1);
32 }
33
34 /*
35  * Reallocate a dynamic memory block.
36  */
37
38 YAML_DECLARE(void *)
39 yaml_realloc(void *ptr, size_t size)
40 {
41     return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
42 }
43
44 /*
45  * Free a dynamic memory block.
46  */
47
48 YAML_DECLARE(void)
49 yaml_free(void *ptr)
50 {
51     if (ptr) free(ptr);
52 }
53
54 /*
55  * Create a new parser object.
56  */
57
58 YAML_DECLARE(yaml_parser_t *)
59 yaml_parser_new(void)
60 {
61     yaml_parser_t *parser;
62
63     /* Allocate the parser structure. */
64
65     parser = yaml_malloc(sizeof(yaml_parser_t));
66     if (!parser) goto error;
67
68     memset(parser, 0, sizeof(yaml_parser_t));
69
70     /* Allocate the raw buffer. */
71
72     parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
73     if (!parser->raw_buffer) goto error;
74     memset(parser->raw_buffer, 0, YAML_RAW_BUFFER_SIZE);
75
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);
82     if (!parser->buffer) goto error;
83     memset(parser->buffer, 0, YAML_BUFFER_SIZE);
84
85     parser->buffer_end = parser->buffer;
86     parser->pointer = parser->buffer;
87     parser->unread = 0;
88
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     /* 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
137     /* Done. */
138
139     return parser;
140
141     /* On error, free allocated buffers. */
142
143 error:
144
145     if (!parser) return NULL;
146
147     yaml_free(parser->tag_directives);
148     yaml_free(parser->states);
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;
158 }
159
160 /*
161  * Destroy a parser object.
162  */
163
164 YAML_DECLARE(void)
165 yaml_parser_delete(yaml_parser_t *parser)
166 {
167     assert(parser); /* Non-NULL parser object expected. */
168
169     yaml_free(parser->tag_directives);
170     yaml_free(parser->states);
171     yaml_free(parser->simple_keys);
172     yaml_free(parser->indents);
173     yaml_free(parser->tokens);
174     yaml_free(parser->buffer);
175     yaml_free(parser->raw_buffer);
176
177     memset(parser, 0, sizeof(yaml_parser_t));
178
179     yaml_free(parser);
180 }
181
182 /*
183  * String read handler.
184  */
185
186 static int
187 yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
188         size_t *size_read)
189 {
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;
204     return 1;
205 }
206
207 /*
208  * File read handler.
209  */
210
211 static int
212 yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
213         size_t *size_read)
214 {
215     *size_read = fread(buffer, 1, size, (FILE *)data);
216     return !ferror((FILE *)data);
217 }
218
219 /*
220  * Set a string input.
221  */
222
223 YAML_DECLARE(void)
224 yaml_parser_set_input_string(yaml_parser_t *parser,
225         unsigned char *input, size_t size)
226 {
227     assert(parser); /* Non-NULL parser object expected. */
228     assert(!parser->read_handler);  /* You can set the source only once. */
229     assert(input);  /* Non-NULL input string expected. */
230
231     parser->string_input.start = input;
232     parser->string_input.current = input;
233     parser->string_input.end = input+size;
234
235     parser->read_handler = yaml_string_read_handler;
236     parser->read_handler_data = &parser->string_input;
237 }
238
239 /*
240  * Set a file input.
241  */
242
243 YAML_DECLARE(void)
244 yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
245 {
246     assert(parser); /* Non-NULL parser object expected. */
247     assert(!parser->read_handler);  /* You can set the source only once. */
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
258 YAML_DECLARE(void)
259 yaml_parser_set_input(yaml_parser_t *parser,
260         yaml_read_handler_t *handler, void *data)
261 {
262     assert(parser); /* Non-NULL parser object expected. */
263     assert(!parser->read_handler);  /* You can set the source only once. */
264     assert(handler);    /* Non-NULL read handler expected. */
265
266     parser->read_handler = handler;
267     parser->read_handler_data = data;
268 }
269
270 /*
271  * Set the source encoding.
272  */
273
274 YAML_DECLARE(void)
275 yaml_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;
281 }
282
283 /*
284  * Create a token.
285  */
286
287 YAML_DECLARE(yaml_token_t *)
288 yaml_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
308 YAML_DECLARE(yaml_token_t *)
309 yaml_stream_start_token_new(yaml_encoding_t encoding,
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
317     token->data.stream_start.encoding = encoding;
318
319     return token;
320 }
321
322 /*
323  * Create a STREAM-END token.
324  */
325
326 YAML_DECLARE(yaml_token_t *)
327 yaml_stream_end_token_new(yaml_mark_t start_mark, yaml_mark_t end_mark)
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
341 YAML_DECLARE(yaml_token_t *)
342 yaml_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
360 YAML_DECLARE(yaml_token_t *)
361 yaml_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
379 YAML_DECLARE(yaml_token_t *)
380 yaml_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
388     token->data.alias.value = anchor;
389
390     return token;
391 }
392
393 /*
394  * Create an ANCHOR token.
395  */
396
397 YAML_DECLARE(yaml_token_t *)
398 yaml_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
406     token->data.anchor.value = anchor;
407
408     return token;
409 }
410
411 /*
412  * Create a TAG token.
413  */
414
415 YAML_DECLARE(yaml_token_t *)
416 yaml_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
434 YAML_DECLARE(yaml_token_t *)
435 yaml_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
455 YAML_DECLARE(void)
456 yaml_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:
468             yaml_free(token->data.alias.value);
469             break;
470
471         case YAML_ANCHOR_TOKEN:
472             yaml_free(token->data.anchor.value);
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
490 /*
491  * Create an event.
492  */
493
494 static yaml_event_t *
495 yaml_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
515 YAML_DECLARE(yaml_event_t *)
516 yaml_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
533 YAML_DECLARE(yaml_event_t *)
534 yaml_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
543 YAML_DECLARE(yaml_event_t *)
544 yaml_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
564 YAML_DECLARE(yaml_event_t *)
565 yaml_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
582 YAML_DECLARE(yaml_event_t *)
583 yaml_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
600 YAML_DECLARE(yaml_event_t *)
601 yaml_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
627 YAML_DECLARE(yaml_event_t *)
628 yaml_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
649 YAML_DECLARE(yaml_event_t *)
650 yaml_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
659 YAML_DECLARE(yaml_event_t *)
660 yaml_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
681 YAML_DECLARE(yaml_event_t *)
682 yaml_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
691 YAML_DECLARE(void)
692 yaml_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.322821 seconds and 5 git commands to generate.