]> andersk Git - libyaml.git/blame - src/api.c
Add -Wall to list of compile flags
[libyaml.git] / src / api.c
CommitLineData
a51447c9 1
625fcfe9 2#include "yaml_private.h"
a51447c9 3
625fcfe9
KS
4/*
5 * Get the library version.
6 */
95b98ba9 7
5eff53a4
KS
8YAML_DECLARE(const char *)
9yaml_get_version_string(void)
10{
11 return YAML_VERSION_STRING;
12}
13
625fcfe9
KS
14/*
15 * Get the library version numbers.
16 */
17
5eff53a4
KS
18YAML_DECLARE(void)
19yaml_get_version(int *major, int *minor, int *patch)
20{
21 *major = YAML_VERSION_MAJOR;
22 *minor = YAML_VERSION_MINOR;
23 *patch = YAML_VERSION_PATCH;
24}
25
95b98ba9
KS
26/*
27 * Allocate a dynamic memory block.
28 */
29
f642fd11 30YAML_DECLARE(void *)
95b98ba9
KS
31yaml_malloc(size_t size)
32{
33 return malloc(size ? size : 1);
34}
35
36/*
37 * Reallocate a dynamic memory block.
38 */
39
f642fd11 40YAML_DECLARE(void *)
95b98ba9
KS
41yaml_realloc(void *ptr, size_t size)
42{
43 return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
44}
45
a51447c9 46/*
95b98ba9
KS
47 * Free a dynamic memory block.
48 */
49
f642fd11 50YAML_DECLARE(void)
95b98ba9
KS
51yaml_free(void *ptr)
52{
53 if (ptr) free(ptr);
54}
55
56/*
625fcfe9 57 * Duplicate a string.
a51447c9
KS
58 */
59
cf616166
KS
60YAML_DECLARE(yaml_char_t *)
61yaml_strdup(const yaml_char_t *str)
a51447c9 62{
cf616166
KS
63 if (!str)
64 return NULL;
65
66 return (yaml_char_t *)strdup((char *)str);
625fcfe9 67}
a51447c9 68
625fcfe9
KS
69/*
70 * Extend a string.
71 */
6eb1ded4 72
625fcfe9
KS
73YAML_DECLARE(int)
74yaml_string_extend(yaml_char_t **start,
75 yaml_char_t **pointer, yaml_char_t **end)
76{
0174ed6e 77 yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
f2b59d4d 78
625fcfe9 79 if (!new_start) return 0;
6eb1ded4 80
625fcfe9 81 memset(new_start + (*end - *start), 0, *end - *start);
6eb1ded4 82
625fcfe9
KS
83 *pointer = new_start + (*pointer - *start);
84 *end = new_start + (*end - *start)*2;
85 *start = new_start;
f2b59d4d 86
625fcfe9
KS
87 return 1;
88}
6eb1ded4 89
625fcfe9
KS
90/*
91 * Append a string B to a string A.
92 */
f2b59d4d 93
625fcfe9
KS
94YAML_DECLARE(int)
95yaml_string_join(
96 yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
97 yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end)
98{
99 if (*b_start == *b_pointer)
100 return 1;
f2b59d4d 101
625fcfe9
KS
102 while (*a_end - *a_pointer <= *b_pointer - *b_start) {
103 if (!yaml_string_extend(a_start, a_pointer, a_end))
104 return 0;
105 }
f2b59d4d 106
625fcfe9
KS
107 memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
108 *a_pointer += *b_pointer - *b_start;
f2b59d4d 109
625fcfe9
KS
110 return 1;
111}
f2b59d4d 112
625fcfe9
KS
113/*
114 * Extend a stack.
115 */
f2b59d4d 116
625fcfe9
KS
117YAML_DECLARE(int)
118yaml_stack_extend(void **start, void **top, void **end)
119{
0174ed6e 120 void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
f2b59d4d 121
625fcfe9 122 if (!new_start) return 0;
f2b59d4d 123
0174ed6e
KS
124 *top = (char *)new_start + ((char *)*top - (char *)*start);
125 *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
625fcfe9 126 *start = new_start;
f2b59d4d 127
625fcfe9
KS
128 return 1;
129}
1eb01be7 130
625fcfe9
KS
131/*
132 * Extend or move a queue.
133 */
1eb01be7 134
625fcfe9
KS
135YAML_DECLARE(int)
136yaml_queue_extend(void **start, void **head, void **tail, void **end)
137{
138 /* Check if we need to resize the queue. */
1eb01be7 139
625fcfe9 140 if (*start == *head && *tail == *end) {
0174ed6e
KS
141 void *new_start = yaml_realloc(*start,
142 ((char *)*end - (char *)*start)*2);
1eb01be7 143
625fcfe9 144 if (!new_start) return 0;
1eb01be7 145
0174ed6e
KS
146 *head = (char *)new_start + ((char *)*head - (char *)*start);
147 *tail = (char *)new_start + ((char *)*tail - (char *)*start);
148 *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
625fcfe9
KS
149 *start = new_start;
150 }
ab01bac8 151
625fcfe9 152 /* Check if we need to move the queue at the beginning of the buffer. */
ab01bac8 153
625fcfe9
KS
154 if (*tail == *end) {
155 if (*head != *tail) {
0174ed6e 156 memmove(*start, *head, (char *)*tail - (char *)*head);
625fcfe9 157 }
0174ed6e 158 *tail = (char *)*tail - (char *)*head + (char *)*start;
625fcfe9
KS
159 *head = *start;
160 }
ab01bac8 161
625fcfe9
KS
162 return 1;
163}
1eb01be7 164
1eb01be7 165
625fcfe9
KS
166/*
167 * Create a new parser object.
168 */
1eb01be7 169
625fcfe9
KS
170YAML_DECLARE(int)
171yaml_parser_initialize(yaml_parser_t *parser)
172{
173 assert(parser); /* Non-NULL parser object expected. */
f2b59d4d 174
625fcfe9 175 memset(parser, 0, sizeof(yaml_parser_t));
b1a54000 176 if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
625fcfe9 177 goto error;
b1a54000 178 if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
625fcfe9
KS
179 goto error;
180 if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE))
181 goto error;
182 if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE))
183 goto error;
184 if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE))
185 goto error;
186 if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE))
187 goto error;
188 if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE))
189 goto error;
190 if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE))
191 goto error;
f2b59d4d 192
625fcfe9 193 return 1;
f2b59d4d
KS
194
195error:
196
625fcfe9
KS
197 BUFFER_DEL(parser, parser->raw_buffer);
198 BUFFER_DEL(parser, parser->buffer);
199 QUEUE_DEL(parser, parser->tokens);
200 STACK_DEL(parser, parser->indents);
201 STACK_DEL(parser, parser->simple_keys);
202 STACK_DEL(parser, parser->states);
203 STACK_DEL(parser, parser->marks);
204 STACK_DEL(parser, parser->tag_directives);
f2b59d4d 205
625fcfe9 206 return 0;
a51447c9
KS
207}
208
209/*
210 * Destroy a parser object.
211 */
212
f642fd11 213YAML_DECLARE(void)
a51447c9
KS
214yaml_parser_delete(yaml_parser_t *parser)
215{
95b98ba9
KS
216 assert(parser); /* Non-NULL parser object expected. */
217
625fcfe9
KS
218 BUFFER_DEL(parser, parser->raw_buffer);
219 BUFFER_DEL(parser, parser->buffer);
220 while (!QUEUE_EMPTY(parser, parser->tokens)) {
221 yaml_token_delete(&DEQUEUE(parser, parser->tokens));
222 }
223 QUEUE_DEL(parser, parser->tokens);
224 STACK_DEL(parser, parser->indents);
225 STACK_DEL(parser, parser->simple_keys);
226 STACK_DEL(parser, parser->states);
227 STACK_DEL(parser, parser->marks);
228 while (!STACK_EMPTY(parser, parser->tag_directives)) {
229 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
230 yaml_free(tag_directive.handle);
231 yaml_free(tag_directive.prefix);
232 }
233 STACK_DEL(parser, parser->tag_directives);
95b98ba9
KS
234
235 memset(parser, 0, sizeof(yaml_parser_t));
95b98ba9
KS
236}
237
238/*
6eb1ded4 239 * String read handler.
95b98ba9
KS
240 */
241
242static int
243yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
244 size_t *size_read)
245{
625fcfe9 246 yaml_parser_t *parser = data;
6eb1ded4 247
625fcfe9 248 if (parser->input.string.current == parser->input.string.end) {
6eb1ded4
KS
249 *size_read = 0;
250 return 1;
251 }
252
0174ed6e
KS
253 if (size > (size_t)(parser->input.string.end
254 - parser->input.string.current)) {
625fcfe9 255 size = parser->input.string.end - parser->input.string.current;
6eb1ded4
KS
256 }
257
625fcfe9
KS
258 memcpy(buffer, parser->input.string.current, size);
259 parser->input.string.current += size;
6eb1ded4 260 *size_read = size;
95b98ba9
KS
261 return 1;
262}
263
264/*
265 * File read handler.
266 */
267
268static int
269yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
270 size_t *size_read)
271{
625fcfe9
KS
272 yaml_parser_t *parser = data;
273
274 *size_read = fread(buffer, 1, size, parser->input.file);
275 return !ferror(parser->input.file);
95b98ba9
KS
276}
277
278/*
279 * Set a string input.
280 */
281
f642fd11 282YAML_DECLARE(void)
95b98ba9 283yaml_parser_set_input_string(yaml_parser_t *parser,
a907bf85 284 const unsigned char *input, size_t size)
95b98ba9
KS
285{
286 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 287 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
288 assert(input); /* Non-NULL input string expected. */
289
6eb1ded4 290 parser->read_handler = yaml_string_read_handler;
625fcfe9
KS
291 parser->read_handler_data = parser;
292
293 parser->input.string.start = input;
294 parser->input.string.current = input;
295 parser->input.string.end = input+size;
95b98ba9
KS
296}
297
298/*
299 * Set a file input.
300 */
301
f642fd11 302YAML_DECLARE(void)
95b98ba9
KS
303yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
304{
305 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 306 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
307 assert(file); /* Non-NULL file object expected. */
308
309 parser->read_handler = yaml_file_read_handler;
625fcfe9
KS
310 parser->read_handler_data = parser;
311
312 parser->input.file = file;
95b98ba9
KS
313}
314
315/*
316 * Set a generic input.
317 */
318
f642fd11 319YAML_DECLARE(void)
95b98ba9
KS
320yaml_parser_set_input(yaml_parser_t *parser,
321 yaml_read_handler_t *handler, void *data)
322{
323 assert(parser); /* Non-NULL parser object expected. */
6eb1ded4 324 assert(!parser->read_handler); /* You can set the source only once. */
95b98ba9
KS
325 assert(handler); /* Non-NULL read handler expected. */
326
327 parser->read_handler = handler;
6eb1ded4 328 parser->read_handler_data = data;
95b98ba9
KS
329}
330
331/*
332 * Set the source encoding.
333 */
334
f642fd11 335YAML_DECLARE(void)
95b98ba9
KS
336yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
337{
338 assert(parser); /* Non-NULL parser object expected. */
339 assert(!parser->encoding); /* Encoding is already set or detected. */
340
341 parser->encoding = encoding;
a51447c9
KS
342}
343
b1a54000
KS
344/*
345 * Create a new emitter object.
346 */
347
348YAML_DECLARE(int)
349yaml_emitter_initialize(yaml_emitter_t *emitter)
350{
351 assert(emitter); /* Non-NULL emitter object expected. */
352
353 memset(emitter, 0, sizeof(yaml_emitter_t));
354 if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
355 goto error;
356 if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
357 goto error;
358 if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE))
359 goto error;
360 if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE))
361 goto error;
362 if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE))
363 goto error;
364 if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE))
365 goto error;
366
367 return 1;
368
369error:
370
371 BUFFER_DEL(emitter, emitter->buffer);
372 BUFFER_DEL(emitter, emitter->raw_buffer);
373 STACK_DEL(emitter, emitter->states);
374 QUEUE_DEL(emitter, emitter->events);
375 STACK_DEL(emitter, emitter->indents);
376 STACK_DEL(emitter, emitter->tag_directives);
377
378 return 0;
379}
380
381/*
382 * Destroy an emitter object.
383 */
384
385YAML_DECLARE(void)
386yaml_emitter_delete(yaml_emitter_t *emitter)
387{
388 assert(emitter); /* Non-NULL emitter object expected. */
389
390 BUFFER_DEL(emitter, emitter->buffer);
391 BUFFER_DEL(emitter, emitter->raw_buffer);
392 STACK_DEL(emitter, emitter->states);
393 while (!QUEUE_EMPTY(emitter, emitter->events)) {
394 yaml_event_delete(&DEQUEUE(emitter, emitter->events));
395 }
6d167281 396 QUEUE_DEL(emitter, emitter->events);
b1a54000
KS
397 STACK_DEL(emitter, emitter->indents);
398 while (!STACK_EMPTY(empty, emitter->tag_directives)) {
399 yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
400 yaml_free(tag_directive.handle);
401 yaml_free(tag_directive.prefix);
402 }
403 STACK_DEL(emitter, emitter->tag_directives);
e27a3c88 404 yaml_free(emitter->anchors);
b1a54000
KS
405
406 memset(emitter, 0, sizeof(yaml_emitter_t));
407}
408
409/*
410 * String write handler.
411 */
412
413static int
414yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
415{
416 yaml_emitter_t *emitter = data;
417
686b2d85 418 if (emitter->output.string.size - *emitter->output.string.size_written
b1a54000
KS
419 < size) {
420 memcpy(emitter->output.string.buffer
421 + *emitter->output.string.size_written,
422 buffer,
423 emitter->output.string.size
424 - *emitter->output.string.size_written);
425 *emitter->output.string.size_written = emitter->output.string.size;
426 return 0;
427 }
428
429 memcpy(emitter->output.string.buffer
430 + *emitter->output.string.size_written, buffer, size);
431 *emitter->output.string.size_written += size;
432 return 1;
433}
434
435/*
436 * File write handler.
437 */
438
439static int
440yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
441{
442 yaml_emitter_t *emitter = data;
443
444 return (fwrite(buffer, 1, size, emitter->output.file) == size);
445}
446/*
447 * Set a string output.
448 */
449
450YAML_DECLARE(void)
451yaml_emitter_set_output_string(yaml_emitter_t *emitter,
452 unsigned char *output, size_t size, size_t *size_written)
453{
454 assert(emitter); /* Non-NULL emitter object expected. */
455 assert(!emitter->write_handler); /* You can set the output only once. */
456 assert(output); /* Non-NULL output string expected. */
457
458 emitter->write_handler = yaml_string_write_handler;
459 emitter->write_handler_data = emitter;
460
461 emitter->output.string.buffer = output;
462 emitter->output.string.size = size;
463 emitter->output.string.size_written = size_written;
464 *size_written = 0;
465}
466
467/*
468 * Set a file output.
469 */
470
471YAML_DECLARE(void)
472yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
473{
474 assert(emitter); /* Non-NULL emitter object expected. */
475 assert(!emitter->write_handler); /* You can set the output only once. */
476 assert(file); /* Non-NULL file object expected. */
477
478 emitter->write_handler = yaml_file_write_handler;
479 emitter->write_handler_data = emitter;
480
481 emitter->output.file = file;
482}
483
484/*
485 * Set a generic output handler.
486 */
487
488YAML_DECLARE(void)
489yaml_emitter_set_output(yaml_emitter_t *emitter,
490 yaml_write_handler_t *handler, void *data)
491{
492 assert(emitter); /* Non-NULL emitter object expected. */
493 assert(!emitter->write_handler); /* You can set the output only once. */
494 assert(handler); /* Non-NULL handler object expected. */
495
496 emitter->write_handler = handler;
497 emitter->write_handler_data = data;
498}
499
500/*
501 * Set the output encoding.
502 */
503
504YAML_DECLARE(void)
505yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
506{
507 assert(emitter); /* Non-NULL emitter object expected. */
508 assert(!emitter->encoding); /* You can set encoding only once. */
509
510 emitter->encoding = encoding;
511}
512
513/*
514 * Set the canonical output style.
515 */
516
517YAML_DECLARE(void)
518yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
519{
520 assert(emitter); /* Non-NULL emitter object expected. */
521
522 emitter->canonical = (canonical != 0);
523}
524
525/*
526 * Set the indentation increment.
527 */
528
529YAML_DECLARE(void)
530yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
531{
532 assert(emitter); /* Non-NULL emitter object expected. */
533
534 emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
535}
536
537/*
538 * Set the preferred line width.
539 */
540
541YAML_DECLARE(void)
542yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
543{
544 assert(emitter); /* Non-NULL emitter object expected. */
545
cf616166 546 emitter->best_width = (width >= 0) ? width : -1;
b1a54000
KS
547}
548
549/*
550 * Set if unescaped non-ASCII characters are allowed.
551 */
552
553YAML_DECLARE(void)
554yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
555{
556 assert(emitter); /* Non-NULL emitter object expected. */
557
558 emitter->unicode = (unicode != 0);
559}
560
561/*
562 * Set the preferred line break character.
563 */
564
565YAML_DECLARE(void)
566yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
567{
568 assert(emitter); /* Non-NULL emitter object expected. */
569
570 emitter->line_break = line_break;
571}
572
f642fd11
KS
573/*
574 * Destroy a token object.
575 */
576
577YAML_DECLARE(void)
578yaml_token_delete(yaml_token_t *token)
579{
580 assert(token); /* Non-NULL token object expected. */
581
582 switch (token->type)
583 {
584 case YAML_TAG_DIRECTIVE_TOKEN:
585 yaml_free(token->data.tag_directive.handle);
586 yaml_free(token->data.tag_directive.prefix);
587 break;
588
589 case YAML_ALIAS_TOKEN:
26687d7d
KS
590 yaml_free(token->data.alias.value);
591 break;
592
f642fd11 593 case YAML_ANCHOR_TOKEN:
26687d7d 594 yaml_free(token->data.anchor.value);
f642fd11
KS
595 break;
596
597 case YAML_TAG_TOKEN:
598 yaml_free(token->data.tag.handle);
599 yaml_free(token->data.tag.suffix);
600 break;
601
602 case YAML_SCALAR_TOKEN:
603 yaml_free(token->data.scalar.value);
604 break;
54815ffd
KS
605
606 default:
607 break;
f642fd11
KS
608 }
609
610 memset(token, 0, sizeof(yaml_token_t));
26687d7d
KS
611}
612
5a00d8fe
KS
613/*
614 * Check if a string is a valid UTF-8 sequence.
615 *
616 * Check 'reader.c' for more details on UTF-8 encoding.
617 */
618
619static int
620yaml_check_utf8(yaml_char_t *start, size_t length)
621{
622 yaml_char_t *end = start+length;
623 yaml_char_t *pointer = start;
624
625 while (pointer < end) {
626 unsigned char octet;
627 unsigned int width;
628 unsigned int value;
0174ed6e 629 size_t k;
5a00d8fe
KS
630
631 octet = pointer[0];
632 width = (octet & 0x80) == 0x00 ? 1 :
633 (octet & 0xE0) == 0xC0 ? 2 :
634 (octet & 0xF0) == 0xE0 ? 3 :
635 (octet & 0xF8) == 0xF0 ? 4 : 0;
784340c2 636 value = (octet & 0x80) == 0x00 ? octet & 0x7F :
5a00d8fe
KS
637 (octet & 0xE0) == 0xC0 ? octet & 0x1F :
638 (octet & 0xF0) == 0xE0 ? octet & 0x0F :
639 (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
640 if (!width) return 0;
641 if (pointer+width > end) return 0;
642 for (k = 1; k < width; k ++) {
643 octet = pointer[k];
644 if ((octet & 0xC0) != 0x80) return 0;
645 value = (value << 6) + (octet & 0x3F);
646 }
647 if (!((width == 1) ||
648 (width == 2 && value >= 0x80) ||
649 (width == 3 && value >= 0x800) ||
650 (width == 4 && value >= 0x10000))) return 0;
651
652 pointer += width;
653 }
654
655 return 1;
656}
657
658/*
659 * Create STREAM-START.
660 */
661
662YAML_DECLARE(int)
663yaml_stream_start_event_initialize(yaml_event_t *event,
664 yaml_encoding_t encoding)
665{
666 yaml_mark_t mark = { 0, 0, 0 };
667
668 assert(event); /* Non-NULL event object is expected. */
669
670 STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
671
672 return 1;
673}
674
675/*
676 * Create STREAM-END.
677 */
678
679YAML_DECLARE(int)
680yaml_stream_end_event_initialize(yaml_event_t *event)
681{
682 yaml_mark_t mark = { 0, 0, 0 };
683
684 assert(event); /* Non-NULL event object is expected. */
685
686 STREAM_END_EVENT_INIT(*event, mark, mark);
687
688 return 1;
689}
690
691/*
692 * Create DOCUMENT-START.
693 */
694
695YAML_DECLARE(int)
696yaml_document_start_event_initialize(yaml_event_t *event,
697 yaml_version_directive_t *version_directive,
698 yaml_tag_directive_t *tag_directives_start,
699 yaml_tag_directive_t *tag_directives_end,
700 int implicit)
701{
702 struct {
703 yaml_error_type_t error;
704 } context;
705 yaml_mark_t mark = { 0, 0, 0 };
706 yaml_version_directive_t *version_directive_copy = NULL;
707 struct {
708 yaml_tag_directive_t *start;
709 yaml_tag_directive_t *end;
710 yaml_tag_directive_t *top;
711 } tag_directives_copy = { NULL, NULL, NULL };
712 yaml_tag_directive_t value = { NULL, NULL };
713
714 assert(event); /* Non-NULL event object is expected. */
715 assert((tag_directives_start && tag_directives_end) ||
716 (tag_directives_start == tag_directives_end));
717 /* Valid tag directives are expected. */
718
719 if (version_directive) {
720 version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
721 if (!version_directive_copy) goto error;
722 version_directive_copy->major = version_directive->major;
723 version_directive_copy->minor = version_directive->minor;
724 }
725
726 if (tag_directives_start != tag_directives_end) {
727 yaml_tag_directive_t *tag_directive;
728 if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
729 goto error;
730 for (tag_directive = tag_directives_start;
731 tag_directive != tag_directives_end; tag_directive ++) {
732 assert(tag_directive->handle);
733 assert(tag_directive->prefix);
734 if (!yaml_check_utf8(tag_directive->handle,
735 strlen((char *)tag_directive->handle)))
736 goto error;
737 if (!yaml_check_utf8(tag_directive->prefix,
738 strlen((char *)tag_directive->prefix)))
739 goto error;
740 value.handle = yaml_strdup(tag_directive->handle);
741 value.prefix = yaml_strdup(tag_directive->prefix);
742 if (!value.handle || !value.prefix) goto error;
743 if (!PUSH(&context, tag_directives_copy, value))
744 goto error;
745 value.handle = NULL;
746 value.prefix = NULL;
747 }
748 }
749
750 DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
6d167281 751 tag_directives_copy.start, tag_directives_copy.top,
5a00d8fe
KS
752 implicit, mark, mark);
753
754 return 1;
755
756error:
757 yaml_free(version_directive_copy);
758 while (!STACK_EMPTY(context, tag_directives_copy)) {
759 yaml_tag_directive_t value = POP(context, tag_directives_copy);
760 yaml_free(value.handle);
761 yaml_free(value.prefix);
762 }
763 STACK_DEL(context, tag_directives_copy);
764 yaml_free(value.handle);
765 yaml_free(value.prefix);
766
767 return 0;
768}
769
770/*
771 * Create DOCUMENT-END.
772 */
773
774YAML_DECLARE(int)
775yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
776{
777 yaml_mark_t mark = { 0, 0, 0 };
778
779 assert(event); /* Non-NULL emitter object is expected. */
780
781 DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
782
783 return 1;
784}
785
786/*
787 * Create ALIAS.
788 */
789
790YAML_DECLARE(int)
791yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
792{
793 yaml_mark_t mark = { 0, 0, 0 };
794 yaml_char_t *anchor_copy = NULL;
795
796 assert(event); /* Non-NULL event object is expected. */
797 assert(anchor); /* Non-NULL anchor is expected. */
798
799 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
800
801 anchor_copy = yaml_strdup(anchor);
802 if (!anchor_copy)
803 return 0;
804
805 ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
806
807 return 1;
808}
809
810/*
811 * Create SCALAR.
812 */
813
814YAML_DECLARE(int)
815yaml_scalar_event_initialize(yaml_event_t *event,
816 yaml_char_t *anchor, yaml_char_t *tag,
2a02dfd2 817 yaml_char_t *value, int length,
5a00d8fe
KS
818 int plain_implicit, int quoted_implicit,
819 yaml_scalar_style_t style)
820{
821 yaml_mark_t mark = { 0, 0, 0 };
822 yaml_char_t *anchor_copy = NULL;
823 yaml_char_t *tag_copy = NULL;
824 yaml_char_t *value_copy = NULL;
825
826 assert(event); /* Non-NULL event object is expected. */
827 assert(value); /* Non-NULL anchor is expected. */
828
5a00d8fe
KS
829 if (anchor) {
830 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
831 anchor_copy = yaml_strdup(anchor);
832 if (!anchor_copy) goto error;
833 }
834
835 if (tag) {
836 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
837 tag_copy = yaml_strdup(tag);
838 if (!tag_copy) goto error;
839 }
840
2a02dfd2
KS
841 if (length < 0) {
842 length = strlen((char *)value);
843 }
844
5a00d8fe
KS
845 if (!yaml_check_utf8(value, length)) goto error;
846 value_copy = yaml_malloc(length+1);
847 if (!value_copy) goto error;
848 memcpy(value_copy, value, length);
849 value_copy[length] = '\0';
850
851 SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
852 plain_implicit, quoted_implicit, style, mark, mark);
853
854 return 1;
855
856error:
857 yaml_free(anchor_copy);
858 yaml_free(tag_copy);
859 yaml_free(value_copy);
860
861 return 0;
862}
863
864/*
865 * Create SEQUENCE-START.
866 */
867
868YAML_DECLARE(int)
869yaml_sequence_start_event_initialize(yaml_event_t *event,
870 yaml_char_t *anchor, yaml_char_t *tag, int implicit,
871 yaml_sequence_style_t style)
872{
873 yaml_mark_t mark = { 0, 0, 0 };
874 yaml_char_t *anchor_copy = NULL;
875 yaml_char_t *tag_copy = NULL;
876
877 assert(event); /* Non-NULL event object is expected. */
878
879 if (anchor) {
880 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
881 anchor_copy = yaml_strdup(anchor);
882 if (!anchor_copy) goto error;
883 }
884
885 if (tag) {
886 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
887 tag_copy = yaml_strdup(tag);
888 if (!tag_copy) goto error;
889 }
890
891 SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
892 implicit, style, mark, mark);
893
894 return 1;
895
896error:
897 yaml_free(anchor_copy);
898 yaml_free(tag_copy);
899
900 return 0;
901}
902
903/*
904 * Create SEQUENCE-END.
905 */
906
907YAML_DECLARE(int)
908yaml_sequence_end_event_initialize(yaml_event_t *event)
909{
910 yaml_mark_t mark = { 0, 0, 0 };
911
912 assert(event); /* Non-NULL event object is expected. */
913
914 SEQUENCE_END_EVENT_INIT(*event, mark, mark);
915
916 return 1;
917}
918
919/*
920 * Create MAPPING-START.
921 */
922
923YAML_DECLARE(int)
924yaml_mapping_start_event_initialize(yaml_event_t *event,
925 yaml_char_t *anchor, yaml_char_t *tag, int implicit,
926 yaml_mapping_style_t style)
927{
928 yaml_mark_t mark = { 0, 0, 0 };
929 yaml_char_t *anchor_copy = NULL;
930 yaml_char_t *tag_copy = NULL;
931
932 assert(event); /* Non-NULL event object is expected. */
933
934 if (anchor) {
935 if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
936 anchor_copy = yaml_strdup(anchor);
937 if (!anchor_copy) goto error;
938 }
939
940 if (tag) {
941 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
942 tag_copy = yaml_strdup(tag);
943 if (!tag_copy) goto error;
944 }
945
946 MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
947 implicit, style, mark, mark);
948
949 return 1;
950
951error:
952 yaml_free(anchor_copy);
953 yaml_free(tag_copy);
954
955 return 0;
956}
957
958/*
959 * Create MAPPING-END.
960 */
961
962YAML_DECLARE(int)
963yaml_mapping_end_event_initialize(yaml_event_t *event)
964{
965 yaml_mark_t mark = { 0, 0, 0 };
966
967 assert(event); /* Non-NULL event object is expected. */
968
969 MAPPING_END_EVENT_INIT(*event, mark, mark);
970
971 return 1;
972}
973
26687d7d
KS
974/*
975 * Destroy an event object.
976 */
977
978YAML_DECLARE(void)
979yaml_event_delete(yaml_event_t *event)
980{
625fcfe9
KS
981 yaml_tag_directive_t *tag_directive;
982
26687d7d
KS
983 assert(event); /* Non-NULL event object expected. */
984
985 switch (event->type)
986 {
987 case YAML_DOCUMENT_START_EVENT:
625fcfe9
KS
988 yaml_free(event->data.document_start.version_directive);
989 for (tag_directive = event->data.document_start.tag_directives.start;
990 tag_directive != event->data.document_start.tag_directives.end;
991 tag_directive++) {
992 yaml_free(tag_directive->handle);
993 yaml_free(tag_directive->prefix);
994 }
995 yaml_free(event->data.document_start.tag_directives.start);
26687d7d
KS
996 break;
997
998 case YAML_ALIAS_EVENT:
999 yaml_free(event->data.alias.anchor);
1000 break;
1001
1002 case YAML_SCALAR_EVENT:
1003 yaml_free(event->data.scalar.anchor);
1004 yaml_free(event->data.scalar.tag);
1005 yaml_free(event->data.scalar.value);
1006 break;
1007
1008 case YAML_SEQUENCE_START_EVENT:
1009 yaml_free(event->data.sequence_start.anchor);
1010 yaml_free(event->data.sequence_start.tag);
1011 break;
1012
1013 case YAML_MAPPING_START_EVENT:
1014 yaml_free(event->data.mapping_start.anchor);
1015 yaml_free(event->data.mapping_start.tag);
1016 break;
54815ffd
KS
1017
1018 default:
1019 break;
26687d7d
KS
1020 }
1021
1022 memset(event, 0, sizeof(yaml_event_t));
26687d7d
KS
1023}
1024
e27a3c88
KS
1025/*
1026 * Create a document object.
1027 */
1028
1029YAML_DECLARE(int)
1030yaml_document_initialize(yaml_document_t *document,
1031 yaml_version_directive_t *version_directive,
1032 yaml_tag_directive_t *tag_directives_start,
1033 yaml_tag_directive_t *tag_directives_end,
1034 int start_implicit, int end_implicit)
1035{
1036 struct {
1037 yaml_error_type_t error;
1038 } context;
1039 struct {
1040 yaml_node_t *start;
1041 yaml_node_t *end;
1042 yaml_node_t *top;
1043 } nodes = { NULL, NULL, NULL };
1044 yaml_version_directive_t *version_directive_copy = NULL;
1045 struct {
1046 yaml_tag_directive_t *start;
1047 yaml_tag_directive_t *end;
1048 yaml_tag_directive_t *top;
1049 } tag_directives_copy = { NULL, NULL, NULL };
1050 yaml_tag_directive_t value = { NULL, NULL };
1051 yaml_mark_t mark = { 0, 0, 0 };
1052
1053 assert(document); /* Non-NULL document object is expected. */
1054 assert((tag_directives_start && tag_directives_end) ||
1055 (tag_directives_start == tag_directives_end));
1056 /* Valid tag directives are expected. */
1057
1058 if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error;
1059
1060 if (version_directive) {
1061 version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t));
1062 if (!version_directive_copy) goto error;
1063 version_directive_copy->major = version_directive->major;
1064 version_directive_copy->minor = version_directive->minor;
1065 }
1066
1067 if (tag_directives_start != tag_directives_end) {
1068 yaml_tag_directive_t *tag_directive;
1069 if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))
1070 goto error;
1071 for (tag_directive = tag_directives_start;
1072 tag_directive != tag_directives_end; tag_directive ++) {
1073 assert(tag_directive->handle);
1074 assert(tag_directive->prefix);
1075 if (!yaml_check_utf8(tag_directive->handle,
1076 strlen((char *)tag_directive->handle)))
1077 goto error;
1078 if (!yaml_check_utf8(tag_directive->prefix,
1079 strlen((char *)tag_directive->prefix)))
1080 goto error;
1081 value.handle = yaml_strdup(tag_directive->handle);
1082 value.prefix = yaml_strdup(tag_directive->prefix);
1083 if (!value.handle || !value.prefix) goto error;
1084 if (!PUSH(&context, tag_directives_copy, value))
1085 goto error;
1086 value.handle = NULL;
1087 value.prefix = NULL;
1088 }
1089 }
1090
1091 DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
1092 tag_directives_copy.start, tag_directives_copy.top,
1093 start_implicit, end_implicit, mark, mark);
1094
1095 return 1;
1096
1097error:
1098 STACK_DEL(&context, nodes);
1099 yaml_free(version_directive_copy);
1100 while (!STACK_EMPTY(&context, tag_directives_copy)) {
1101 yaml_tag_directive_t value = POP(&context, tag_directives_copy);
1102 yaml_free(value.handle);
1103 yaml_free(value.prefix);
1104 }
1105 STACK_DEL(&context, tag_directives_copy);
1106 yaml_free(value.handle);
1107 yaml_free(value.prefix);
1108
1109 return 0;
1110}
1111
1112/*
1113 * Destroy a document object.
1114 */
1115
1116YAML_DECLARE(void)
1117yaml_document_delete(yaml_document_t *document)
1118{
1119 struct {
1120 yaml_error_type_t error;
c9b74def 1121 } context;
e27a3c88
KS
1122 yaml_tag_directive_t *tag_directive;
1123
c9b74def
KS
1124 context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */
1125
e27a3c88
KS
1126 assert(document); /* Non-NULL document object is expected. */
1127
1128 while (!STACK_EMPTY(&context, document->nodes)) {
1129 yaml_node_t node = POP(&context, document->nodes);
1130 yaml_free(node.tag);
1131 switch (node.type) {
1132 case YAML_SCALAR_NODE:
1133 yaml_free(node.data.scalar.value);
1134 break;
1135 case YAML_SEQUENCE_NODE:
1136 STACK_DEL(&context, node.data.sequence.items);
1137 break;
1138 case YAML_MAPPING_NODE:
1139 STACK_DEL(&context, node.data.mapping.pairs);
1140 break;
1141 default:
1142 assert(0); /* Should not happen. */
1143 }
1144 }
1145 STACK_DEL(&context, document->nodes);
1146
1147 yaml_free(document->version_directive);
1148 for (tag_directive = document->tag_directives.start;
1149 tag_directive != document->tag_directives.end;
1150 tag_directive++) {
1151 yaml_free(tag_directive->handle);
1152 yaml_free(tag_directive->prefix);
1153 }
1154 yaml_free(document->tag_directives.start);
1155
1156 memset(document, 0, sizeof(yaml_document_t));
1157}
1158
1159/**
1160 * Get a document node.
1161 */
1162
1163YAML_DECLARE(yaml_node_t *)
c9b74def 1164yaml_document_get_node(yaml_document_t *document, int index)
e27a3c88
KS
1165{
1166 assert(document); /* Non-NULL document object is expected. */
1167
c9b74def
KS
1168 if (index > 0 && document->nodes.start + index <= document->nodes.top) {
1169 return document->nodes.start + index - 1;
e27a3c88
KS
1170 }
1171 return NULL;
1172}
1173
1174/**
1175 * Get the root object.
1176 */
1177
1178YAML_DECLARE(yaml_node_t *)
1179yaml_document_get_root_node(yaml_document_t *document)
1180{
1181 assert(document); /* Non-NULL document object is expected. */
1182
1183 if (document->nodes.top != document->nodes.start) {
1184 return document->nodes.start;
1185 }
1186 return NULL;
1187}
a907bf85
KS
1188
1189/*
e27a3c88 1190 * Add a scalar node to a document.
a907bf85
KS
1191 */
1192
1193YAML_DECLARE(int)
e27a3c88 1194yaml_document_add_scalar(yaml_document_t *document,
a907bf85
KS
1195 yaml_char_t *tag, yaml_char_t *value, int length,
1196 yaml_scalar_style_t style)
1197{
e27a3c88
KS
1198 struct {
1199 yaml_error_type_t error;
1200 } context;
a907bf85
KS
1201 yaml_mark_t mark = { 0, 0, 0 };
1202 yaml_char_t *tag_copy = NULL;
1203 yaml_char_t *value_copy = NULL;
e27a3c88 1204 yaml_node_t node;
a907bf85 1205
e27a3c88
KS
1206 assert(document); /* Non-NULL document object is expected. */
1207 assert(value); /* Non-NULL value is expected. */
a907bf85
KS
1208
1209 if (!tag) {
c9b74def 1210 tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
a907bf85
KS
1211 }
1212
1213 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1214 tag_copy = yaml_strdup(tag);
1215 if (!tag_copy) goto error;
1216
1217 if (length < 0) {
1218 length = strlen((char *)value);
1219 }
1220
1221 if (!yaml_check_utf8(value, length)) goto error;
1222 value_copy = yaml_malloc(length+1);
1223 if (!value_copy) goto error;
1224 memcpy(value_copy, value, length);
1225 value_copy[length] = '\0';
1226
e27a3c88
KS
1227 SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
1228 if (!PUSH(&context, document->nodes, node)) goto error;
a907bf85 1229
e27a3c88 1230 return document->nodes.top - document->nodes.start;
a907bf85
KS
1231
1232error:
1233 yaml_free(tag_copy);
1234 yaml_free(value_copy);
1235
1236 return 0;
1237}
1238
1239/*
e27a3c88 1240 * Add a sequence node to a document.
a907bf85
KS
1241 */
1242
1243YAML_DECLARE(int)
e27a3c88 1244yaml_document_add_sequence(yaml_document_t *document,
a907bf85
KS
1245 yaml_char_t *tag, yaml_sequence_style_t style)
1246{
1247 struct {
1248 yaml_error_type_t error;
1249 } context;
1250 yaml_mark_t mark = { 0, 0, 0 };
1251 yaml_char_t *tag_copy = NULL;
1252 struct {
1253 yaml_node_item_t *start;
1254 yaml_node_item_t *end;
1255 yaml_node_item_t *top;
1256 } items = { NULL, NULL, NULL };
e27a3c88 1257 yaml_node_t node;
a907bf85 1258
e27a3c88 1259 assert(document); /* Non-NULL document object is expected. */
a907bf85
KS
1260
1261 if (!tag) {
c9b74def 1262 tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
a907bf85
KS
1263 }
1264
e27a3c88
KS
1265 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1266 tag_copy = yaml_strdup(tag);
1267 if (!tag_copy) goto error;
a907bf85 1268
e27a3c88 1269 if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
a907bf85 1270
e27a3c88
KS
1271 SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
1272 style, mark, mark);
1273 if (!PUSH(&context, document->nodes, node)) goto error;
a907bf85 1274
e27a3c88 1275 return document->nodes.top - document->nodes.start;
a907bf85
KS
1276
1277error:
e27a3c88 1278 STACK_DEL(&context, items);
a907bf85 1279 yaml_free(tag_copy);
a907bf85
KS
1280
1281 return 0;
1282}
1283
1284/*
e27a3c88 1285 * Add a mapping node to a document.
a907bf85
KS
1286 */
1287
1288YAML_DECLARE(int)
e27a3c88 1289yaml_document_add_mapping(yaml_document_t *document,
a907bf85
KS
1290 yaml_char_t *tag, yaml_mapping_style_t style)
1291{
1292 struct {
1293 yaml_error_type_t error;
1294 } context;
1295 yaml_mark_t mark = { 0, 0, 0 };
1296 yaml_char_t *tag_copy = NULL;
1297 struct {
1298 yaml_node_pair_t *start;
1299 yaml_node_pair_t *end;
1300 yaml_node_pair_t *top;
1301 } pairs = { NULL, NULL, NULL };
e27a3c88 1302 yaml_node_t node;
a907bf85 1303
e27a3c88 1304 assert(document); /* Non-NULL document object is expected. */
a907bf85
KS
1305
1306 if (!tag) {
c9b74def 1307 tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
a907bf85
KS
1308 }
1309
e27a3c88
KS
1310 if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1311 tag_copy = yaml_strdup(tag);
1312 if (!tag_copy) goto error;
a907bf85 1313
e27a3c88 1314 if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
a907bf85 1315
e27a3c88
KS
1316 MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
1317 style, mark, mark);
1318 if (!PUSH(&context, document->nodes, node)) goto error;
a907bf85 1319
e27a3c88 1320 return document->nodes.top - document->nodes.start;
a907bf85
KS
1321
1322error:
e27a3c88 1323 STACK_DEL(&context, pairs);
a907bf85 1324 yaml_free(tag_copy);
a907bf85
KS
1325
1326 return 0;
1327}
1328
1329/*
e27a3c88 1330 * Append an item to a sequence node.
a907bf85
KS
1331 */
1332
e27a3c88
KS
1333YAML_DECLARE(int)
1334yaml_document_append_sequence_item(yaml_document_t *document,
1335 int sequence, int item)
a907bf85
KS
1336{
1337 struct {
1338 yaml_error_type_t error;
1339 } context;
a907bf85 1340
e27a3c88
KS
1341 assert(document); /* Non-NULL document is required. */
1342 assert(sequence > 0
1343 && document->nodes.start + sequence <= document->nodes.top);
1344 /* Valid sequence id is required. */
1345 assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
1346 /* A sequence node is required. */
1347 assert(item > 0 && document->nodes.start + item <= document->nodes.top);
1348 /* Valid item id is required. */
1349
1350 if (!PUSH(&context,
1351 document->nodes.start[sequence-1].data.sequence.items, item))
1352 return 0;
a907bf85 1353
e27a3c88
KS
1354 return 1;
1355}
a907bf85 1356
e27a3c88
KS
1357/*
1358 * Append a pair of a key and a value to a mapping node.
1359 */
a907bf85 1360
e27a3c88
KS
1361YAML_DECLARE(int)
1362yaml_document_append_mapping_pair(yaml_document_t *document,
1363 int mapping, int key, int value)
1364{
1365 struct {
1366 yaml_error_type_t error;
1367 } context;
252c575a
KS
1368
1369 yaml_node_pair_t pair;
e27a3c88
KS
1370
1371 assert(document); /* Non-NULL document is required. */
1372 assert(mapping > 0
1373 && document->nodes.start + mapping <= document->nodes.top);
1374 /* Valid mapping id is required. */
1375 assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
1376 /* A mapping node is required. */
1377 assert(key > 0 && document->nodes.start + key <= document->nodes.top);
1378 /* Valid key id is required. */
1379 assert(value > 0 && document->nodes.start + value <= document->nodes.top);
1380 /* Valid value id is required. */
1381
252c575a
KS
1382 pair.key = key;
1383 pair.value = value;
1384
e27a3c88
KS
1385 if (!PUSH(&context,
1386 document->nodes.start[mapping-1].data.mapping.pairs, pair))
1387 return 0;
a907bf85 1388
e27a3c88
KS
1389 return 1;
1390}
a907bf85 1391
0174ed6e 1392
This page took 0.581134 seconds and 5 git commands to generate.