source: libyaml/trunk/src/api.c @ 183

Revision 183, 8.2 KB checked in by xi, 8 years ago (diff)

Add token constructors and destructors.

Add YAML_DECLARE to the API declarations (Thanks to Peter Murphy for suggestion).

RevLine 
[178]1
2#if HAVE_CONFIG_H
3#include <config.h>
4#endif
5
6#include <yaml/yaml.h>
7
[179]8#include <assert.h>
9
[178]10/*
[179]11 * Allocate a dynamic memory block.
[178]12 */
13
[183]14YAML_DECLARE(void *)
[179]15yaml_malloc(size_t size)
16{
17    return malloc(size ? size : 1);
18}
19
20/*
21 * Reallocate a dynamic memory block.
22 */
23
[183]24YAML_DECLARE(void *)
[179]25yaml_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
[183]34YAML_DECLARE(void)
[179]35yaml_free(void *ptr)
36{
37    if (ptr) free(ptr);
38}
39
40/*
41 * Create a new parser object.
42 */
43
[183]44YAML_DECLARE(yaml_parser_t *)
[178]45yaml_parser_new(void)
46{
47    yaml_parser_t *parser;
48
[180]49    /* Allocate the parser structure. */
50
[179]51    parser = yaml_malloc(sizeof(yaml_parser_t));
[178]52    if (!parser) return NULL;
53
54    memset(parser, 0, sizeof(yaml_parser_t));
55
[180]56    /* Allocate the raw buffer. */
57
58    parser->raw_buffer = yaml_malloc(YAML_RAW_BUFFER_SIZE);
59    if (!parser->raw_buffer) {
60        yaml_free(parser);
61        return NULL;
62    }
63    parser->raw_pointer = parser->raw_buffer;
64    parser->raw_unread = 0;
65
66    /* Allocate the character buffer. */
67
68    parser->buffer = yaml_malloc(YAML_BUFFER_SIZE);
69    if (!parser->buffer) {
70        yaml_free(parser->raw_buffer);
71        yaml_free(parser);
72        return NULL;
73    }
74    parser->buffer_end = parser->buffer;
75    parser->pointer = parser->buffer;
76    parser->unread = 0;
77
[178]78    return parser;
79}
80
81/*
82 * Destroy a parser object.
83 */
84
[183]85YAML_DECLARE(void)
[178]86yaml_parser_delete(yaml_parser_t *parser)
87{
[179]88    assert(parser); /* Non-NULL parser object expected. */
89
90    yaml_free(parser->buffer);
[180]91    yaml_free(parser->raw_buffer);
[179]92
93    memset(parser, 0, sizeof(yaml_parser_t));
94
95    yaml_free(parser);
[178]96}
97
[179]98/*
[180]99 * String read handler.
[179]100 */
101
102static int
103yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
104        size_t *size_read)
105{
[180]106    yaml_string_input_t *input = data;
107
108    if (input->current == input->end) {
109        *size_read = 0;
110        return 1;
111    }
112
113    if (size > (input->end - input->current)) {
114        size = input->end - input->current;
115    }
116
117    memcpy(buffer, input->current, size);
118    input->current += size;
119    *size_read = size;
[179]120    return 1;
121}
122
123/*
124 * File read handler.
125 */
126
127static int
128yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
129        size_t *size_read)
130{
[180]131    *size_read = fread(buffer, 1, size, (FILE *)data);
132    return !ferror((FILE *)data);
[179]133}
134
135/*
136 * Set a string input.
137 */
138
[183]139YAML_DECLARE(void)
[179]140yaml_parser_set_input_string(yaml_parser_t *parser,
141        unsigned char *input, size_t size)
142{
143    assert(parser); /* Non-NULL parser object expected. */
[180]144    assert(!parser->read_handler);  /* You can set the source only once. */
[179]145    assert(input);  /* Non-NULL input string expected. */
146
[180]147    parser->string_input.start = input;
148    parser->string_input.current = input;
149    parser->string_input.end = input+size;
150
[179]151    parser->read_handler = yaml_string_read_handler;
[180]152    parser->read_handler_data = &parser->string_input;
[179]153}
154
155/*
156 * Set a file input.
157 */
158
[183]159YAML_DECLARE(void)
[179]160yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
161{
162    assert(parser); /* Non-NULL parser object expected. */
[180]163    assert(!parser->read_handler);  /* You can set the source only once. */
[179]164    assert(file);   /* Non-NULL file object expected. */
165
166    parser->read_handler = yaml_file_read_handler;
167    parser->read_handler_data = file;
168}
169
170/*
171 * Set a generic input.
172 */
173
[183]174YAML_DECLARE(void)
[179]175yaml_parser_set_input(yaml_parser_t *parser,
176        yaml_read_handler_t *handler, void *data)
177{
178    assert(parser); /* Non-NULL parser object expected. */
[180]179    assert(!parser->read_handler);  /* You can set the source only once. */
[179]180    assert(handler);    /* Non-NULL read handler expected. */
181
182    parser->read_handler = handler;
[180]183    parser->read_handler_data = data;
[179]184}
185
186/*
187 * Set the source encoding.
188 */
189
[183]190YAML_DECLARE(void)
[179]191yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
192{
193    assert(parser); /* Non-NULL parser object expected. */
194    assert(!parser->encoding); /* Encoding is already set or detected. */
195
196    parser->encoding = encoding;
197}
198
[183]199/*
200 * Create a token.
201 */
202
203YAML_DECLARE(yaml_token_t *)
204yaml_token_new(yaml_token_type_t type,
205        yaml_mark_t start_mark, yaml_mark_t end_mark)
206{
207    yaml_token_t *token = yaml_malloc(sizeof(yaml_token_t));
208
209    if (!token) return NULL;
210
211    memset(token, 0, sizeof(yaml_token_t));
212
213    token->type = type;
214    token->start_mark = start_mark;
215    token->end_mark = end_mark;
216
217    return token;
218}
219
220/*
221 * Create a STREAM-START token.
222 */
223
224YAML_DECLARE(yaml_token_t *)
225yaml_stream_start_token(yaml_encoding_t encoding,
226        yaml_mark_t start_mark, yaml_mark_t end_mark)
227{
228    yaml_token_t *token = yaml_token_new(YAML_STREAM_START_TOKEN,
229            start_mark, end_mark);
230
231    if (!token) return NULL;
232
233    token->data.encoding = encoding;
234
235    return token;
236}
237
238/*
239 * Create a STREAM-END token.
240 */
241
242YAML_DECLARE(yaml_token_t *)
243yaml_stream_end_token(yaml_mark_t start_mark, yaml_mark_t end_mark)
244{
245    yaml_token_t *token = yaml_token_new(YAML_STREAM_END_TOKEN,
246            start_mark, end_mark);
247
248    if (!token) return NULL;
249
250    return token;
251}
252
253/*
254 * Create a VERSION-DIRECTIVE token.
255 */
256
257YAML_DECLARE(yaml_token_t *)
258yaml_version_directive_token_new(int major, int minor,
259        yaml_mark_t start_mark, yaml_mark_t end_mark)
260{
261    yaml_token_t *token = yaml_token_new(YAML_VERSION_DIRECTIVE_TOKEN,
262            start_mark, end_mark);
263
264    if (!token) return NULL;
265
266    token->data.version_directive.major = major;
267    token->data.version_directive.minor = minor;
268
269    return token;
270}
271
272/*
273 * Create a TAG-DIRECTIVE token.
274 */
275
276YAML_DECLARE(yaml_token_t *)
277yaml_tag_directive_token_new(yaml_char_t *handle, yaml_char_t *prefix,
278        yaml_mark_t start_mark, yaml_mark_t end_mark)
279{
280    yaml_token_t *token = yaml_token_new(YAML_TAG_DIRECTIVE_TOKEN,
281            start_mark, end_mark);
282
283    if (!token) return NULL;
284
285    token->data.tag_directive.handle = handle;
286    token->data.tag_directive.prefix = prefix;
287
288    return token;
289}
290
291/*
292 * Create an ALIAS token.
293 */
294
295YAML_DECLARE(yaml_token_t *)
296yaml_alias_token_new(yaml_char_t *anchor,
297        yaml_mark_t start_mark, yaml_mark_t end_mark)
298{
299    yaml_token_t *token = yaml_token_new(YAML_ALIAS_TOKEN,
300            start_mark, end_mark);
301
302    if (!token) return NULL;
303
304    token->data.anchor = anchor;
305
306    return token;
307}
308
309/*
310 * Create an ANCHOR token.
311 */
312
313YAML_DECLARE(yaml_token_t *)
314yaml_anchor_token_new(yaml_char_t *anchor,
315        yaml_mark_t start_mark, yaml_mark_t end_mark)
316{
317    yaml_token_t *token = yaml_token_new(YAML_ANCHOR_TOKEN,
318            start_mark, end_mark);
319
320    if (!token) return NULL;
321
322    token->data.anchor = anchor;
323
324    return token;
325}
326
327/*
328 * Create a TAG token.
329 */
330
331YAML_DECLARE(yaml_token_t *)
332yaml_tag_token_new(yaml_char_t *handle, yaml_char_t *suffix,
333        yaml_mark_t start_mark, yaml_mark_t end_mark)
334{
335    yaml_token_t *token = yaml_token_new(YAML_TAG_TOKEN,
336            start_mark, end_mark);
337
338    if (!token) return NULL;
339
340    token->data.tag.handle = handle;
341    token->data.tag.suffix = suffix;
342
343    return token;
344}
345
346/*
347 * Create a SCALAR token.
348 */
349
350YAML_DECLARE(yaml_token_t *)
351yaml_scalar_token_new(yaml_char_t *value, size_t length,
352        yaml_scalar_style_t style,
353        yaml_mark_t start_mark, yaml_mark_t end_mark)
354{
355    yaml_token_t *token = yaml_token_new(YAML_SCALAR_TOKEN,
356            start_mark, end_mark);
357
358    if (!token) return NULL;
359
360    token->data.scalar.value = value;
361    token->data.scalar.length = length;
362    token->data.scalar.style = style;
363
364    return token;
365}
366
367/*
368 * Destroy a token object.
369 */
370
371YAML_DECLARE(void)
372yaml_token_delete(yaml_token_t *token)
373{
374    assert(token);  /* Non-NULL token object expected. */
375
376    switch (token->type)
377    {
378        case YAML_TAG_DIRECTIVE_TOKEN:
379            yaml_free(token->data.tag_directive.handle);
380            yaml_free(token->data.tag_directive.prefix);
381            break;
382
383        case YAML_ALIAS_TOKEN:
384        case YAML_ANCHOR_TOKEN:
385            yaml_free(token->data.anchor);
386            break;
387
388        case YAML_TAG_TOKEN:
389            yaml_free(token->data.tag.handle);
390            yaml_free(token->data.tag.suffix);
391            break;
392
393        case YAML_SCALAR_TOKEN:
394            yaml_free(token->data.scalar.value);
395            break;
396    }
397
398    memset(token, 0, sizeof(yaml_token_t));
399
400    yaml_free(token);
401}
402
Note: See TracBrowser for help on using the repository browser.