]> andersk Git - libyaml.git/blob - src/api.c
c63da4519dfc04a5b49d7de5f7a3f4beaee9e079
[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(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.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(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.anchor = 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 = 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         case YAML_ANCHOR_TOKEN:
431             yaml_free(token->data.anchor);
432             break;
433
434         case YAML_TAG_TOKEN:
435             yaml_free(token->data.tag.handle);
436             yaml_free(token->data.tag.suffix);
437             break;
438
439         case YAML_SCALAR_TOKEN:
440             yaml_free(token->data.scalar.value);
441             break;
442     }
443
444     memset(token, 0, sizeof(yaml_token_t));
445
446     yaml_free(token);
447 }
448
This page took 0.054454 seconds and 3 git commands to generate.