on master help sign in
Included libyaml source in the tree
55c22e0Michael Snoyman
c/api.cnew file+1388
@@ -0,0 +1,1388 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * Get the library version.
6+ */
7+
8+YAML_DECLARE(const char *)
9+yaml_get_version_string(void)
10+{
11+ return YAML_VERSION_STRING;
12+}
13+
14+/*
15+ * Get the library version numbers.
16+ */
17+
18+YAML_DECLARE(void)
19+yaml_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+
26+/*
27+ * Allocate a dynamic memory block.
28+ */
29+
30+YAML_DECLARE(void *)
31+yaml_malloc(size_t size)
32+{
33+ return malloc(size ? size : 1);
34+}
35+
36+/*
37+ * Reallocate a dynamic memory block.
38+ */
39+
40+YAML_DECLARE(void *)
41+yaml_realloc(void *ptr, size_t size)
42+{
43+ return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
44+}
45+
46+/*
47+ * Free a dynamic memory block.
48+ */
49+
50+YAML_DECLARE(void)
51+yaml_free(void *ptr)
52+{
53+ if (ptr) free(ptr);
54+}
55+
56+/*
57+ * Duplicate a string.
58+ */
59+
60+YAML_DECLARE(yaml_char_t *)
61+yaml_strdup(const yaml_char_t *str)
62+{
63+ if (!str)
64+ return NULL;
65+
66+ return (yaml_char_t *)strdup((char *)str);
67+}
68+
69+/*
70+ * Extend a string.
71+ */
72+
73+YAML_DECLARE(int)
74+yaml_string_extend(yaml_char_t **start,
75+ yaml_char_t **pointer, yaml_char_t **end)
76+{
77+ yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2);
78+
79+ if (!new_start) return 0;
80+
81+ memset(new_start + (*end - *start), 0, *end - *start);
82+
83+ *pointer = new_start + (*pointer - *start);
84+ *end = new_start + (*end - *start)*2;
85+ *start = new_start;
86+
87+ return 1;
88+}
89+
90+/*
91+ * Append a string B to a string A.
92+ */
93+
94+YAML_DECLARE(int)
95+yaml_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;
101+
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+ }
106+
107+ memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
108+ *a_pointer += *b_pointer - *b_start;
109+
110+ return 1;
111+}
112+
113+/*
114+ * Extend a stack.
115+ */
116+
117+YAML_DECLARE(int)
118+yaml_stack_extend(void **start, void **top, void **end)
119+{
120+ void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
121+
122+ if (!new_start) return 0;
123+
124+ *top = (char *)new_start + ((char *)*top - (char *)*start);
125+ *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
126+ *start = new_start;
127+
128+ return 1;
129+}
130+
131+/*
132+ * Extend or move a queue.
133+ */
134+
135+YAML_DECLARE(int)
136+yaml_queue_extend(void **start, void **head, void **tail, void **end)
137+{
138+ /* Check if we need to resize the queue. */
139+
140+ if (*start == *head && *tail == *end) {
141+ void *new_start = yaml_realloc(*start,
142+ ((char *)*end - (char *)*start)*2);
143+
144+ if (!new_start) return 0;
145+
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;
149+ *start = new_start;
150+ }
151+
152+ /* Check if we need to move the queue at the beginning of the buffer. */
153+
154+ if (*tail == *end) {
155+ if (*head != *tail) {
156+ memmove(*start, *head, (char *)*tail - (char *)*head);
157+ }
158+ *tail = (char *)*tail - (char *)*head + (char *)*start;
159+ *head = *start;
160+ }
161+
162+ return 1;
163+}
164+
165+
166+/*
167+ * Create a new parser object.
168+ */
169+
170+YAML_DECLARE(int)
171+yaml_parser_initialize(yaml_parser_t *parser)
172+{
173+ assert(parser); /* Non-NULL parser object expected. */
174+
175+ memset(parser, 0, sizeof(yaml_parser_t));
176+ if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
177+ goto error;
178+ if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
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;
192+
193+ return 1;
194+
195+error:
196+
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);
205+
206+ return 0;
207+}
208+
209+/*
210+ * Destroy a parser object.
211+ */
212+
213+YAML_DECLARE(void)
214+yaml_parser_delete(yaml_parser_t *parser)
215+{
216+ assert(parser); /* Non-NULL parser object expected. */
217+
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);
234+
235+ memset(parser, 0, sizeof(yaml_parser_t));
236+}
237+
238+/*
239+ * String read handler.
240+ */
241+
242+static int
243+yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
244+ size_t *size_read)
245+{
246+ yaml_parser_t *parser = data;
247+
248+ if (parser->input.string.current == parser->input.string.end) {
249+ *size_read = 0;
250+ return 1;
251+ }
252+
253+ if (size > (size_t)(parser->input.string.end
254+ - parser->input.string.current)) {
255+ size = parser->input.string.end - parser->input.string.current;
256+ }
257+
258+ memcpy(buffer, parser->input.string.current, size);
259+ parser->input.string.current += size;
260+ *size_read = size;
261+ return 1;
262+}
263+
264+/*
265+ * File read handler.
266+ */
267+
268+static int
269+yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
270+ size_t *size_read)
271+{
272+ yaml_parser_t *parser = data;
273+
274+ *size_read = fread(buffer, 1, size, parser->input.file);
275+ return !ferror(parser->input.file);
276+}
277+
278+/*
279+ * Set a string input.
280+ */
281+
282+YAML_DECLARE(void)
283+yaml_parser_set_input_string(yaml_parser_t *parser,
284+ const unsigned char *input, size_t size)
285+{
286+ assert(parser); /* Non-NULL parser object expected. */
287+ assert(!parser->read_handler); /* You can set the source only once. */
288+ assert(input); /* Non-NULL input string expected. */
289+
290+ parser->read_handler = yaml_string_read_handler;
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;
296+}
297+
298+/*
299+ * Set a file input.
300+ */
301+
302+YAML_DECLARE(void)
303+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
304+{
305+ assert(parser); /* Non-NULL parser object expected. */
306+ assert(!parser->read_handler); /* You can set the source only once. */
307+ assert(file); /* Non-NULL file object expected. */
308+
309+ parser->read_handler = yaml_file_read_handler;
310+ parser->read_handler_data = parser;
311+
312+ parser->input.file = file;
313+}
314+
315+/*
316+ * Set a generic input.
317+ */
318+
319+YAML_DECLARE(void)
320+yaml_parser_set_input(yaml_parser_t *parser,
321+ yaml_read_handler_t *handler, void *data)
322+{
323+ assert(parser); /* Non-NULL parser object expected. */
324+ assert(!parser->read_handler); /* You can set the source only once. */
325+ assert(handler); /* Non-NULL read handler expected. */
326+
327+ parser->read_handler = handler;
328+ parser->read_handler_data = data;
329+}
330+
331+/*
332+ * Set the source encoding.
333+ */
334+
335+YAML_DECLARE(void)
336+yaml_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;
342+}
343+
344+/*
345+ * Create a new emitter object.
346+ */
347+
348+YAML_DECLARE(int)
349+yaml_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+
369+error:
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+
385+YAML_DECLARE(void)
386+yaml_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+ }
396+ QUEUE_DEL(emitter, emitter->events);
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);
404+ yaml_free(emitter->anchors);
405+
406+ memset(emitter, 0, sizeof(yaml_emitter_t));
407+}
408+
409+/*
410+ * String write handler.
411+ */
412+
413+static int
414+yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
415+{
416+ yaml_emitter_t *emitter = data;
417+
418+ if (emitter->output.string.size + *emitter->output.string.size_written
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+
439+static int
440+yaml_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+
450+YAML_DECLARE(void)
451+yaml_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+
471+YAML_DECLARE(void)
472+yaml_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+
488+YAML_DECLARE(void)
489+yaml_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+
504+YAML_DECLARE(void)
505+yaml_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+
517+YAML_DECLARE(void)
518+yaml_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+
529+YAML_DECLARE(void)
530+yaml_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+
541+YAML_DECLARE(void)
542+yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
543+{
544+ assert(emitter); /* Non-NULL emitter object expected. */
545+
546+ emitter->best_width = (width >= 0) ? width : -1;
547+}
548+
549+/*
550+ * Set if unescaped non-ASCII characters are allowed.
551+ */
552+
553+YAML_DECLARE(void)
554+yaml_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+
565+YAML_DECLARE(void)
566+yaml_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+
573+/*
574+ * Destroy a token object.
575+ */
576+
577+YAML_DECLARE(void)
578+yaml_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:
590+ yaml_free(token->data.alias.value);
591+ break;
592+
593+ case YAML_ANCHOR_TOKEN:
594+ yaml_free(token->data.anchor.value);
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;
605+
606+ default:
607+ break;
608+ }
609+
610+ memset(token, 0, sizeof(yaml_token_t));
611+}
612+
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+
619+static int
620+yaml_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;
629+ size_t k;
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;
636+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
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+
662+YAML_DECLARE(int)
663+yaml_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+
679+YAML_DECLARE(int)
680+yaml_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+
695+YAML_DECLARE(int)
696+yaml_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,
751+ tag_directives_copy.start, tag_directives_copy.top,
752+ implicit, mark, mark);
753+
754+ return 1;
755+
756+error:
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+
774+YAML_DECLARE(int)
775+yaml_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+
790+YAML_DECLARE(int)
791+yaml_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+
814+YAML_DECLARE(int)
815+yaml_scalar_event_initialize(yaml_event_t *event,
816+ yaml_char_t *anchor, yaml_char_t *tag,
817+ yaml_char_t *value, int length,
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+
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+
841+ if (length < 0) {
842+ length = strlen((char *)value);
843+ }
844+
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+
856+error:
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+
868+YAML_DECLARE(int)
869+yaml_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+
896+error:
897+ yaml_free(anchor_copy);
898+ yaml_free(tag_copy);
899+
900+ return 0;
901+}
902+
903+/*
904+ * Create SEQUENCE-END.
905+ */
906+
907+YAML_DECLARE(int)
908+yaml_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+
923+YAML_DECLARE(int)
924+yaml_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+
951+error:
952+ yaml_free(anchor_copy);
953+ yaml_free(tag_copy);
954+
955+ return 0;
956+}
957+
958+/*
959+ * Create MAPPING-END.
960+ */
961+
962+YAML_DECLARE(int)
963+yaml_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+
974+/*
975+ * Destroy an event object.
976+ */
977+
978+YAML_DECLARE(void)
979+yaml_event_delete(yaml_event_t *event)
980+{
981+ yaml_tag_directive_t *tag_directive;
982+
983+ assert(event); /* Non-NULL event object expected. */
984+
985+ switch (event->type)
986+ {
987+ case YAML_DOCUMENT_START_EVENT:
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);
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;
1017+
1018+ default:
1019+ break;
1020+ }
1021+
1022+ memset(event, 0, sizeof(yaml_event_t));
1023+}
1024+
1025+/*
1026+ * Create a document object.
1027+ */
1028+
1029+YAML_DECLARE(int)
1030+yaml_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+
1097+error:
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+
1116+YAML_DECLARE(void)
1117+yaml_document_delete(yaml_document_t *document)
1118+{
1119+ struct {
1120+ yaml_error_type_t error;
1121+ } context;
1122+ yaml_tag_directive_t *tag_directive;
1123+
1124+ context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */
1125+
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+
1163+YAML_DECLARE(yaml_node_t *)
1164+yaml_document_get_node(yaml_document_t *document, int index)
1165+{
1166+ assert(document); /* Non-NULL document object is expected. */
1167+
1168+ if (index > 0 && document->nodes.start + index <= document->nodes.top) {
1169+ return document->nodes.start + index - 1;
1170+ }
1171+ return NULL;
1172+}
1173+
1174+/**
1175+ * Get the root object.
1176+ */
1177+
1178+YAML_DECLARE(yaml_node_t *)
1179+yaml_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+}
1188+
1189+/*
1190+ * Add a scalar node to a document.
1191+ */
1192+
1193+YAML_DECLARE(int)
1194+yaml_document_add_scalar(yaml_document_t *document,
1195+ yaml_char_t *tag, yaml_char_t *value, int length,
1196+ yaml_scalar_style_t style)
1197+{
1198+ struct {
1199+ yaml_error_type_t error;
1200+ } context;
1201+ yaml_mark_t mark = { 0, 0, 0 };
1202+ yaml_char_t *tag_copy = NULL;
1203+ yaml_char_t *value_copy = NULL;
1204+ yaml_node_t node;
1205+
1206+ assert(document); /* Non-NULL document object is expected. */
1207+ assert(value); /* Non-NULL value is expected. */
1208+
1209+ if (!tag) {
1210+ tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
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+
1227+ SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
1228+ if (!PUSH(&context, document->nodes, node)) goto error;
1229+
1230+ return document->nodes.top - document->nodes.start;
1231+
1232+error:
1233+ yaml_free(tag_copy);
1234+ yaml_free(value_copy);
1235+
1236+ return 0;
1237+}
1238+
1239+/*
1240+ * Add a sequence node to a document.
1241+ */
1242+
1243+YAML_DECLARE(int)
1244+yaml_document_add_sequence(yaml_document_t *document,
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 };
1257+ yaml_node_t node;
1258+
1259+ assert(document); /* Non-NULL document object is expected. */
1260+
1261+ if (!tag) {
1262+ tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
1263+ }
1264+
1265+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1266+ tag_copy = yaml_strdup(tag);
1267+ if (!tag_copy) goto error;
1268+
1269+ if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error;
1270+
1271+ SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
1272+ style, mark, mark);
1273+ if (!PUSH(&context, document->nodes, node)) goto error;
1274+
1275+ return document->nodes.top - document->nodes.start;
1276+
1277+error:
1278+ STACK_DEL(&context, items);
1279+ yaml_free(tag_copy);
1280+
1281+ return 0;
1282+}
1283+
1284+/*
1285+ * Add a mapping node to a document.
1286+ */
1287+
1288+YAML_DECLARE(int)
1289+yaml_document_add_mapping(yaml_document_t *document,
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 };
1302+ yaml_node_t node;
1303+
1304+ assert(document); /* Non-NULL document object is expected. */
1305+
1306+ if (!tag) {
1307+ tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
1308+ }
1309+
1310+ if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1311+ tag_copy = yaml_strdup(tag);
1312+ if (!tag_copy) goto error;
1313+
1314+ if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error;
1315+
1316+ MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
1317+ style, mark, mark);
1318+ if (!PUSH(&context, document->nodes, node)) goto error;
1319+
1320+ return document->nodes.top - document->nodes.start;
1321+
1322+error:
1323+ STACK_DEL(&context, pairs);
1324+ yaml_free(tag_copy);
1325+
1326+ return 0;
1327+}
1328+
1329+/*
1330+ * Append an item to a sequence node.
1331+ */
1332+
1333+YAML_DECLARE(int)
1334+yaml_document_append_sequence_item(yaml_document_t *document,
1335+ int sequence, int item)
1336+{
1337+ struct {
1338+ yaml_error_type_t error;
1339+ } context;
1340+
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;
1353+
1354+ return 1;
1355+}
1356+
1357+/*
1358+ * Append a pair of a key and a value to a mapping node.
1359+ */
1360+
1361+YAML_DECLARE(int)
1362+yaml_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;
1368+ yaml_node_pair_t pair = { key, value };
1369+
1370+ assert(document); /* Non-NULL document is required. */
1371+ assert(mapping > 0
1372+ && document->nodes.start + mapping <= document->nodes.top);
1373+ /* Valid mapping id is required. */
1374+ assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
1375+ /* A mapping node is required. */
1376+ assert(key > 0 && document->nodes.start + key <= document->nodes.top);
1377+ /* Valid key id is required. */
1378+ assert(value > 0 && document->nodes.start + value <= document->nodes.top);
1379+ /* Valid value id is required. */
1380+
1381+ if (!PUSH(&context,
1382+ document->nodes.start[mapping-1].data.mapping.pairs, pair))
1383+ return 0;
1384+
1385+ return 1;
1386+}
1387+
1388+
c/dumper.cnew file+394
@@ -0,0 +1,394 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * API functions.
6+ */
7+
8+YAML_DECLARE(int)
9+yaml_emitter_open(yaml_emitter_t *emitter);
10+
11+YAML_DECLARE(int)
12+yaml_emitter_close(yaml_emitter_t *emitter);
13+
14+YAML_DECLARE(int)
15+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
16+
17+/*
18+ * Clean up functions.
19+ */
20+
21+static void
22+yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
23+
24+/*
25+ * Anchor functions.
26+ */
27+
28+static void
29+yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
30+
31+static yaml_char_t *
32+yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
33+
34+
35+/*
36+ * Serialize functions.
37+ */
38+
39+static int
40+yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
41+
42+static int
43+yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
44+
45+static int
46+yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
47+ yaml_char_t *anchor);
48+
49+static int
50+yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
51+ yaml_char_t *anchor);
52+
53+static int
54+yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
55+ yaml_char_t *anchor);
56+
57+/*
58+ * Issue a STREAM-START event.
59+ */
60+
61+YAML_DECLARE(int)
62+yaml_emitter_open(yaml_emitter_t *emitter)
63+{
64+ yaml_event_t event;
65+ yaml_mark_t mark = { 0, 0, 0 };
66+
67+ assert(emitter); /* Non-NULL emitter object is required. */
68+ assert(!emitter->opened); /* Emitter should not be opened yet. */
69+
70+ STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
71+
72+ if (!yaml_emitter_emit(emitter, &event)) {
73+ return 0;
74+ }
75+
76+ emitter->opened = 1;
77+
78+ return 1;
79+}
80+
81+/*
82+ * Issue a STREAM-END event.
83+ */
84+
85+YAML_DECLARE(int)
86+yaml_emitter_close(yaml_emitter_t *emitter)
87+{
88+ yaml_event_t event;
89+ yaml_mark_t mark = { 0, 0, 0 };
90+
91+ assert(emitter); /* Non-NULL emitter object is required. */
92+ assert(emitter->opened); /* Emitter should be opened. */
93+
94+ if (emitter->closed) return 1;
95+
96+ STREAM_END_EVENT_INIT(event, mark, mark);
97+
98+ if (!yaml_emitter_emit(emitter, &event)) {
99+ return 0;
100+ }
101+
102+ emitter->closed = 1;
103+
104+ return 1;
105+}
106+
107+/*
108+ * Dump a YAML document.
109+ */
110+
111+YAML_DECLARE(int)
112+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
113+{
114+ yaml_event_t event;
115+ yaml_mark_t mark = { 0, 0, 0 };
116+
117+ assert(emitter); /* Non-NULL emitter object is required. */
118+ assert(document); /* Non-NULL emitter object is expected. */
119+
120+ emitter->document = document;
121+
122+ if (!emitter->opened) {
123+ if (!yaml_emitter_open(emitter)) goto error;
124+ }
125+
126+ if (STACK_EMPTY(emitter, document->nodes)) {
127+ if (!yaml_emitter_close(emitter)) goto error;
128+ yaml_emitter_delete_document_and_anchors(emitter);
129+ return 1;
130+ }
131+
132+ assert(emitter->opened); /* Emitter should be opened. */
133+
134+ emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
135+ * (document->nodes.top - document->nodes.start));
136+ if (!emitter->anchors) goto error;
137+ memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
138+ * (document->nodes.top - document->nodes.start));
139+
140+ DOCUMENT_START_EVENT_INIT(event, document->version_directive,
141+ document->tag_directives.start, document->tag_directives.end,
142+ document->start_implicit, mark, mark);
143+ if (!yaml_emitter_emit(emitter, &event)) goto error;
144+
145+ yaml_emitter_anchor_node(emitter, 1);
146+ if (!yaml_emitter_dump_node(emitter, 1)) goto error;
147+
148+ DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
149+ if (!yaml_emitter_emit(emitter, &event)) goto error;
150+
151+ yaml_emitter_delete_document_and_anchors(emitter);
152+
153+ return 1;
154+
155+error:
156+
157+ yaml_emitter_delete_document_and_anchors(emitter);
158+
159+ return 0;
160+}
161+
162+/*
163+ * Clean up the emitter object after a document is dumped.
164+ */
165+
166+static void
167+yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
168+{
169+ int index;
170+
171+ if (!emitter->anchors) {
172+ yaml_document_delete(emitter->document);
173+ emitter->document = NULL;
174+ return;
175+ }
176+
177+ for (index = 0; emitter->document->nodes.start + index
178+ < emitter->document->nodes.top; index ++) {
179+ yaml_node_t node = emitter->document->nodes.start[index];
180+ if (!emitter->anchors[index].serialized) {
181+ yaml_free(node.tag);
182+ if (node.type == YAML_SCALAR_NODE) {
183+ yaml_free(node.data.scalar.value);
184+ }
185+ }
186+ if (node.type == YAML_SEQUENCE_NODE) {
187+ STACK_DEL(emitter, node.data.sequence.items);
188+ }
189+ if (node.type == YAML_MAPPING_NODE) {
190+ STACK_DEL(emitter, node.data.mapping.pairs);
191+ }
192+ }
193+
194+ STACK_DEL(emitter, emitter->document->nodes);
195+ yaml_free(emitter->anchors);
196+
197+ emitter->anchors = NULL;
198+ emitter->last_anchor_id = 0;
199+ emitter->document = NULL;
200+}
201+
202+/*
203+ * Check the references of a node and assign the anchor id if needed.
204+ */
205+
206+static void
207+yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
208+{
209+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
210+ yaml_node_item_t *item;
211+ yaml_node_pair_t *pair;
212+
213+ emitter->anchors[index-1].references ++;
214+
215+ if (emitter->anchors[index-1].references == 1) {
216+ switch (node->type) {
217+ case YAML_SEQUENCE_NODE:
218+ for (item = node->data.sequence.items.start;
219+ item < node->data.sequence.items.top; item ++) {
220+ yaml_emitter_anchor_node(emitter, *item);
221+ }
222+ break;
223+ case YAML_MAPPING_NODE:
224+ for (pair = node->data.mapping.pairs.start;
225+ pair < node->data.mapping.pairs.top; pair ++) {
226+ yaml_emitter_anchor_node(emitter, pair->key);
227+ yaml_emitter_anchor_node(emitter, pair->value);
228+ }
229+ break;
230+ default:
231+ break;
232+ }
233+ }
234+
235+ else if (emitter->anchors[index-1].references == 2) {
236+ emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
237+ }
238+}
239+
240+/*
241+ * Generate a textual representation for an anchor.
242+ */
243+
244+#define ANCHOR_TEMPLATE "id%03d"
245+#define ANCHOR_TEMPLATE_LENGTH 16
246+
247+static yaml_char_t *
248+yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
249+{
250+ yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
251+
252+ if (!anchor) return NULL;
253+
254+ sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
255+
256+ return anchor;
257+}
258+
259+/*
260+ * Serialize a node.
261+ */
262+
263+static int
264+yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
265+{
266+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
267+ int anchor_id = emitter->anchors[index-1].anchor;
268+ yaml_char_t *anchor = NULL;
269+
270+ if (anchor_id) {
271+ anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
272+ if (!anchor) return 0;
273+ }
274+
275+ if (emitter->anchors[index-1].serialized) {
276+ return yaml_emitter_dump_alias(emitter, anchor);
277+ }
278+
279+ emitter->anchors[index-1].serialized = 1;
280+
281+ switch (node->type) {
282+ case YAML_SCALAR_NODE:
283+ return yaml_emitter_dump_scalar(emitter, node, anchor);
284+ case YAML_SEQUENCE_NODE:
285+ return yaml_emitter_dump_sequence(emitter, node, anchor);
286+ case YAML_MAPPING_NODE:
287+ return yaml_emitter_dump_mapping(emitter, node, anchor);
288+ default:
289+ assert(0); /* Could not happen. */
290+ break;
291+ }
292+
293+ return 0; /* Could not happen. */
294+}
295+
296+/*
297+ * Serialize an alias.
298+ */
299+
300+static int
301+yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
302+{
303+ yaml_event_t event;
304+ yaml_mark_t mark = { 0, 0, 0 };
305+
306+ ALIAS_EVENT_INIT(event, anchor, mark, mark);
307+
308+ return yaml_emitter_emit(emitter, &event);
309+}
310+
311+/*
312+ * Serialize a scalar.
313+ */
314+
315+static int
316+yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
317+ yaml_char_t *anchor)
318+{
319+ yaml_event_t event;
320+ yaml_mark_t mark = { 0, 0, 0 };
321+
322+ int plain_implicit = (strcmp((char *)node->tag,
323+ YAML_DEFAULT_SCALAR_TAG) == 0);
324+ int quoted_implicit = (strcmp((char *)node->tag,
325+ YAML_DEFAULT_SCALAR_TAG) == 0);
326+
327+ SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
328+ node->data.scalar.length, plain_implicit, quoted_implicit,
329+ node->data.scalar.style, mark, mark);
330+
331+ return yaml_emitter_emit(emitter, &event);
332+}
333+
334+/*
335+ * Serialize a sequence.
336+ */
337+
338+static int
339+yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
340+ yaml_char_t *anchor)
341+{
342+ yaml_event_t event;
343+ yaml_mark_t mark = { 0, 0, 0 };
344+
345+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
346+
347+ yaml_node_item_t *item;
348+
349+ SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
350+ node->data.sequence.style, mark, mark);
351+ if (!yaml_emitter_emit(emitter, &event)) return 0;
352+
353+ for (item = node->data.sequence.items.start;
354+ item < node->data.sequence.items.top; item ++) {
355+ if (!yaml_emitter_dump_node(emitter, *item)) return 0;
356+ }
357+
358+ SEQUENCE_END_EVENT_INIT(event, mark, mark);
359+ if (!yaml_emitter_emit(emitter, &event)) return 0;
360+
361+ return 1;
362+}
363+
364+/*
365+ * Serialize a mapping.
366+ */
367+
368+static int
369+yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
370+ yaml_char_t *anchor)
371+{
372+ yaml_event_t event;
373+ yaml_mark_t mark = { 0, 0, 0 };
374+
375+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
376+
377+ yaml_node_pair_t *pair;
378+
379+ MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
380+ node->data.mapping.style, mark, mark);
381+ if (!yaml_emitter_emit(emitter, &event)) return 0;
382+
383+ for (pair = node->data.mapping.pairs.start;
384+ pair < node->data.mapping.pairs.top; pair ++) {
385+ if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
386+ if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
387+ }
388+
389+ MAPPING_END_EVENT_INIT(event, mark, mark);
390+ if (!yaml_emitter_emit(emitter, &event)) return 0;
391+
392+ return 1;
393+}
394+
c/emitter.cnew file+2297
@@ -0,0 +1,2297 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * Flush the buffer if needed.
6+ */
7+
8+#define FLUSH(emitter) \
9+ ((emitter->buffer.pointer+5 < emitter->buffer.end) \
10+ || yaml_emitter_flush(emitter))
11+
12+/*
13+ * Put a character to the output buffer.
14+ */
15+
16+#define PUT(emitter,value) \
17+ (FLUSH(emitter) \
18+ && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
19+ emitter->column ++, \
20+ 1))
21+
22+/*
23+ * Put a line break to the output buffer.
24+ */
25+
26+#define PUT_BREAK(emitter) \
27+ (FLUSH(emitter) \
28+ && ((emitter->line_break == YAML_CR_BREAK ? \
29+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
30+ emitter->line_break == YAML_LN_BREAK ? \
31+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
32+ emitter->line_break == YAML_CRLN_BREAK ? \
33+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
34+ *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
35+ emitter->column = 0, \
36+ emitter->line ++, \
37+ 1))
38+
39+/*
40+ * Copy a character from a string into buffer.
41+ */
42+
43+#define WRITE(emitter,string) \
44+ (FLUSH(emitter) \
45+ && (COPY(emitter->buffer,string), \
46+ emitter->column ++, \
47+ 1))
48+
49+/*
50+ * Copy a line break character from a string into buffer.
51+ */
52+
53+#define WRITE_BREAK(emitter,string) \
54+ (FLUSH(emitter) \
55+ && (CHECK(string,'\n') ? \
56+ (PUT_BREAK(emitter), \
57+ string.pointer ++, \
58+ 1) : \
59+ (COPY(emitter->buffer,string), \
60+ emitter->column = 0, \
61+ emitter->line ++, \
62+ 1)))
63+
64+/*
65+ * API functions.
66+ */
67+
68+YAML_DECLARE(int)
69+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
70+
71+/*
72+ * Utility functions.
73+ */
74+
75+static int
76+yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
77+
78+static int
79+yaml_emitter_need_more_events(yaml_emitter_t *emitter);
80+
81+static int
82+yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
83+ yaml_tag_directive_t value, int allow_duplicates);
84+
85+static int
86+yaml_emitter_increase_indent(yaml_emitter_t *emitter,
87+ int flow, int indentless);
88+
89+/*
90+ * State functions.
91+ */
92+
93+static int
94+yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
95+
96+static int
97+yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
98+ yaml_event_t *event);
99+
100+static int
101+yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
102+ yaml_event_t *event, int first);
103+
104+static int
105+yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
106+ yaml_event_t *event);
107+
108+static int
109+yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
110+ yaml_event_t *event);
111+
112+static int
113+yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
114+ yaml_event_t *event, int first);
115+
116+static int
117+yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
118+ yaml_event_t *event, int first);
119+
120+static int
121+yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
122+ yaml_event_t *event, int simple);
123+
124+static int
125+yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
126+ yaml_event_t *event, int first);
127+
128+static int
129+yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
130+ yaml_event_t *event, int first);
131+
132+static int
133+yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
134+ yaml_event_t *event, int simple);
135+
136+static int
137+yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
138+ int root, int sequence, int mapping, int simple_key);
139+
140+static int
141+yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
142+
143+static int
144+yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
145+
146+static int
147+yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
148+
149+static int
150+yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
151+
152+/*
153+ * Checkers.
154+ */
155+
156+static int
157+yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
158+
159+static int
160+yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
161+
162+static int
163+yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
164+
165+static int
166+yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
167+
168+static int
169+yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
170+
171+/*
172+ * Processors.
173+ */
174+
175+static int
176+yaml_emitter_process_anchor(yaml_emitter_t *emitter);
177+
178+static int
179+yaml_emitter_process_tag(yaml_emitter_t *emitter);
180+
181+static int
182+yaml_emitter_process_scalar(yaml_emitter_t *emitter);
183+
184+/*
185+ * Analyzers.
186+ */
187+
188+static int
189+yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
190+ yaml_version_directive_t version_directive);
191+
192+static int
193+yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
194+ yaml_tag_directive_t tag_directive);
195+
196+static int
197+yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
198+ yaml_char_t *anchor, int alias);
199+
200+static int
201+yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
202+ yaml_char_t *tag);
203+
204+static int
205+yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
206+ yaml_char_t *value, size_t length);
207+
208+static int
209+yaml_emitter_analyze_event(yaml_emitter_t *emitter,
210+ yaml_event_t *event);
211+
212+/*
213+ * Writers.
214+ */
215+
216+static int
217+yaml_emitter_write_bom(yaml_emitter_t *emitter);
218+
219+static int
220+yaml_emitter_write_indent(yaml_emitter_t *emitter);
221+
222+static int
223+yaml_emitter_write_indicator(yaml_emitter_t *emitter,
224+ char *indicator, int need_whitespace,
225+ int is_whitespace, int is_indention);
226+
227+static int
228+yaml_emitter_write_anchor(yaml_emitter_t *emitter,
229+ yaml_char_t *value, size_t length);
230+
231+static int
232+yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
233+ yaml_char_t *value, size_t length);
234+
235+static int
236+yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
237+ yaml_char_t *value, size_t length, int need_whitespace);
238+
239+static int
240+yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
241+ yaml_char_t *value, size_t length, int allow_breaks);
242+
243+static int
244+yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
245+ yaml_char_t *value, size_t length, int allow_breaks);
246+
247+static int
248+yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
249+ yaml_char_t *value, size_t length, int allow_breaks);
250+
251+static int
252+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
253+ yaml_string_t string);
254+
255+static int
256+yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
257+ yaml_char_t *value, size_t length);
258+
259+static int
260+yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
261+ yaml_char_t *value, size_t length);
262+
263+/*
264+ * Set an emitter error and return 0.
265+ */
266+
267+static int
268+yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
269+{
270+ emitter->error = YAML_EMITTER_ERROR;
271+ emitter->problem = problem;
272+
273+ return 0;
274+}
275+
276+/*
277+ * Emit an event.
278+ */
279+
280+YAML_DECLARE(int)
281+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
282+{
283+ if (!ENQUEUE(emitter, emitter->events, *event)) {
284+ yaml_event_delete(event);
285+ return 0;
286+ }
287+
288+ while (!yaml_emitter_need_more_events(emitter)) {
289+ if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
290+ return 0;
291+ if (!yaml_emitter_state_machine(emitter, emitter->events.head))
292+ return 0;
293+ yaml_event_delete(&DEQUEUE(emitter, emitter->events));
294+ }
295+
296+ return 1;
297+}
298+
299+/*
300+ * Check if we need to accumulate more events before emitting.
301+ *
302+ * We accumulate extra
303+ * - 1 event for DOCUMENT-START
304+ * - 2 events for SEQUENCE-START
305+ * - 3 events for MAPPING-START
306+ */
307+
308+static int
309+yaml_emitter_need_more_events(yaml_emitter_t *emitter)
310+{
311+ int level = 0;
312+ int accumulate = 0;
313+ yaml_event_t *event;
314+
315+ if (QUEUE_EMPTY(emitter, emitter->events))
316+ return 1;
317+
318+ switch (emitter->events.head->type) {
319+ case YAML_DOCUMENT_START_EVENT:
320+ accumulate = 1;
321+ break;
322+ case YAML_SEQUENCE_START_EVENT:
323+ accumulate = 2;
324+ break;
325+ case YAML_MAPPING_START_EVENT:
326+ accumulate = 3;
327+ break;
328+ default:
329+ return 0;
330+ }
331+
332+ if (emitter->events.tail - emitter->events.head > accumulate)
333+ return 0;
334+
335+ for (event = emitter->events.head; event != emitter->events.tail; event ++) {
336+ switch (event->type) {
337+ case YAML_STREAM_START_EVENT:
338+ case YAML_DOCUMENT_START_EVENT:
339+ case YAML_SEQUENCE_START_EVENT:
340+ case YAML_MAPPING_START_EVENT:
341+ level += 1;
342+ break;
343+ case YAML_STREAM_END_EVENT:
344+ case YAML_DOCUMENT_END_EVENT:
345+ case YAML_SEQUENCE_END_EVENT:
346+ case YAML_MAPPING_END_EVENT:
347+ level -= 1;
348+ break;
349+ default:
350+ break;
351+ }
352+ if (!level)
353+ return 0;
354+ }
355+
356+ return 1;
357+}
358+
359+/*
360+ * Append a directive to the directives stack.
361+ */
362+
363+static int
364+yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
365+ yaml_tag_directive_t value, int allow_duplicates)
366+{
367+ yaml_tag_directive_t *tag_directive;
368+ yaml_tag_directive_t copy = { NULL, NULL };
369+
370+ for (tag_directive = emitter->tag_directives.start;
371+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
372+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
373+ if (allow_duplicates)
374+ return 1;
375+ return yaml_emitter_set_emitter_error(emitter,
376+ "duplicate %TAG directive");
377+ }
378+ }
379+
380+ copy.handle = yaml_strdup(value.handle);
381+ copy.prefix = yaml_strdup(value.prefix);
382+ if (!copy.handle || !copy.prefix) {
383+ emitter->error = YAML_MEMORY_ERROR;
384+ goto error;
385+ }
386+
387+ if (!PUSH(emitter, emitter->tag_directives, copy))
388+ goto error;
389+
390+ return 1;
391+
392+error:
393+ yaml_free(copy.handle);
394+ yaml_free(copy.prefix);
395+ return 0;
396+}
397+
398+/*
399+ * Increase the indentation level.
400+ */
401+
402+static int
403+yaml_emitter_increase_indent(yaml_emitter_t *emitter,
404+ int flow, int indentless)
405+{
406+ if (!PUSH(emitter, emitter->indents, emitter->indent))
407+ return 0;
408+
409+ if (emitter->indent < 0) {
410+ emitter->indent = flow ? emitter->best_indent : 0;
411+ }
412+ else if (!indentless) {
413+ emitter->indent += emitter->best_indent;
414+ }
415+
416+ return 1;
417+}
418+
419+/*
420+ * State dispatcher.
421+ */
422+
423+static int
424+yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
425+{
426+ switch (emitter->state)
427+ {
428+ case YAML_EMIT_STREAM_START_STATE:
429+ return yaml_emitter_emit_stream_start(emitter, event);
430+
431+ case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
432+ return yaml_emitter_emit_document_start(emitter, event, 1);
433+
434+ case YAML_EMIT_DOCUMENT_START_STATE:
435+ return yaml_emitter_emit_document_start(emitter, event, 0);
436+
437+ case YAML_EMIT_DOCUMENT_CONTENT_STATE:
438+ return yaml_emitter_emit_document_content(emitter, event);
439+
440+ case YAML_EMIT_DOCUMENT_END_STATE:
441+ return yaml_emitter_emit_document_end(emitter, event);
442+
443+ case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
444+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
445+
446+ case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
447+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
448+
449+ case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
450+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
451+
452+ case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
453+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
454+
455+ case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
456+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
457+
458+ case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
459+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
460+
461+ case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
462+ return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
463+
464+ case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
465+ return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
466+
467+ case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
468+ return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
469+
470+ case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
471+ return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
472+
473+ case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
474+ return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
475+
476+ case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
477+ return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
478+
479+ case YAML_EMIT_END_STATE:
480+ return yaml_emitter_set_emitter_error(emitter,
481+ "expected nothing after STREAM-END");
482+
483+ default:
484+ assert(1); /* Invalid state. */
485+ }
486+
487+ return 0;
488+}
489+
490+/*
491+ * Expect STREAM-START.
492+ */
493+
494+static int
495+yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
496+ yaml_event_t *event)
497+{
498+ if (event->type == YAML_STREAM_START_EVENT)
499+ {
500+ if (!emitter->encoding) {
501+ emitter->encoding = event->data.stream_start.encoding;
502+ }
503+
504+ if (!emitter->encoding) {
505+ emitter->encoding = YAML_UTF8_ENCODING;
506+ }
507+
508+ if (emitter->best_indent < 2 || emitter->best_indent > 9) {
509+ emitter->best_indent = 2;
510+ }
511+
512+ if (emitter->best_width >= 0
513+ && emitter->best_width <= emitter->best_indent*2) {
514+ emitter->best_width = 80;
515+ }
516+
517+ if (emitter->best_width < 0) {
518+ emitter->best_width = INT_MAX;
519+ }
520+
521+ if (!emitter->line_break) {
522+ emitter->line_break = YAML_LN_BREAK;
523+ }
524+
525+ emitter->indent = -1;
526+
527+ emitter->line = 0;
528+ emitter->column = 0;
529+ emitter->whitespace = 1;
530+ emitter->indention = 1;
531+
532+ if (emitter->encoding != YAML_UTF8_ENCODING) {
533+ if (!yaml_emitter_write_bom(emitter))
534+ return 0;
535+ }
536+
537+ emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
538+
539+ return 1;
540+ }
541+
542+ return yaml_emitter_set_emitter_error(emitter,
543+ "expected STREAM-START");
544+}
545+
546+/*
547+ * Expect DOCUMENT-START or STREAM-END.
548+ */
549+
550+static int
551+yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
552+ yaml_event_t *event, int first)
553+{
554+ if (event->type == YAML_DOCUMENT_START_EVENT)
555+ {
556+ yaml_tag_directive_t default_tag_directives[] = {
557+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
558+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
559+ {NULL, NULL}
560+ };
561+ yaml_tag_directive_t *tag_directive;
562+ int implicit;
563+
564+ if (event->data.document_start.version_directive) {
565+ if (!yaml_emitter_analyze_version_directive(emitter,
566+ *event->data.document_start.version_directive))
567+ return 0;
568+ }
569+
570+ for (tag_directive = event->data.document_start.tag_directives.start;
571+ tag_directive != event->data.document_start.tag_directives.end;
572+ tag_directive ++) {
573+ if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
574+ return 0;
575+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
576+ return 0;
577+ }
578+
579+ for (tag_directive = default_tag_directives;
580+ tag_directive->handle; tag_directive ++) {
581+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
582+ return 0;
583+ }
584+
585+ implicit = event->data.document_start.implicit;
586+ if (!first || emitter->canonical) {
587+ implicit = 0;
588+ }
589+
590+ if ((event->data.document_start.version_directive ||
591+ (event->data.document_start.tag_directives.start
592+ != event->data.document_start.tag_directives.end)) &&
593+ emitter->open_ended)
594+ {
595+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
596+ return 0;
597+ if (!yaml_emitter_write_indent(emitter))
598+ return 0;
599+ }
600+
601+ if (event->data.document_start.version_directive) {
602+ implicit = 0;
603+ if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
604+ return 0;
605+ if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
606+ return 0;
607+ if (!yaml_emitter_write_indent(emitter))
608+ return 0;
609+ }
610+
611+ if (event->data.document_start.tag_directives.start
612+ != event->data.document_start.tag_directives.end) {
613+ implicit = 0;
614+ for (tag_directive = event->data.document_start.tag_directives.start;
615+ tag_directive != event->data.document_start.tag_directives.end;
616+ tag_directive ++) {
617+ if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
618+ return 0;
619+ if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
620+ strlen((char *)tag_directive->handle)))
621+ return 0;
622+ if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
623+ strlen((char *)tag_directive->prefix), 1))
624+ return 0;
625+ if (!yaml_emitter_write_indent(emitter))
626+ return 0;
627+ }
628+ }
629+
630+ if (yaml_emitter_check_empty_document(emitter)) {
631+ implicit = 0;
632+ }
633+
634+ if (!implicit) {
635+ if (!yaml_emitter_write_indent(emitter))
636+ return 0;
637+ if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
638+ return 0;
639+ if (emitter->canonical) {
640+ if (!yaml_emitter_write_indent(emitter))
641+ return 0;
642+ }
643+ }
644+
645+ emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
646+
647+ return 1;
648+ }
649+
650+ else if (event->type == YAML_STREAM_END_EVENT)
651+ {
652+ if (emitter->open_ended)
653+ {
654+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
655+ return 0;
656+ if (!yaml_emitter_write_indent(emitter))
657+ return 0;
658+ }
659+
660+ if (!yaml_emitter_flush(emitter))
661+ return 0;
662+
663+ emitter->state = YAML_EMIT_END_STATE;
664+
665+ return 1;
666+ }
667+
668+ return yaml_emitter_set_emitter_error(emitter,
669+ "expected DOCUMENT-START or STREAM-END");
670+}
671+
672+/*
673+ * Expect the root node.
674+ */
675+
676+static int
677+yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
678+ yaml_event_t *event)
679+{
680+ if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
681+ return 0;
682+
683+ return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
684+}
685+
686+/*
687+ * Expect DOCUMENT-END.
688+ */
689+
690+static int
691+yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
692+ yaml_event_t *event)
693+{
694+ if (event->type == YAML_DOCUMENT_END_EVENT)
695+ {
696+ if (!yaml_emitter_write_indent(emitter))
697+ return 0;
698+ if (!event->data.document_end.implicit) {
699+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
700+ return 0;
701+ if (!yaml_emitter_write_indent(emitter))
702+ return 0;
703+ }
704+ if (!yaml_emitter_flush(emitter))
705+ return 0;
706+
707+ emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
708+
709+ while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
710+ yaml_tag_directive_t tag_directive = POP(emitter,
711+ emitter->tag_directives);
712+ yaml_free(tag_directive.handle);
713+ yaml_free(tag_directive.prefix);
714+ }
715+
716+ return 1;
717+ }
718+
719+ return yaml_emitter_set_emitter_error(emitter,
720+ "expected DOCUMENT-END");
721+}
722+
723+/*
724+ *
725+ * Expect a flow item node.
726+ */
727+
728+static int
729+yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
730+ yaml_event_t *event, int first)
731+{
732+ if (first)
733+ {
734+ if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
735+ return 0;
736+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
737+ return 0;
738+ emitter->flow_level ++;
739+ }
740+
741+ if (event->type == YAML_SEQUENCE_END_EVENT)
742+ {
743+ emitter->flow_level --;
744+ emitter->indent = POP(emitter, emitter->indents);
745+ if (emitter->canonical && !first) {
746+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
747+ return 0;
748+ if (!yaml_emitter_write_indent(emitter))
749+ return 0;
750+ }
751+ if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
752+ return 0;
753+ emitter->state = POP(emitter, emitter->states);
754+
755+ return 1;
756+ }
757+
758+ if (!first) {
759+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
760+ return 0;
761+ }
762+
763+ if (emitter->canonical || emitter->column > emitter->best_width) {
764+ if (!yaml_emitter_write_indent(emitter))
765+ return 0;
766+ }
767+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
768+ return 0;
769+
770+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
771+}
772+
773+/*
774+ * Expect a flow key node.
775+ */
776+
777+static int
778+yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
779+ yaml_event_t *event, int first)
780+{
781+ if (first)
782+ {
783+ if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
784+ return 0;
785+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
786+ return 0;
787+ emitter->flow_level ++;
788+ }
789+
790+ if (event->type == YAML_MAPPING_END_EVENT)
791+ {
792+ emitter->flow_level --;
793+ emitter->indent = POP(emitter, emitter->indents);
794+ if (emitter->canonical && !first) {
795+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
796+ return 0;
797+ if (!yaml_emitter_write_indent(emitter))
798+ return 0;
799+ }
800+ if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
801+ return 0;
802+ emitter->state = POP(emitter, emitter->states);
803+
804+ return 1;
805+ }
806+
807+ if (!first) {
808+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
809+ return 0;
810+ }
811+ if (emitter->canonical || emitter->column > emitter->best_width) {
812+ if (!yaml_emitter_write_indent(emitter))
813+ return 0;
814+ }
815+
816+ if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
817+ {
818+ if (!PUSH(emitter, emitter->states,
819+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
820+ return 0;
821+
822+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
823+ }
824+ else
825+ {
826+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
827+ return 0;
828+ if (!PUSH(emitter, emitter->states,
829+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
830+ return 0;
831+
832+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
833+ }
834+}
835+
836+/*
837+ * Expect a flow value node.
838+ */
839+
840+static int
841+yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
842+ yaml_event_t *event, int simple)
843+{
844+ if (simple) {
845+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
846+ return 0;
847+ }
848+ else {
849+ if (emitter->canonical || emitter->column > emitter->best_width) {
850+ if (!yaml_emitter_write_indent(emitter))
851+ return 0;
852+ }
853+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
854+ return 0;
855+ }
856+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
857+ return 0;
858+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
859+}
860+
861+/*
862+ * Expect a block item node.
863+ */
864+
865+static int
866+yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
867+ yaml_event_t *event, int first)
868+{
869+ if (first)
870+ {
871+ if (!yaml_emitter_increase_indent(emitter, 0,
872+ (emitter->mapping_context && !emitter->indention)))
873+ return 0;
874+ }
875+
876+ if (event->type == YAML_SEQUENCE_END_EVENT)
877+ {
878+ emitter->indent = POP(emitter, emitter->indents);
879+ emitter->state = POP(emitter, emitter->states);
880+
881+ return 1;
882+ }
883+
884+ if (!yaml_emitter_write_indent(emitter))
885+ return 0;
886+ if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
887+ return 0;
888+ if (!PUSH(emitter, emitter->states,
889+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
890+ return 0;
891+
892+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
893+}
894+
895+/*
896+ * Expect a block key node.
897+ */
898+
899+static int
900+yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
901+ yaml_event_t *event, int first)
902+{
903+ if (first)
904+ {
905+ if (!yaml_emitter_increase_indent(emitter, 0, 0))
906+ return 0;
907+ }
908+
909+ if (event->type == YAML_MAPPING_END_EVENT)
910+ {
911+ emitter->indent = POP(emitter, emitter->indents);
912+ emitter->state = POP(emitter, emitter->states);
913+
914+ return 1;
915+ }
916+
917+ if (!yaml_emitter_write_indent(emitter))
918+ return 0;
919+
920+ if (yaml_emitter_check_simple_key(emitter))
921+ {
922+ if (!PUSH(emitter, emitter->states,
923+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
924+ return 0;
925+
926+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
927+ }
928+ else
929+ {
930+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
931+ return 0;
932+ if (!PUSH(emitter, emitter->states,
933+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
934+ return 0;
935+
936+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
937+ }
938+}
939+
940+/*
941+ * Expect a block value node.
942+ */
943+
944+static int
945+yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
946+ yaml_event_t *event, int simple)
947+{
948+ if (simple) {
949+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
950+ return 0;
951+ }
952+ else {
953+ if (!yaml_emitter_write_indent(emitter))
954+ return 0;
955+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
956+ return 0;
957+ }
958+ if (!PUSH(emitter, emitter->states,
959+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
960+ return 0;
961+
962+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
963+}
964+
965+/*
966+ * Expect a node.
967+ */
968+
969+static int
970+yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
971+ int root, int sequence, int mapping, int simple_key)
972+{
973+ emitter->root_context = root;
974+ emitter->sequence_context = sequence;
975+ emitter->mapping_context = mapping;
976+ emitter->simple_key_context = simple_key;
977+
978+ switch (event->type)
979+ {
980+ case YAML_ALIAS_EVENT:
981+ return yaml_emitter_emit_alias(emitter, event);
982+
983+ case YAML_SCALAR_EVENT:
984+ return yaml_emitter_emit_scalar(emitter, event);
985+
986+ case YAML_SEQUENCE_START_EVENT:
987+ return yaml_emitter_emit_sequence_start(emitter, event);
988+
989+ case YAML_MAPPING_START_EVENT:
990+ return yaml_emitter_emit_mapping_start(emitter, event);
991+
992+ default:
993+ return yaml_emitter_set_emitter_error(emitter,
994+ "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
995+ }
996+
997+ return 0;
998+}
999+
1000+/*
1001+ * Expect ALIAS.
1002+ */
1003+
1004+static int
1005+yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
1006+{
1007+ if (!yaml_emitter_process_anchor(emitter))
1008+ return 0;
1009+ emitter->state = POP(emitter, emitter->states);
1010+
1011+ return 1;
1012+}
1013+
1014+/*
1015+ * Expect SCALAR.
1016+ */
1017+
1018+static int
1019+yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
1020+{
1021+ if (!yaml_emitter_select_scalar_style(emitter, event))
1022+ return 0;
1023+ if (!yaml_emitter_process_anchor(emitter))
1024+ return 0;
1025+ if (!yaml_emitter_process_tag(emitter))
1026+ return 0;
1027+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
1028+ return 0;
1029+ if (!yaml_emitter_process_scalar(emitter))
1030+ return 0;
1031+ emitter->indent = POP(emitter, emitter->indents);
1032+ emitter->state = POP(emitter, emitter->states);
1033+
1034+ return 1;
1035+}
1036+
1037+/*
1038+ * Expect SEQUENCE-START.
1039+ */
1040+
1041+static int
1042+yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1043+{
1044+ if (!yaml_emitter_process_anchor(emitter))
1045+ return 0;
1046+ if (!yaml_emitter_process_tag(emitter))
1047+ return 0;
1048+
1049+ if (emitter->flow_level || emitter->canonical
1050+ || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1051+ || yaml_emitter_check_empty_sequence(emitter)) {
1052+ emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1053+ }
1054+ else {
1055+ emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1056+ }
1057+
1058+ return 1;
1059+}
1060+
1061+/*
1062+ * Expect MAPPING-START.
1063+ */
1064+
1065+static int
1066+yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1067+{
1068+ if (!yaml_emitter_process_anchor(emitter))
1069+ return 0;
1070+ if (!yaml_emitter_process_tag(emitter))
1071+ return 0;
1072+
1073+ if (emitter->flow_level || emitter->canonical
1074+ || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1075+ || yaml_emitter_check_empty_mapping(emitter)) {
1076+ emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1077+ }
1078+ else {
1079+ emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1080+ }
1081+
1082+ return 1;
1083+}
1084+
1085+/*
1086+ * Check if the document content is an empty scalar.
1087+ */
1088+
1089+static int
1090+yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
1091+{
1092+ return 0;
1093+}
1094+
1095+/*
1096+ * Check if the next events represent an empty sequence.
1097+ */
1098+
1099+static int
1100+yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1101+{
1102+ if (emitter->events.tail - emitter->events.head < 2)
1103+ return 0;
1104+
1105+ return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1106+ && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1107+}
1108+
1109+/*
1110+ * Check if the next events represent an empty mapping.
1111+ */
1112+
1113+static int
1114+yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1115+{
1116+ if (emitter->events.tail - emitter->events.head < 2)
1117+ return 0;
1118+
1119+ return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1120+ && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1121+}
1122+
1123+/*
1124+ * Check if the next node can be expressed as a simple key.
1125+ */
1126+
1127+static int
1128+yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1129+{
1130+ yaml_event_t *event = emitter->events.head;
1131+ size_t length = 0;
1132+
1133+ switch (event->type)
1134+ {
1135+ case YAML_ALIAS_EVENT:
1136+ length += emitter->anchor_data.anchor_length;
1137+ break;
1138+
1139+ case YAML_SCALAR_EVENT:
1140+ if (emitter->scalar_data.multiline)
1141+ return 0;
1142+ length += emitter->anchor_data.anchor_length
1143+ + emitter->tag_data.handle_length
1144+ + emitter->tag_data.suffix_length
1145+ + emitter->scalar_data.length;
1146+ break;
1147+
1148+ case YAML_SEQUENCE_START_EVENT:
1149+ if (!yaml_emitter_check_empty_sequence(emitter))
1150+ return 0;
1151+ length += emitter->anchor_data.anchor_length
1152+ + emitter->tag_data.handle_length
1153+ + emitter->tag_data.suffix_length;
1154+ break;
1155+
1156+ case YAML_MAPPING_START_EVENT:
1157+ if (!yaml_emitter_check_empty_sequence(emitter))
1158+ return 0;
1159+ length += emitter->anchor_data.anchor_length
1160+ + emitter->tag_data.handle_length
1161+ + emitter->tag_data.suffix_length;
1162+ break;
1163+
1164+ default:
1165+ return 0;
1166+ }
1167+
1168+ if (length > 128)
1169+ return 0;
1170+
1171+ return 1;
1172+}
1173+
1174+/*
1175+ * Determine an acceptable scalar style.
1176+ */
1177+
1178+static int
1179+yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1180+{
1181+ yaml_scalar_style_t style = event->data.scalar.style;
1182+ int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
1183+
1184+ if (no_tag && !event->data.scalar.plain_implicit
1185+ && !event->data.scalar.quoted_implicit) {
1186+ return yaml_emitter_set_emitter_error(emitter,
1187+ "neither tag nor implicit flags are specified");
1188+ }
1189+
1190+ if (style == YAML_ANY_SCALAR_STYLE)
1191+ style = YAML_PLAIN_SCALAR_STYLE;
1192+
1193+ if (emitter->canonical)
1194+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1195+
1196+ if (emitter->simple_key_context && emitter->scalar_data.multiline)
1197+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1198+
1199+ if (style == YAML_PLAIN_SCALAR_STYLE)
1200+ {
1201+ if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1202+ || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1203+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1204+ if (!emitter->scalar_data.length
1205+ && (emitter->flow_level || emitter->simple_key_context))
1206+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1207+ if (no_tag && !event->data.scalar.plain_implicit)
1208+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1209+ }
1210+
1211+ if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1212+ {
1213+ if (!emitter->scalar_data.single_quoted_allowed)
1214+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1215+ }
1216+
1217+ if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1218+ {
1219+ if (!emitter->scalar_data.block_allowed
1220+ || emitter->flow_level || emitter->simple_key_context)
1221+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1222+ }
1223+
1224+ if (no_tag && !event->data.scalar.quoted_implicit
1225+ && style != YAML_PLAIN_SCALAR_STYLE)
1226+ {
1227+ emitter->tag_data.handle = (yaml_char_t *)"!";
1228+ emitter->tag_data.handle_length = 1;
1229+ }
1230+
1231+ emitter->scalar_data.style = style;
1232+
1233+ return 1;
1234+}
1235+
1236+/*
1237+ * Write an achor.
1238+ */
1239+
1240+static int
1241+yaml_emitter_process_anchor(yaml_emitter_t *emitter)
1242+{
1243+ if (!emitter->anchor_data.anchor)
1244+ return 1;
1245+
1246+ if (!yaml_emitter_write_indicator(emitter,
1247+ (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1248+ return 0;
1249+
1250+ return yaml_emitter_write_anchor(emitter,
1251+ emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1252+}
1253+
1254+/*
1255+ * Write a tag.
1256+ */
1257+
1258+static int
1259+yaml_emitter_process_tag(yaml_emitter_t *emitter)
1260+{
1261+ if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1262+ return 1;
1263+
1264+ if (emitter->tag_data.handle)
1265+ {
1266+ if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1267+ emitter->tag_data.handle_length))
1268+ return 0;
1269+ if (emitter->tag_data.suffix) {
1270+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1271+ emitter->tag_data.suffix_length, 0))
1272+ return 0;
1273+ }
1274+ }
1275+ else
1276+ {
1277+ if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1278+ return 0;
1279+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1280+ emitter->tag_data.suffix_length, 0))
1281+ return 0;
1282+ if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1283+ return 0;
1284+ }
1285+
1286+ return 1;
1287+}
1288+
1289+/*
1290+ * Write a scalar.
1291+ */
1292+
1293+static int
1294+yaml_emitter_process_scalar(yaml_emitter_t *emitter)
1295+{
1296+ switch (emitter->scalar_data.style)
1297+ {
1298+ case YAML_PLAIN_SCALAR_STYLE:
1299+ return yaml_emitter_write_plain_scalar(emitter,
1300+ emitter->scalar_data.value, emitter->scalar_data.length,
1301+ !emitter->simple_key_context);
1302+
1303+ case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1304+ return yaml_emitter_write_single_quoted_scalar(emitter,
1305+ emitter->scalar_data.value, emitter->scalar_data.length,
1306+ !emitter->simple_key_context);
1307+
1308+ case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1309+ return yaml_emitter_write_double_quoted_scalar(emitter,
1310+ emitter->scalar_data.value, emitter->scalar_data.length,
1311+ !emitter->simple_key_context);
1312+
1313+ case YAML_LITERAL_SCALAR_STYLE:
1314+ return yaml_emitter_write_literal_scalar(emitter,
1315+ emitter->scalar_data.value, emitter->scalar_data.length);
1316+
1317+ case YAML_FOLDED_SCALAR_STYLE:
1318+ return yaml_emitter_write_folded_scalar(emitter,
1319+ emitter->scalar_data.value, emitter->scalar_data.length);
1320+
1321+ default:
1322+ assert(1); /* Impossible. */
1323+ }
1324+
1325+ return 0;
1326+}
1327+
1328+/*
1329+ * Check if a %YAML directive is valid.
1330+ */
1331+
1332+static int
1333+yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1334+ yaml_version_directive_t version_directive)
1335+{
1336+ if (version_directive.major != 1 || version_directive.minor != 1) {
1337+ return yaml_emitter_set_emitter_error(emitter,
1338+ "incompatible %YAML directive");
1339+ }
1340+
1341+ return 1;
1342+}
1343+
1344+/*
1345+ * Check if a %TAG directive is valid.
1346+ */
1347+
1348+static int
1349+yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1350+ yaml_tag_directive_t tag_directive)
1351+{
1352+ yaml_string_t handle = STRING(tag_directive.handle,
1353+ strlen((char *)tag_directive.handle));
1354+ yaml_string_t prefix = STRING(tag_directive.prefix,
1355+ strlen((char *)tag_directive.prefix));
1356+
1357+ if (handle.start == handle.end) {
1358+ return yaml_emitter_set_emitter_error(emitter,
1359+ "tag handle must not be empty");
1360+ }
1361+
1362+ if (handle.start[0] != '!') {
1363+ return yaml_emitter_set_emitter_error(emitter,
1364+ "tag handle must start with '!'");
1365+ }
1366+
1367+ if (handle.end[-1] != '!') {
1368+ return yaml_emitter_set_emitter_error(emitter,
1369+ "tag handle must end with '!'");
1370+ }
1371+
1372+ handle.pointer ++;
1373+
1374+ while (handle.pointer < handle.end-1) {
1375+ if (!IS_ALPHA(handle)) {
1376+ return yaml_emitter_set_emitter_error(emitter,
1377+ "tag handle must contain alphanumerical characters only");
1378+ }
1379+ MOVE(handle);
1380+ }
1381+
1382+ if (prefix.start == prefix.end) {
1383+ return yaml_emitter_set_emitter_error(emitter,
1384+ "tag prefix must not be empty");
1385+ }
1386+
1387+ return 1;
1388+}
1389+
1390+/*
1391+ * Check if an anchor is valid.
1392+ */
1393+
1394+static int
1395+yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1396+ yaml_char_t *anchor, int alias)
1397+{
1398+ yaml_string_t string = STRING(anchor, strlen((char *)anchor));
1399+
1400+ if (string.start == string.end) {
1401+ return yaml_emitter_set_emitter_error(emitter, alias ?
1402+ "alias value must not be empty" :
1403+ "anchor value must not be empty");
1404+ }
1405+
1406+ while (string.pointer != string.end) {
1407+ if (!IS_ALPHA(string)) {
1408+ return yaml_emitter_set_emitter_error(emitter, alias ?
1409+ "alias value must contain alphanumerical characters only" :
1410+ "anchor value must contain alphanumerical characters only");
1411+ }
1412+ MOVE(string);
1413+ }
1414+
1415+ emitter->anchor_data.anchor = string.start;
1416+ emitter->anchor_data.anchor_length = string.end - string.start;
1417+ emitter->anchor_data.alias = alias;
1418+
1419+ return 1;
1420+}
1421+
1422+/*
1423+ * Check if a tag is valid.
1424+ */
1425+
1426+static int
1427+yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1428+ yaml_char_t *tag)
1429+{
1430+ yaml_string_t string = STRING(tag, strlen((char *)tag));
1431+ yaml_tag_directive_t *tag_directive;
1432+
1433+ if (string.start == string.end) {
1434+ return yaml_emitter_set_emitter_error(emitter,
1435+ "tag value must not be empty");
1436+ }
1437+
1438+ for (tag_directive = emitter->tag_directives.start;
1439+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
1440+ size_t prefix_length = strlen((char *)tag_directive->prefix);
1441+ if (prefix_length < (size_t)(string.end - string.start)
1442+ && strncmp((char *)tag_directive->prefix, (char *)string.start,
1443+ prefix_length) == 0)
1444+ {
1445+ emitter->tag_data.handle = tag_directive->handle;
1446+ emitter->tag_data.handle_length =
1447+ strlen((char *)tag_directive->handle);
1448+ emitter->tag_data.suffix = string.start + prefix_length;
1449+ emitter->tag_data.suffix_length =
1450+ (string.end - string.start) - prefix_length;
1451+ return 1;
1452+ }
1453+ }
1454+
1455+ emitter->tag_data.suffix = string.start;
1456+ emitter->tag_data.suffix_length = string.end - string.start;
1457+
1458+ return 1;
1459+}
1460+
1461+/*
1462+ * Check if a scalar is valid.
1463+ */
1464+
1465+static int
1466+yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1467+ yaml_char_t *value, size_t length)
1468+{
1469+ yaml_string_t string = STRING(value, length);
1470+
1471+ int block_indicators = 0;
1472+ int flow_indicators = 0;
1473+ int line_breaks = 0;
1474+ int special_characters = 0;
1475+
1476+ int leading_space = 0;
1477+ int leading_break = 0;
1478+ int trailing_space = 0;
1479+ int trailing_break = 0;
1480+ int break_space = 0;
1481+ int space_break = 0;
1482+
1483+ int preceeded_by_whitespace = 0;
1484+ int followed_by_whitespace = 0;
1485+ int previous_space = 0;
1486+ int previous_break = 0;
1487+
1488+ emitter->scalar_data.value = value;
1489+ emitter->scalar_data.length = length;
1490+
1491+ if (string.start == string.end)
1492+ {
1493+ emitter->scalar_data.multiline = 0;
1494+ emitter->scalar_data.flow_plain_allowed = 0;
1495+ emitter->scalar_data.block_plain_allowed = 1;
1496+ emitter->scalar_data.single_quoted_allowed = 1;
1497+ emitter->scalar_data.block_allowed = 0;
1498+
1499+ return 1;
1500+ }
1501+
1502+ if ((CHECK_AT(string, '-', 0)
1503+ && CHECK_AT(string, '-', 1)
1504+ && CHECK_AT(string, '-', 2))
1505+ || (CHECK_AT(string, '.', 0)
1506+ && CHECK_AT(string, '.', 1)
1507+ && CHECK_AT(string, '.', 2))) {
1508+ block_indicators = 1;
1509+ flow_indicators = 1;
1510+ }
1511+
1512+ preceeded_by_whitespace = 1;
1513+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1514+
1515+ while (string.pointer != string.end)
1516+ {
1517+ if (string.start == string.pointer)
1518+ {
1519+ if (CHECK(string, '#') || CHECK(string, ',')
1520+ || CHECK(string, '[') || CHECK(string, ']')
1521+ || CHECK(string, '{') || CHECK(string, '}')
1522+ || CHECK(string, '&') || CHECK(string, '*')
1523+ || CHECK(string, '!') || CHECK(string, '|')
1524+ || CHECK(string, '>') || CHECK(string, '\'')
1525+ || CHECK(string, '"') || CHECK(string, '%')
1526+ || CHECK(string, '@') || CHECK(string, '`')) {
1527+ flow_indicators = 1;
1528+ block_indicators = 1;
1529+ }
1530+
1531+ if (CHECK(string, '?') || CHECK(string, ':')) {
1532+ flow_indicators = 1;
1533+ if (followed_by_whitespace) {
1534+ block_indicators = 1;
1535+ }
1536+ }
1537+
1538+ if (CHECK(string, '-') && followed_by_whitespace) {
1539+ flow_indicators = 1;
1540+ block_indicators = 1;
1541+ }
1542+ }
1543+ else
1544+ {
1545+ if (CHECK(string, ',') || CHECK(string, '?')
1546+ || CHECK(string, '[') || CHECK(string, ']')
1547+ || CHECK(string, '{') || CHECK(string, '}')) {
1548+ flow_indicators = 1;
1549+ }
1550+
1551+ if (CHECK(string, ':')) {
1552+ flow_indicators = 1;
1553+ if (followed_by_whitespace) {
1554+ block_indicators = 1;
1555+ }
1556+ }
1557+
1558+ if (CHECK(string, '#') && preceeded_by_whitespace) {
1559+ flow_indicators = 1;
1560+ block_indicators = 1;
1561+ }
1562+ }
1563+
1564+ if (!IS_PRINTABLE(string)
1565+ || (!IS_ASCII(string) && !emitter->unicode)) {
1566+ special_characters = 1;
1567+ }
1568+
1569+ if (IS_BREAK(string)) {
1570+ line_breaks = 1;
1571+ }
1572+
1573+ if (IS_SPACE(string))
1574+ {
1575+ if (string.start == string.pointer) {
1576+ leading_space = 1;
1577+ }
1578+ if (string.pointer+WIDTH(string) == string.end) {
1579+ trailing_space = 1;
1580+ }
1581+ if (previous_break) {
1582+ break_space = 1;
1583+ }
1584+ previous_space = 1;
1585+ previous_break = 0;
1586+ }
1587+ else if (IS_BREAK(string))
1588+ {
1589+ if (string.start == string.pointer) {
1590+ leading_break = 1;
1591+ }
1592+ if (string.pointer+WIDTH(string) == string.end) {
1593+ trailing_break = 1;
1594+ }
1595+ if (previous_space) {
1596+ space_break = 1;
1597+ }
1598+ previous_space = 0;
1599+ previous_break = 1;
1600+ }
1601+ else
1602+ {
1603+ previous_space = 0;
1604+ previous_break = 0;
1605+ }
1606+
1607+ preceeded_by_whitespace = IS_BLANKZ(string);
1608+ MOVE(string);
1609+ if (string.pointer != string.end) {
1610+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1611+ }
1612+ }
1613+
1614+ emitter->scalar_data.multiline = line_breaks;
1615+
1616+ emitter->scalar_data.flow_plain_allowed = 1;
1617+ emitter->scalar_data.block_plain_allowed = 1;
1618+ emitter->scalar_data.single_quoted_allowed = 1;
1619+ emitter->scalar_data.block_allowed = 1;
1620+
1621+ if (leading_space || leading_break || trailing_space || trailing_break) {
1622+ emitter->scalar_data.flow_plain_allowed = 0;
1623+ emitter->scalar_data.block_plain_allowed = 0;
1624+ }
1625+
1626+ if (trailing_space) {
1627+ emitter->scalar_data.block_allowed = 0;
1628+ }
1629+
1630+ if (break_space) {
1631+ emitter->scalar_data.flow_plain_allowed = 0;
1632+ emitter->scalar_data.block_plain_allowed = 0;
1633+ emitter->scalar_data.single_quoted_allowed = 0;
1634+ }
1635+
1636+ if (space_break || special_characters) {
1637+ emitter->scalar_data.flow_plain_allowed = 0;
1638+ emitter->scalar_data.block_plain_allowed = 0;
1639+ emitter->scalar_data.single_quoted_allowed = 0;
1640+ emitter->scalar_data.block_allowed = 0;
1641+ }
1642+
1643+ if (line_breaks) {
1644+ emitter->scalar_data.flow_plain_allowed = 0;
1645+ emitter->scalar_data.block_plain_allowed = 0;
1646+ }
1647+
1648+ if (flow_indicators) {
1649+ emitter->scalar_data.flow_plain_allowed = 0;
1650+ }
1651+
1652+ if (block_indicators) {
1653+ emitter->scalar_data.block_plain_allowed = 0;
1654+ }
1655+
1656+ return 1;
1657+}
1658+
1659+/*
1660+ * Check if the event data is valid.
1661+ */
1662+
1663+static int
1664+yaml_emitter_analyze_event(yaml_emitter_t *emitter,
1665+ yaml_event_t *event)
1666+{
1667+ emitter->anchor_data.anchor = NULL;
1668+ emitter->anchor_data.anchor_length = 0;
1669+ emitter->tag_data.handle = NULL;
1670+ emitter->tag_data.handle_length = 0;
1671+ emitter->tag_data.suffix = NULL;
1672+ emitter->tag_data.suffix_length = 0;
1673+ emitter->scalar_data.value = NULL;
1674+ emitter->scalar_data.length = 0;
1675+
1676+ switch (event->type)
1677+ {
1678+ case YAML_ALIAS_EVENT:
1679+ if (!yaml_emitter_analyze_anchor(emitter,
1680+ event->data.alias.anchor, 1))
1681+ return 0;
1682+ return 1;
1683+
1684+ case YAML_SCALAR_EVENT:
1685+ if (event->data.scalar.anchor) {
1686+ if (!yaml_emitter_analyze_anchor(emitter,
1687+ event->data.scalar.anchor, 0))
1688+ return 0;
1689+ }
1690+ if (event->data.scalar.tag && (emitter->canonical ||
1691+ (!event->data.scalar.plain_implicit
1692+ && !event->data.scalar.quoted_implicit))) {
1693+ if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1694+ return 0;
1695+ }
1696+ if (!yaml_emitter_analyze_scalar(emitter,
1697+ event->data.scalar.value, event->data.scalar.length))
1698+ return 0;
1699+ return 1;
1700+
1701+ case YAML_SEQUENCE_START_EVENT:
1702+ if (event->data.sequence_start.anchor) {
1703+ if (!yaml_emitter_analyze_anchor(emitter,
1704+ event->data.sequence_start.anchor, 0))
1705+ return 0;
1706+ }
1707+ if (event->data.sequence_start.tag && (emitter->canonical ||
1708+ !event->data.sequence_start.implicit)) {
1709+ if (!yaml_emitter_analyze_tag(emitter,
1710+ event->data.sequence_start.tag))
1711+ return 0;
1712+ }
1713+ return 1;
1714+
1715+ case YAML_MAPPING_START_EVENT:
1716+ if (event->data.mapping_start.anchor) {
1717+ if (!yaml_emitter_analyze_anchor(emitter,
1718+ event->data.mapping_start.anchor, 0))
1719+ return 0;
1720+ }
1721+ if (event->data.mapping_start.tag && (emitter->canonical ||
1722+ !event->data.mapping_start.implicit)) {
1723+ if (!yaml_emitter_analyze_tag(emitter,
1724+ event->data.mapping_start.tag))
1725+ return 0;
1726+ }
1727+ return 1;
1728+
1729+ default:
1730+ return 1;
1731+ }
1732+}
1733+
1734+/*
1735+ * Write the BOM character.
1736+ */
1737+
1738+static int
1739+yaml_emitter_write_bom(yaml_emitter_t *emitter)
1740+{
1741+ if (!FLUSH(emitter)) return 0;
1742+
1743+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1744+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1745+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1746+
1747+ return 1;
1748+}
1749+
1750+static int
1751+yaml_emitter_write_indent(yaml_emitter_t *emitter)
1752+{
1753+ int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1754+
1755+ if (!emitter->indention || emitter->column > indent
1756+ || (emitter->column == indent && !emitter->whitespace)) {
1757+ if (!PUT_BREAK(emitter)) return 0;
1758+ }
1759+
1760+ while (emitter->column < indent) {
1761+ if (!PUT(emitter, ' ')) return 0;
1762+ }
1763+
1764+ emitter->whitespace = 1;
1765+ emitter->indention = 1;
1766+
1767+ return 1;
1768+}
1769+
1770+static int
1771+yaml_emitter_write_indicator(yaml_emitter_t *emitter,
1772+ char *indicator, int need_whitespace,
1773+ int is_whitespace, int is_indention)
1774+{
1775+ yaml_string_t string = STRING((yaml_char_t *)indicator, strlen(indicator));
1776+
1777+ if (need_whitespace && !emitter->whitespace) {
1778+ if (!PUT(emitter, ' ')) return 0;
1779+ }
1780+
1781+ while (string.pointer != string.end) {
1782+ if (!WRITE(emitter, string)) return 0;
1783+ }
1784+
1785+ emitter->whitespace = is_whitespace;
1786+ emitter->indention = (emitter->indention && is_indention);
1787+ emitter->open_ended = 0;
1788+
1789+ return 1;
1790+}
1791+
1792+static int
1793+yaml_emitter_write_anchor(yaml_emitter_t *emitter,
1794+ yaml_char_t *value, size_t length)
1795+{
1796+ yaml_string_t string = STRING(value, length);
1797+
1798+ while (string.pointer != string.end) {
1799+ if (!WRITE(emitter, string)) return 0;
1800+ }
1801+
1802+ emitter->whitespace = 0;
1803+ emitter->indention = 0;
1804+
1805+ return 1;
1806+}
1807+
1808+static int
1809+yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1810+ yaml_char_t *value, size_t length)
1811+{
1812+ yaml_string_t string = STRING(value, length);
1813+
1814+ if (!emitter->whitespace) {
1815+ if (!PUT(emitter, ' ')) return 0;
1816+ }
1817+
1818+ while (string.pointer != string.end) {
1819+ if (!WRITE(emitter, string)) return 0;
1820+ }
1821+
1822+ emitter->whitespace = 0;
1823+ emitter->indention = 0;
1824+
1825+ return 1;
1826+}
1827+
1828+static int
1829+yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1830+ yaml_char_t *value, size_t length,
1831+ int need_whitespace)
1832+{
1833+ yaml_string_t string = STRING(value, length);
1834+
1835+ if (need_whitespace && !emitter->whitespace) {
1836+ if (!PUT(emitter, ' ')) return 0;
1837+ }
1838+
1839+ while (string.pointer != string.end) {
1840+ if (IS_ALPHA(string)
1841+ || CHECK(string, ';') || CHECK(string, '/')
1842+ || CHECK(string, '?') || CHECK(string, ':')
1843+ || CHECK(string, '@') || CHECK(string, '&')
1844+ || CHECK(string, '=') || CHECK(string, '+')
1845+ || CHECK(string, '$') || CHECK(string, ',')
1846+ || CHECK(string, '_') || CHECK(string, '.')
1847+ || CHECK(string, '~') || CHECK(string, '*')
1848+ || CHECK(string, '\'') || CHECK(string, '(')
1849+ || CHECK(string, ')') || CHECK(string, '[')
1850+ || CHECK(string, ']')) {
1851+ if (!WRITE(emitter, string)) return 0;
1852+ }
1853+ else {
1854+ int width = WIDTH(string);
1855+ unsigned int value;
1856+ while (width --) {
1857+ value = *(string.pointer++);
1858+ if (!PUT(emitter, '%')) return 0;
1859+ if (!PUT(emitter, (value >> 4)
1860+ + ((value >> 4) < 10 ? '0' : 'A' - 10)))
1861+ return 0;
1862+ if (!PUT(emitter, (value & 0x0F)
1863+ + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
1864+ return 0;
1865+ }
1866+ }
1867+ }
1868+
1869+ emitter->whitespace = 0;
1870+ emitter->indention = 0;
1871+
1872+ return 1;
1873+}
1874+
1875+static int
1876+yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1877+ yaml_char_t *value, size_t length, int allow_breaks)
1878+{
1879+ yaml_string_t string = STRING(value, length);
1880+ int spaces = 0;
1881+ int breaks = 0;
1882+
1883+ if (!emitter->whitespace) {
1884+ if (!PUT(emitter, ' ')) return 0;
1885+ }
1886+
1887+ while (string.pointer != string.end)
1888+ {
1889+ if (IS_SPACE(string))
1890+ {
1891+ if (allow_breaks && !spaces
1892+ && emitter->column > emitter->best_width
1893+ && !IS_SPACE_AT(string, 1)) {
1894+ if (!yaml_emitter_write_indent(emitter)) return 0;
1895+ MOVE(string);
1896+ }
1897+ else {
1898+ if (!WRITE(emitter, string)) return 0;
1899+ }
1900+ spaces = 1;
1901+ }
1902+ else if (IS_BREAK(string))
1903+ {
1904+ if (!breaks && CHECK(string, '\n')) {
1905+ if (!PUT_BREAK(emitter)) return 0;
1906+ }
1907+ if (!WRITE_BREAK(emitter, string)) return 0;
1908+ emitter->indention = 1;
1909+ breaks = 1;
1910+ }
1911+ else
1912+ {
1913+ if (breaks) {
1914+ if (!yaml_emitter_write_indent(emitter)) return 0;
1915+ }
1916+ if (!WRITE(emitter, string)) return 0;
1917+ emitter->indention = 0;
1918+ spaces = 0;
1919+ breaks = 0;
1920+ }
1921+ }
1922+
1923+ emitter->whitespace = 0;
1924+ emitter->indention = 0;
1925+ if (emitter->root_context)
1926+ {
1927+ emitter->open_ended = 1;
1928+ }
1929+
1930+ return 1;
1931+}
1932+
1933+static int
1934+yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1935+ yaml_char_t *value, size_t length, int allow_breaks)
1936+{
1937+ yaml_string_t string = STRING(value, length);
1938+ int spaces = 0;
1939+ int breaks = 0;
1940+
1941+ if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
1942+ return 0;
1943+
1944+ while (string.pointer != string.end)
1945+ {
1946+ if (IS_SPACE(string))
1947+ {
1948+ if (allow_breaks && !spaces
1949+ && emitter->column > emitter->best_width
1950+ && string.pointer != string.start
1951+ && string.pointer != string.end - 1
1952+ && !IS_SPACE_AT(string, 1)) {
1953+ if (!yaml_emitter_write_indent(emitter)) return 0;
1954+ MOVE(string);
1955+ }
1956+ else {
1957+ if (!WRITE(emitter, string)) return 0;
1958+ }
1959+ spaces = 1;
1960+ }
1961+ else if (IS_BREAK(string))
1962+ {
1963+ if (!breaks && CHECK(string, '\n')) {
1964+ if (!PUT_BREAK(emitter)) return 0;
1965+ }
1966+ if (!WRITE_BREAK(emitter, string)) return 0;
1967+ emitter->indention = 1;
1968+ breaks = 1;
1969+ }
1970+ else
1971+ {
1972+ if (breaks) {
1973+ if (!yaml_emitter_write_indent(emitter)) return 0;
1974+ }
1975+ if (CHECK(string, '\'')) {
1976+ if (!PUT(emitter, '\'')) return 0;
1977+ }
1978+ if (!WRITE(emitter, string)) return 0;
1979+ emitter->indention = 0;
1980+ spaces = 0;
1981+ breaks = 0;
1982+ }
1983+ }
1984+
1985+ if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
1986+ return 0;
1987+
1988+ emitter->whitespace = 0;
1989+ emitter->indention = 0;
1990+
1991+ return 1;
1992+}
1993+
1994+static int
1995+yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
1996+ yaml_char_t *value, size_t length, int allow_breaks)
1997+{
1998+ yaml_string_t string = STRING(value, length);
1999+ int spaces = 0;
2000+
2001+ if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
2002+ return 0;
2003+
2004+ while (string.pointer != string.end)
2005+ {
2006+ if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
2007+ || IS_BOM(string) || IS_BREAK(string)
2008+ || CHECK(string, '"') || CHECK(string, '\\'))
2009+ {
2010+ unsigned char octet;
2011+ unsigned int width;
2012+ unsigned int value;
2013+ int k;
2014+
2015+ octet = string.pointer[0];
2016+ width = (octet & 0x80) == 0x00 ? 1 :
2017+ (octet & 0xE0) == 0xC0 ? 2 :
2018+ (octet & 0xF0) == 0xE0 ? 3 :
2019+ (octet & 0xF8) == 0xF0 ? 4 : 0;
2020+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2021+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2022+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2023+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2024+ for (k = 1; k < (int)width; k ++) {
2025+ octet = string.pointer[k];
2026+ value = (value << 6) + (octet & 0x3F);
2027+ }
2028+ string.pointer += width;
2029+
2030+ if (!PUT(emitter, '\\')) return 0;
2031+
2032+ switch (value)
2033+ {
2034+ case 0x00:
2035+ if (!PUT(emitter, '0')) return 0;
2036+ break;
2037+
2038+ case 0x07:
2039+ if (!PUT(emitter, 'a')) return 0;
2040+ break;
2041+
2042+ case 0x08:
2043+ if (!PUT(emitter, 'b')) return 0;
2044+ break;
2045+
2046+ case 0x09:
2047+ if (!PUT(emitter, 't')) return 0;
2048+ break;
2049+
2050+ case 0x0A:
2051+ if (!PUT(emitter, 'n')) return 0;
2052+ break;
2053+
2054+ case 0x0B:
2055+ if (!PUT(emitter, 'v')) return 0;
2056+ break;
2057+
2058+ case 0x0C:
2059+ if (!PUT(emitter, 'f')) return 0;
2060+ break;
2061+
2062+ case 0x0D:
2063+ if (!PUT(emitter, 'r')) return 0;
2064+ break;
2065+
2066+ case 0x1B:
2067+ if (!PUT(emitter, 'e')) return 0;
2068+ break;
2069+
2070+ case 0x22:
2071+ if (!PUT(emitter, '\"')) return 0;
2072+ break;
2073+
2074+ case 0x5C:
2075+ if (!PUT(emitter, '\\')) return 0;
2076+ break;
2077+
2078+ case 0x85:
2079+ if (!PUT(emitter, 'N')) return 0;
2080+ break;
2081+
2082+ case 0xA0:
2083+ if (!PUT(emitter, '_')) return 0;
2084+ break;
2085+
2086+ case 0x2028:
2087+ if (!PUT(emitter, 'L')) return 0;
2088+ break;
2089+
2090+ case 0x2029:
2091+ if (!PUT(emitter, 'P')) return 0;
2092+ break;
2093+
2094+ default:
2095+ if (value <= 0xFF) {
2096+ if (!PUT(emitter, 'x')) return 0;
2097+ width = 2;
2098+ }
2099+ else if (value <= 0xFFFF) {
2100+ if (!PUT(emitter, 'u')) return 0;
2101+ width = 4;
2102+ }
2103+ else {
2104+ if (!PUT(emitter, 'U')) return 0;
2105+ width = 8;
2106+ }
2107+ for (k = (width-1)*4; k >= 0; k -= 4) {
2108+ int digit = (value >> k) & 0x0F;
2109+ if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
2110+ return 0;
2111+ }
2112+ }
2113+ spaces = 0;
2114+ }
2115+ else if (IS_SPACE(string))
2116+ {
2117+ if (allow_breaks && !spaces
2118+ && emitter->column > emitter->best_width
2119+ && string.pointer != string.start
2120+ && string.pointer != string.end - 1) {
2121+ if (!yaml_emitter_write_indent(emitter)) return 0;
2122+ if (IS_SPACE_AT(string, 1)) {
2123+ if (!PUT(emitter, '\\')) return 0;
2124+ }
2125+ MOVE(string);
2126+ }
2127+ else {
2128+ if (!WRITE(emitter, string)) return 0;
2129+ }
2130+ spaces = 1;
2131+ }
2132+ else
2133+ {
2134+ if (!WRITE(emitter, string)) return 0;
2135+ spaces = 0;
2136+ }
2137+ }
2138+
2139+ if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
2140+ return 0;
2141+
2142+ emitter->whitespace = 0;
2143+ emitter->indention = 0;
2144+
2145+ return 1;
2146+}
2147+
2148+static int
2149+yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
2150+ yaml_string_t string)
2151+{
2152+ char indent_hint[2];
2153+ char *chomp_hint = NULL;
2154+
2155+ if (IS_SPACE(string) || IS_BREAK(string))
2156+ {
2157+ indent_hint[0] = '0' + (char)emitter->best_indent;
2158+ indent_hint[1] = '\0';
2159+ if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
2160+ return 0;
2161+ }
2162+
2163+ emitter->open_ended = 0;
2164+
2165+ string.pointer = string.end;
2166+ if (string.start == string.pointer)
2167+ {
2168+ chomp_hint = "-";
2169+ }
2170+ else
2171+ {
2172+ do {
2173+ string.pointer --;
2174+ } while ((*string.pointer & 0xC0) == 0x80);
2175+ if (!IS_BREAK(string))
2176+ {
2177+ chomp_hint = "-";
2178+ }
2179+ else if (string.start == string.pointer)
2180+ {
2181+ chomp_hint = "+";
2182+ emitter->open_ended = 1;
2183+ }
2184+ else
2185+ {
2186+ do {
2187+ string.pointer --;
2188+ } while ((*string.pointer & 0xC0) == 0x80);
2189+ if (IS_BREAK(string))
2190+ {
2191+ chomp_hint = "+";
2192+ emitter->open_ended = 1;
2193+ }
2194+ }
2195+ }
2196+
2197+ if (chomp_hint)
2198+ {
2199+ if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
2200+ return 0;
2201+ }
2202+
2203+ return 1;
2204+}
2205+
2206+static int
2207+yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
2208+ yaml_char_t *value, size_t length)
2209+{
2210+ yaml_string_t string = STRING(value, length);
2211+ int breaks = 1;
2212+
2213+ if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
2214+ return 0;
2215+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2216+ return 0;
2217+ if (!PUT_BREAK(emitter)) return 0;
2218+ emitter->indention = 1;
2219+ emitter->whitespace = 1;
2220+
2221+ while (string.pointer != string.end)
2222+ {
2223+ if (IS_BREAK(string))
2224+ {
2225+ if (!WRITE_BREAK(emitter, string)) return 0;
2226+ emitter->indention = 1;
2227+ breaks = 1;
2228+ }
2229+ else
2230+ {
2231+ if (breaks) {
2232+ if (!yaml_emitter_write_indent(emitter)) return 0;
2233+ }
2234+ if (!WRITE(emitter, string)) return 0;
2235+ emitter->indention = 0;
2236+ breaks = 0;
2237+ }
2238+ }
2239+
2240+ return 1;
2241+}
2242+
2243+static int
2244+yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
2245+ yaml_char_t *value, size_t length)
2246+{
2247+ yaml_string_t string = STRING(value, length);
2248+ int breaks = 1;
2249+ int leading_spaces = 1;
2250+
2251+ if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
2252+ return 0;
2253+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2254+ return 0;
2255+ if (!PUT_BREAK(emitter)) return 0;
2256+ emitter->indention = 1;
2257+ emitter->whitespace = 1;
2258+
2259+ while (string.pointer != string.end)
2260+ {
2261+ if (IS_BREAK(string))
2262+ {
2263+ if (!breaks && !leading_spaces && CHECK(string, '\n')) {
2264+ int k = 0;
2265+ while (IS_BREAK_AT(string, k)) {
2266+ k += WIDTH_AT(string, k);
2267+ }
2268+ if (!IS_BLANKZ_AT(string, k)) {
2269+ if (!PUT_BREAK(emitter)) return 0;
2270+ }
2271+ }
2272+ if (!WRITE_BREAK(emitter, string)) return 0;
2273+ emitter->indention = 1;
2274+ breaks = 1;
2275+ }
2276+ else
2277+ {
2278+ if (breaks) {
2279+ if (!yaml_emitter_write_indent(emitter)) return 0;
2280+ leading_spaces = IS_BLANK(string);
2281+ }
2282+ if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
2283+ && emitter->column > emitter->best_width) {
2284+ if (!yaml_emitter_write_indent(emitter)) return 0;
2285+ MOVE(string);
2286+ }
2287+ else {
2288+ if (!WRITE(emitter, string)) return 0;
2289+ }
2290+ emitter->indention = 0;
2291+ breaks = 0;
2292+ }
2293+ }
2294+
2295+ return 1;
2296+}
2297+
c/loader.cnew file+430
@@ -0,0 +1,430 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * API functions.
6+ */
7+
8+YAML_DECLARE(int)
9+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
10+
11+/*
12+ * Error handling.
13+ */
14+
15+static int
16+yaml_parser_set_composer_error(yaml_parser_t *parser,
17+ const char *problem, yaml_mark_t problem_mark);
18+
19+static int
20+yaml_parser_set_composer_error_context(yaml_parser_t *parser,
21+ const char *context, yaml_mark_t context_mark,
22+ const char *problem, yaml_mark_t problem_mark);
23+
24+
25+/*
26+ * Alias handling.
27+ */
28+
29+static int
30+yaml_parser_register_anchor(yaml_parser_t *parser,
31+ int index, yaml_char_t *anchor);
32+
33+/*
34+ * Clean up functions.
35+ */
36+
37+static void
38+yaml_parser_delete_aliases(yaml_parser_t *parser);
39+
40+/*
41+ * Composer functions.
42+ */
43+
44+static int
45+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
46+
47+static int
48+yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
49+
50+static int
51+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
52+
53+static int
54+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
55+
56+static int
57+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
58+
59+static int
60+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
61+
62+/*
63+ * Load the next document of the stream.
64+ */
65+
66+YAML_DECLARE(int)
67+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
68+{
69+ yaml_event_t event;
70+
71+ assert(parser); /* Non-NULL parser object is expected. */
72+ assert(document); /* Non-NULL document object is expected. */
73+
74+ memset(document, 0, sizeof(yaml_document_t));
75+ if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
76+ goto error;
77+
78+ if (!parser->stream_start_produced) {
79+ if (!yaml_parser_parse(parser, &event)) goto error;
80+ assert(event.type == YAML_STREAM_START_EVENT);
81+ /* STREAM-START is expected. */
82+ }
83+
84+ if (parser->stream_end_produced) {
85+ return 1;
86+ }
87+
88+ if (!yaml_parser_parse(parser, &event)) goto error;
89+ if (event.type == YAML_STREAM_END_EVENT) {
90+ return 1;
91+ }
92+
93+ if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
94+ goto error;
95+
96+ parser->document = document;
97+
98+ if (!yaml_parser_load_document(parser, &event)) goto error;
99+
100+ yaml_parser_delete_aliases(parser);
101+ parser->document = NULL;
102+
103+ return 1;
104+
105+error:
106+
107+ yaml_parser_delete_aliases(parser);
108+ yaml_document_delete(document);
109+ parser->document = NULL;
110+
111+ return 0;
112+}
113+
114+/*
115+ * Set composer error.
116+ */
117+
118+static int
119+yaml_parser_set_composer_error(yaml_parser_t *parser,
120+ const char *problem, yaml_mark_t problem_mark)
121+{
122+ parser->error = YAML_COMPOSER_ERROR;
123+ parser->problem = problem;
124+ parser->problem_mark = problem_mark;
125+
126+ return 0;
127+}
128+
129+/*
130+ * Set composer error with context.
131+ */
132+
133+static int
134+yaml_parser_set_composer_error_context(yaml_parser_t *parser,
135+ const char *context, yaml_mark_t context_mark,
136+ const char *problem, yaml_mark_t problem_mark)
137+{
138+ parser->error = YAML_COMPOSER_ERROR;
139+ parser->context = context;
140+ parser->context_mark = context_mark;
141+ parser->problem = problem;
142+ parser->problem_mark = problem_mark;
143+
144+ return 0;
145+}
146+
147+/*
148+ * Delete the stack of aliases.
149+ */
150+
151+static void
152+yaml_parser_delete_aliases(yaml_parser_t *parser)
153+{
154+ while (!STACK_EMPTY(parser, parser->aliases)) {
155+ yaml_free(POP(parser, parser->aliases).anchor);
156+ }
157+ STACK_DEL(parser, parser->aliases);
158+}
159+
160+/*
161+ * Compose a document object.
162+ */
163+
164+static int
165+yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
166+{
167+ yaml_event_t event;
168+
169+ assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170+ /* DOCUMENT-START is expected. */
171+
172+ parser->document->version_directive
173+ = first_event->data.document_start.version_directive;
174+ parser->document->tag_directives.start
175+ = first_event->data.document_start.tag_directives.start;
176+ parser->document->tag_directives.end
177+ = first_event->data.document_start.tag_directives.end;
178+ parser->document->start_implicit
179+ = first_event->data.document_start.implicit;
180+ parser->document->start_mark = first_event->start_mark;
181+
182+ if (!yaml_parser_parse(parser, &event)) return 0;
183+
184+ if (!yaml_parser_load_node(parser, &event)) return 0;
185+
186+ if (!yaml_parser_parse(parser, &event)) return 0;
187+ assert(event.type == YAML_DOCUMENT_END_EVENT);
188+ /* DOCUMENT-END is expected. */
189+
190+ parser->document->end_implicit = event.data.document_end.implicit;
191+ parser->document->end_mark = event.end_mark;
192+
193+ return 1;
194+}
195+
196+/*
197+ * Compose a node.
198+ */
199+
200+static int
201+yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
202+{
203+ switch (first_event->type) {
204+ case YAML_ALIAS_EVENT:
205+ return yaml_parser_load_alias(parser, first_event);
206+ case YAML_SCALAR_EVENT:
207+ return yaml_parser_load_scalar(parser, first_event);
208+ case YAML_SEQUENCE_START_EVENT:
209+ return yaml_parser_load_sequence(parser, first_event);
210+ case YAML_MAPPING_START_EVENT:
211+ return yaml_parser_load_mapping(parser, first_event);
212+ default:
213+ assert(0); /* Could not happen. */
214+ return 0;
215+ }
216+
217+ return 0;
218+}
219+
220+/*
221+ * Add an anchor.
222+ */
223+
224+static int
225+yaml_parser_register_anchor(yaml_parser_t *parser,
226+ int index, yaml_char_t *anchor)
227+{
228+ yaml_alias_data_t data = { anchor, index, { 0, 0, 0 } };
229+ yaml_alias_data_t *alias_data;
230+
231+ if (!anchor) return 1;
232+
233+ data.mark = parser->document->nodes.start[index-1].start_mark;
234+
235+ for (alias_data = parser->aliases.start;
236+ alias_data != parser->aliases.top; alias_data ++) {
237+ if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
238+ yaml_free(anchor);
239+ return yaml_parser_set_composer_error_context(parser,
240+ "found duplicate anchor; first occurence",
241+ alias_data->mark, "second occurence", data.mark);
242+ }
243+ }
244+
245+ if (!PUSH(parser, parser->aliases, data)) {
246+ yaml_free(anchor);
247+ return 0;
248+ }
249+
250+ return 1;
251+}
252+
253+/*
254+ * Compose a node corresponding to an alias.
255+ */
256+
257+static int
258+yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
259+{
260+ yaml_char_t *anchor = first_event->data.alias.anchor;
261+ yaml_alias_data_t *alias_data;
262+
263+ for (alias_data = parser->aliases.start;
264+ alias_data != parser->aliases.top; alias_data ++) {
265+ if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
266+ yaml_free(anchor);
267+ return alias_data->index;
268+ }
269+ }
270+
271+ yaml_free(anchor);
272+ return yaml_parser_set_composer_error(parser, "found undefined alias",
273+ first_event->start_mark);
274+}
275+
276+/*
277+ * Compose a scalar node.
278+ */
279+
280+static int
281+yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
282+{
283+ yaml_node_t node;
284+ int index;
285+ yaml_char_t *tag = first_event->data.scalar.tag;
286+
287+ if (!tag || strcmp((char *)tag, "!") == 0) {
288+ yaml_free(tag);
289+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
290+ if (!tag) goto error;
291+ }
292+
293+ SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
294+ first_event->data.scalar.length, first_event->data.scalar.style,
295+ first_event->start_mark, first_event->end_mark);
296+
297+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
298+
299+ index = parser->document->nodes.top - parser->document->nodes.start;
300+
301+ if (!yaml_parser_register_anchor(parser, index,
302+ first_event->data.scalar.anchor)) return 0;
303+
304+ return index;
305+
306+error:
307+ yaml_free(tag);
308+ yaml_free(first_event->data.scalar.anchor);
309+ yaml_free(first_event->data.scalar.value);
310+ return 0;
311+}
312+
313+/*
314+ * Compose a sequence node.
315+ */
316+
317+static int
318+yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
319+{
320+ yaml_event_t event;
321+ yaml_node_t node;
322+ struct {
323+ yaml_node_item_t *start;
324+ yaml_node_item_t *end;
325+ yaml_node_item_t *top;
326+ } items = { NULL, NULL, NULL };
327+ int index, item_index;
328+ yaml_char_t *tag = first_event->data.sequence_start.tag;
329+
330+ if (!tag || strcmp((char *)tag, "!") == 0) {
331+ yaml_free(tag);
332+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
333+ if (!tag) goto error;
334+ }
335+
336+ if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
337+
338+ SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
339+ first_event->data.sequence_start.style,
340+ first_event->start_mark, first_event->end_mark);
341+
342+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
343+
344+ index = parser->document->nodes.top - parser->document->nodes.start;
345+
346+ if (!yaml_parser_register_anchor(parser, index,
347+ first_event->data.sequence_start.anchor)) return 0;
348+
349+ if (!yaml_parser_parse(parser, &event)) return 0;
350+
351+ while (event.type != YAML_SEQUENCE_END_EVENT) {
352+ item_index = yaml_parser_load_node(parser, &event);
353+ if (!item_index) return 0;
354+ if (!PUSH(parser,
355+ parser->document->nodes.start[index-1].data.sequence.items,
356+ item_index)) return 0;
357+ if (!yaml_parser_parse(parser, &event)) return 0;
358+ }
359+
360+ parser->document->nodes.start[index-1].end_mark = event.end_mark;
361+
362+ return index;
363+
364+error:
365+ yaml_free(tag);
366+ yaml_free(first_event->data.sequence_start.anchor);
367+ return 0;
368+}
369+
370+/*
371+ * Compose a mapping node.
372+ */
373+
374+static int
375+yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
376+{
377+ yaml_event_t event;
378+ yaml_node_t node;
379+ struct {
380+ yaml_node_pair_t *start;
381+ yaml_node_pair_t *end;
382+ yaml_node_pair_t *top;
383+ } pairs = { NULL, NULL, NULL };
384+ int index;
385+ yaml_node_pair_t pair;
386+ yaml_char_t *tag = first_event->data.mapping_start.tag;
387+
388+ if (!tag || strcmp((char *)tag, "!") == 0) {
389+ yaml_free(tag);
390+ tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
391+ if (!tag) goto error;
392+ }
393+
394+ if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
395+
396+ MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
397+ first_event->data.mapping_start.style,
398+ first_event->start_mark, first_event->end_mark);
399+
400+ if (!PUSH(parser, parser->document->nodes, node)) goto error;
401+
402+ index = parser->document->nodes.top - parser->document->nodes.start;
403+
404+ if (!yaml_parser_register_anchor(parser, index,
405+ first_event->data.mapping_start.anchor)) return 0;
406+
407+ if (!yaml_parser_parse(parser, &event)) return 0;
408+
409+ while (event.type != YAML_MAPPING_END_EVENT) {
410+ pair.key = yaml_parser_load_node(parser, &event);
411+ if (!pair.key) return 0;
412+ if (!yaml_parser_parse(parser, &event)) return 0;
413+ pair.value = yaml_parser_load_node(parser, &event);
414+ if (!pair.value) return 0;
415+ if (!PUSH(parser,
416+ parser->document->nodes.start[index-1].data.mapping.pairs,
417+ pair)) return 0;
418+ if (!yaml_parser_parse(parser, &event)) return 0;
419+ }
420+
421+ parser->document->nodes.start[index-1].end_mark = event.end_mark;
422+
423+ return index;
424+
425+error:
426+ yaml_free(tag);
427+ yaml_free(first_event->data.mapping_start.anchor);
428+ return 0;
429+}
430+
c/parser.cnew file+1374
@@ -0,0 +1,1374 @@
1+
2+/*
3+ * The parser implements the following grammar:
4+ *
5+ * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
6+ * implicit_document ::= block_node DOCUMENT-END*
7+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8+ * block_node_or_indentless_sequence ::=
9+ * ALIAS
10+ * | properties (block_content | indentless_block_sequence)?
11+ * | block_content
12+ * | indentless_block_sequence
13+ * block_node ::= ALIAS
14+ * | properties block_content?
15+ * | block_content
16+ * flow_node ::= ALIAS
17+ * | properties flow_content?
18+ * | flow_content
19+ * properties ::= TAG ANCHOR? | ANCHOR TAG?
20+ * block_content ::= block_collection | flow_collection | SCALAR
21+ * flow_content ::= flow_collection | SCALAR
22+ * block_collection ::= block_sequence | block_mapping
23+ * flow_collection ::= flow_sequence | flow_mapping
24+ * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25+ * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
26+ * block_mapping ::= BLOCK-MAPPING_START
27+ * ((KEY block_node_or_indentless_sequence?)?
28+ * (VALUE block_node_or_indentless_sequence?)?)*
29+ * BLOCK-END
30+ * flow_sequence ::= FLOW-SEQUENCE-START
31+ * (flow_sequence_entry FLOW-ENTRY)*
32+ * flow_sequence_entry?
33+ * FLOW-SEQUENCE-END
34+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35+ * flow_mapping ::= FLOW-MAPPING-START
36+ * (flow_mapping_entry FLOW-ENTRY)*
37+ * flow_mapping_entry?
38+ * FLOW-MAPPING-END
39+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40+ */
41+
42+#include "yaml_private.h"
43+
44+/*
45+ * Peek the next token in the token queue.
46+ */
47+
48+#define PEEK_TOKEN(parser) \
49+ ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
50+ parser->tokens.head : NULL)
51+
52+/*
53+ * Remove the next token from the queue (must be called after PEEK_TOKEN).
54+ */
55+
56+#define SKIP_TOKEN(parser) \
57+ (parser->token_available = 0, \
58+ parser->tokens_parsed ++, \
59+ parser->stream_end_produced = \
60+ (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \
61+ parser->tokens.head ++)
62+
63+/*
64+ * Public API declarations.
65+ */
66+
67+YAML_DECLARE(int)
68+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
69+
70+/*
71+ * Error handling.
72+ */
73+
74+static int
75+yaml_parser_set_parser_error(yaml_parser_t *parser,
76+ const char *problem, yaml_mark_t problem_mark);
77+
78+static int
79+yaml_parser_set_parser_error_context(yaml_parser_t *parser,
80+ const char *context, yaml_mark_t context_mark,
81+ const char *problem, yaml_mark_t problem_mark);
82+
83+/*
84+ * State functions.
85+ */
86+
87+static int
88+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
89+
90+static int
91+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
92+
93+static int
94+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95+ int implicit);
96+
97+static int
98+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
99+
100+static int
101+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
102+
103+static int
104+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105+ int block, int indentless_sequence);
106+
107+static int
108+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109+ yaml_event_t *event, int first);
110+
111+static int
112+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113+ yaml_event_t *event);
114+
115+static int
116+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117+ yaml_event_t *event, int first);
118+
119+static int
120+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121+ yaml_event_t *event);
122+
123+static int
124+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125+ yaml_event_t *event, int first);
126+
127+static int
128+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129+ yaml_event_t *event);
130+
131+static int
132+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133+ yaml_event_t *event);
134+
135+static int
136+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137+ yaml_event_t *event);
138+
139+static int
140+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141+ yaml_event_t *event, int first);
142+
143+static int
144+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145+ yaml_event_t *event, int empty);
146+
147+/*
148+ * Utility functions.
149+ */
150+
151+static int
152+yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153+ yaml_event_t *event, yaml_mark_t mark);
154+
155+static int
156+yaml_parser_process_directives(yaml_parser_t *parser,
157+ yaml_version_directive_t **version_directive_ref,
158+ yaml_tag_directive_t **tag_directives_start_ref,
159+ yaml_tag_directive_t **tag_directives_end_ref);
160+
161+static int
162+yaml_parser_append_tag_directive(yaml_parser_t *parser,
163+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
164+
165+/*
166+ * Get the next event.
167+ */
168+
169+YAML_DECLARE(int)
170+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
171+{
172+ assert(parser); /* Non-NULL parser object is expected. */
173+ assert(event); /* Non-NULL event object is expected. */
174+
175+ /* Erase the event object. */
176+
177+ memset(event, 0, sizeof(yaml_event_t));
178+
179+ /* No events after the end of the stream or error. */
180+
181+ if (parser->stream_end_produced || parser->error ||
182+ parser->state == YAML_PARSE_END_STATE) {
183+ return 1;
184+ }
185+
186+ /* Generate the next event. */
187+
188+ return yaml_parser_state_machine(parser, event);
189+}
190+
191+/*
192+ * Set parser error.
193+ */
194+
195+static int
196+yaml_parser_set_parser_error(yaml_parser_t *parser,
197+ const char *problem, yaml_mark_t problem_mark)
198+{
199+ parser->error = YAML_PARSER_ERROR;
200+ parser->problem = problem;
201+ parser->problem_mark = problem_mark;
202+
203+ return 0;
204+}
205+
206+static int
207+yaml_parser_set_parser_error_context(yaml_parser_t *parser,
208+ const char *context, yaml_mark_t context_mark,
209+ const char *problem, yaml_mark_t problem_mark)
210+{
211+ parser->error = YAML_PARSER_ERROR;
212+ parser->context = context;
213+ parser->context_mark = context_mark;
214+ parser->problem = problem;
215+ parser->problem_mark = problem_mark;
216+
217+ return 0;
218+}
219+
220+
221+/*
222+ * State dispatcher.
223+ */
224+
225+static int
226+yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
227+{
228+ switch (parser->state)
229+ {
230+ case YAML_PARSE_STREAM_START_STATE:
231+ return yaml_parser_parse_stream_start(parser, event);
232+
233+ case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234+ return yaml_parser_parse_document_start(parser, event, 1);
235+
236+ case YAML_PARSE_DOCUMENT_START_STATE:
237+ return yaml_parser_parse_document_start(parser, event, 0);
238+
239+ case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240+ return yaml_parser_parse_document_content(parser, event);
241+
242+ case YAML_PARSE_DOCUMENT_END_STATE:
243+ return yaml_parser_parse_document_end(parser, event);
244+
245+ case YAML_PARSE_BLOCK_NODE_STATE:
246+ return yaml_parser_parse_node(parser, event, 1, 0);
247+
248+ case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249+ return yaml_parser_parse_node(parser, event, 1, 1);
250+
251+ case YAML_PARSE_FLOW_NODE_STATE:
252+ return yaml_parser_parse_node(parser, event, 0, 0);
253+
254+ case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255+ return yaml_parser_parse_block_sequence_entry(parser, event, 1);
256+
257+ case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258+ return yaml_parser_parse_block_sequence_entry(parser, event, 0);
259+
260+ case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261+ return yaml_parser_parse_indentless_sequence_entry(parser, event);
262+
263+ case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264+ return yaml_parser_parse_block_mapping_key(parser, event, 1);
265+
266+ case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267+ return yaml_parser_parse_block_mapping_key(parser, event, 0);
268+
269+ case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270+ return yaml_parser_parse_block_mapping_value(parser, event);
271+
272+ case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273+ return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
274+
275+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276+ return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
277+
278+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279+ return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
280+
281+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282+ return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
283+
284+ case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285+ return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
286+
287+ case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288+ return yaml_parser_parse_flow_mapping_key(parser, event, 1);
289+
290+ case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291+ return yaml_parser_parse_flow_mapping_key(parser, event, 0);
292+
293+ case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294+ return yaml_parser_parse_flow_mapping_value(parser, event, 0);
295+
296+ case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297+ return yaml_parser_parse_flow_mapping_value(parser, event, 1);
298+
299+ default:
300+ assert(1); /* Invalid state. */
301+ }
302+
303+ return 0;
304+}
305+
306+/*
307+ * Parse the production:
308+ * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
309+ * ************
310+ */
311+
312+static int
313+yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314+{
315+ yaml_token_t *token;
316+
317+ token = PEEK_TOKEN(parser);
318+ if (!token) return 0;
319+
320+ if (token->type != YAML_STREAM_START_TOKEN) {
321+ return yaml_parser_set_parser_error(parser,
322+ "did not find expected <stream-start>", token->start_mark);
323+ }
324+
325+ parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
326+ STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
327+ token->start_mark, token->start_mark);
328+ SKIP_TOKEN(parser);
329+
330+ return 1;
331+}
332+
333+/*
334+ * Parse the productions:
335+ * implicit_document ::= block_node DOCUMENT-END*
336+ * *
337+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338+ * *************************
339+ */
340+
341+static int
342+yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
343+ int implicit)
344+{
345+ yaml_token_t *token;
346+ yaml_version_directive_t *version_directive = NULL;
347+ struct {
348+ yaml_tag_directive_t *start;
349+ yaml_tag_directive_t *end;
350+ } tag_directives = { NULL, NULL };
351+
352+ token = PEEK_TOKEN(parser);
353+ if (!token) return 0;
354+
355+ /* Parse extra document end indicators. */
356+
357+ if (!implicit)
358+ {
359+ while (token->type == YAML_DOCUMENT_END_TOKEN) {
360+ SKIP_TOKEN(parser);
361+ token = PEEK_TOKEN(parser);
362+ if (!token) return 0;
363+ }
364+ }
365+
366+ /* Parse an implicit document. */
367+
368+ if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369+ token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370+ token->type != YAML_DOCUMENT_START_TOKEN &&
371+ token->type != YAML_STREAM_END_TOKEN)
372+ {
373+ if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374+ return 0;
375+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376+ return 0;
377+ parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378+ DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379+ token->start_mark, token->start_mark);
380+ return 1;
381+ }
382+
383+ /* Parse an explicit document. */
384+
385+ else if (token->type != YAML_STREAM_END_TOKEN)
386+ {
387+ yaml_mark_t start_mark, end_mark;
388+ start_mark = token->start_mark;
389+ if (!yaml_parser_process_directives(parser, &version_directive,
390+ &tag_directives.start, &tag_directives.end))
391+ return 0;
392+ token = PEEK_TOKEN(parser);
393+ if (!token) goto error;
394+ if (token->type != YAML_DOCUMENT_START_TOKEN) {
395+ yaml_parser_set_parser_error(parser,
396+ "did not find expected <document start>", token->start_mark);
397+ goto error;
398+ }
399+ if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400+ goto error;
401+ parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402+ end_mark = token->end_mark;
403+ DOCUMENT_START_EVENT_INIT(*event, version_directive,
404+ tag_directives.start, tag_directives.end, 0,
405+ start_mark, end_mark);
406+ SKIP_TOKEN(parser);
407+ version_directive = NULL;
408+ tag_directives.start = tag_directives.end = NULL;
409+ return 1;
410+ }
411+
412+ /* Parse the stream end. */
413+
414+ else
415+ {
416+ parser->state = YAML_PARSE_END_STATE;
417+ STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418+ SKIP_TOKEN(parser);
419+ return 1;
420+ }
421+
422+error:
423+ yaml_free(version_directive);
424+ while (tag_directives.start != tag_directives.end) {
425+ yaml_free(tag_directives.end[-1].handle);
426+ yaml_free(tag_directives.end[-1].prefix);
427+ tag_directives.end --;
428+ }
429+ yaml_free(tag_directives.start);
430+ return 0;
431+}
432+
433+/*
434+ * Parse the productions:
435+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436+ * ***********
437+ */
438+
439+static int
440+yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441+{
442+ yaml_token_t *token;
443+
444+ token = PEEK_TOKEN(parser);
445+ if (!token) return 0;
446+
447+ if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448+ token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449+ token->type == YAML_DOCUMENT_START_TOKEN ||
450+ token->type == YAML_DOCUMENT_END_TOKEN ||
451+ token->type == YAML_STREAM_END_TOKEN) {
452+ parser->state = POP(parser, parser->states);
453+ return yaml_parser_process_empty_scalar(parser, event,
454+ token->start_mark);
455+ }
456+ else {
457+ return yaml_parser_parse_node(parser, event, 1, 0);
458+ }
459+}
460+
461+/*
462+ * Parse the productions:
463+ * implicit_document ::= block_node DOCUMENT-END*
464+ * *************
465+ * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466+ * *************
467+ */
468+
469+static int
470+yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471+{
472+ yaml_token_t *token;
473+ yaml_mark_t start_mark, end_mark;
474+ int implicit = 1;
475+
476+ token = PEEK_TOKEN(parser);
477+ if (!token) return 0;
478+
479+ start_mark = end_mark = token->start_mark;
480+
481+ if (token->type == YAML_DOCUMENT_END_TOKEN) {
482+ end_mark = token->end_mark;
483+ SKIP_TOKEN(parser);
484+ implicit = 0;
485+ }
486+
487+ while (!STACK_EMPTY(parser, parser->tag_directives)) {
488+ yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489+ yaml_free(tag_directive.handle);
490+ yaml_free(tag_directive.prefix);
491+ }
492+
493+ parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494+ DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
495+
496+ return 1;
497+}
498+
499+/*
500+ * Parse the productions:
501+ * block_node_or_indentless_sequence ::=
502+ * ALIAS
503+ * *****
504+ * | properties (block_content | indentless_block_sequence)?
505+ * ********** *
506+ * | block_content | indentless_block_sequence
507+ * *
508+ * block_node ::= ALIAS
509+ * *****
510+ * | properties block_content?
511+ * ********** *
512+ * | block_content
513+ * *
514+ * flow_node ::= ALIAS
515+ * *****
516+ * | properties flow_content?
517+ * ********** *
518+ * | flow_content
519+ * *
520+ * properties ::= TAG ANCHOR? | ANCHOR TAG?
521+ * *************************
522+ * block_content ::= block_collection | flow_collection | SCALAR
523+ * ******
524+ * flow_content ::= flow_collection | SCALAR
525+ * ******
526+ */
527+
528+static int
529+yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530+ int block, int indentless_sequence)
531+{
532+ yaml_token_t *token;
533+ yaml_char_t *anchor = NULL;
534+ yaml_char_t *tag_handle = NULL;
535+ yaml_char_t *tag_suffix = NULL;
536+ yaml_char_t *tag = NULL;
537+ yaml_mark_t start_mark, end_mark, tag_mark;
538+ int implicit;
539+
540+ token = PEEK_TOKEN(parser);
541+ if (!token) return 0;
542+
543+ if (token->type == YAML_ALIAS_TOKEN)
544+ {
545+ parser->state = POP(parser, parser->states);
546+ ALIAS_EVENT_INIT(*event, token->data.alias.value,
547+ token->start_mark, token->end_mark);
548+ SKIP_TOKEN(parser);
549+ return 1;
550+ }
551+
552+ else
553+ {
554+ start_mark = end_mark = token->start_mark;
555+
556+ if (token->type == YAML_ANCHOR_TOKEN)
557+ {
558+ anchor = token->data.anchor.value;
559+ start_mark = token->start_mark;
560+ end_mark = token->end_mark;
561+ SKIP_TOKEN(parser);
562+ token = PEEK_TOKEN(parser);
563+ if (!token) goto error;
564+ if (token->type == YAML_TAG_TOKEN)
565+ {
566+ tag_handle = token->data.tag.handle;
567+ tag_suffix = token->data.tag.suffix;
568+ tag_mark = token->start_mark;
569+ end_mark = token->end_mark;
570+ SKIP_TOKEN(parser);
571+ token = PEEK_TOKEN(parser);
572+ if (!token) goto error;
573+ }
574+ }
575+ else if (token->type == YAML_TAG_TOKEN)
576+ {
577+ tag_handle = token->data.tag.handle;
578+ tag_suffix = token->data.tag.suffix;
579+ start_mark = tag_mark = token->start_mark;
580+ end_mark = token->end_mark;
581+ SKIP_TOKEN(parser);
582+ token = PEEK_TOKEN(parser);
583+ if (!token) goto error;
584+ if (token->type == YAML_ANCHOR_TOKEN)
585+ {
586+ anchor = token->data.anchor.value;
587+ end_mark = token->end_mark;
588+ SKIP_TOKEN(parser);
589+ token = PEEK_TOKEN(parser);
590+ if (!token) goto error;
591+ }
592+ }
593+
594+ if (tag_handle) {
595+ if (!*tag_handle) {
596+ tag = tag_suffix;
597+ yaml_free(tag_handle);
598+ tag_handle = tag_suffix = NULL;
599+ }
600+ else {
601+ yaml_tag_directive_t *tag_directive;
602+ for (tag_directive = parser->tag_directives.start;
603+ tag_directive != parser->tag_directives.top;
604+ tag_directive ++) {
605+ if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606+ size_t prefix_len = strlen((char *)tag_directive->prefix);
607+ size_t suffix_len = strlen((char *)tag_suffix);
608+ tag = yaml_malloc(prefix_len+suffix_len+1);
609+ if (!tag) {
610+ parser->error = YAML_MEMORY_ERROR;
611+ goto error;
612+ }
613+ memcpy(tag, tag_directive->prefix, prefix_len);
614+ memcpy(tag+prefix_len, tag_suffix, suffix_len);
615+ tag[prefix_len+suffix_len] = '\0';
616+ yaml_free(tag_handle);
617+ yaml_free(tag_suffix);
618+ tag_handle = tag_suffix = NULL;
619+ break;
620+ }
621+ }
622+ if (!tag) {
623+ yaml_parser_set_parser_error_context(parser,
624+ "while parsing a node", start_mark,
625+ "found undefined tag handle", tag_mark);
626+ goto error;
627+ }
628+ }
629+ }
630+
631+ implicit = (!tag || !*tag);
632+ if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633+ end_mark = token->end_mark;
634+ parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636+ YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
637+ return 1;
638+ }
639+ else {
640+ if (token->type == YAML_SCALAR_TOKEN) {
641+ int plain_implicit = 0;
642+ int quoted_implicit = 0;
643+ end_mark = token->end_mark;
644+ if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645+ || (tag && strcmp((char *)tag, "!") == 0)) {
646+ plain_implicit = 1;
647+ }
648+ else if (!tag) {
649+ quoted_implicit = 1;
650+ }
651+ parser->state = POP(parser, parser->states);
652+ SCALAR_EVENT_INIT(*event, anchor, tag,
653+ token->data.scalar.value, token->data.scalar.length,
654+ plain_implicit, quoted_implicit,
655+ token->data.scalar.style, start_mark, end_mark);
656+ SKIP_TOKEN(parser);
657+ return 1;
658+ }
659+ else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660+ end_mark = token->end_mark;
661+ parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663+ YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
664+ return 1;
665+ }
666+ else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667+ end_mark = token->end_mark;
668+ parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670+ YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
671+ return 1;
672+ }
673+ else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674+ end_mark = token->end_mark;
675+ parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676+ SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677+ YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
678+ return 1;
679+ }
680+ else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681+ end_mark = token->end_mark;
682+ parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683+ MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684+ YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
685+ return 1;
686+ }
687+ else if (anchor || tag) {
688+ yaml_char_t *value = yaml_malloc(1);
689+ if (!value) {
690+ parser->error = YAML_MEMORY_ERROR;
691+ goto error;
692+ }
693+ value[0] = '\0';
694+ parser->state = POP(parser, parser->states);
695+ SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696+ implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697+ start_mark, end_mark);
698+ return 1;
699+ }
700+ else {
701+ yaml_parser_set_parser_error_context(parser,
702+ (block ? "while parsing a block node"
703+ : "while parsing a flow node"), start_mark,
704+ "did not find expected node content", token->start_mark);
705+ goto error;
706+ }
707+ }
708+ }
709+
710+error:
711+ yaml_free(anchor);
712+ yaml_free(tag_handle);
713+ yaml_free(tag_suffix);
714+ yaml_free(tag);
715+
716+ return 0;
717+}
718+
719+/*
720+ * Parse the productions:
721+ * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722+ * ******************** *********** * *********
723+ */
724+
725+static int
726+yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727+ yaml_event_t *event, int first)
728+{
729+ yaml_token_t *token;
730+
731+ if (first) {
732+ token = PEEK_TOKEN(parser);
733+ if (!PUSH(parser, parser->marks, token->start_mark))
734+ return 0;
735+ SKIP_TOKEN(parser);
736+ }
737+
738+ token = PEEK_TOKEN(parser);
739+ if (!token) return 0;
740+
741+ if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742+ {
743+ yaml_mark_t mark = token->end_mark;
744+ SKIP_TOKEN(parser);
745+ token = PEEK_TOKEN(parser);
746+ if (!token) return 0;
747+ if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748+ token->type != YAML_BLOCK_END_TOKEN) {
749+ if (!PUSH(parser, parser->states,
750+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
751+ return 0;
752+ return yaml_parser_parse_node(parser, event, 1, 0);
753+ }
754+ else {
755+ parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756+ return yaml_parser_process_empty_scalar(parser, event, mark);
757+ }
758+ }
759+
760+ else if (token->type == YAML_BLOCK_END_TOKEN)
761+ {
762+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
763+ parser->state = POP(parser, parser->states);
764+ dummy_mark = POP(parser, parser->marks);
765+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
766+ SKIP_TOKEN(parser);
767+ return 1;
768+ }
769+
770+ else
771+ {
772+ return yaml_parser_set_parser_error_context(parser,
773+ "while parsing a block collection", POP(parser, parser->marks),
774+ "did not find expected '-' indicator", token->start_mark);
775+ }
776+}
777+
778+/*
779+ * Parse the productions:
780+ * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
781+ * *********** *
782+ */
783+
784+static int
785+yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
786+ yaml_event_t *event)
787+{
788+ yaml_token_t *token;
789+
790+ token = PEEK_TOKEN(parser);
791+ if (!token) return 0;
792+
793+ if (token->type == YAML_BLOCK_ENTRY_TOKEN)
794+ {
795+ yaml_mark_t mark = token->end_mark;
796+ SKIP_TOKEN(parser);
797+ token = PEEK_TOKEN(parser);
798+ if (!token) return 0;
799+ if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
800+ token->type != YAML_KEY_TOKEN &&
801+ token->type != YAML_VALUE_TOKEN &&
802+ token->type != YAML_BLOCK_END_TOKEN) {
803+ if (!PUSH(parser, parser->states,
804+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
805+ return 0;
806+ return yaml_parser_parse_node(parser, event, 1, 0);
807+ }
808+ else {
809+ parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
810+ return yaml_parser_process_empty_scalar(parser, event, mark);
811+ }
812+ }
813+
814+ else
815+ {
816+ parser->state = POP(parser, parser->states);
817+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
818+ return 1;
819+ }
820+}
821+
822+/*
823+ * Parse the productions:
824+ * block_mapping ::= BLOCK-MAPPING_START
825+ * *******************
826+ * ((KEY block_node_or_indentless_sequence?)?
827+ * *** *
828+ * (VALUE block_node_or_indentless_sequence?)?)*
829+ *
830+ * BLOCK-END
831+ * *********
832+ */
833+
834+static int
835+yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
836+ yaml_event_t *event, int first)
837+{
838+ yaml_token_t *token;
839+
840+ if (first) {
841+ token = PEEK_TOKEN(parser);
842+ if (!PUSH(parser, parser->marks, token->start_mark))
843+ return 0;
844+ SKIP_TOKEN(parser);
845+ }
846+
847+ token = PEEK_TOKEN(parser);
848+ if (!token) return 0;
849+
850+ if (token->type == YAML_KEY_TOKEN)
851+ {
852+ yaml_mark_t mark = token->end_mark;
853+ SKIP_TOKEN(parser);
854+ token = PEEK_TOKEN(parser);
855+ if (!token) return 0;
856+ if (token->type != YAML_KEY_TOKEN &&
857+ token->type != YAML_VALUE_TOKEN &&
858+ token->type != YAML_BLOCK_END_TOKEN) {
859+ if (!PUSH(parser, parser->states,
860+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
861+ return 0;
862+ return yaml_parser_parse_node(parser, event, 1, 1);
863+ }
864+ else {
865+ parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
866+ return yaml_parser_process_empty_scalar(parser, event, mark);
867+ }
868+ }
869+
870+ else if (token->type == YAML_BLOCK_END_TOKEN)
871+ {
872+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
873+ parser->state = POP(parser, parser->states);
874+ dummy_mark = POP(parser, parser->marks);
875+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
876+ SKIP_TOKEN(parser);
877+ return 1;
878+ }
879+
880+ else
881+ {
882+ return yaml_parser_set_parser_error_context(parser,
883+ "while parsing a block mapping", POP(parser, parser->marks),
884+ "did not find expected key", token->start_mark);
885+ }
886+}
887+
888+/*
889+ * Parse the productions:
890+ * block_mapping ::= BLOCK-MAPPING_START
891+ *
892+ * ((KEY block_node_or_indentless_sequence?)?
893+ *
894+ * (VALUE block_node_or_indentless_sequence?)?)*
895+ * ***** *
896+ * BLOCK-END
897+ *
898+ */
899+
900+static int
901+yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
902+ yaml_event_t *event)
903+{
904+ yaml_token_t *token;
905+
906+ token = PEEK_TOKEN(parser);
907+ if (!token) return 0;
908+
909+ if (token->type == YAML_VALUE_TOKEN)
910+ {
911+ yaml_mark_t mark = token->end_mark;
912+ SKIP_TOKEN(parser);
913+ token = PEEK_TOKEN(parser);
914+ if (!token) return 0;
915+ if (token->type != YAML_KEY_TOKEN &&
916+ token->type != YAML_VALUE_TOKEN &&
917+ token->type != YAML_BLOCK_END_TOKEN) {
918+ if (!PUSH(parser, parser->states,
919+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
920+ return 0;
921+ return yaml_parser_parse_node(parser, event, 1, 1);
922+ }
923+ else {
924+ parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
925+ return yaml_parser_process_empty_scalar(parser, event, mark);
926+ }
927+ }
928+
929+ else
930+ {
931+ parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
932+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
933+ }
934+}
935+
936+/*
937+ * Parse the productions:
938+ * flow_sequence ::= FLOW-SEQUENCE-START
939+ * *******************
940+ * (flow_sequence_entry FLOW-ENTRY)*
941+ * * **********
942+ * flow_sequence_entry?
943+ * *
944+ * FLOW-SEQUENCE-END
945+ * *****************
946+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
947+ * *
948+ */
949+
950+static int
951+yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
952+ yaml_event_t *event, int first)
953+{
954+ yaml_token_t *token;
955+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
956+
957+ if (first) {
958+ token = PEEK_TOKEN(parser);
959+ if (!PUSH(parser, parser->marks, token->start_mark))
960+ return 0;
961+ SKIP_TOKEN(parser);
962+ }
963+
964+ token = PEEK_TOKEN(parser);
965+ if (!token) return 0;
966+
967+ if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
968+ {
969+ if (!first) {
970+ if (token->type == YAML_FLOW_ENTRY_TOKEN) {
971+ SKIP_TOKEN(parser);
972+ token = PEEK_TOKEN(parser);
973+ if (!token) return 0;
974+ }
975+ else {
976+ return yaml_parser_set_parser_error_context(parser,
977+ "while parsing a flow sequence", POP(parser, parser->marks),
978+ "did not find expected ',' or ']'", token->start_mark);
979+ }
980+ }
981+
982+ if (token->type == YAML_KEY_TOKEN) {
983+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
984+ MAPPING_START_EVENT_INIT(*event, NULL, NULL,
985+ 1, YAML_FLOW_MAPPING_STYLE,
986+ token->start_mark, token->end_mark);
987+ SKIP_TOKEN(parser);
988+ return 1;
989+ }
990+
991+ else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
992+ if (!PUSH(parser, parser->states,
993+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
994+ return 0;
995+ return yaml_parser_parse_node(parser, event, 0, 0);
996+ }
997+ }
998+
999+ parser->state = POP(parser, parser->states);
1000+ dummy_mark = POP(parser, parser->marks);
1001+ SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1002+ SKIP_TOKEN(parser);
1003+ return 1;
1004+}
1005+
1006+/*
1007+ * Parse the productions:
1008+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1009+ * *** *
1010+ */
1011+
1012+static int
1013+yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1014+ yaml_event_t *event)
1015+{
1016+ yaml_token_t *token;
1017+
1018+ token = PEEK_TOKEN(parser);
1019+ if (!token) return 0;
1020+
1021+ if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1022+ && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1023+ if (!PUSH(parser, parser->states,
1024+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1025+ return 0;
1026+ return yaml_parser_parse_node(parser, event, 0, 0);
1027+ }
1028+ else {
1029+ yaml_mark_t mark = token->end_mark;
1030+ SKIP_TOKEN(parser);
1031+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1032+ return yaml_parser_process_empty_scalar(parser, event, mark);
1033+ }
1034+}
1035+
1036+/*
1037+ * Parse the productions:
1038+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1039+ * ***** *
1040+ */
1041+
1042+static int
1043+yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1044+ yaml_event_t *event)
1045+{
1046+ yaml_token_t *token;
1047+
1048+ token = PEEK_TOKEN(parser);
1049+ if (!token) return 0;
1050+
1051+ if (token->type == YAML_VALUE_TOKEN) {
1052+ SKIP_TOKEN(parser);
1053+ token = PEEK_TOKEN(parser);
1054+ if (!token) return 0;
1055+ if (token->type != YAML_FLOW_ENTRY_TOKEN
1056+ && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1057+ if (!PUSH(parser, parser->states,
1058+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1059+ return 0;
1060+ return yaml_parser_parse_node(parser, event, 0, 0);
1061+ }
1062+ }
1063+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1064+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1065+}
1066+
1067+/*
1068+ * Parse the productions:
1069+ * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1070+ * *
1071+ */
1072+
1073+static int
1074+yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1075+ yaml_event_t *event)
1076+{
1077+ yaml_token_t *token;
1078+
1079+ token = PEEK_TOKEN(parser);
1080+ if (!token) return 0;
1081+
1082+ parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1083+
1084+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1085+ return 1;
1086+}
1087+
1088+/*
1089+ * Parse the productions:
1090+ * flow_mapping ::= FLOW-MAPPING-START
1091+ * ******************
1092+ * (flow_mapping_entry FLOW-ENTRY)*
1093+ * * **********
1094+ * flow_mapping_entry?
1095+ * ******************
1096+ * FLOW-MAPPING-END
1097+ * ****************
1098+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1099+ * * *** *
1100+ */
1101+
1102+static int
1103+yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1104+ yaml_event_t *event, int first)
1105+{
1106+ yaml_token_t *token;
1107+ yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */
1108+
1109+ if (first) {
1110+ token = PEEK_TOKEN(parser);
1111+ if (!PUSH(parser, parser->marks, token->start_mark))
1112+ return 0;
1113+ SKIP_TOKEN(parser);
1114+ }
1115+
1116+ token = PEEK_TOKEN(parser);
1117+ if (!token) return 0;
1118+
1119+ if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1120+ {
1121+ if (!first) {
1122+ if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1123+ SKIP_TOKEN(parser);
1124+ token = PEEK_TOKEN(parser);
1125+ if (!token) return 0;
1126+ }
1127+ else {
1128+ return yaml_parser_set_parser_error_context(parser,
1129+ "while parsing a flow mapping", POP(parser, parser->marks),
1130+ "did not find expected ',' or '}'", token->start_mark);
1131+ }
1132+ }
1133+
1134+ if (token->type == YAML_KEY_TOKEN) {
1135+ SKIP_TOKEN(parser);
1136+ token = PEEK_TOKEN(parser);
1137+ if (!token) return 0;
1138+ if (token->type != YAML_VALUE_TOKEN
1139+ && token->type != YAML_FLOW_ENTRY_TOKEN
1140+ && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1141+ if (!PUSH(parser, parser->states,
1142+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1143+ return 0;
1144+ return yaml_parser_parse_node(parser, event, 0, 0);
1145+ }
1146+ else {
1147+ parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1148+ return yaml_parser_process_empty_scalar(parser, event,
1149+ token->start_mark);
1150+ }
1151+ }
1152+ else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1153+ if (!PUSH(parser, parser->states,
1154+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1155+ return 0;
1156+ return yaml_parser_parse_node(parser, event, 0, 0);
1157+ }
1158+ }
1159+
1160+ parser->state = POP(parser, parser->states);
1161+ dummy_mark = POP(parser, parser->marks);
1162+ MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1163+ SKIP_TOKEN(parser);
1164+ return 1;
1165+}
1166+
1167+/*
1168+ * Parse the productions:
1169+ * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1170+ * * ***** *
1171+ */
1172+
1173+static int
1174+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1175+ yaml_event_t *event, int empty)
1176+{
1177+ yaml_token_t *token;
1178+
1179+ token = PEEK_TOKEN(parser);
1180+ if (!token) return 0;
1181+
1182+ if (empty) {
1183+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1184+ return yaml_parser_process_empty_scalar(parser, event,
1185+ token->start_mark);
1186+ }
1187+
1188+ if (token->type == YAML_VALUE_TOKEN) {
1189+ SKIP_TOKEN(parser);
1190+ token = PEEK_TOKEN(parser);
1191+ if (!token) return 0;
1192+ if (token->type != YAML_FLOW_ENTRY_TOKEN
1193+ && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1194+ if (!PUSH(parser, parser->states,
1195+ YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1196+ return 0;
1197+ return yaml_parser_parse_node(parser, event, 0, 0);
1198+ }
1199+ }
1200+
1201+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1202+ return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1203+}
1204+
1205+/*
1206+ * Generate an empty scalar event.
1207+ */
1208+
1209+static int
1210+yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1211+ yaml_mark_t mark)
1212+{
1213+ yaml_char_t *value;
1214+
1215+ value = yaml_malloc(1);
1216+ if (!value) {
1217+ parser->error = YAML_MEMORY_ERROR;
1218+ return 0;
1219+ }
1220+ value[0] = '\0';
1221+
1222+ SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1223+ 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1224+
1225+ return 1;
1226+}
1227+
1228+/*
1229+ * Parse directives.
1230+ */
1231+
1232+static int
1233+yaml_parser_process_directives(yaml_parser_t *parser,
1234+ yaml_version_directive_t **version_directive_ref,
1235+ yaml_tag_directive_t **tag_directives_start_ref,
1236+ yaml_tag_directive_t **tag_directives_end_ref)
1237+{
1238+ yaml_tag_directive_t default_tag_directives[] = {
1239+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1240+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1241+ {NULL, NULL}
1242+ };
1243+ yaml_tag_directive_t *default_tag_directive;
1244+ yaml_version_directive_t *version_directive = NULL;
1245+ struct {
1246+ yaml_tag_directive_t *start;
1247+ yaml_tag_directive_t *end;
1248+ yaml_tag_directive_t *top;
1249+ } tag_directives = { NULL, NULL, NULL };
1250+ yaml_token_t *token;
1251+
1252+ if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1253+ goto error;
1254+
1255+ token = PEEK_TOKEN(parser);
1256+ if (!token) goto error;
1257+
1258+ while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1259+ token->type == YAML_TAG_DIRECTIVE_TOKEN)
1260+ {
1261+ if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1262+ if (version_directive) {
1263+ yaml_parser_set_parser_error(parser,
1264+ "found duplicate %YAML directive", token->start_mark);
1265+ goto error;
1266+ }
1267+ if (token->data.version_directive.major != 1
1268+ || token->data.version_directive.minor != 1) {
1269+ yaml_parser_set_parser_error(parser,
1270+ "found incompatible YAML document", token->start_mark);
1271+ goto error;
1272+ }
1273+ version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1274+ if (!version_directive) {
1275+ parser->error = YAML_MEMORY_ERROR;
1276+ goto error;
1277+ }
1278+ version_directive->major = token->data.version_directive.major;
1279+ version_directive->minor = token->data.version_directive.minor;
1280+ }
1281+
1282+ else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1283+ yaml_tag_directive_t value = {
1284+ token->data.tag_directive.handle,
1285+ token->data.tag_directive.prefix
1286+ };
1287+ if (!yaml_parser_append_tag_directive(parser, value, 0,
1288+ token->start_mark))
1289+ goto error;
1290+ if (!PUSH(parser, tag_directives, value))
1291+ goto error;
1292+ }
1293+
1294+ SKIP_TOKEN(parser);
1295+ token = PEEK_TOKEN(parser);
1296+ if (!token) goto error;
1297+ }
1298+
1299+ for (default_tag_directive = default_tag_directives;
1300+ default_tag_directive->handle; default_tag_directive++) {
1301+ if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1302+ token->start_mark))
1303+ goto error;
1304+ }
1305+
1306+ if (version_directive_ref) {
1307+ *version_directive_ref = version_directive;
1308+ }
1309+ if (tag_directives_start_ref) {
1310+ if (STACK_EMPTY(parser, tag_directives)) {
1311+ *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1312+ STACK_DEL(parser, tag_directives);
1313+ }
1314+ else {
1315+ *tag_directives_start_ref = tag_directives.start;
1316+ *tag_directives_end_ref = tag_directives.top;
1317+ }
1318+ }
1319+ else {
1320+ STACK_DEL(parser, tag_directives);
1321+ }
1322+
1323+ return 1;
1324+
1325+error:
1326+ yaml_free(version_directive);
1327+ while (!STACK_EMPTY(parser, tag_directives)) {
1328+ yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1329+ yaml_free(tag_directive.handle);
1330+ yaml_free(tag_directive.prefix);
1331+ }
1332+ STACK_DEL(parser, tag_directives);
1333+ return 0;
1334+}
1335+
1336+/*
1337+ * Append a tag directive to the directives stack.
1338+ */
1339+
1340+static int
1341+yaml_parser_append_tag_directive(yaml_parser_t *parser,
1342+ yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1343+{
1344+ yaml_tag_directive_t *tag_directive;
1345+ yaml_tag_directive_t copy = { NULL, NULL };
1346+
1347+ for (tag_directive = parser->tag_directives.start;
1348+ tag_directive != parser->tag_directives.top; tag_directive ++) {
1349+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1350+ if (allow_duplicates)
1351+ return 1;
1352+ return yaml_parser_set_parser_error(parser,
1353+ "found duplicate %TAG directive", mark);
1354+ }
1355+ }
1356+
1357+ copy.handle = yaml_strdup(value.handle);
1358+ copy.prefix = yaml_strdup(value.prefix);
1359+ if (!copy.handle || !copy.prefix) {
1360+ parser->error = YAML_MEMORY_ERROR;
1361+ goto error;
1362+ }
1363+
1364+ if (!PUSH(parser, parser->tag_directives, copy))
1365+ goto error;
1366+
1367+ return 1;
1368+
1369+error:
1370+ yaml_free(copy.handle);
1371+ yaml_free(copy.prefix);
1372+ return 0;
1373+}
1374+
c/reader.cnew file+460
@@ -0,0 +1,460 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * Declarations.
6+ */
7+
8+static int
9+yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
10+ size_t offset, int value);
11+
12+static int
13+yaml_parser_update_raw_buffer(yaml_parser_t *parser);
14+
15+static int
16+yaml_parser_determine_encoding(yaml_parser_t *parser);
17+
18+YAML_DECLARE(int)
19+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
20+
21+/*
22+ * Set the reader error and return 0.
23+ */
24+
25+static int
26+yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
27+ size_t offset, int value)
28+{
29+ parser->error = YAML_READER_ERROR;
30+ parser->problem = problem;
31+ parser->problem_offset = offset;
32+ parser->problem_value = value;
33+
34+ return 0;
35+}
36+
37+/*
38+ * Byte order marks.
39+ */
40+
41+#define BOM_UTF8 "\xef\xbb\xbf"
42+#define BOM_UTF16LE "\xff\xfe"
43+#define BOM_UTF16BE "\xfe\xff"
44+
45+/*
46+ * Determine the input stream encoding by checking the BOM symbol. If no BOM is
47+ * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
48+ */
49+
50+static int
51+yaml_parser_determine_encoding(yaml_parser_t *parser)
52+{
53+ /* Ensure that we had enough bytes in the raw buffer. */
54+
55+ while (!parser->eof
56+ && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
57+ if (!yaml_parser_update_raw_buffer(parser)) {
58+ return 0;
59+ }
60+ }
61+
62+ /* Determine the encoding. */
63+
64+ if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
65+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
66+ parser->encoding = YAML_UTF16LE_ENCODING;
67+ parser->raw_buffer.pointer += 2;
68+ parser->offset += 2;
69+ }
70+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
71+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
72+ parser->encoding = YAML_UTF16BE_ENCODING;
73+ parser->raw_buffer.pointer += 2;
74+ parser->offset += 2;
75+ }
76+ else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
77+ && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
78+ parser->encoding = YAML_UTF8_ENCODING;
79+ parser->raw_buffer.pointer += 3;
80+ parser->offset += 3;
81+ }
82+ else {
83+ parser->encoding = YAML_UTF8_ENCODING;
84+ }
85+
86+ return 1;
87+}
88+
89+/*
90+ * Update the raw buffer.
91+ */
92+
93+static int
94+yaml_parser_update_raw_buffer(yaml_parser_t *parser)
95+{
96+ size_t size_read = 0;
97+
98+ /* Return if the raw buffer is full. */
99+
100+ if (parser->raw_buffer.start == parser->raw_buffer.pointer
101+ && parser->raw_buffer.last == parser->raw_buffer.end)
102+ return 1;
103+
104+ /* Return on EOF. */
105+
106+ if (parser->eof) return 1;
107+
108+ /* Move the remaining bytes in the raw buffer to the beginning. */
109+
110+ if (parser->raw_buffer.start < parser->raw_buffer.pointer
111+ && parser->raw_buffer.pointer < parser->raw_buffer.last) {
112+ memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
113+ parser->raw_buffer.last - parser->raw_buffer.pointer);
114+ }
115+ parser->raw_buffer.last -=
116+ parser->raw_buffer.pointer - parser->raw_buffer.start;
117+ parser->raw_buffer.pointer = parser->raw_buffer.start;
118+
119+ /* Call the read handler to fill the buffer. */
120+
121+ if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
122+ parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
123+ return yaml_parser_set_reader_error(parser, "Input error",
124+ parser->offset, -1);
125+ }
126+ parser->raw_buffer.last += size_read;
127+ if (!size_read) {
128+ parser->eof = 1;
129+ }
130+
131+ return 1;
132+}
133+
134+/*
135+ * Ensure that the buffer contains at least `length` characters.
136+ * Return 1 on success, 0 on failure.
137+ *
138+ * The length is supposed to be significantly less that the buffer size.
139+ */
140+
141+YAML_DECLARE(int)
142+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
143+{
144+ assert(parser->read_handler); /* Read handler must be set. */
145+
146+ /* If the EOF flag is set and the raw buffer is empty, do nothing. */
147+
148+ if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
149+ return 1;
150+
151+ /* Return if the buffer contains enough characters. */
152+
153+ if (parser->unread >= length)
154+ return 1;
155+
156+ /* Determine the input encoding if it is not known yet. */
157+
158+ if (!parser->encoding) {
159+ if (!yaml_parser_determine_encoding(parser))
160+ return 0;
161+ }
162+
163+ /* Move the unread characters to the beginning of the buffer. */
164+
165+ if (parser->buffer.start < parser->buffer.pointer
166+ && parser->buffer.pointer < parser->buffer.last) {
167+ size_t size = parser->buffer.last - parser->buffer.pointer;
168+ memmove(parser->buffer.start, parser->buffer.pointer, size);
169+ parser->buffer.pointer = parser->buffer.start;
170+ parser->buffer.last = parser->buffer.start + size;
171+ }
172+ else if (parser->buffer.pointer == parser->buffer.last) {
173+ parser->buffer.pointer = parser->buffer.start;
174+ parser->buffer.last = parser->buffer.start;
175+ }
176+
177+ /* Fill the buffer until it has enough characters. */
178+
179+ while (parser->unread < length)
180+ {
181+ /* Fill the raw buffer. */
182+
183+ if (!yaml_parser_update_raw_buffer(parser)) return 0;
184+
185+ /* Decode the raw buffer. */
186+
187+ while (parser->raw_buffer.pointer != parser->raw_buffer.last)
188+ {
189+ unsigned int value = 0, value2 = 0;
190+ int incomplete = 0;
191+ unsigned char octet;
192+ unsigned int width = 0;
193+ int low, high;
194+ size_t k;
195+ size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
196+
197+ /* Decode the next character. */
198+
199+ switch (parser->encoding)
200+ {
201+ case YAML_UTF8_ENCODING:
202+
203+ /*
204+ * Decode a UTF-8 character. Check RFC 3629
205+ * (http://www.ietf.org/rfc/rfc3629.txt) for more details.
206+ *
207+ * The following table (taken from the RFC) is used for
208+ * decoding.
209+ *
210+ * Char. number range | UTF-8 octet sequence
211+ * (hexadecimal) | (binary)
212+ * --------------------+------------------------------------
213+ * 0000 0000-0000 007F | 0xxxxxxx
214+ * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
215+ * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
216+ * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
217+ *
218+ * Additionally, the characters in the range 0xD800-0xDFFF
219+ * are prohibited as they are reserved for use with UTF-16
220+ * surrogate pairs.
221+ */
222+
223+ /* Determine the length of the UTF-8 sequence. */
224+
225+ octet = parser->raw_buffer.pointer[0];
226+ width = (octet & 0x80) == 0x00 ? 1 :
227+ (octet & 0xE0) == 0xC0 ? 2 :
228+ (octet & 0xF0) == 0xE0 ? 3 :
229+ (octet & 0xF8) == 0xF0 ? 4 : 0;
230+
231+ /* Check if the leading octet is valid. */
232+
233+ if (!width)
234+ return yaml_parser_set_reader_error(parser,
235+ "Invalid leading UTF-8 octet",
236+ parser->offset, octet);
237+
238+ /* Check if the raw buffer contains an incomplete character. */
239+
240+ if (width > raw_unread) {
241+ if (parser->eof) {
242+ return yaml_parser_set_reader_error(parser,
243+ "Incomplete UTF-8 octet sequence",
244+ parser->offset, -1);
245+ }
246+ incomplete = 1;
247+ break;
248+ }
249+
250+ /* Decode the leading octet. */
251+
252+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
253+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
254+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
255+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
256+
257+ /* Check and decode the trailing octets. */
258+
259+ for (k = 1; k < width; k ++)
260+ {
261+ octet = parser->raw_buffer.pointer[k];
262+
263+ /* Check if the octet is valid. */
264+
265+ if ((octet & 0xC0) != 0x80)
266+ return yaml_parser_set_reader_error(parser,
267+ "Invalid trailing UTF-8 octet",
268+ parser->offset+k, octet);
269+
270+ /* Decode the octet. */
271+
272+ value = (value << 6) + (octet & 0x3F);
273+ }
274+
275+ /* Check the length of the sequence against the value. */
276+
277+ if (!((width == 1) ||
278+ (width == 2 && value >= 0x80) ||
279+ (width == 3 && value >= 0x800) ||
280+ (width == 4 && value >= 0x10000)))
281+ return yaml_parser_set_reader_error(parser,
282+ "Invalid length of a UTF-8 sequence",
283+ parser->offset, -1);
284+
285+ /* Check the range of the value. */
286+
287+ if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
288+ return yaml_parser_set_reader_error(parser,
289+ "Invalid Unicode character",
290+ parser->offset, value);
291+
292+ break;
293+
294+ case YAML_UTF16LE_ENCODING:
295+ case YAML_UTF16BE_ENCODING:
296+
297+ low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
298+ high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
299+
300+ /*
301+ * The UTF-16 encoding is not as simple as one might
302+ * naively think. Check RFC 2781
303+ * (http://www.ietf.org/rfc/rfc2781.txt).
304+ *
305+ * Normally, two subsequent bytes describe a Unicode
306+ * character. However a special technique (called a
307+ * surrogate pair) is used for specifying character
308+ * values larger than 0xFFFF.
309+ *
310+ * A surrogate pair consists of two pseudo-characters:
311+ * high surrogate area (0xD800-0xDBFF)
312+ * low surrogate area (0xDC00-0xDFFF)
313+ *
314+ * The following formulas are used for decoding
315+ * and encoding characters using surrogate pairs:
316+ *
317+ * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
318+ * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
319+ * W1 = 110110yyyyyyyyyy
320+ * W2 = 110111xxxxxxxxxx
321+ *
322+ * where U is the character value, W1 is the high surrogate
323+ * area, W2 is the low surrogate area.
324+ */
325+
326+ /* Check for incomplete UTF-16 character. */
327+
328+ if (raw_unread < 2) {
329+ if (parser->eof) {
330+ return yaml_parser_set_reader_error(parser,
331+ "Incomplete UTF-16 character",
332+ parser->offset, -1);
333+ }
334+ incomplete = 1;
335+ break;
336+ }
337+
338+ /* Get the character. */
339+
340+ value = parser->raw_buffer.pointer[low]
341+ + (parser->raw_buffer.pointer[high] << 8);
342+
343+ /* Check for unexpected low surrogate area. */
344+
345+ if ((value & 0xFC00) == 0xDC00)
346+ return yaml_parser_set_reader_error(parser,
347+ "Unexpected low surrogate area",
348+ parser->offset, value);
349+
350+ /* Check for a high surrogate area. */
351+
352+ if ((value & 0xFC00) == 0xD800) {
353+
354+ width = 4;
355+
356+ /* Check for incomplete surrogate pair. */
357+
358+ if (raw_unread < 4) {
359+ if (parser->eof) {
360+ return yaml_parser_set_reader_error(parser,
361+ "Incomplete UTF-16 surrogate pair",
362+ parser->offset, -1);
363+ }
364+ incomplete = 1;
365+ break;
366+ }
367+
368+ /* Get the next character. */
369+
370+ value2 = parser->raw_buffer.pointer[low+2]
371+ + (parser->raw_buffer.pointer[high+2] << 8);
372+
373+ /* Check for a low surrogate area. */
374+
375+ if ((value2 & 0xFC00) != 0xDC00)
376+ return yaml_parser_set_reader_error(parser,
377+ "Expected low surrogate area",
378+ parser->offset+2, value2);
379+
380+ /* Generate the value of the surrogate pair. */
381+
382+ value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
383+ }
384+
385+ else {
386+ width = 2;
387+ }
388+
389+ break;
390+
391+ default:
392+ assert(1); /* Impossible. */
393+ }
394+
395+ /* Check if the raw buffer contains enough bytes to form a character. */
396+
397+ if (incomplete) break;
398+
399+ /*
400+ * Check if the character is in the allowed range:
401+ * #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
402+ * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
403+ * | [#x10000-#x10FFFF] (32 bit)
404+ */
405+
406+ if (! (value == 0x09 || value == 0x0A || value == 0x0D
407+ || (value >= 0x20 && value <= 0x7E)
408+ || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
409+ || (value >= 0xE000 && value <= 0xFFFD)
410+ || (value >= 0x10000 && value <= 0x10FFFF)))
411+ return yaml_parser_set_reader_error(parser,
412+ "Control characters are not allowed",
413+ parser->offset, value);
414+
415+ /* Move the raw pointers. */
416+
417+ parser->raw_buffer.pointer += width;
418+ parser->offset += width;
419+
420+ /* Finally put the character into the buffer. */
421+
422+ /* 0000 0000-0000 007F -> 0xxxxxxx */
423+ if (value <= 0x7F) {
424+ *(parser->buffer.last++) = value;
425+ }
426+ /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
427+ else if (value <= 0x7FF) {
428+ *(parser->buffer.last++) = 0xC0 + (value >> 6);
429+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
430+ }
431+ /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
432+ else if (value <= 0xFFFF) {
433+ *(parser->buffer.last++) = 0xE0 + (value >> 12);
434+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
435+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
436+ }
437+ /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
438+ else {
439+ *(parser->buffer.last++) = 0xF0 + (value >> 18);
440+ *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
441+ *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
442+ *(parser->buffer.last++) = 0x80 + (value & 0x3F);
443+ }
444+
445+ parser->unread ++;
446+ }
447+
448+ /* On EOF, put NUL into the buffer and return. */
449+
450+ if (parser->eof) {
451+ *(parser->buffer.last++) = '\0';
452+ parser->unread ++;
453+ return 1;
454+ }
455+
456+ }
457+
458+ return 1;
459+}
460+
c/scanner.cnew file+3568
@@ -0,0 +1,3568 @@
1+
2+/*
3+ * Introduction
4+ * ************
5+ *
6+ * The following notes assume that you are familiar with the YAML specification
7+ * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
8+ * some cases we are less restrictive that it requires.
9+ *
10+ * The process of transforming a YAML stream into a sequence of events is
11+ * divided on two steps: Scanning and Parsing.
12+ *
13+ * The Scanner transforms the input stream into a sequence of tokens, while the
14+ * parser transform the sequence of tokens produced by the Scanner into a
15+ * sequence of parsing events.
16+ *
17+ * The Scanner is rather clever and complicated. The Parser, on the contrary,
18+ * is a straightforward implementation of a recursive-descendant parser (or,
19+ * LL(1) parser, as it is usually called).
20+ *
21+ * Actually there are two issues of Scanning that might be called "clever", the
22+ * rest is quite straightforward. The issues are "block collection start" and
23+ * "simple keys". Both issues are explained below in details.
24+ *
25+ * Here the Scanning step is explained and implemented. We start with the list
26+ * of all the tokens produced by the Scanner together with short descriptions.
27+ *
28+ * Now, tokens:
29+ *
30+ * STREAM-START(encoding) # The stream start.
31+ * STREAM-END # The stream end.
32+ * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
33+ * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
34+ * DOCUMENT-START # '---'
35+ * DOCUMENT-END # '...'
36+ * BLOCK-SEQUENCE-START # Indentation increase denoting a block
37+ * BLOCK-MAPPING-START # sequence or a block mapping.
38+ * BLOCK-END # Indentation decrease.
39+ * FLOW-SEQUENCE-START # '['
40+ * FLOW-SEQUENCE-END # ']'
41+ * BLOCK-SEQUENCE-START # '{'
42+ * BLOCK-SEQUENCE-END # '}'
43+ * BLOCK-ENTRY # '-'
44+ * FLOW-ENTRY # ','
45+ * KEY # '?' or nothing (simple keys).
46+ * VALUE # ':'
47+ * ALIAS(anchor) # '*anchor'
48+ * ANCHOR(anchor) # '&anchor'
49+ * TAG(handle,suffix) # '!handle!suffix'
50+ * SCALAR(value,style) # A scalar.
51+ *
52+ * The following two tokens are "virtual" tokens denoting the beginning and the
53+ * end of the stream:
54+ *
55+ * STREAM-START(encoding)
56+ * STREAM-END
57+ *
58+ * We pass the information about the input stream encoding with the
59+ * STREAM-START token.
60+ *
61+ * The next two tokens are responsible for tags:
62+ *
63+ * VERSION-DIRECTIVE(major,minor)
64+ * TAG-DIRECTIVE(handle,prefix)
65+ *
66+ * Example:
67+ *
68+ * %YAML 1.1
69+ * %TAG ! !foo
70+ * %TAG !yaml! tag:yaml.org,2002:
71+ * ---
72+ *
73+ * The correspoding sequence of tokens:
74+ *
75+ * STREAM-START(utf-8)
76+ * VERSION-DIRECTIVE(1,1)
77+ * TAG-DIRECTIVE("!","!foo")
78+ * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
79+ * DOCUMENT-START
80+ * STREAM-END
81+ *
82+ * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
83+ * line.
84+ *
85+ * The document start and end indicators are represented by:
86+ *
87+ * DOCUMENT-START
88+ * DOCUMENT-END
89+ *
90+ * Note that if a YAML stream contains an implicit document (without '---'
91+ * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
92+ * produced.
93+ *
94+ * In the following examples, we present whole documents together with the
95+ * produced tokens.
96+ *
97+ * 1. An implicit document:
98+ *
99+ * 'a scalar'
100+ *
101+ * Tokens:
102+ *
103+ * STREAM-START(utf-8)
104+ * SCALAR("a scalar",single-quoted)
105+ * STREAM-END
106+ *
107+ * 2. An explicit document:
108+ *
109+ * ---
110+ * 'a scalar'
111+ * ...
112+ *
113+ * Tokens:
114+ *
115+ * STREAM-START(utf-8)
116+ * DOCUMENT-START
117+ * SCALAR("a scalar",single-quoted)
118+ * DOCUMENT-END
119+ * STREAM-END
120+ *
121+ * 3. Several documents in a stream:
122+ *
123+ * 'a scalar'
124+ * ---
125+ * 'another scalar'
126+ * ---
127+ * 'yet another scalar'
128+ *
129+ * Tokens:
130+ *
131+ * STREAM-START(utf-8)
132+ * SCALAR("a scalar",single-quoted)
133+ * DOCUMENT-START
134+ * SCALAR("another scalar",single-quoted)
135+ * DOCUMENT-START
136+ * SCALAR("yet another scalar",single-quoted)
137+ * STREAM-END
138+ *
139+ * We have already introduced the SCALAR token above. The following tokens are
140+ * used to describe aliases, anchors, tag, and scalars:
141+ *
142+ * ALIAS(anchor)
143+ * ANCHOR(anchor)
144+ * TAG(handle,suffix)
145+ * SCALAR(value,style)
146+ *
147+ * The following series of examples illustrate the usage of these tokens:
148+ *
149+ * 1. A recursive sequence:
150+ *
151+ * &A [ *A ]
152+ *
153+ * Tokens:
154+ *
155+ * STREAM-START(utf-8)
156+ * ANCHOR("A")
157+ * FLOW-SEQUENCE-START
158+ * ALIAS("A")
159+ * FLOW-SEQUENCE-END
160+ * STREAM-END
161+ *
162+ * 2. A tagged scalar:
163+ *
164+ * !!float "3.14" # A good approximation.
165+ *
166+ * Tokens:
167+ *
168+ * STREAM-START(utf-8)
169+ * TAG("!!","float")
170+ * SCALAR("3.14",double-quoted)
171+ * STREAM-END
172+ *
173+ * 3. Various scalar styles:
174+ *
175+ * --- # Implicit empty plain scalars do not produce tokens.
176+ * --- a plain scalar
177+ * --- 'a single-quoted scalar'
178+ * --- "a double-quoted scalar"
179+ * --- |-
180+ * a literal scalar
181+ * --- >-
182+ * a folded
183+ * scalar
184+ *
185+ * Tokens:
186+ *
187+ * STREAM-START(utf-8)
188+ * DOCUMENT-START
189+ * DOCUMENT-START
190+ * SCALAR("a plain scalar",plain)
191+ * DOCUMENT-START
192+ * SCALAR("a single-quoted scalar",single-quoted)
193+ * DOCUMENT-START
194+ * SCALAR("a double-quoted scalar",double-quoted)
195+ * DOCUMENT-START
196+ * SCALAR("a literal scalar",literal)
197+ * DOCUMENT-START
198+ * SCALAR("a folded scalar",folded)
199+ * STREAM-END
200+ *
201+ * Now it's time to review collection-related tokens. We will start with
202+ * flow collections:
203+ *
204+ * FLOW-SEQUENCE-START
205+ * FLOW-SEQUENCE-END
206+ * FLOW-MAPPING-START
207+ * FLOW-MAPPING-END
208+ * FLOW-ENTRY
209+ * KEY
210+ * VALUE
211+ *
212+ * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
213+ * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
214+ * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
215+ * indicators '?' and ':', which are used for denoting mapping keys and values,
216+ * are represented by the KEY and VALUE tokens.
217+ *
218+ * The following examples show flow collections:
219+ *
220+ * 1. A flow sequence:
221+ *
222+ * [item 1, item 2, item 3]
223+ *
224+ * Tokens:
225+ *
226+ * STREAM-START(utf-8)
227+ * FLOW-SEQUENCE-START
228+ * SCALAR("item 1",plain)
229+ * FLOW-ENTRY
230+ * SCALAR("item 2",plain)
231+ * FLOW-ENTRY
232+ * SCALAR("item 3",plain)
233+ * FLOW-SEQUENCE-END
234+ * STREAM-END
235+ *
236+ * 2. A flow mapping:
237+ *
238+ * {
239+ * a simple key: a value, # Note that the KEY token is produced.
240+ * ? a complex key: another value,
241+ * }
242+ *
243+ * Tokens:
244+ *
245+ * STREAM-START(utf-8)
246+ * FLOW-MAPPING-START
247+ * KEY
248+ * SCALAR("a simple key",plain)
249+ * VALUE
250+ * SCALAR("a value",plain)
251+ * FLOW-ENTRY
252+ * KEY
253+ * SCALAR("a complex key",plain)
254+ * VALUE
255+ * SCALAR("another value",plain)
256+ * FLOW-ENTRY
257+ * FLOW-MAPPING-END
258+ * STREAM-END
259+ *
260+ * A simple key is a key which is not denoted by the '?' indicator. Note that
261+ * the Scanner still produce the KEY token whenever it encounters a simple key.
262+ *
263+ * For scanning block collections, the following tokens are used (note that we
264+ * repeat KEY and VALUE here):
265+ *
266+ * BLOCK-SEQUENCE-START
267+ * BLOCK-MAPPING-START
268+ * BLOCK-END
269+ * BLOCK-ENTRY
270+ * KEY
271+ * VALUE
272+ *
273+ * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
274+ * increase that precedes a block collection (cf. the INDENT token in Python).
275+ * The token BLOCK-END denote indentation decrease that ends a block collection
276+ * (cf. the DEDENT token in Python). However YAML has some syntax pecularities
277+ * that makes detections of these tokens more complex.
278+ *
279+ * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
280+ * '-', '?', and ':' correspondingly.
281+ *
282+ * The following examples show how the tokens BLOCK-SEQUENCE-START,
283+ * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
284+ *
285+ * 1. Block sequences:
286+ *
287+ * - item 1
288+ * - item 2
289+ * -
290+ * - item 3.1
291+ * - item 3.2
292+ * -
293+ * key 1: value 1
294+ * key 2: value 2
295+ *
296+ * Tokens:
297+ *
298+ * STREAM-START(utf-8)
299+ * BLOCK-SEQUENCE-START
300+ * BLOCK-ENTRY
301+ * SCALAR("item 1",plain)
302+ * BLOCK-ENTRY
303+ * SCALAR("item 2",plain)
304+ * BLOCK-ENTRY
305+ * BLOCK-SEQUENCE-START
306+ * BLOCK-ENTRY
307+ * SCALAR("item 3.1",plain)
308+ * BLOCK-ENTRY
309+ * SCALAR("item 3.2",plain)
310+ * BLOCK-END
311+ * BLOCK-ENTRY
312+ * BLOCK-MAPPING-START
313+ * KEY
314+ * SCALAR("key 1",plain)
315+ * VALUE
316+ * SCALAR("value 1",plain)
317+ * KEY
318+ * SCALAR("key 2",plain)
319+ * VALUE
320+ * SCALAR("value 2",plain)
321+ * BLOCK-END
322+ * BLOCK-END
323+ * STREAM-END
324+ *
325+ * 2. Block mappings:
326+ *
327+ * a simple key: a value # The KEY token is produced here.
328+ * ? a complex key
329+ * : another value
330+ * a mapping:
331+ * key 1: value 1
332+ * key 2: value 2
333+ * a sequence:
334+ * - item 1
335+ * - item 2
336+ *
337+ * Tokens:
338+ *
339+ * STREAM-START(utf-8)
340+ * BLOCK-MAPPING-START
341+ * KEY
342+ * SCALAR("a simple key",plain)
343+ * VALUE
344+ * SCALAR("a value",plain)
345+ * KEY
346+ * SCALAR("a complex key",plain)
347+ * VALUE
348+ * SCALAR("another value",plain)
349+ * KEY
350+ * SCALAR("a mapping",plain)
351+ * BLOCK-MAPPING-START
352+ * KEY
353+ * SCALAR("key 1",plain)
354+ * VALUE
355+ * SCALAR("value 1",plain)
356+ * KEY
357+ * SCALAR("key 2",plain)
358+ * VALUE
359+ * SCALAR("value 2",plain)
360+ * BLOCK-END
361+ * KEY
362+ * SCALAR("a sequence",plain)
363+ * VALUE
364+ * BLOCK-SEQUENCE-START
365+ * BLOCK-ENTRY
366+ * SCALAR("item 1",plain)
367+ * BLOCK-ENTRY
368+ * SCALAR("item 2",plain)
369+ * BLOCK-END
370+ * BLOCK-END
371+ * STREAM-END
372+ *
373+ * YAML does not always require to start a new block collection from a new
374+ * line. If the current line contains only '-', '?', and ':' indicators, a new
375+ * block collection may start at the current line. The following examples
376+ * illustrate this case:
377+ *
378+ * 1. Collections in a sequence:
379+ *
380+ * - - item 1
381+ * - item 2
382+ * - key 1: value 1
383+ * key 2: value 2
384+ * - ? complex key
385+ * : complex value
386+ *
387+ * Tokens:
388+ *
389+ * STREAM-START(utf-8)
390+ * BLOCK-SEQUENCE-START
391+ * BLOCK-ENTRY
392+ * BLOCK-SEQUENCE-START
393+ * BLOCK-ENTRY
394+ * SCALAR("item 1",plain)
395+ * BLOCK-ENTRY
396+ * SCALAR("item 2",plain)
397+ * BLOCK-END
398+ * BLOCK-ENTRY
399+ * BLOCK-MAPPING-START
400+ * KEY
401+ * SCALAR("key 1",plain)
402+ * VALUE
403+ * SCALAR("value 1",plain)
404+ * KEY
405+ * SCALAR("key 2",plain)
406+ * VALUE
407+ * SCALAR("value 2",plain)
408+ * BLOCK-END
409+ * BLOCK-ENTRY
410+ * BLOCK-MAPPING-START
411+ * KEY
412+ * SCALAR("complex key")
413+ * VALUE
414+ * SCALAR("complex value")
415+ * BLOCK-END
416+ * BLOCK-END
417+ * STREAM-END
418+ *
419+ * 2. Collections in a mapping:
420+ *
421+ * ? a sequence
422+ * : - item 1
423+ * - item 2
424+ * ? a mapping
425+ * : key 1: value 1
426+ * key 2: value 2
427+ *
428+ * Tokens:
429+ *
430+ * STREAM-START(utf-8)
431+ * BLOCK-MAPPING-START
432+ * KEY
433+ * SCALAR("a sequence",plain)
434+ * VALUE
435+ * BLOCK-SEQUENCE-START
436+ * BLOCK-ENTRY
437+ * SCALAR("item 1",plain)
438+ * BLOCK-ENTRY
439+ * SCALAR("item 2",plain)
440+ * BLOCK-END
441+ * KEY
442+ * SCALAR("a mapping",plain)
443+ * VALUE
444+ * BLOCK-MAPPING-START
445+ * KEY
446+ * SCALAR("key 1",plain)
447+ * VALUE
448+ * SCALAR("value 1",plain)
449+ * KEY
450+ * SCALAR("key 2",plain)
451+ * VALUE
452+ * SCALAR("value 2",plain)
453+ * BLOCK-END
454+ * BLOCK-END
455+ * STREAM-END
456+ *
457+ * YAML also permits non-indented sequences if they are included into a block
458+ * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
459+ *
460+ * key:
461+ * - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
462+ * - item 2
463+ *
464+ * Tokens:
465+ *
466+ * STREAM-START(utf-8)
467+ * BLOCK-MAPPING-START
468+ * KEY
469+ * SCALAR("key",plain)
470+ * VALUE
471+ * BLOCK-ENTRY
472+ * SCALAR("item 1",plain)
473+ * BLOCK-ENTRY
474+ * SCALAR("item 2",plain)
475+ * BLOCK-END
476+ */
477+
478+#include "yaml_private.h"
479+
480+/*
481+ * Ensure that the buffer contains the required number of characters.
482+ * Return 1 on success, 0 on failure (reader error or memory error).
483+ */
484+
485+#define CACHE(parser,length) \
486+ (parser->unread >= (length) \
487+ ? 1 \
488+ : yaml_parser_update_buffer(parser, (length)))
489+
490+/*
491+ * Advance the buffer pointer.
492+ */
493+
494+#define SKIP(parser) \
495+ (parser->mark.index ++, \
496+ parser->mark.column ++, \
497+ parser->unread --, \
498+ parser->buffer.pointer += WIDTH(parser->buffer))
499+
500+#define SKIP_LINE(parser) \
501+ (IS_CRLF(parser->buffer) ? \
502+ (parser->mark.index += 2, \
503+ parser->mark.column = 0, \
504+ parser->mark.line ++, \
505+ parser->unread -= 2, \
506+ parser->buffer.pointer += 2) : \
507+ IS_BREAK(parser->buffer) ? \
508+ (parser->mark.index ++, \
509+ parser->mark.column = 0, \
510+ parser->mark.line ++, \
511+ parser->unread --, \
512+ parser->buffer.pointer += WIDTH(parser->buffer)) : 0)
513+
514+/*
515+ * Copy a character to a string buffer and advance pointers.
516+ */
517+
518+#define READ(parser,string) \
519+ (STRING_EXTEND(parser,string) ? \
520+ (COPY(string,parser->buffer), \
521+ parser->mark.index ++, \
522+ parser->mark.column ++, \
523+ parser->unread --, \
524+ 1) : 0)
525+
526+/*
527+ * Copy a line break character to a string buffer and advance pointers.
528+ */
529+
530+#define READ_LINE(parser,string) \
531+ (STRING_EXTEND(parser,string) ? \
532+ (((CHECK_AT(parser->buffer,'\r',0) \
533+ && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \
534+ (*((string).pointer++) = (yaml_char_t) '\n', \
535+ parser->buffer.pointer += 2, \
536+ parser->mark.index += 2, \
537+ parser->mark.column = 0, \
538+ parser->mark.line ++, \
539+ parser->unread -= 2) : \
540+ (CHECK_AT(parser->buffer,'\r',0) \
541+ || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \
542+ (*((string).pointer++) = (yaml_char_t) '\n', \
543+ parser->buffer.pointer ++, \
544+ parser->mark.index ++, \
545+ parser->mark.column = 0, \
546+ parser->mark.line ++, \
547+ parser->unread --) : \
548+ (CHECK_AT(parser->buffer,'\xC2',0) \
549+ && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \
550+ (*((string).pointer++) = (yaml_char_t) '\n', \
551+ parser->buffer.pointer += 2, \
552+ parser->mark.index ++, \
553+ parser->mark.column = 0, \
554+ parser->mark.line ++, \
555+ parser->unread --) : \
556+ (CHECK_AT(parser->buffer,'\xE2',0) && \
557+ CHECK_AT(parser->buffer,'\x80',1) && \
558+ (CHECK_AT(parser->buffer,'\xA8',2) || \
559+ CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \
560+ (*((string).pointer++) = *(parser->buffer.pointer++), \
561+ *((string).pointer++) = *(parser->buffer.pointer++), \
562+ *((string).pointer++) = *(parser->buffer.pointer++), \
563+ parser->mark.index ++, \
564+ parser->mark.column = 0, \
565+ parser->mark.line ++, \
566+ parser->unread --) : 0), \
567+ 1) : 0)
568+
569+/*
570+ * Public API declarations.
571+ */
572+
573+YAML_DECLARE(int)
574+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
575+
576+/*
577+ * Error handling.
578+ */
579+
580+static int
581+yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
582+ yaml_mark_t context_mark, const char *problem);
583+
584+/*
585+ * High-level token API.
586+ */
587+
588+YAML_DECLARE(int)
589+yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
590+
591+static int
592+yaml_parser_fetch_next_token(yaml_parser_t *parser);
593+
594+/*
595+ * Potential simple keys.
596+ */
597+
598+static int
599+yaml_parser_stale_simple_keys(yaml_parser_t *parser);
600+
601+static int
602+yaml_parser_save_simple_key(yaml_parser_t *parser);
603+
604+static int
605+yaml_parser_remove_simple_key(yaml_parser_t *parser);
606+
607+static int
608+yaml_parser_increase_flow_level(yaml_parser_t *parser);
609+
610+static int
611+yaml_parser_decrease_flow_level(yaml_parser_t *parser);
612+
613+/*
614+ * Indentation treatment.
615+ */
616+
617+static int
618+yaml_parser_roll_indent(yaml_parser_t *parser, int column,
619+ int number, yaml_token_type_t type, yaml_mark_t mark);
620+
621+static int
622+yaml_parser_unroll_indent(yaml_parser_t *parser, int column);
623+
624+/*
625+ * Token fetchers.
626+ */
627+
628+static int
629+yaml_parser_fetch_stream_start(yaml_parser_t *parser);
630+
631+static int
632+yaml_parser_fetch_stream_end(yaml_parser_t *parser);
633+
634+static int
635+yaml_parser_fetch_directive(yaml_parser_t *parser);
636+
637+static int
638+yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
639+ yaml_token_type_t type);
640+
641+static int
642+yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
643+ yaml_token_type_t type);
644+
645+static int
646+yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
647+ yaml_token_type_t type);
648+
649+static int
650+yaml_parser_fetch_flow_entry(yaml_parser_t *parser);
651+
652+static int
653+yaml_parser_fetch_block_entry(yaml_parser_t *parser);
654+
655+static int
656+yaml_parser_fetch_key(yaml_parser_t *parser);
657+
658+static int
659+yaml_parser_fetch_value(yaml_parser_t *parser);
660+
661+static int
662+yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type);
663+
664+static int
665+yaml_parser_fetch_tag(yaml_parser_t *parser);
666+
667+static int
668+yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal);
669+
670+static int
671+yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single);
672+
673+static int
674+yaml_parser_fetch_plain_scalar(yaml_parser_t *parser);
675+
676+/*
677+ * Token scanners.
678+ */
679+
680+static int
681+yaml_parser_scan_to_next_token(yaml_parser_t *parser);
682+
683+static int
684+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token);
685+
686+static int
687+yaml_parser_scan_directive_name(yaml_parser_t *parser,
688+ yaml_mark_t start_mark, yaml_char_t **name);
689+
690+static int
691+yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
692+ yaml_mark_t start_mark, int *major, int *minor);
693+
694+static int
695+yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
696+ yaml_mark_t start_mark, int *number);
697+
698+static int
699+yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
700+ yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix);
701+
702+static int
703+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
704+ yaml_token_type_t type);
705+
706+static int
707+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token);
708+
709+static int
710+yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
711+ yaml_mark_t start_mark, yaml_char_t **handle);
712+
713+static int
714+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
715+ yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
716+
717+static int
718+yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
719+ yaml_mark_t start_mark, yaml_string_t *string);
720+
721+static int
722+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
723+ int literal);
724+
725+static int
726+yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
727+ int *indent, yaml_string_t *breaks,
728+ yaml_mark_t start_mark, yaml_mark_t *end_mark);
729+
730+static int
731+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
732+ int single);
733+
734+static int
735+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token);
736+
737+/*
738+ * Get the next token.
739+ */
740+
741+YAML_DECLARE(int)
742+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
743+{
744+ assert(parser); /* Non-NULL parser object is expected. */
745+ assert(token); /* Non-NULL token object is expected. */
746+
747+ /* Erase the token object. */
748+
749+ memset(token, 0, sizeof(yaml_token_t));
750+
751+ /* No tokens after STREAM-END or error. */
752+
753+ if (parser->stream_end_produced || parser->error) {
754+ return 1;
755+ }
756+
757+ /* Ensure that the tokens queue contains enough tokens. */
758+
759+ if (!parser->token_available) {
760+ if (!yaml_parser_fetch_more_tokens(parser))
761+ return 0;
762+ }
763+
764+ /* Fetch the next token from the queue. */
765+
766+ *token = DEQUEUE(parser, parser->tokens);
767+ parser->token_available = 0;
768+ parser->tokens_parsed ++;
769+
770+ if (token->type == YAML_STREAM_END_TOKEN) {
771+ parser->stream_end_produced = 1;
772+ }
773+
774+ return 1;
775+}
776+
777+/*
778+ * Set the scanner error and return 0.
779+ */
780+
781+static int
782+yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
783+ yaml_mark_t context_mark, const char *problem)
784+{
785+ parser->error = YAML_SCANNER_ERROR;
786+ parser->context = context;
787+ parser->context_mark = context_mark;
788+ parser->problem = problem;
789+ parser->problem_mark = parser->mark;
790+
791+ return 0;
792+}
793+
794+/*
795+ * Ensure that the tokens queue contains at least one token which can be
796+ * returned to the Parser.
797+ */
798+
799+YAML_DECLARE(int)
800+yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
801+{
802+ int need_more_tokens;
803+
804+ /* While we need more tokens to fetch, do it. */
805+
806+ while (1)
807+ {
808+ /*
809+ * Check if we really need to fetch more tokens.
810+ */
811+
812+ need_more_tokens = 0;
813+
814+ if (parser->tokens.head == parser->tokens.tail)
815+ {
816+ /* Queue is empty. */
817+
818+ need_more_tokens = 1;
819+ }
820+ else
821+ {
822+ yaml_simple_key_t *simple_key;
823+
824+ /* Check if any potential simple key may occupy the head position. */
825+
826+ if (!yaml_parser_stale_simple_keys(parser))
827+ return 0;
828+
829+ for (simple_key = parser->simple_keys.start;
830+ simple_key != parser->simple_keys.top; simple_key++) {
831+ if (simple_key->possible
832+ && simple_key->token_number == parser->tokens_parsed) {
833+ need_more_tokens = 1;
834+ break;
835+ }
836+ }
837+ }
838+
839+ /* We are finished. */
840+
841+ if (!need_more_tokens)
842+ break;
843+
844+ /* Fetch the next token. */
845+
846+ if (!yaml_parser_fetch_next_token(parser))
847+ return 0;
848+ }
849+
850+ parser->token_available = 1;
851+
852+ return 1;
853+}
854+
855+/*
856+ * The dispatcher for token fetchers.
857+ */
858+
859+static int
860+yaml_parser_fetch_next_token(yaml_parser_t *parser)
861+{
862+ /* Ensure that the buffer is initialized. */
863+
864+ if (!CACHE(parser, 1))
865+ return 0;
866+
867+ /* Check if we just started scanning. Fetch STREAM-START then. */
868+
869+ if (!parser->stream_start_produced)
870+ return yaml_parser_fetch_stream_start(parser);
871+
872+ /* Eat whitespaces and comments until we reach the next token. */
873+
874+ if (!yaml_parser_scan_to_next_token(parser))
875+ return 0;
876+
877+ /* Remove obsolete potential simple keys. */
878+
879+ if (!yaml_parser_stale_simple_keys(parser))
880+ return 0;
881+
882+ /* Check the indentation level against the current column. */
883+
884+ if (!yaml_parser_unroll_indent(parser, parser->mark.column))
885+ return 0;
886+
887+ /*
888+ * Ensure that the buffer contains at least 4 characters. 4 is the length
889+ * of the longest indicators ('--- ' and '... ').
890+ */
891+
892+ if (!CACHE(parser, 4))
893+ return 0;
894+
895+ /* Is it the end of the stream? */
896+
897+ if (IS_Z(parser->buffer))
898+ return yaml_parser_fetch_stream_end(parser);
899+
900+ /* Is it a directive? */
901+
902+ if (parser->mark.column == 0 && CHECK(parser->buffer, '%'))
903+ return yaml_parser_fetch_directive(parser);
904+
905+ /* Is it the document start indicator? */
906+
907+ if (parser->mark.column == 0
908+ && CHECK_AT(parser->buffer, '-', 0)
909+ && CHECK_AT(parser->buffer, '-', 1)
910+ && CHECK_AT(parser->buffer, '-', 2)
911+ && IS_BLANKZ_AT(parser->buffer, 3))
912+ return yaml_parser_fetch_document_indicator(parser,
913+ YAML_DOCUMENT_START_TOKEN);
914+
915+ /* Is it the document end indicator? */
916+
917+ if (parser->mark.column == 0
918+ && CHECK_AT(parser->buffer, '.', 0)
919+ && CHECK_AT(parser->buffer, '.', 1)
920+ && CHECK_AT(parser->buffer, '.', 2)
921+ && IS_BLANKZ_AT(parser->buffer, 3))
922+ return yaml_parser_fetch_document_indicator(parser,
923+ YAML_DOCUMENT_END_TOKEN);
924+
925+ /* Is it the flow sequence start indicator? */
926+
927+ if (CHECK(parser->buffer, '['))
928+ return yaml_parser_fetch_flow_collection_start(parser,
929+ YAML_FLOW_SEQUENCE_START_TOKEN);
930+
931+ /* Is it the flow mapping start indicator? */
932+
933+ if (CHECK(parser->buffer, '{'))
934+ return yaml_parser_fetch_flow_collection_start(parser,
935+ YAML_FLOW_MAPPING_START_TOKEN);
936+
937+ /* Is it the flow sequence end indicator? */
938+
939+ if (CHECK(parser->buffer, ']'))
940+ return yaml_parser_fetch_flow_collection_end(parser,
941+ YAML_FLOW_SEQUENCE_END_TOKEN);
942+
943+ /* Is it the flow mapping end indicator? */
944+
945+ if (CHECK(parser->buffer, '}'))
946+ return yaml_parser_fetch_flow_collection_end(parser,
947+ YAML_FLOW_MAPPING_END_TOKEN);
948+
949+ /* Is it the flow entry indicator? */
950+
951+ if (CHECK(parser->buffer, ','))
952+ return yaml_parser_fetch_flow_entry(parser);
953+
954+ /* Is it the block entry indicator? */
955+
956+ if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1))
957+ return yaml_parser_fetch_block_entry(parser);
958+
959+ /* Is it the key indicator? */
960+
961+ if (CHECK(parser->buffer, '?')
962+ && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
963+ return yaml_parser_fetch_key(parser);
964+
965+ /* Is it the value indicator? */
966+
967+ if (CHECK(parser->buffer, ':')
968+ && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
969+ return yaml_parser_fetch_value(parser);
970+
971+ /* Is it an alias? */
972+
973+ if (CHECK(parser->buffer, '*'))
974+ return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
975+
976+ /* Is it an anchor? */
977+
978+ if (CHECK(parser->buffer, '&'))
979+ return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
980+
981+ /* Is it a tag? */
982+
983+ if (CHECK(parser->buffer, '!'))
984+ return yaml_parser_fetch_tag(parser);
985+
986+ /* Is it a literal scalar? */
987+
988+ if (CHECK(parser->buffer, '|') && !parser->flow_level)
989+ return yaml_parser_fetch_block_scalar(parser, 1);
990+
991+ /* Is it a folded scalar? */
992+
993+ if (CHECK(parser->buffer, '>') && !parser->flow_level)
994+ return yaml_parser_fetch_block_scalar(parser, 0);
995+
996+ /* Is it a single-quoted scalar? */
997+
998+ if (CHECK(parser->buffer, '\''))
999+ return yaml_parser_fetch_flow_scalar(parser, 1);
1000+
1001+ /* Is it a double-quoted scalar? */
1002+
1003+ if (CHECK(parser->buffer, '"'))
1004+ return yaml_parser_fetch_flow_scalar(parser, 0);
1005+
1006+ /*
1007+ * Is it a plain scalar?
1008+ *
1009+ * A plain scalar may start with any non-blank characters except
1010+ *
1011+ * '-', '?', ':', ',', '[', ']', '{', '}',
1012+ * '#', '&', '*', '!', '|', '>', '\'', '\"',
1013+ * '%', '@', '`'.
1014+ *
1015+ * In the block context (and, for the '-' indicator, in the flow context
1016+ * too), it may also start with the characters
1017+ *
1018+ * '-', '?', ':'
1019+ *
1020+ * if it is followed by a non-space character.
1021+ *
1022+ * The last rule is more restrictive than the specification requires.
1023+ */
1024+
1025+ if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-')
1026+ || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')
1027+ || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[')
1028+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
1029+ || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#')
1030+ || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*')
1031+ || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|')
1032+ || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'')
1033+ || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%')
1034+ || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) ||
1035+ (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) ||
1036+ (!parser->flow_level &&
1037+ (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':'))
1038+ && !IS_BLANKZ_AT(parser->buffer, 1)))
1039+ return yaml_parser_fetch_plain_scalar(parser);
1040+
1041+ /*
1042+ * If we don't determine the token type so far, it is an error.
1043+ */
1044+
1045+ return yaml_parser_set_scanner_error(parser,
1046+ "while scanning for the next token", parser->mark,
1047+ "found character that cannot start any token");
1048+}
1049+
1050+/*
1051+ * Check the list of potential simple keys and remove the positions that
1052+ * cannot contain simple keys anymore.
1053+ */
1054+
1055+static int
1056+yaml_parser_stale_simple_keys(yaml_parser_t *parser)
1057+{
1058+ yaml_simple_key_t *simple_key;
1059+
1060+ /* Check for a potential simple key for each flow level. */
1061+
1062+ for (simple_key = parser->simple_keys.start;
1063+ simple_key != parser->simple_keys.top; simple_key ++)
1064+ {
1065+ /*
1066+ * The specification requires that a simple key
1067+ *
1068+ * - is limited to a single line,
1069+ * - is shorter than 1024 characters.
1070+ */
1071+
1072+ if (simple_key->possible
1073+ && (simple_key->mark.line < parser->mark.line
1074+ || simple_key->mark.index+1024 < parser->mark.index)) {
1075+
1076+ /* Check if the potential simple key to be removed is required. */
1077+
1078+ if (simple_key->required) {
1079+ return yaml_parser_set_scanner_error(parser,
1080+ "while scanning a simple key", simple_key->mark,
1081+ "could not find expected ':'");
1082+ }
1083+
1084+ simple_key->possible = 0;
1085+ }
1086+ }
1087+
1088+ return 1;
1089+}
1090+
1091+/*
1092+ * Check if a simple key may start at the current position and add it if
1093+ * needed.
1094+ */
1095+
1096+static int
1097+yaml_parser_save_simple_key(yaml_parser_t *parser)
1098+{
1099+ /*
1100+ * A simple key is required at the current position if the scanner is in
1101+ * the block context and the current column coincides with the indentation
1102+ * level.
1103+ */
1104+
1105+ int required = (!parser->flow_level
1106+ && parser->indent == (int)parser->mark.column);
1107+
1108+ /*
1109+ * A simple key is required only when it is the first token in the current
1110+ * line. Therefore it is always allowed. But we add a check anyway.
1111+ */
1112+
1113+ assert(parser->simple_key_allowed || !required); /* Impossible. */
1114+
1115+ /*
1116+ * If the current position may start a simple key, save it.
1117+ */
1118+
1119+ if (parser->simple_key_allowed)
1120+ {
1121+ yaml_simple_key_t simple_key = { 1, required,
1122+ parser->tokens_parsed + parser->tokens.tail - parser->tokens.head,
1123+ { 0, 0, 0 } };
1124+ simple_key.mark = parser->mark;
1125+
1126+ if (!yaml_parser_remove_simple_key(parser)) return 0;
1127+
1128+ *(parser->simple_keys.top-1) = simple_key;
1129+ }
1130+
1131+ return 1;
1132+}
1133+
1134+/*
1135+ * Remove a potential simple key at the current flow level.
1136+ */
1137+
1138+static int
1139+yaml_parser_remove_simple_key(yaml_parser_t *parser)
1140+{
1141+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
1142+
1143+ if (simple_key->possible)
1144+ {
1145+ /* If the key is required, it is an error. */
1146+
1147+ if (simple_key->required) {
1148+ return yaml_parser_set_scanner_error(parser,
1149+ "while scanning a simple key", simple_key->mark,
1150+ "could not find expected ':'");
1151+ }
1152+ }
1153+
1154+ /* Remove the key from the stack. */
1155+
1156+ simple_key->possible = 0;
1157+
1158+ return 1;
1159+}
1160+
1161+/*
1162+ * Increase the flow level and resize the simple key list if needed.
1163+ */
1164+
1165+static int
1166+yaml_parser_increase_flow_level(yaml_parser_t *parser)
1167+{
1168+ yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } };
1169+
1170+ /* Reset the simple key on the next level. */
1171+
1172+ if (!PUSH(parser, parser->simple_keys, empty_simple_key))
1173+ return 0;
1174+
1175+ /* Increase the flow level. */
1176+
1177+ parser->flow_level++;
1178+
1179+ return 1;
1180+}
1181+
1182+/*
1183+ * Decrease the flow level.
1184+ */
1185+
1186+static int
1187+yaml_parser_decrease_flow_level(yaml_parser_t *parser)
1188+{
1189+ yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */
1190+
1191+ if (parser->flow_level) {
1192+ parser->flow_level --;
1193+ dummy_key = POP(parser, parser->simple_keys);
1194+ }
1195+
1196+ return 1;
1197+}
1198+
1199+/*
1200+ * Push the current indentation level to the stack and set the new level
1201+ * the current column is greater than the indentation level. In this case,
1202+ * append or insert the specified token into the token queue.
1203+ *
1204+ */
1205+
1206+static int
1207+yaml_parser_roll_indent(yaml_parser_t *parser, int column,
1208+ int number, yaml_token_type_t type, yaml_mark_t mark)
1209+{
1210+ yaml_token_t token;
1211+
1212+ /* In the flow context, do nothing. */
1213+
1214+ if (parser->flow_level)
1215+ return 1;
1216+
1217+ if (parser->indent < column)
1218+ {
1219+ /*
1220+ * Push the current indentation level to the stack and set the new
1221+ * indentation level.
1222+ */
1223+
1224+ if (!PUSH(parser, parser->indents, parser->indent))
1225+ return 0;
1226+
1227+ parser->indent = column;
1228+
1229+ /* Create a token and insert it into the queue. */
1230+
1231+ TOKEN_INIT(token, type, mark, mark);
1232+
1233+ if (number == -1) {
1234+ if (!ENQUEUE(parser, parser->tokens, token))
1235+ return 0;
1236+ }
1237+ else {
1238+ if (!QUEUE_INSERT(parser,
1239+ parser->tokens, number - parser->tokens_parsed, token))
1240+ return 0;
1241+ }
1242+ }
1243+
1244+ return 1;
1245+}
1246+
1247+/*
1248+ * Pop indentation levels from the indents stack until the current level
1249+ * becomes less or equal to the column. For each intendation level, append
1250+ * the BLOCK-END token.
1251+ */
1252+
1253+
1254+static int
1255+yaml_parser_unroll_indent(yaml_parser_t *parser, int column)
1256+{
1257+ yaml_token_t token;
1258+
1259+ /* In the flow context, do nothing. */
1260+
1261+ if (parser->flow_level)
1262+ return 1;
1263+
1264+ /* Loop through the intendation levels in the stack. */
1265+
1266+ while (parser->indent > column)
1267+ {
1268+ /* Create a token and append it to the queue. */
1269+
1270+ TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
1271+
1272+ if (!ENQUEUE(parser, parser->tokens, token))
1273+ return 0;
1274+
1275+ /* Pop the indentation level. */
1276+
1277+ parser->indent = POP(parser, parser->indents);
1278+ }
1279+
1280+ return 1;
1281+}
1282+
1283+/*
1284+ * Initialize the scanner and produce the STREAM-START token.
1285+ */
1286+
1287+static int
1288+yaml_parser_fetch_stream_start(yaml_parser_t *parser)
1289+{
1290+ yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } };
1291+ yaml_token_t token;
1292+
1293+ /* Set the initial indentation. */
1294+
1295+ parser->indent = -1;
1296+
1297+ /* Initialize the simple key stack. */
1298+
1299+ if (!PUSH(parser, parser->simple_keys, simple_key))
1300+ return 0;
1301+
1302+ /* A simple key is allowed at the beginning of the stream. */
1303+
1304+ parser->simple_key_allowed = 1;
1305+
1306+ /* We have started. */
1307+
1308+ parser->stream_start_produced = 1;
1309+
1310+ /* Create the STREAM-START token and append it to the queue. */
1311+
1312+ STREAM_START_TOKEN_INIT(token, parser->encoding,
1313+ parser->mark, parser->mark);
1314+
1315+ if (!ENQUEUE(parser, parser->tokens, token))
1316+ return 0;
1317+
1318+ return 1;
1319+}
1320+
1321+/*
1322+ * Produce the STREAM-END token and shut down the scanner.
1323+ */
1324+
1325+static int
1326+yaml_parser_fetch_stream_end(yaml_parser_t *parser)
1327+{
1328+ yaml_token_t token;
1329+
1330+ /* Force new line. */
1331+
1332+ if (parser->mark.column != 0) {
1333+ parser->mark.column = 0;
1334+ parser->mark.line ++;
1335+ }
1336+
1337+ /* Reset the indentation level. */
1338+
1339+ if (!yaml_parser_unroll_indent(parser, -1))
1340+ return 0;
1341+
1342+ /* Reset simple keys. */
1343+
1344+ if (!yaml_parser_remove_simple_key(parser))
1345+ return 0;
1346+
1347+ parser->simple_key_allowed = 0;
1348+
1349+ /* Create the STREAM-END token and append it to the queue. */
1350+
1351+ STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark);
1352+
1353+ if (!ENQUEUE(parser, parser->tokens, token))
1354+ return 0;
1355+
1356+ return 1;
1357+}
1358+
1359+/*
1360+ * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
1361+ */
1362+
1363+static int
1364+yaml_parser_fetch_directive(yaml_parser_t *parser)
1365+{
1366+ yaml_token_t token;
1367+
1368+ /* Reset the indentation level. */
1369+
1370+ if (!yaml_parser_unroll_indent(parser, -1))
1371+ return 0;
1372+
1373+ /* Reset simple keys. */
1374+
1375+ if (!yaml_parser_remove_simple_key(parser))
1376+ return 0;
1377+
1378+ parser->simple_key_allowed = 0;
1379+
1380+ /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
1381+
1382+ if (!yaml_parser_scan_directive(parser, &token))
1383+ return 0;
1384+
1385+ /* Append the token to the queue. */
1386+
1387+ if (!ENQUEUE(parser, parser->tokens, token)) {
1388+ yaml_token_delete(&token);
1389+ return 0;
1390+ }
1391+
1392+ return 1;
1393+}
1394+
1395+/*
1396+ * Produce the DOCUMENT-START or DOCUMENT-END token.
1397+ */
1398+
1399+static int
1400+yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
1401+ yaml_token_type_t type)
1402+{
1403+ yaml_mark_t start_mark, end_mark;
1404+ yaml_token_t token;
1405+
1406+ /* Reset the indentation level. */
1407+
1408+ if (!yaml_parser_unroll_indent(parser, -1))
1409+ return 0;
1410+
1411+ /* Reset simple keys. */
1412+
1413+ if (!yaml_parser_remove_simple_key(parser))
1414+ return 0;
1415+
1416+ parser->simple_key_allowed = 0;
1417+
1418+ /* Consume the token. */
1419+
1420+ start_mark = parser->mark;
1421+
1422+ SKIP(parser);
1423+ SKIP(parser);
1424+ SKIP(parser);
1425+
1426+ end_mark = parser->mark;
1427+
1428+ /* Create the DOCUMENT-START or DOCUMENT-END token. */
1429+
1430+ TOKEN_INIT(token, type, start_mark, end_mark);
1431+
1432+ /* Append the token to the queue. */
1433+
1434+ if (!ENQUEUE(parser, parser->tokens, token))
1435+ return 0;
1436+
1437+ return 1;
1438+}
1439+
1440+/*
1441+ * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
1442+ */
1443+
1444+static int
1445+yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
1446+ yaml_token_type_t type)
1447+{
1448+ yaml_mark_t start_mark, end_mark;
1449+ yaml_token_t token;
1450+
1451+ /* The indicators '[' and '{' may start a simple key. */
1452+
1453+ if (!yaml_parser_save_simple_key(parser))
1454+ return 0;
1455+
1456+ /* Increase the flow level. */
1457+
1458+ if (!yaml_parser_increase_flow_level(parser))
1459+ return 0;
1460+
1461+ /* A simple key may follow the indicators '[' and '{'. */
1462+
1463+ parser->simple_key_allowed = 1;
1464+
1465+ /* Consume the token. */
1466+
1467+ start_mark = parser->mark;
1468+ SKIP(parser);
1469+ end_mark = parser->mark;
1470+
1471+ /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
1472+
1473+ TOKEN_INIT(token, type, start_mark, end_mark);
1474+
1475+ /* Append the token to the queue. */
1476+
1477+ if (!ENQUEUE(parser, parser->tokens, token))
1478+ return 0;
1479+
1480+ return 1;
1481+}
1482+
1483+/*
1484+ * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
1485+ */
1486+
1487+static int
1488+yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
1489+ yaml_token_type_t type)
1490+{
1491+ yaml_mark_t start_mark, end_mark;
1492+ yaml_token_t token;
1493+
1494+ /* Reset any potential simple key on the current flow level. */
1495+
1496+ if (!yaml_parser_remove_simple_key(parser))
1497+ return 0;
1498+
1499+ /* Decrease the flow level. */
1500+
1501+ if (!yaml_parser_decrease_flow_level(parser))
1502+ return 0;
1503+
1504+ /* No simple keys after the indicators ']' and '}'. */
1505+
1506+ parser->simple_key_allowed = 0;
1507+
1508+ /* Consume the token. */
1509+
1510+ start_mark = parser->mark;
1511+ SKIP(parser);
1512+ end_mark = parser->mark;
1513+
1514+ /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
1515+
1516+ TOKEN_INIT(token, type, start_mark, end_mark);
1517+
1518+ /* Append the token to the queue. */
1519+
1520+ if (!ENQUEUE(parser, parser->tokens, token))
1521+ return 0;
1522+
1523+ return 1;
1524+}
1525+
1526+/*
1527+ * Produce the FLOW-ENTRY token.
1528+ */
1529+
1530+static int
1531+yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
1532+{
1533+ yaml_mark_t start_mark, end_mark;
1534+ yaml_token_t token;
1535+
1536+ /* Reset any potential simple keys on the current flow level. */
1537+
1538+ if (!yaml_parser_remove_simple_key(parser))
1539+ return 0;
1540+
1541+ /* Simple keys are allowed after ','. */
1542+
1543+ parser->simple_key_allowed = 1;
1544+
1545+ /* Consume the token. */
1546+
1547+ start_mark = parser->mark;
1548+ SKIP(parser);
1549+ end_mark = parser->mark;
1550+
1551+ /* Create the FLOW-ENTRY token and append it to the queue. */
1552+
1553+ TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
1554+
1555+ if (!ENQUEUE(parser, parser->tokens, token))
1556+ return 0;
1557+
1558+ return 1;
1559+}
1560+
1561+/*
1562+ * Produce the BLOCK-ENTRY token.
1563+ */
1564+
1565+static int
1566+yaml_parser_fetch_block_entry(yaml_parser_t *parser)
1567+{
1568+ yaml_mark_t start_mark, end_mark;
1569+ yaml_token_t token;
1570+
1571+ /* Check if the scanner is in the block context. */
1572+
1573+ if (!parser->flow_level)
1574+ {
1575+ /* Check if we are allowed to start a new entry. */
1576+
1577+ if (!parser->simple_key_allowed) {
1578+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1579+ "block sequence entries are not allowed in this context");
1580+ }
1581+
1582+ /* Add the BLOCK-SEQUENCE-START token if needed. */
1583+
1584+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1585+ YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark))
1586+ return 0;
1587+ }
1588+ else
1589+ {
1590+ /*
1591+ * It is an error for the '-' indicator to occur in the flow context,
1592+ * but we let the Parser detect and report about it because the Parser
1593+ * is able to point to the context.
1594+ */
1595+ }
1596+
1597+ /* Reset any potential simple keys on the current flow level. */
1598+
1599+ if (!yaml_parser_remove_simple_key(parser))
1600+ return 0;
1601+
1602+ /* Simple keys are allowed after '-'. */
1603+
1604+ parser->simple_key_allowed = 1;
1605+
1606+ /* Consume the token. */
1607+
1608+ start_mark = parser->mark;
1609+ SKIP(parser);
1610+ end_mark = parser->mark;
1611+
1612+ /* Create the BLOCK-ENTRY token and append it to the queue. */
1613+
1614+ TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
1615+
1616+ if (!ENQUEUE(parser, parser->tokens, token))
1617+ return 0;
1618+
1619+ return 1;
1620+}
1621+
1622+/*
1623+ * Produce the KEY token.
1624+ */
1625+
1626+static int
1627+yaml_parser_fetch_key(yaml_parser_t *parser)
1628+{
1629+ yaml_mark_t start_mark, end_mark;
1630+ yaml_token_t token;
1631+
1632+ /* In the block context, additional checks are required. */
1633+
1634+ if (!parser->flow_level)
1635+ {
1636+ /* Check if we are allowed to start a new key (not nessesary simple). */
1637+
1638+ if (!parser->simple_key_allowed) {
1639+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1640+ "mapping keys are not allowed in this context");
1641+ }
1642+
1643+ /* Add the BLOCK-MAPPING-START token if needed. */
1644+
1645+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1646+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
1647+ return 0;
1648+ }
1649+
1650+ /* Reset any potential simple keys on the current flow level. */
1651+
1652+ if (!yaml_parser_remove_simple_key(parser))
1653+ return 0;
1654+
1655+ /* Simple keys are allowed after '?' in the block context. */
1656+
1657+ parser->simple_key_allowed = (!parser->flow_level);
1658+
1659+ /* Consume the token. */
1660+
1661+ start_mark = parser->mark;
1662+ SKIP(parser);
1663+ end_mark = parser->mark;
1664+
1665+ /* Create the KEY token and append it to the queue. */
1666+
1667+ TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark);
1668+
1669+ if (!ENQUEUE(parser, parser->tokens, token))
1670+ return 0;
1671+
1672+ return 1;
1673+}
1674+
1675+/*
1676+ * Produce the VALUE token.
1677+ */
1678+
1679+static int
1680+yaml_parser_fetch_value(yaml_parser_t *parser)
1681+{
1682+ yaml_mark_t start_mark, end_mark;
1683+ yaml_token_t token;
1684+ yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
1685+
1686+ /* Have we found a simple key? */
1687+
1688+ if (simple_key->possible)
1689+ {
1690+
1691+ /* Create the KEY token and insert it into the queue. */
1692+
1693+ TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
1694+
1695+ if (!QUEUE_INSERT(parser, parser->tokens,
1696+ simple_key->token_number - parser->tokens_parsed, token))
1697+ return 0;
1698+
1699+ /* In the block context, we may need to add the BLOCK-MAPPING-START token. */
1700+
1701+ if (!yaml_parser_roll_indent(parser, simple_key->mark.column,
1702+ simple_key->token_number,
1703+ YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark))
1704+ return 0;
1705+
1706+ /* Remove the simple key. */
1707+
1708+ simple_key->possible = 0;
1709+
1710+ /* A simple key cannot follow another simple key. */
1711+
1712+ parser->simple_key_allowed = 0;
1713+ }
1714+ else
1715+ {
1716+ /* The ':' indicator follows a complex key. */
1717+
1718+ /* In the block context, extra checks are required. */
1719+
1720+ if (!parser->flow_level)
1721+ {
1722+ /* Check if we are allowed to start a complex value. */
1723+
1724+ if (!parser->simple_key_allowed) {
1725+ return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1726+ "mapping values are not allowed in this context");
1727+ }
1728+
1729+ /* Add the BLOCK-MAPPING-START token if needed. */
1730+
1731+ if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1732+ YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
1733+ return 0;
1734+ }
1735+
1736+ /* Simple keys after ':' are allowed in the block context. */
1737+
1738+ parser->simple_key_allowed = (!parser->flow_level);
1739+ }
1740+
1741+ /* Consume the token. */
1742+
1743+ start_mark = parser->mark;
1744+ SKIP(parser);
1745+ end_mark = parser->mark;
1746+
1747+ /* Create the VALUE token and append it to the queue. */
1748+
1749+ TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark);
1750+
1751+ if (!ENQUEUE(parser, parser->tokens, token))
1752+ return 0;
1753+
1754+ return 1;
1755+}
1756+
1757+/*
1758+ * Produce the ALIAS or ANCHOR token.
1759+ */
1760+
1761+static int
1762+yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
1763+{
1764+ yaml_token_t token;
1765+
1766+ /* An anchor or an alias could be a simple key. */
1767+
1768+ if (!yaml_parser_save_simple_key(parser))
1769+ return 0;
1770+
1771+ /* A simple key cannot follow an anchor or an alias. */
1772+
1773+ parser->simple_key_allowed = 0;
1774+
1775+ /* Create the ALIAS or ANCHOR token and append it to the queue. */
1776+
1777+ if (!yaml_parser_scan_anchor(parser, &token, type))
1778+ return 0;
1779+
1780+ if (!ENQUEUE(parser, parser->tokens, token)) {
1781+ yaml_token_delete(&token);
1782+ return 0;
1783+ }
1784+ return 1;
1785+}
1786+
1787+/*
1788+ * Produce the TAG token.
1789+ */
1790+
1791+static int
1792+yaml_parser_fetch_tag(yaml_parser_t *parser)
1793+{
1794+ yaml_token_t token;
1795+
1796+ /* A tag could be a simple key. */
1797+
1798+ if (!yaml_parser_save_simple_key(parser))
1799+ return 0;
1800+
1801+ /* A simple key cannot follow a tag. */
1802+
1803+ parser->simple_key_allowed = 0;
1804+
1805+ /* Create the TAG token and append it to the queue. */
1806+
1807+ if (!yaml_parser_scan_tag(parser, &token))
1808+ return 0;
1809+
1810+ if (!ENQUEUE(parser, parser->tokens, token)) {
1811+ yaml_token_delete(&token);
1812+ return 0;
1813+ }
1814+
1815+ return 1;
1816+}
1817+
1818+/*
1819+ * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
1820+ */
1821+
1822+static int
1823+yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
1824+{
1825+ yaml_token_t token;
1826+
1827+ /* Remove any potential simple keys. */
1828+
1829+ if (!yaml_parser_remove_simple_key(parser))
1830+ return 0;
1831+
1832+ /* A simple key may follow a block scalar. */
1833+
1834+ parser->simple_key_allowed = 1;
1835+
1836+ /* Create the SCALAR token and append it to the queue. */
1837+
1838+ if (!yaml_parser_scan_block_scalar(parser, &token, literal))
1839+ return 0;
1840+
1841+ if (!ENQUEUE(parser, parser->tokens, token)) {
1842+ yaml_token_delete(&token);
1843+ return 0;
1844+ }
1845+
1846+ return 1;
1847+}
1848+
1849+/*
1850+ * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
1851+ */
1852+
1853+static int
1854+yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
1855+{
1856+ yaml_token_t token;
1857+
1858+ /* A plain scalar could be a simple key. */
1859+
1860+ if (!yaml_parser_save_simple_key(parser))
1861+ return 0;
1862+
1863+ /* A simple key cannot follow a flow scalar. */
1864+
1865+ parser->simple_key_allowed = 0;
1866+
1867+ /* Create the SCALAR token and append it to the queue. */
1868+
1869+ if (!yaml_parser_scan_flow_scalar(parser, &token, single))
1870+ return 0;
1871+
1872+ if (!ENQUEUE(parser, parser->tokens, token)) {
1873+ yaml_token_delete(&token);
1874+ return 0;
1875+ }
1876+
1877+ return 1;
1878+}
1879+
1880+/*
1881+ * Produce the SCALAR(...,plain) token.
1882+ */
1883+
1884+static int
1885+yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
1886+{
1887+ yaml_token_t token;
1888+
1889+ /* A plain scalar could be a simple key. */
1890+
1891+ if (!yaml_parser_save_simple_key(parser))
1892+ return 0;
1893+
1894+ /* A simple key cannot follow a flow scalar. */
1895+
1896+ parser->simple_key_allowed = 0;
1897+
1898+ /* Create the SCALAR token and append it to the queue. */
1899+
1900+ if (!yaml_parser_scan_plain_scalar(parser, &token))
1901+ return 0;
1902+
1903+ if (!ENQUEUE(parser, parser->tokens, token)) {
1904+ yaml_token_delete(&token);
1905+ return 0;
1906+ }
1907+
1908+ return 1;
1909+}
1910+
1911+/*
1912+ * Eat whitespaces and comments until the next token is found.
1913+ */
1914+
1915+static int
1916+yaml_parser_scan_to_next_token(yaml_parser_t *parser)
1917+{
1918+ /* Until the next token is not found. */
1919+
1920+ while (1)
1921+ {
1922+ /* Allow the BOM mark to start a line. */
1923+
1924+ if (!CACHE(parser, 1)) return 0;
1925+
1926+ if (parser->mark.column == 0 && IS_BOM(parser->buffer))
1927+ SKIP(parser);
1928+
1929+ /*
1930+ * Eat whitespaces.
1931+ *
1932+ * Tabs are allowed:
1933+ *
1934+ * - in the flow context;
1935+ * - in the block context, but not at the beginning of the line or
1936+ * after '-', '?', or ':' (complex value).
1937+ */
1938+
1939+ if (!CACHE(parser, 1)) return 0;
1940+
1941+ while (CHECK(parser->buffer,' ') ||
1942+ ((parser->flow_level || !parser->simple_key_allowed) &&
1943+ CHECK(parser->buffer, '\t'))) {
1944+ SKIP(parser);
1945+ if (!CACHE(parser, 1)) return 0;
1946+ }
1947+
1948+ /* Eat a comment until a line break. */
1949+
1950+ if (CHECK(parser->buffer, '#')) {
1951+ while (!IS_BREAKZ(parser->buffer)) {
1952+ SKIP(parser);
1953+ if (!CACHE(parser, 1)) return 0;
1954+ }
1955+ }
1956+
1957+ /* If it is a line break, eat it. */
1958+
1959+ if (IS_BREAK(parser->buffer))
1960+ {
1961+ if (!CACHE(parser, 2)) return 0;
1962+ SKIP_LINE(parser);
1963+
1964+ /* In the block context, a new line may start a simple key. */
1965+
1966+ if (!parser->flow_level) {
1967+ parser->simple_key_allowed = 1;
1968+ }
1969+ }
1970+ else
1971+ {
1972+ /* We have found a token. */
1973+
1974+ break;
1975+ }
1976+ }
1977+
1978+ return 1;
1979+}
1980+
1981+/*
1982+ * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
1983+ *
1984+ * Scope:
1985+ * %YAML 1.1 # a comment \n
1986+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1987+ * %TAG !yaml! tag:yaml.org,2002: \n
1988+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1989+ */
1990+
1991+int
1992+yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
1993+{
1994+ yaml_mark_t start_mark, end_mark;
1995+ yaml_char_t *name = NULL;
1996+ int major, minor;
1997+ yaml_char_t *handle = NULL, *prefix = NULL;
1998+
1999+ /* Eat '%'. */
2000+
2001+ start_mark = parser->mark;
2002+
2003+ SKIP(parser);
2004+
2005+ /* Scan the directive name. */
2006+
2007+ if (!yaml_parser_scan_directive_name(parser, start_mark, &name))
2008+ goto error;
2009+
2010+ /* Is it a YAML directive? */
2011+
2012+ if (strcmp((char *)name, "YAML") == 0)
2013+ {
2014+ /* Scan the VERSION directive value. */
2015+
2016+ if (!yaml_parser_scan_version_directive_value(parser, start_mark,
2017+ &major, &minor))
2018+ goto error;
2019+
2020+ end_mark = parser->mark;
2021+
2022+ /* Create a VERSION-DIRECTIVE token. */
2023+
2024+ VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor,
2025+ start_mark, end_mark);
2026+ }
2027+
2028+ /* Is it a TAG directive? */
2029+
2030+ else if (strcmp((char *)name, "TAG") == 0)
2031+ {
2032+ /* Scan the TAG directive value. */
2033+
2034+ if (!yaml_parser_scan_tag_directive_value(parser, start_mark,
2035+ &handle, &prefix))
2036+ goto error;
2037+
2038+ end_mark = parser->mark;
2039+
2040+ /* Create a TAG-DIRECTIVE token. */
2041+
2042+ TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix,
2043+ start_mark, end_mark);
2044+ }
2045+
2046+ /* Unknown directive. */
2047+
2048+ else
2049+ {
2050+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
2051+ start_mark, "found uknown directive name");
2052+ goto error;
2053+ }
2054+
2055+ /* Eat the rest of the line including any comments. */
2056+
2057+ if (!CACHE(parser, 1)) goto error;
2058+
2059+ while (IS_BLANK(parser->buffer)) {
2060+ SKIP(parser);
2061+ if (!CACHE(parser, 1)) goto error;
2062+ }
2063+
2064+ if (CHECK(parser->buffer, '#')) {
2065+ while (!IS_BREAKZ(parser->buffer)) {
2066+ SKIP(parser);
2067+ if (!CACHE(parser, 1)) goto error;
2068+ }
2069+ }
2070+
2071+ /* Check if we are at the end of the line. */
2072+
2073+ if (!IS_BREAKZ(parser->buffer)) {
2074+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
2075+ start_mark, "did not find expected comment or line break");
2076+ goto error;
2077+ }
2078+
2079+ /* Eat a line break. */
2080+
2081+ if (IS_BREAK(parser->buffer)) {
2082+ if (!CACHE(parser, 2)) goto error;
2083+ SKIP_LINE(parser);
2084+ }
2085+
2086+ yaml_free(name);
2087+
2088+ return 1;
2089+
2090+error:
2091+ yaml_free(prefix);
2092+ yaml_free(handle);
2093+ yaml_free(name);
2094+ return 0;
2095+}
2096+
2097+/*
2098+ * Scan the directive name.
2099+ *
2100+ * Scope:
2101+ * %YAML 1.1 # a comment \n
2102+ * ^^^^
2103+ * %TAG !yaml! tag:yaml.org,2002: \n
2104+ * ^^^
2105+ */
2106+
2107+static int
2108+yaml_parser_scan_directive_name(yaml_parser_t *parser,
2109+ yaml_mark_t start_mark, yaml_char_t **name)
2110+{
2111+ yaml_string_t string = NULL_STRING;
2112+
2113+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2114+
2115+ /* Consume the directive name. */
2116+
2117+ if (!CACHE(parser, 1)) goto error;
2118+
2119+ while (IS_ALPHA(parser->buffer))
2120+ {
2121+ if (!READ(parser, string)) goto error;
2122+ if (!CACHE(parser, 1)) goto error;
2123+ }
2124+
2125+ /* Check if the name is empty. */
2126+
2127+ if (string.start == string.pointer) {
2128+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
2129+ start_mark, "could not find expected directive name");
2130+ goto error;
2131+ }
2132+
2133+ /* Check for an blank character after the name. */
2134+
2135+ if (!IS_BLANKZ(parser->buffer)) {
2136+ yaml_parser_set_scanner_error(parser, "while scanning a directive",
2137+ start_mark, "found unexpected non-alphabetical character");
2138+ goto error;
2139+ }
2140+
2141+ *name = string.start;
2142+
2143+ return 1;
2144+
2145+error:
2146+ STRING_DEL(parser, string);
2147+ return 0;
2148+}
2149+
2150+/*
2151+ * Scan the value of VERSION-DIRECTIVE.
2152+ *
2153+ * Scope:
2154+ * %YAML 1.1 # a comment \n
2155+ * ^^^^^^
2156+ */
2157+
2158+static int
2159+yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
2160+ yaml_mark_t start_mark, int *major, int *minor)
2161+{
2162+ /* Eat whitespaces. */
2163+
2164+ if (!CACHE(parser, 1)) return 0;
2165+
2166+ while (IS_BLANK(parser->buffer)) {
2167+ SKIP(parser);
2168+ if (!CACHE(parser, 1)) return 0;
2169+ }
2170+
2171+ /* Consume the major version number. */
2172+
2173+ if (!yaml_parser_scan_version_directive_number(parser, start_mark, major))
2174+ return 0;
2175+
2176+ /* Eat '.'. */
2177+
2178+ if (!CHECK(parser->buffer, '.')) {
2179+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2180+ start_mark, "did not find expected digit or '.' character");
2181+ }
2182+
2183+ SKIP(parser);
2184+
2185+ /* Consume the minor version number. */
2186+
2187+ if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor))
2188+ return 0;
2189+
2190+ return 1;
2191+}
2192+
2193+#define MAX_NUMBER_LENGTH 9
2194+
2195+/*
2196+ * Scan the version number of VERSION-DIRECTIVE.
2197+ *
2198+ * Scope:
2199+ * %YAML 1.1 # a comment \n
2200+ * ^
2201+ * %YAML 1.1 # a comment \n
2202+ * ^
2203+ */
2204+
2205+static int
2206+yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
2207+ yaml_mark_t start_mark, int *number)
2208+{
2209+ int value = 0;
2210+ size_t length = 0;
2211+
2212+ /* Repeat while the next character is digit. */
2213+
2214+ if (!CACHE(parser, 1)) return 0;
2215+
2216+ while (IS_DIGIT(parser->buffer))
2217+ {
2218+ /* Check if the number is too long. */
2219+
2220+ if (++length > MAX_NUMBER_LENGTH) {
2221+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2222+ start_mark, "found extremely long version number");
2223+ }
2224+
2225+ value = value*10 + AS_DIGIT(parser->buffer);
2226+
2227+ SKIP(parser);
2228+
2229+ if (!CACHE(parser, 1)) return 0;
2230+ }
2231+
2232+ /* Check if the number was present. */
2233+
2234+ if (!length) {
2235+ return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2236+ start_mark, "did not find expected version number");
2237+ }
2238+
2239+ *number = value;
2240+
2241+ return 1;
2242+}
2243+
2244+/*
2245+ * Scan the value of a TAG-DIRECTIVE token.
2246+ *
2247+ * Scope:
2248+ * %TAG !yaml! tag:yaml.org,2002: \n
2249+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2250+ */
2251+
2252+static int
2253+yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
2254+ yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix)
2255+{
2256+ yaml_char_t *handle_value = NULL;
2257+ yaml_char_t *prefix_value = NULL;
2258+
2259+ /* Eat whitespaces. */
2260+
2261+ if (!CACHE(parser, 1)) goto error;
2262+
2263+ while (IS_BLANK(parser->buffer)) {
2264+ SKIP(parser);
2265+ if (!CACHE(parser, 1)) goto error;
2266+ }
2267+
2268+ /* Scan a handle. */
2269+
2270+ if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value))
2271+ goto error;
2272+
2273+ /* Expect a whitespace. */
2274+
2275+ if (!CACHE(parser, 1)) goto error;
2276+
2277+ if (!IS_BLANK(parser->buffer)) {
2278+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
2279+ start_mark, "did not find expected whitespace");
2280+ goto error;
2281+ }
2282+
2283+ /* Eat whitespaces. */
2284+
2285+ while (IS_BLANK(parser->buffer)) {
2286+ SKIP(parser);
2287+ if (!CACHE(parser, 1)) goto error;
2288+ }
2289+
2290+ /* Scan a prefix. */
2291+
2292+ if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value))
2293+ goto error;
2294+
2295+ /* Expect a whitespace or line break. */
2296+
2297+ if (!CACHE(parser, 1)) goto error;
2298+
2299+ if (!IS_BLANKZ(parser->buffer)) {
2300+ yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
2301+ start_mark, "did not find expected whitespace or line break");
2302+ goto error;
2303+ }
2304+
2305+ *handle = handle_value;
2306+ *prefix = prefix_value;
2307+
2308+ return 1;
2309+
2310+error:
2311+ yaml_free(handle_value);
2312+ yaml_free(prefix_value);
2313+ return 0;
2314+}
2315+
2316+static int
2317+yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
2318+ yaml_token_type_t type)
2319+{
2320+ int length = 0;
2321+ yaml_mark_t start_mark, end_mark;
2322+ yaml_string_t string = NULL_STRING;
2323+
2324+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2325+
2326+ /* Eat the indicator character. */
2327+
2328+ start_mark = parser->mark;
2329+
2330+ SKIP(parser);
2331+
2332+ /* Consume the value. */
2333+
2334+ if (!CACHE(parser, 1)) goto error;
2335+
2336+ while (IS_ALPHA(parser->buffer)) {
2337+ if (!READ(parser, string)) goto error;
2338+ if (!CACHE(parser, 1)) goto error;
2339+ length ++;
2340+ }
2341+
2342+ end_mark = parser->mark;
2343+
2344+ /*
2345+ * Check if length of the anchor is greater than 0 and it is followed by
2346+ * a whitespace character or one of the indicators:
2347+ *
2348+ * '?', ':', ',', ']', '}', '%', '@', '`'.
2349+ */
2350+
2351+ if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?')
2352+ || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',')
2353+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}')
2354+ || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@')
2355+ || CHECK(parser->buffer, '`'))) {
2356+ yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ?
2357+ "while scanning an anchor" : "while scanning an alias", start_mark,
2358+ "did not find expected alphabetic or numeric character");
2359+ goto error;
2360+ }
2361+
2362+ /* Create a token. */
2363+
2364+ if (type == YAML_ANCHOR_TOKEN) {
2365+ ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
2366+ }
2367+ else {
2368+ ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
2369+ }
2370+
2371+ return 1;
2372+
2373+error:
2374+ STRING_DEL(parser, string);
2375+ return 0;
2376+}
2377+
2378+/*
2379+ * Scan a TAG token.
2380+ */
2381+
2382+static int
2383+yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
2384+{
2385+ yaml_char_t *handle = NULL;
2386+ yaml_char_t *suffix = NULL;
2387+ yaml_mark_t start_mark, end_mark;
2388+
2389+ start_mark = parser->mark;
2390+
2391+ /* Check if the tag is in the canonical form. */
2392+
2393+ if (!CACHE(parser, 2)) goto error;
2394+
2395+ if (CHECK_AT(parser->buffer, '<', 1))
2396+ {
2397+ /* Set the handle to '' */
2398+
2399+ handle = yaml_malloc(1);
2400+ if (!handle) goto error;
2401+ handle[0] = '\0';
2402+
2403+ /* Eat '!<' */
2404+
2405+ SKIP(parser);
2406+ SKIP(parser);
2407+
2408+ /* Consume the tag value. */
2409+
2410+ if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
2411+ goto error;
2412+
2413+ /* Check for '>' and eat it. */
2414+
2415+ if (!CHECK(parser->buffer, '>')) {
2416+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
2417+ start_mark, "did not find the expected '>'");
2418+ goto error;
2419+ }
2420+
2421+ SKIP(parser);
2422+ }
2423+ else
2424+ {
2425+ /* The tag has either the '!suffix' or the '!handle!suffix' form. */
2426+
2427+ /* First, try to scan a handle. */
2428+
2429+ if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle))
2430+ goto error;
2431+
2432+ /* Check if it is, indeed, handle. */
2433+
2434+ if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!')
2435+ {
2436+ /* Scan the suffix now. */
2437+
2438+ if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
2439+ goto error;
2440+ }
2441+ else
2442+ {
2443+ /* It wasn't a handle after all. Scan the rest of the tag. */
2444+
2445+ if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix))
2446+ goto error;
2447+
2448+ /* Set the handle to '!'. */
2449+
2450+ yaml_free(handle);
2451+ handle = yaml_malloc(2);
2452+ if (!handle) goto error;
2453+ handle[0] = '!';
2454+ handle[1] = '\0';
2455+
2456+ /*
2457+ * A special case: the '!' tag. Set the handle to '' and the
2458+ * suffix to '!'.
2459+ */
2460+
2461+ if (suffix[0] == '\0') {
2462+ yaml_char_t *tmp = handle;
2463+ handle = suffix;
2464+ suffix = tmp;
2465+ }
2466+ }
2467+ }
2468+
2469+ /* Check the character which ends the tag. */
2470+
2471+ if (!CACHE(parser, 1)) goto error;
2472+
2473+ if (!IS_BLANKZ(parser->buffer)) {
2474+ yaml_parser_set_scanner_error(parser, "while scanning a tag",
2475+ start_mark, "did not find expected whitespace or line break");
2476+ goto error;
2477+ }
2478+
2479+ end_mark = parser->mark;
2480+
2481+ /* Create a token. */
2482+
2483+ TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark);
2484+
2485+ return 1;
2486+
2487+error:
2488+ yaml_free(handle);
2489+ yaml_free(suffix);
2490+ return 0;
2491+}
2492+
2493+/*
2494+ * Scan a tag handle.
2495+ */
2496+
2497+static int
2498+yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
2499+ yaml_mark_t start_mark, yaml_char_t **handle)
2500+{
2501+ yaml_string_t string = NULL_STRING;
2502+
2503+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2504+
2505+ /* Check the initial '!' character. */
2506+
2507+ if (!CACHE(parser, 1)) goto error;
2508+
2509+ if (!CHECK(parser->buffer, '!')) {
2510+ yaml_parser_set_scanner_error(parser, directive ?
2511+ "while scanning a tag directive" : "while scanning a tag",
2512+ start_mark, "did not find expected '!'");
2513+ goto error;
2514+ }
2515+
2516+ /* Copy the '!' character. */
2517+
2518+ if (!READ(parser, string)) goto error;
2519+
2520+ /* Copy all subsequent alphabetical and numerical characters. */
2521+
2522+ if (!CACHE(parser, 1)) goto error;
2523+
2524+ while (IS_ALPHA(parser->buffer))
2525+ {
2526+ if (!READ(parser, string)) goto error;
2527+ if (!CACHE(parser, 1)) goto error;
2528+ }
2529+
2530+ /* Check if the trailing character is '!' and copy it. */
2531+
2532+ if (CHECK(parser->buffer, '!'))
2533+ {
2534+ if (!READ(parser, string)) goto error;
2535+ }
2536+ else
2537+ {
2538+ /*
2539+ * It's either the '!' tag or not really a tag handle. If it's a %TAG
2540+ * directive, it's an error. If it's a tag token, it must be a part of
2541+ * URI.
2542+ */
2543+
2544+ if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) {
2545+ yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
2546+ start_mark, "did not find expected '!'");
2547+ goto error;
2548+ }
2549+ }
2550+
2551+ *handle = string.start;
2552+
2553+ return 1;
2554+
2555+error:
2556+ STRING_DEL(parser, string);
2557+ return 0;
2558+}
2559+
2560+/*
2561+ * Scan a tag.
2562+ */
2563+
2564+static int
2565+yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
2566+ yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
2567+{
2568+ size_t length = head ? strlen((char *)head) : 0;
2569+ yaml_string_t string = NULL_STRING;
2570+
2571+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2572+
2573+ /* Resize the string to include the head. */
2574+
2575+ while (string.end - string.start <= (int)length) {
2576+ if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
2577+ parser->error = YAML_MEMORY_ERROR;
2578+ goto error;
2579+ }
2580+ }
2581+
2582+ /*
2583+ * Copy the head if needed.
2584+ *
2585+ * Note that we don't copy the leading '!' character.
2586+ */
2587+
2588+ if (length > 1) {
2589+ memcpy(string.start, head+1, length-1);
2590+ string.pointer += length-1;
2591+ }
2592+
2593+ /* Scan the tag. */
2594+
2595+ if (!CACHE(parser, 1)) goto error;
2596+
2597+ /*
2598+ * The set of characters that may appear in URI is as follows:
2599+ *
2600+ * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
2601+ * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
2602+ * '%'.
2603+ */
2604+
2605+ while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
2606+ || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?')
2607+ || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
2608+ || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
2609+ || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
2610+ || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
2611+ || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
2612+ || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
2613+ || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
2614+ || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
2615+ || CHECK(parser->buffer, '%'))
2616+ {
2617+ /* Check if it is a URI-escape sequence. */
2618+
2619+ if (CHECK(parser->buffer, '%')) {
2620+ if (!yaml_parser_scan_uri_escapes(parser,
2621+ directive, start_mark, &string)) goto error;
2622+ }
2623+ else {
2624+ if (!READ(parser, string)) goto error;
2625+ }
2626+
2627+ length ++;
2628+ if (!CACHE(parser, 1)) goto error;
2629+ }
2630+
2631+ /* Check if the tag is non-empty. */
2632+
2633+ if (!length) {
2634+ if (!STRING_EXTEND(parser, string))
2635+ goto error;
2636+
2637+ yaml_parser_set_scanner_error(parser, directive ?
2638+ "while parsing a %TAG directive" : "while parsing a tag",
2639+ start_mark, "did not find expected tag URI");
2640+ goto error;
2641+ }
2642+
2643+ *uri = string.start;
2644+
2645+ return 1;
2646+
2647+error:
2648+ STRING_DEL(parser, string);
2649+ return 0;
2650+}
2651+
2652+/*
2653+ * Decode an URI-escape sequence corresponding to a single UTF-8 character.
2654+ */
2655+
2656+static int
2657+yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
2658+ yaml_mark_t start_mark, yaml_string_t *string)
2659+{
2660+ int width = 0;
2661+
2662+ /* Decode the required number of characters. */
2663+
2664+ do {
2665+
2666+ unsigned char octet = 0;
2667+
2668+ /* Check for a URI-escaped octet. */
2669+
2670+ if (!CACHE(parser, 3)) return 0;
2671+
2672+ if (!(CHECK(parser->buffer, '%')
2673+ && IS_HEX_AT(parser->buffer, 1)
2674+ && IS_HEX_AT(parser->buffer, 2))) {
2675+ return yaml_parser_set_scanner_error(parser, directive ?
2676+ "while parsing a %TAG directive" : "while parsing a tag",
2677+ start_mark, "did not find URI escaped octet");
2678+ }
2679+
2680+ /* Get the octet. */
2681+
2682+ octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2);
2683+
2684+ /* If it is the leading octet, determine the length of the UTF-8 sequence. */
2685+
2686+ if (!width)
2687+ {
2688+ width = (octet & 0x80) == 0x00 ? 1 :
2689+ (octet & 0xE0) == 0xC0 ? 2 :
2690+ (octet & 0xF0) == 0xE0 ? 3 :
2691+ (octet & 0xF8) == 0xF0 ? 4 : 0;
2692+ if (!width) {
2693+ return yaml_parser_set_scanner_error(parser, directive ?
2694+ "while parsing a %TAG directive" : "while parsing a tag",
2695+ start_mark, "found an incorrect leading UTF-8 octet");
2696+ }
2697+ }
2698+ else
2699+ {
2700+ /* Check if the trailing octet is correct. */
2701+
2702+ if ((octet & 0xC0) != 0x80) {
2703+ return yaml_parser_set_scanner_error(parser, directive ?
2704+ "while parsing a %TAG directive" : "while parsing a tag",
2705+ start_mark, "found an incorrect trailing UTF-8 octet");
2706+ }
2707+ }
2708+
2709+ /* Copy the octet and move the pointers. */
2710+
2711+ *(string->pointer++) = octet;
2712+ SKIP(parser);
2713+ SKIP(parser);
2714+ SKIP(parser);
2715+
2716+ } while (--width);
2717+
2718+ return 1;
2719+}
2720+
2721+/*
2722+ * Scan a block scalar.
2723+ */
2724+
2725+static int
2726+yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
2727+ int literal)
2728+{
2729+ yaml_mark_t start_mark;
2730+ yaml_mark_t end_mark;
2731+ yaml_string_t string = NULL_STRING;
2732+ yaml_string_t leading_break = NULL_STRING;
2733+ yaml_string_t trailing_breaks = NULL_STRING;
2734+ int chomping = 0;
2735+ int increment = 0;
2736+ int indent = 0;
2737+ int leading_blank = 0;
2738+ int trailing_blank = 0;
2739+
2740+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2741+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
2742+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
2743+
2744+ /* Eat the indicator '|' or '>'. */
2745+
2746+ start_mark = parser->mark;
2747+
2748+ SKIP(parser);
2749+
2750+ /* Scan the additional block scalar indicators. */
2751+
2752+ if (!CACHE(parser, 1)) goto error;
2753+
2754+ /* Check for a chomping indicator. */
2755+
2756+ if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-'))
2757+ {
2758+ /* Set the chomping method and eat the indicator. */
2759+
2760+ chomping = CHECK(parser->buffer, '+') ? +1 : -1;
2761+
2762+ SKIP(parser);
2763+
2764+ /* Check for an indentation indicator. */
2765+
2766+ if (!CACHE(parser, 1)) goto error;
2767+
2768+ if (IS_DIGIT(parser->buffer))
2769+ {
2770+ /* Check that the intendation is greater than 0. */
2771+
2772+ if (CHECK(parser->buffer, '0')) {
2773+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2774+ start_mark, "found an intendation indicator equal to 0");
2775+ goto error;
2776+ }
2777+
2778+ /* Get the intendation level and eat the indicator. */
2779+
2780+ increment = AS_DIGIT(parser->buffer);
2781+
2782+ SKIP(parser);
2783+ }
2784+ }
2785+
2786+ /* Do the same as above, but in the opposite order. */
2787+
2788+ else if (IS_DIGIT(parser->buffer))
2789+ {
2790+ if (CHECK(parser->buffer, '0')) {
2791+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2792+ start_mark, "found an intendation indicator equal to 0");
2793+ goto error;
2794+ }
2795+
2796+ increment = AS_DIGIT(parser->buffer);
2797+
2798+ SKIP(parser);
2799+
2800+ if (!CACHE(parser, 1)) goto error;
2801+
2802+ if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) {
2803+ chomping = CHECK(parser->buffer, '+') ? +1 : -1;
2804+
2805+ SKIP(parser);
2806+ }
2807+ }
2808+
2809+ /* Eat whitespaces and comments to the end of the line. */
2810+
2811+ if (!CACHE(parser, 1)) goto error;
2812+
2813+ while (IS_BLANK(parser->buffer)) {
2814+ SKIP(parser);
2815+ if (!CACHE(parser, 1)) goto error;
2816+ }
2817+
2818+ if (CHECK(parser->buffer, '#')) {
2819+ while (!IS_BREAKZ(parser->buffer)) {
2820+ SKIP(parser);
2821+ if (!CACHE(parser, 1)) goto error;
2822+ }
2823+ }
2824+
2825+ /* Check if we are at the end of the line. */
2826+
2827+ if (!IS_BREAKZ(parser->buffer)) {
2828+ yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2829+ start_mark, "did not find expected comment or line break");
2830+ goto error;
2831+ }
2832+
2833+ /* Eat a line break. */
2834+
2835+ if (IS_BREAK(parser->buffer)) {
2836+ if (!CACHE(parser, 2)) goto error;
2837+ SKIP_LINE(parser);
2838+ }
2839+
2840+ end_mark = parser->mark;
2841+
2842+ /* Set the intendation level if it was specified. */
2843+
2844+ if (increment) {
2845+ indent = parser->indent >= 0 ? parser->indent+increment : increment;
2846+ }
2847+
2848+ /* Scan the leading line breaks and determine the indentation level if needed. */
2849+
2850+ if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks,
2851+ start_mark, &end_mark)) goto error;
2852+
2853+ /* Scan the block scalar content. */
2854+
2855+ if (!CACHE(parser, 1)) goto error;
2856+
2857+ while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
2858+ {
2859+ /*
2860+ * We are at the beginning of a non-empty line.
2861+ */
2862+
2863+ /* Is it a trailing whitespace? */
2864+
2865+ trailing_blank = IS_BLANK(parser->buffer);
2866+
2867+ /* Check if we need to fold the leading line break. */
2868+
2869+ if (!literal && (*leading_break.start == '\n')
2870+ && !leading_blank && !trailing_blank)
2871+ {
2872+ /* Do we need to join the lines by space? */
2873+
2874+ if (*trailing_breaks.start == '\0') {
2875+ if (!STRING_EXTEND(parser, string)) goto error;
2876+ *(string.pointer ++) = ' ';
2877+ }
2878+
2879+ CLEAR(parser, leading_break);
2880+ }
2881+ else {
2882+ if (!JOIN(parser, string, leading_break)) goto error;
2883+ CLEAR(parser, leading_break);
2884+ }
2885+
2886+ /* Append the remaining line breaks. */
2887+
2888+ if (!JOIN(parser, string, trailing_breaks)) goto error;
2889+ CLEAR(parser, trailing_breaks);
2890+
2891+ /* Is it a leading whitespace? */
2892+
2893+ leading_blank = IS_BLANK(parser->buffer);
2894+
2895+ /* Consume the current line. */
2896+
2897+ while (!IS_BREAKZ(parser->buffer)) {
2898+ if (!READ(parser, string)) goto error;
2899+ if (!CACHE(parser, 1)) goto error;
2900+ }
2901+
2902+ /* Consume the line break. */
2903+
2904+ if (!CACHE(parser, 2)) goto error;
2905+
2906+ if (!READ_LINE(parser, leading_break)) goto error;
2907+
2908+ /* Eat the following intendation spaces and line breaks. */
2909+
2910+ if (!yaml_parser_scan_block_scalar_breaks(parser,
2911+ &indent, &trailing_breaks, start_mark, &end_mark)) goto error;
2912+ }
2913+
2914+ /* Chomp the tail. */
2915+
2916+ if (chomping != -1) {
2917+ if (!JOIN(parser, string, leading_break)) goto error;
2918+ }
2919+ if (chomping == 1) {
2920+ if (!JOIN(parser, string, trailing_breaks)) goto error;
2921+ }
2922+
2923+ /* Create a token. */
2924+
2925+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
2926+ literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
2927+ start_mark, end_mark);
2928+
2929+ STRING_DEL(parser, leading_break);
2930+ STRING_DEL(parser, trailing_breaks);
2931+
2932+ return 1;
2933+
2934+error:
2935+ STRING_DEL(parser, string);
2936+ STRING_DEL(parser, leading_break);
2937+ STRING_DEL(parser, trailing_breaks);
2938+
2939+ return 0;
2940+}
2941+
2942+/*
2943+ * Scan intendation spaces and line breaks for a block scalar. Determine the
2944+ * intendation level if needed.
2945+ */
2946+
2947+static int
2948+yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
2949+ int *indent, yaml_string_t *breaks,
2950+ yaml_mark_t start_mark, yaml_mark_t *end_mark)
2951+{
2952+ int max_indent = 0;
2953+
2954+ *end_mark = parser->mark;
2955+
2956+ /* Eat the intendation spaces and line breaks. */
2957+
2958+ while (1)
2959+ {
2960+ /* Eat the intendation spaces. */
2961+
2962+ if (!CACHE(parser, 1)) return 0;
2963+
2964+ while ((!*indent || (int)parser->mark.column < *indent)
2965+ && IS_SPACE(parser->buffer)) {
2966+ SKIP(parser);
2967+ if (!CACHE(parser, 1)) return 0;
2968+ }
2969+
2970+ if ((int)parser->mark.column > max_indent)
2971+ max_indent = (int)parser->mark.column;
2972+
2973+ /* Check for a tab character messing the intendation. */
2974+
2975+ if ((!*indent || (int)parser->mark.column < *indent)
2976+ && IS_TAB(parser->buffer)) {
2977+ return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2978+ start_mark, "found a tab character where an intendation space is expected");
2979+ }
2980+
2981+ /* Have we found a non-empty line? */
2982+
2983+ if (!IS_BREAK(parser->buffer)) break;
2984+
2985+ /* Consume the line break. */
2986+
2987+ if (!CACHE(parser, 2)) return 0;
2988+ if (!READ_LINE(parser, *breaks)) return 0;
2989+ *end_mark = parser->mark;
2990+ }
2991+
2992+ /* Determine the indentation level if needed. */
2993+
2994+ if (!*indent) {
2995+ *indent = max_indent;
2996+ if (*indent < parser->indent + 1)
2997+ *indent = parser->indent + 1;
2998+ if (*indent < 1)
2999+ *indent = 1;
3000+ }
3001+
3002+ return 1;
3003+}
3004+
3005+/*
3006+ * Scan a quoted scalar.
3007+ */
3008+
3009+static int
3010+yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
3011+ int single)
3012+{
3013+ yaml_mark_t start_mark;
3014+ yaml_mark_t end_mark;
3015+ yaml_string_t string = NULL_STRING;
3016+ yaml_string_t leading_break = NULL_STRING;
3017+ yaml_string_t trailing_breaks = NULL_STRING;
3018+ yaml_string_t whitespaces = NULL_STRING;
3019+ int leading_blanks;
3020+
3021+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
3022+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
3023+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
3024+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
3025+
3026+ /* Eat the left quote. */
3027+
3028+ start_mark = parser->mark;
3029+
3030+ SKIP(parser);
3031+
3032+ /* Consume the content of the quoted scalar. */
3033+
3034+ while (1)
3035+ {
3036+ /* Check that there are no document indicators at the beginning of the line. */
3037+
3038+ if (!CACHE(parser, 4)) goto error;
3039+
3040+ if (parser->mark.column == 0 &&
3041+ ((CHECK_AT(parser->buffer, '-', 0) &&
3042+ CHECK_AT(parser->buffer, '-', 1) &&
3043+ CHECK_AT(parser->buffer, '-', 2)) ||
3044+ (CHECK_AT(parser->buffer, '.', 0) &&
3045+ CHECK_AT(parser->buffer, '.', 1) &&
3046+ CHECK_AT(parser->buffer, '.', 2))) &&
3047+ IS_BLANKZ_AT(parser->buffer, 3))
3048+ {
3049+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
3050+ start_mark, "found unexpected document indicator");
3051+ goto error;
3052+ }
3053+
3054+ /* Check for EOF. */
3055+
3056+ if (IS_Z(parser->buffer)) {
3057+ yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
3058+ start_mark, "found unexpected end of stream");
3059+ goto error;
3060+ }
3061+
3062+ /* Consume non-blank characters. */
3063+
3064+ if (!CACHE(parser, 2)) goto error;
3065+
3066+ leading_blanks = 0;
3067+
3068+ while (!IS_BLANKZ(parser->buffer))
3069+ {
3070+ /* Check for an escaped single quote. */
3071+
3072+ if (single && CHECK_AT(parser->buffer, '\'', 0)
3073+ && CHECK_AT(parser->buffer, '\'', 1))
3074+ {
3075+ if (!STRING_EXTEND(parser, string)) goto error;
3076+ *(string.pointer++) = '\'';
3077+ SKIP(parser);
3078+ SKIP(parser);
3079+ }
3080+
3081+ /* Check for the right quote. */
3082+
3083+ else if (CHECK(parser->buffer, single ? '\'' : '"'))
3084+ {
3085+ break;
3086+ }
3087+
3088+ /* Check for an escaped line break. */
3089+
3090+ else if (!single && CHECK(parser->buffer, '\\')
3091+ && IS_BREAK_AT(parser->buffer, 1))
3092+ {
3093+ if (!CACHE(parser, 3)) goto error;
3094+ SKIP(parser);
3095+ SKIP_LINE(parser);
3096+ leading_blanks = 1;
3097+ break;
3098+ }
3099+
3100+ /* Check for an escape sequence. */
3101+
3102+ else if (!single && CHECK(parser->buffer, '\\'))
3103+ {
3104+ size_t code_length = 0;
3105+
3106+ if (!STRING_EXTEND(parser, string)) goto error;
3107+
3108+ /* Check the escape character. */
3109+
3110+ switch (parser->buffer.pointer[1])
3111+ {
3112+ case '0':
3113+ *(string.pointer++) = '\0';
3114+ break;
3115+
3116+ case 'a':
3117+ *(string.pointer++) = '\x07';
3118+ break;
3119+
3120+ case 'b':
3121+ *(string.pointer++) = '\x08';
3122+ break;
3123+
3124+ case 't':
3125+ case '\t':
3126+ *(string.pointer++) = '\x09';
3127+ break;
3128+
3129+ case 'n':
3130+ *(string.pointer++) = '\x0A';
3131+ break;
3132+
3133+ case 'v':
3134+ *(string.pointer++) = '\x0B';
3135+ break;
3136+
3137+ case 'f':
3138+ *(string.pointer++) = '\x0C';
3139+ break;
3140+
3141+ case 'r':
3142+ *(string.pointer++) = '\x0D';
3143+ break;
3144+
3145+ case 'e':
3146+ *(string.pointer++) = '\x1B';
3147+ break;
3148+
3149+ case ' ':
3150+ *(string.pointer++) = '\x20';
3151+ break;
3152+
3153+ case '"':
3154+ *(string.pointer++) = '"';
3155+ break;
3156+
3157+ case '\'':
3158+ *(string.pointer++) = '\'';
3159+ break;
3160+
3161+ case '\\':
3162+ *(string.pointer++) = '\\';
3163+ break;
3164+
3165+ case 'N': /* NEL (#x85) */
3166+ *(string.pointer++) = '\xC2';
3167+ *(string.pointer++) = '\x85';
3168+ break;
3169+
3170+ case '_': /* #xA0 */
3171+ *(string.pointer++) = '\xC2';
3172+ *(string.pointer++) = '\xA0';
3173+ break;
3174+
3175+ case 'L': /* LS (#x2028) */
3176+ *(string.pointer++) = '\xE2';
3177+ *(string.pointer++) = '\x80';
3178+ *(string.pointer++) = '\xA8';
3179+ break;
3180+
3181+ case 'P': /* PS (#x2029) */
3182+ *(string.pointer++) = '\xE2';
3183+ *(string.pointer++) = '\x80';
3184+ *(string.pointer++) = '\xA9';
3185+ break;
3186+
3187+ case 'x':
3188+ code_length = 2;
3189+ break;
3190+
3191+ case 'u':
3192+ code_length = 4;
3193+ break;
3194+
3195+ case 'U':
3196+ code_length = 8;
3197+ break;
3198+
3199+ default:
3200+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3201+ start_mark, "found unknown escape character");
3202+ goto error;
3203+ }
3204+
3205+ SKIP(parser);
3206+ SKIP(parser);
3207+
3208+ /* Consume an arbitrary escape code. */
3209+
3210+ if (code_length)
3211+ {
3212+ unsigned int value = 0;
3213+ size_t k;
3214+
3215+ /* Scan the character value. */
3216+
3217+ if (!CACHE(parser, code_length)) goto error;
3218+
3219+ for (k = 0; k < code_length; k ++) {
3220+ if (!IS_HEX_AT(parser->buffer, k)) {
3221+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3222+ start_mark, "did not find expected hexdecimal number");
3223+ goto error;
3224+ }
3225+ value = (value << 4) + AS_HEX_AT(parser->buffer, k);
3226+ }
3227+
3228+ /* Check the value and write the character. */
3229+
3230+ if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
3231+ yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3232+ start_mark, "found invalid Unicode character escape code");
3233+ goto error;
3234+ }
3235+
3236+ if (value <= 0x7F) {
3237+ *(string.pointer++) = value;
3238+ }
3239+ else if (value <= 0x7FF) {
3240+ *(string.pointer++) = 0xC0 + (value >> 6);
3241+ *(string.pointer++) = 0x80 + (value & 0x3F);
3242+ }
3243+ else if (value <= 0xFFFF) {
3244+ *(string.pointer++) = 0xE0 + (value >> 12);
3245+ *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
3246+ *(string.pointer++) = 0x80 + (value & 0x3F);
3247+ }
3248+ else {
3249+ *(string.pointer++) = 0xF0 + (value >> 18);
3250+ *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F);
3251+ *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
3252+ *(string.pointer++) = 0x80 + (value & 0x3F);
3253+ }
3254+
3255+ /* Advance the pointer. */
3256+
3257+ for (k = 0; k < code_length; k ++) {
3258+ SKIP(parser);
3259+ }
3260+ }
3261+ }
3262+
3263+ else
3264+ {
3265+ /* It is a non-escaped non-blank character. */
3266+
3267+ if (!READ(parser, string)) goto error;
3268+ }
3269+
3270+ if (!CACHE(parser, 2)) goto error;
3271+ }
3272+
3273+ /* Check if we are at the end of the scalar. */
3274+
3275+ if (CHECK(parser->buffer, single ? '\'' : '"'))
3276+ break;
3277+
3278+ /* Consume blank characters. */
3279+
3280+ if (!CACHE(parser, 1)) goto error;
3281+
3282+ while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
3283+ {
3284+ if (IS_BLANK(parser->buffer))
3285+ {
3286+ /* Consume a space or a tab character. */
3287+
3288+ if (!leading_blanks) {
3289+ if (!READ(parser, whitespaces)) goto error;
3290+ }
3291+ else {
3292+ SKIP(parser);
3293+ }
3294+ }
3295+ else
3296+ {
3297+ if (!CACHE(parser, 2)) goto error;
3298+
3299+ /* Check if it is a first line break. */
3300+
3301+ if (!leading_blanks)
3302+ {
3303+ CLEAR(parser, whitespaces);
3304+ if (!READ_LINE(parser, leading_break)) goto error;
3305+ leading_blanks = 1;
3306+ }
3307+ else
3308+ {
3309+ if (!READ_LINE(parser, trailing_breaks)) goto error;
3310+ }
3311+ }
3312+ if (!CACHE(parser, 1)) goto error;
3313+ }
3314+
3315+ /* Join the whitespaces or fold line breaks. */
3316+
3317+ if (leading_blanks)
3318+ {
3319+ /* Do we need to fold line breaks? */
3320+
3321+ if (leading_break.start[0] == '\n') {
3322+ if (trailing_breaks.start[0] == '\0') {
3323+ if (!STRING_EXTEND(parser, string)) goto error;
3324+ *(string.pointer++) = ' ';
3325+ }
3326+ else {
3327+ if (!JOIN(parser, string, trailing_breaks)) goto error;
3328+ CLEAR(parser, trailing_breaks);
3329+ }
3330+ CLEAR(parser, leading_break);
3331+ }
3332+ else {
3333+ if (!JOIN(parser, string, leading_break)) goto error;
3334+ if (!JOIN(parser, string, trailing_breaks)) goto error;
3335+ CLEAR(parser, leading_break);
3336+ CLEAR(parser, trailing_breaks);
3337+ }
3338+ }
3339+ else
3340+ {
3341+ if (!JOIN(parser, string, whitespaces)) goto error;
3342+ CLEAR(parser, whitespaces);
3343+ }
3344+ }
3345+
3346+ /* Eat the right quote. */
3347+
3348+ SKIP(parser);
3349+
3350+ end_mark = parser->mark;
3351+
3352+ /* Create a token. */
3353+
3354+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
3355+ single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
3356+ start_mark, end_mark);
3357+
3358+ STRING_DEL(parser, leading_break);
3359+ STRING_DEL(parser, trailing_breaks);
3360+ STRING_DEL(parser, whitespaces);
3361+
3362+ return 1;
3363+
3364+error:
3365+ STRING_DEL(parser, string);
3366+ STRING_DEL(parser, leading_break);
3367+ STRING_DEL(parser, trailing_breaks);
3368+ STRING_DEL(parser, whitespaces);
3369+
3370+ return 0;
3371+}
3372+
3373+/*
3374+ * Scan a plain scalar.
3375+ */
3376+
3377+static int
3378+yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
3379+{
3380+ yaml_mark_t start_mark;
3381+ yaml_mark_t end_mark;
3382+ yaml_string_t string = NULL_STRING;
3383+ yaml_string_t leading_break = NULL_STRING;
3384+ yaml_string_t trailing_breaks = NULL_STRING;
3385+ yaml_string_t whitespaces = NULL_STRING;
3386+ int leading_blanks = 0;
3387+ int indent = parser->indent+1;
3388+
3389+ if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
3390+ if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
3391+ if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
3392+ if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
3393+
3394+ start_mark = end_mark = parser->mark;
3395+
3396+ /* Consume the content of the plain scalar. */
3397+
3398+ while (1)
3399+ {
3400+ /* Check for a document indicator. */
3401+
3402+ if (!CACHE(parser, 4)) goto error;
3403+
3404+ if (parser->mark.column == 0 &&
3405+ ((CHECK_AT(parser->buffer, '-', 0) &&
3406+ CHECK_AT(parser->buffer, '-', 1) &&
3407+ CHECK_AT(parser->buffer, '-', 2)) ||
3408+ (CHECK_AT(parser->buffer, '.', 0) &&
3409+ CHECK_AT(parser->buffer, '.', 1) &&
3410+ CHECK_AT(parser->buffer, '.', 2))) &&
3411+ IS_BLANKZ_AT(parser->buffer, 3)) break;
3412+
3413+ /* Check for a comment. */
3414+
3415+ if (CHECK(parser->buffer, '#'))
3416+ break;
3417+
3418+ /* Consume non-blank characters. */
3419+
3420+ while (!IS_BLANKZ(parser->buffer))
3421+ {
3422+ /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
3423+
3424+ if (parser->flow_level
3425+ && CHECK(parser->buffer, ':')
3426+ && !IS_BLANKZ_AT(parser->buffer, 1)) {
3427+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
3428+ start_mark, "found unexpected ':'");
3429+ goto error;
3430+ }
3431+
3432+ /* Check for indicators that may end a plain scalar. */
3433+
3434+ if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
3435+ || (parser->flow_level &&
3436+ (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
3437+ || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
3438+ || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
3439+ || CHECK(parser->buffer, '}'))))
3440+ break;
3441+
3442+ /* Check if we need to join whitespaces and breaks. */
3443+
3444+ if (leading_blanks || whitespaces.start != whitespaces.pointer)
3445+ {
3446+ if (leading_blanks)
3447+ {
3448+ /* Do we need to fold line breaks? */
3449+
3450+ if (leading_break.start[0] == '\n') {
3451+ if (trailing_breaks.start[0] == '\0') {
3452+ if (!STRING_EXTEND(parser, string)) goto error;
3453+ *(string.pointer++) = ' ';
3454+ }
3455+ else {
3456+ if (!JOIN(parser, string, trailing_breaks)) goto error;
3457+ CLEAR(parser, trailing_breaks);
3458+ }
3459+ CLEAR(parser, leading_break);
3460+ }
3461+ else {
3462+ if (!JOIN(parser, string, leading_break)) goto error;
3463+ if (!JOIN(parser, string, trailing_breaks)) goto error;
3464+ CLEAR(parser, leading_break);
3465+ CLEAR(parser, trailing_breaks);
3466+ }
3467+
3468+ leading_blanks = 0;
3469+ }
3470+ else
3471+ {
3472+ if (!JOIN(parser, string, whitespaces)) goto error;
3473+ CLEAR(parser, whitespaces);
3474+ }
3475+ }
3476+
3477+ /* Copy the character. */
3478+
3479+ if (!READ(parser, string)) goto error;
3480+
3481+ end_mark = parser->mark;
3482+
3483+ if (!CACHE(parser, 2)) goto error;
3484+ }
3485+
3486+ /* Is it the end? */
3487+
3488+ if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)))
3489+ break;
3490+
3491+ /* Consume blank characters. */
3492+
3493+ if (!CACHE(parser, 1)) goto error;
3494+
3495+ while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
3496+ {
3497+ if (IS_BLANK(parser->buffer))
3498+ {
3499+ /* Check for tab character that abuse intendation. */
3500+
3501+ if (leading_blanks && (int)parser->mark.column < indent
3502+ && IS_TAB(parser->buffer)) {
3503+ yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
3504+ start_mark, "found a tab character that violate intendation");
3505+ goto error;
3506+ }
3507+
3508+ /* Consume a space or a tab character. */
3509+
3510+ if (!leading_blanks) {
3511+ if (!READ(parser, whitespaces)) goto error;
3512+ }
3513+ else {
3514+ SKIP(parser);
3515+ }
3516+ }
3517+ else
3518+ {
3519+ if (!CACHE(parser, 2)) goto error;
3520+
3521+ /* Check if it is a first line break. */
3522+
3523+ if (!leading_blanks)
3524+ {
3525+ CLEAR(parser, whitespaces);
3526+ if (!READ_LINE(parser, leading_break)) goto error;
3527+ leading_blanks = 1;
3528+ }
3529+ else
3530+ {
3531+ if (!READ_LINE(parser, trailing_breaks)) goto error;
3532+ }
3533+ }
3534+ if (!CACHE(parser, 1)) goto error;
3535+ }
3536+
3537+ /* Check intendation level. */
3538+
3539+ if (!parser->flow_level && (int)parser->mark.column < indent)
3540+ break;
3541+ }
3542+
3543+ /* Create a token. */
3544+
3545+ SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
3546+ YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
3547+
3548+ /* Note that we change the 'simple_key_allowed' flag. */
3549+
3550+ if (leading_blanks) {
3551+ parser->simple_key_allowed = 1;
3552+ }
3553+
3554+ STRING_DEL(parser, leading_break);
3555+ STRING_DEL(parser, trailing_breaks);
3556+ STRING_DEL(parser, whitespaces);
3557+
3558+ return 1;
3559+
3560+error:
3561+ STRING_DEL(parser, string);
3562+ STRING_DEL(parser, leading_break);
3563+ STRING_DEL(parser, trailing_breaks);
3564+ STRING_DEL(parser, whitespaces);
3565+
3566+ return 0;
3567+}
3568+
c/writer.cnew file+141
@@ -0,0 +1,141 @@
1+
2+#include "yaml_private.h"
3+
4+/*
5+ * Declarations.
6+ */
7+
8+static int
9+yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
10+
11+YAML_DECLARE(int)
12+yaml_emitter_flush(yaml_emitter_t *emitter);
13+
14+/*
15+ * Set the writer error and return 0.
16+ */
17+
18+static int
19+yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
20+{
21+ emitter->error = YAML_WRITER_ERROR;
22+ emitter->problem = problem;
23+
24+ return 0;
25+}
26+
27+/*
28+ * Flush the output buffer.
29+ */
30+
31+YAML_DECLARE(int)
32+yaml_emitter_flush(yaml_emitter_t *emitter)
33+{
34+ int low, high;
35+
36+ assert(emitter); /* Non-NULL emitter object is expected. */
37+ assert(emitter->write_handler); /* Write handler must be set. */
38+ assert(emitter->encoding); /* Output encoding must be set. */
39+
40+ emitter->buffer.last = emitter->buffer.pointer;
41+ emitter->buffer.pointer = emitter->buffer.start;
42+
43+ /* Check if the buffer is empty. */
44+
45+ if (emitter->buffer.start == emitter->buffer.last) {
46+ return 1;
47+ }
48+
49+ /* If the output encoding is UTF-8, we don't need to recode the buffer. */
50+
51+ if (emitter->encoding == YAML_UTF8_ENCODING)
52+ {
53+ if (emitter->write_handler(emitter->write_handler_data,
54+ emitter->buffer.start,
55+ emitter->buffer.last - emitter->buffer.start)) {
56+ emitter->buffer.last = emitter->buffer.start;
57+ emitter->buffer.pointer = emitter->buffer.start;
58+ return 1;
59+ }
60+ else {
61+ return yaml_emitter_set_writer_error(emitter, "Write error");
62+ }
63+ }
64+
65+ /* Recode the buffer into the raw buffer. */
66+
67+ low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
68+ high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
69+
70+ while (emitter->buffer.pointer != emitter->buffer.last)
71+ {
72+ unsigned char octet;
73+ unsigned int width;
74+ unsigned int value;
75+ size_t k;
76+
77+ /*
78+ * See the "reader.c" code for more details on UTF-8 encoding. Note
79+ * that we assume that the buffer contains a valid UTF-8 sequence.
80+ */
81+
82+ /* Read the next UTF-8 character. */
83+
84+ octet = emitter->buffer.pointer[0];
85+
86+ width = (octet & 0x80) == 0x00 ? 1 :
87+ (octet & 0xE0) == 0xC0 ? 2 :
88+ (octet & 0xF0) == 0xE0 ? 3 :
89+ (octet & 0xF8) == 0xF0 ? 4 : 0;
90+
91+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
92+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
93+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
94+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
95+
96+ for (k = 1; k < width; k ++) {
97+ octet = emitter->buffer.pointer[k];
98+ value = (value << 6) + (octet & 0x3F);
99+ }
100+
101+ emitter->buffer.pointer += width;
102+
103+ /* Write the character. */
104+
105+ if (value < 0x10000)
106+ {
107+ emitter->raw_buffer.last[high] = value >> 8;
108+ emitter->raw_buffer.last[low] = value & 0xFF;
109+
110+ emitter->raw_buffer.last += 2;
111+ }
112+ else
113+ {
114+ /* Write the character using a surrogate pair (check "reader.c"). */
115+
116+ value -= 0x10000;
117+ emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
118+ emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
119+ emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
120+ emitter->raw_buffer.last[low+2] = value & 0xFF;
121+
122+ emitter->raw_buffer.last += 4;
123+ }
124+ }
125+
126+ /* Write the raw buffer. */
127+
128+ if (emitter->write_handler(emitter->write_handler_data,
129+ emitter->raw_buffer.start,
130+ emitter->raw_buffer.last - emitter->raw_buffer.start)) {
131+ emitter->buffer.last = emitter->buffer.start;
132+ emitter->buffer.pointer = emitter->buffer.start;
133+ emitter->raw_buffer.last = emitter->raw_buffer.start;
134+ emitter->raw_buffer.pointer = emitter->raw_buffer.start;
135+ return 1;
136+ }
137+ else {
138+ return yaml_emitter_set_writer_error(emitter, "Write error");
139+ }
140+}
141+
c/yaml.hnew file+1971
@@ -0,0 +1,1971 @@
1+/**
2+ * @file yaml.h
3+ * @brief Public interface for libyaml.
4+ *
5+ * Include the header file with the code:
6+ * @code
7+ * #include <yaml.h>
8+ * @endcode
9+ */
10+
11+#ifndef YAML_H
12+#define YAML_H
13+
14+#ifdef __cplusplus
15+extern "C" {
16+#endif
17+
18+#include <stdlib.h>
19+#include <stdio.h>
20+#include <string.h>
21+
22+/**
23+ * @defgroup export Export Definitions
24+ * @{
25+ */
26+
27+/** The public API declaration. */
28+
29+#ifdef WIN32
30+# if defined(YAML_DECLARE_STATIC)
31+# define YAML_DECLARE(type) type
32+# elif defined(YAML_DECLARE_EXPORT)
33+# define YAML_DECLARE(type) __declspec(dllexport) type
34+# else
35+# define YAML_DECLARE(type) __declspec(dllimport) type
36+# endif
37+#else
38+# define YAML_DECLARE(type) type
39+#endif
40+
41+/** @} */
42+
43+/**
44+ * @defgroup version Version Information
45+ * @{
46+ */
47+
48+/**
49+ * Get the library version as a string.
50+ *
51+ * @returns The function returns the pointer to a static string of the form
52+ * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version
53+ * number, and @c Z is the patch version number.
54+ */
55+
56+YAML_DECLARE(const char *)
57+yaml_get_version_string(void);
58+
59+/**
60+ * Get the library version numbers.
61+ *
62+ * @param[out] major Major version number.
63+ * @param[out] minor Minor version number.
64+ * @param[out] patch Patch version number.
65+ */
66+
67+YAML_DECLARE(void)
68+yaml_get_version(int *major, int *minor, int *patch);
69+
70+/** @} */
71+
72+/**
73+ * @defgroup basic Basic Types
74+ * @{
75+ */
76+
77+/** The character type (UTF-8 octet). */
78+typedef unsigned char yaml_char_t;
79+
80+/** The version directive data. */
81+typedef struct yaml_version_directive_s {
82+ /** The major version number. */
83+ int major;
84+ /** The minor version number. */
85+ int minor;
86+} yaml_version_directive_t;
87+
88+/** The tag directive data. */
89+typedef struct yaml_tag_directive_s {
90+ /** The tag handle. */
91+ yaml_char_t *handle;
92+ /** The tag prefix. */
93+ yaml_char_t *prefix;
94+} yaml_tag_directive_t;
95+
96+/** The stream encoding. */
97+typedef enum yaml_encoding_e {
98+ /** Let the parser choose the encoding. */
99+ YAML_ANY_ENCODING,
100+ /** The default UTF-8 encoding. */
101+ YAML_UTF8_ENCODING,
102+ /** The UTF-16-LE encoding with BOM. */
103+ YAML_UTF16LE_ENCODING,
104+ /** The UTF-16-BE encoding with BOM. */
105+ YAML_UTF16BE_ENCODING
106+} yaml_encoding_t;
107+
108+/** Line break types. */
109+
110+typedef enum yaml_break_e {
111+ /** Let the parser choose the break type. */
112+ YAML_ANY_BREAK,
113+ /** Use CR for line breaks (Mac style). */
114+ YAML_CR_BREAK,
115+ /** Use LN for line breaks (Unix style). */
116+ YAML_LN_BREAK,
117+ /** Use CR LN for line breaks (DOS style). */
118+ YAML_CRLN_BREAK
119+} yaml_break_t;
120+
121+/** Many bad things could happen with the parser and emitter. */
122+typedef enum yaml_error_type_e {
123+ /** No error is produced. */
124+ YAML_NO_ERROR,
125+
126+ /** Cannot allocate or reallocate a block of memory. */
127+ YAML_MEMORY_ERROR,
128+
129+ /** Cannot read or decode the input stream. */
130+ YAML_READER_ERROR,
131+ /** Cannot scan the input stream. */
132+ YAML_SCANNER_ERROR,
133+ /** Cannot parse the input stream. */
134+ YAML_PARSER_ERROR,
135+ /** Cannot compose a YAML document. */
136+ YAML_COMPOSER_ERROR,
137+
138+ /** Cannot write to the output stream. */
139+ YAML_WRITER_ERROR,
140+ /** Cannot emit a YAML stream. */
141+ YAML_EMITTER_ERROR
142+} yaml_error_type_t;
143+
144+/** The pointer position. */
145+typedef struct yaml_mark_s {
146+ /** The position index. */
147+ size_t index;
148+
149+ /** The position line. */
150+ size_t line;
151+
152+ /** The position column. */
153+ size_t column;
154+} yaml_mark_t;
155+
156+/** @} */
157+
158+/**
159+ * @defgroup styles Node Styles
160+ * @{
161+ */
162+
163+/** Scalar styles. */
164+typedef enum yaml_scalar_style_e {
165+ /** Let the emitter choose the style. */
166+ YAML_ANY_SCALAR_STYLE,
167+
168+ /** The plain scalar style. */
169+ YAML_PLAIN_SCALAR_STYLE,
170+
171+ /** The single-quoted scalar style. */
172+ YAML_SINGLE_QUOTED_SCALAR_STYLE,
173+ /** The double-quoted scalar style. */
174+ YAML_DOUBLE_QUOTED_SCALAR_STYLE,
175+
176+ /** The literal scalar style. */
177+ YAML_LITERAL_SCALAR_STYLE,
178+ /** The folded scalar style. */
179+ YAML_FOLDED_SCALAR_STYLE
180+} yaml_scalar_style_t;
181+
182+/** Sequence styles. */
183+typedef enum yaml_sequence_style_e {
184+ /** Let the emitter choose the style. */
185+ YAML_ANY_SEQUENCE_STYLE,
186+
187+ /** The block sequence style. */
188+ YAML_BLOCK_SEQUENCE_STYLE,
189+ /** The flow sequence style. */
190+ YAML_FLOW_SEQUENCE_STYLE
191+} yaml_sequence_style_t;
192+
193+/** Mapping styles. */
194+typedef enum yaml_mapping_style_e {
195+ /** Let the emitter choose the style. */
196+ YAML_ANY_MAPPING_STYLE,
197+
198+ /** The block mapping style. */
199+ YAML_BLOCK_MAPPING_STYLE,
200+ /** The flow mapping style. */
201+ YAML_FLOW_MAPPING_STYLE
202+/* YAML_FLOW_SET_MAPPING_STYLE */
203+} yaml_mapping_style_t;
204+
205+/** @} */
206+
207+/**
208+ * @defgroup tokens Tokens
209+ * @{
210+ */
211+
212+/** Token types. */
213+typedef enum yaml_token_type_e {
214+ /** An empty token. */
215+ YAML_NO_TOKEN,
216+
217+ /** A STREAM-START token. */
218+ YAML_STREAM_START_TOKEN,
219+ /** A STREAM-END token. */
220+ YAML_STREAM_END_TOKEN,
221+
222+ /** A VERSION-DIRECTIVE token. */
223+ YAML_VERSION_DIRECTIVE_TOKEN,
224+ /** A TAG-DIRECTIVE token. */
225+ YAML_TAG_DIRECTIVE_TOKEN,
226+ /** A DOCUMENT-START token. */
227+ YAML_DOCUMENT_START_TOKEN,
228+ /** A DOCUMENT-END token. */
229+ YAML_DOCUMENT_END_TOKEN,
230+
231+ /** A BLOCK-SEQUENCE-START token. */
232+ YAML_BLOCK_SEQUENCE_START_TOKEN,
233+ /** A BLOCK-SEQUENCE-END token. */
234+ YAML_BLOCK_MAPPING_START_TOKEN,
235+ /** A BLOCK-END token. */
236+ YAML_BLOCK_END_TOKEN,
237+
238+ /** A FLOW-SEQUENCE-START token. */
239+ YAML_FLOW_SEQUENCE_START_TOKEN,
240+ /** A FLOW-SEQUENCE-END token. */
241+ YAML_FLOW_SEQUENCE_END_TOKEN,
242+ /** A FLOW-MAPPING-START token. */
243+ YAML_FLOW_MAPPING_START_TOKEN,
244+ /** A FLOW-MAPPING-END token. */
245+ YAML_FLOW_MAPPING_END_TOKEN,
246+
247+ /** A BLOCK-ENTRY token. */
248+ YAML_BLOCK_ENTRY_TOKEN,
249+ /** A FLOW-ENTRY token. */
250+ YAML_FLOW_ENTRY_TOKEN,
251+ /** A KEY token. */
252+ YAML_KEY_TOKEN,
253+ /** A VALUE token. */
254+ YAML_VALUE_TOKEN,
255+
256+ /** An ALIAS token. */
257+ YAML_ALIAS_TOKEN,
258+ /** An ANCHOR token. */
259+ YAML_ANCHOR_TOKEN,
260+ /** A TAG token. */
261+ YAML_TAG_TOKEN,
262+ /** A SCALAR token. */
263+ YAML_SCALAR_TOKEN
264+} yaml_token_type_t;
265+
266+/** The token structure. */
267+typedef struct yaml_token_s {
268+
269+ /** The token type. */
270+ yaml_token_type_t type;
271+
272+ /** The token data. */
273+ union {
274+
275+ /** The stream start (for @c YAML_STREAM_START_TOKEN). */
276+ struct {
277+ /** The stream encoding. */
278+ yaml_encoding_t encoding;
279+ } stream_start;
280+
281+ /** The alias (for @c YAML_ALIAS_TOKEN). */
282+ struct {
283+ /** The alias value. */
284+ yaml_char_t *value;
285+ } alias;
286+
287+ /** The anchor (for @c YAML_ANCHOR_TOKEN). */
288+ struct {
289+ /** The anchor value. */
290+ yaml_char_t *value;
291+ } anchor;
292+
293+ /** The tag (for @c YAML_TAG_TOKEN). */
294+ struct {
295+ /** The tag handle. */
296+ yaml_char_t *handle;
297+ /** The tag suffix. */
298+ yaml_char_t *suffix;
299+ } tag;
300+
301+ /** The scalar value (for @c YAML_SCALAR_TOKEN). */
302+ struct {
303+ /** The scalar value. */
304+ yaml_char_t *value;
305+ /** The length of the scalar value. */
306+ size_t length;
307+ /** The scalar style. */
308+ yaml_scalar_style_t style;
309+ } scalar;
310+
311+ /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */
312+ struct {
313+ /** The major version number. */
314+ int major;
315+ /** The minor version number. */
316+ int minor;
317+ } version_directive;
318+
319+ /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */
320+ struct {
321+ /** The tag handle. */
322+ yaml_char_t *handle;
323+ /** The tag prefix. */
324+ yaml_char_t *prefix;
325+ } tag_directive;
326+
327+ } data;
328+
329+ /** The beginning of the token. */
330+ yaml_mark_t start_mark;
331+ /** The end of the token. */
332+ yaml_mark_t end_mark;
333+
334+} yaml_token_t;
335+
336+/**
337+ * Free any memory allocated for a token object.
338+ *
339+ * @param[in,out] token A token object.
340+ */
341+
342+YAML_DECLARE(void)
343+yaml_token_delete(yaml_token_t *token);
344+
345+/** @} */
346+
347+/**
348+ * @defgroup events Events
349+ * @{
350+ */
351+
352+/** Event types. */
353+typedef enum yaml_event_type_e {
354+ /** An empty event. */
355+ YAML_NO_EVENT,
356+
357+ /** A STREAM-START event. */
358+ YAML_STREAM_START_EVENT,
359+ /** A STREAM-END event. */
360+ YAML_STREAM_END_EVENT,
361+
362+ /** A DOCUMENT-START event. */
363+ YAML_DOCUMENT_START_EVENT,
364+ /** A DOCUMENT-END event. */
365+ YAML_DOCUMENT_END_EVENT,
366+
367+ /** An ALIAS event. */
368+ YAML_ALIAS_EVENT,
369+ /** A SCALAR event. */
370+ YAML_SCALAR_EVENT,
371+
372+ /** A SEQUENCE-START event. */
373+ YAML_SEQUENCE_START_EVENT,
374+ /** A SEQUENCE-END event. */
375+ YAML_SEQUENCE_END_EVENT,
376+
377+ /** A MAPPING-START event. */
378+ YAML_MAPPING_START_EVENT,
379+ /** A MAPPING-END event. */
380+ YAML_MAPPING_END_EVENT
381+} yaml_event_type_t;
382+
383+/** The event structure. */
384+typedef struct yaml_event_s {
385+
386+ /** The event type. */
387+ yaml_event_type_t type;
388+
389+ /** The event data. */
390+ union {
391+
392+ /** The stream parameters (for @c YAML_STREAM_START_EVENT). */
393+ struct {
394+ /** The document encoding. */
395+ yaml_encoding_t encoding;
396+ } stream_start;
397+
398+ /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */
399+ struct {
400+ /** The version directive. */
401+ yaml_version_directive_t *version_directive;
402+
403+ /** The list of tag directives. */
404+ struct {
405+ /** The beginning of the tag directives list. */
406+ yaml_tag_directive_t *start;
407+ /** The end of the tag directives list. */
408+ yaml_tag_directive_t *end;
409+ } tag_directives;
410+
411+ /** Is the document indicator implicit? */
412+ int implicit;
413+ } document_start;
414+
415+ /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */
416+ struct {
417+ /** Is the document end indicator implicit? */
418+ int implicit;
419+ } document_end;
420+
421+ /** The alias parameters (for @c YAML_ALIAS_EVENT). */
422+ struct {
423+ /** The anchor. */
424+ yaml_char_t *anchor;
425+ } alias;
426+
427+ /** The scalar parameters (for @c YAML_SCALAR_EVENT). */
428+ struct {
429+ /** The anchor. */
430+ yaml_char_t *anchor;
431+ /** The tag. */
432+ yaml_char_t *tag;
433+ /** The scalar value. */
434+ yaml_char_t *value;
435+ /** The length of the scalar value. */
436+ size_t length;
437+ /** Is the tag optional for the plain style? */
438+ int plain_implicit;
439+ /** Is the tag optional for any non-plain style? */
440+ int quoted_implicit;
441+ /** The scalar style. */
442+ yaml_scalar_style_t style;
443+ } scalar;
444+
445+ /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */
446+ struct {
447+ /** The anchor. */
448+ yaml_char_t *anchor;
449+ /** The tag. */
450+ yaml_char_t *tag;
451+ /** Is the tag optional? */
452+ int implicit;
453+ /** The sequence style. */
454+ yaml_sequence_style_t style;
455+ } sequence_start;
456+
457+ /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */
458+ struct {
459+ /** The anchor. */
460+ yaml_char_t *anchor;
461+ /** The tag. */
462+ yaml_char_t *tag;
463+ /** Is the tag optional? */
464+ int implicit;
465+ /** The mapping style. */
466+ yaml_mapping_style_t style;
467+ } mapping_start;
468+
469+ } data;
470+
471+ /** The beginning of the event. */
472+ yaml_mark_t start_mark;
473+ /** The end of the event. */
474+ yaml_mark_t end_mark;
475+
476+} yaml_event_t;
477+
478+/**
479+ * Create the STREAM-START event.
480+ *
481+ * @param[out] event An empty event object.
482+ * @param[in] encoding The stream encoding.
483+ *
484+ * @returns @c 1 if the function succeeded, @c 0 on error.
485+ */
486+
487+YAML_DECLARE(int)
488+yaml_stream_start_event_initialize(yaml_event_t *event,
489+ yaml_encoding_t encoding);
490+
491+/**
492+ * Create the STREAM-END event.
493+ *
494+ * @param[out] event An empty event object.
495+ *
496+ * @returns @c 1 if the function succeeded, @c 0 on error.
497+ */
498+
499+YAML_DECLARE(int)
500+yaml_stream_end_event_initialize(yaml_event_t *event);
501+
502+/**
503+ * Create the DOCUMENT-START event.
504+ *
505+ * The @a implicit argument is considered as a stylistic parameter and may be
506+ * ignored by the emitter.
507+ *
508+ * @param[out] event An empty event object.
509+ * @param[in] version_directive The %YAML directive value or
510+ * @c NULL.
511+ * @param[in] tag_directives_start The beginning of the %TAG
512+ * directives list.
513+ * @param[in] tag_directives_end The end of the %TAG directives
514+ * list.
515+ * @param[in] implicit If the document start indicator is
516+ * implicit.
517+ *
518+ * @returns @c 1 if the function succeeded, @c 0 on error.
519+ */
520+
521+YAML_DECLARE(int)
522+yaml_document_start_event_initialize(yaml_event_t *event,
523+ yaml_version_directive_t *version_directive,
524+ yaml_tag_directive_t *tag_directives_start,
525+ yaml_tag_directive_t *tag_directives_end,
526+ int implicit);
527+
528+/**
529+ * Create the DOCUMENT-END event.
530+ *
531+ * The @a implicit argument is considered as a stylistic parameter and may be
532+ * ignored by the emitter.
533+ *
534+ * @param[out] event An empty event object.
535+ * @param[in] implicit If the document end indicator is implicit.
536+ *
537+ * @returns @c 1 if the function succeeded, @c 0 on error.
538+ */
539+
540+YAML_DECLARE(int)
541+yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
542+
543+/**
544+ * Create an ALIAS event.
545+ *
546+ * @param[out] event An empty event object.
547+ * @param[in] anchor The anchor value.
548+ *
549+ * @returns @c 1 if the function succeeded, @c 0 on error.
550+ */
551+
552+YAML_DECLARE(int)
553+yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
554+
555+/**
556+ * Create a SCALAR event.
557+ *
558+ * The @a style argument may be ignored by the emitter.
559+ *
560+ * Either the @a tag attribute or one of the @a plain_implicit and
561+ * @a quoted_implicit flags must be set.
562+ *
563+ * @param[out] event An empty event object.
564+ * @param[in] anchor The scalar anchor or @c NULL.
565+ * @param[in] tag The scalar tag or @c NULL.
566+ * @param[in] value The scalar value.
567+ * @param[in] length The length of the scalar value.
568+ * @param[in] plain_implicit If the tag may be omitted for the plain
569+ * style.
570+ * @param[in] quoted_implicit If the tag may be omitted for any
571+ * non-plain style.
572+ * @param[in] style The scalar style.
573+ *
574+ * @returns @c 1 if the function succeeded, @c 0 on error.
575+ */
576+
577+YAML_DECLARE(int)
578+yaml_scalar_event_initialize(yaml_event_t *event,
579+ yaml_char_t *anchor, yaml_char_t *tag,
580+ yaml_char_t *value, int length,
581+ int plain_implicit, int quoted_implicit,
582+ yaml_scalar_style_t style);
583+
584+/**
585+ * Create a SEQUENCE-START event.
586+ *
587+ * The @a style argument may be ignored by the emitter.
588+ *
589+ * Either the @a tag attribute or the @a implicit flag must be set.
590+ *
591+ * @param[out] event An empty event object.
592+ * @param[in] anchor The sequence anchor or @c NULL.
593+ * @param[in] tag The sequence tag or @c NULL.
594+ * @param[in] implicit If the tag may be omitted.
595+ * @param[in] style The sequence style.
596+ *
597+ * @returns @c 1 if the function succeeded, @c 0 on error.
598+ */
599+
600+YAML_DECLARE(int)
601+yaml_sequence_start_event_initialize(yaml_event_t *event,
602+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
603+ yaml_sequence_style_t style);
604+
605+/**
606+ * Create a SEQUENCE-END event.
607+ *
608+ * @param[out] event An empty event object.
609+ *
610+ * @returns @c 1 if the function succeeded, @c 0 on error.
611+ */
612+
613+YAML_DECLARE(int)
614+yaml_sequence_end_event_initialize(yaml_event_t *event);
615+
616+/**
617+ * Create a MAPPING-START event.
618+ *
619+ * The @a style argument may be ignored by the emitter.
620+ *
621+ * Either the @a tag attribute or the @a implicit flag must be set.
622+ *
623+ * @param[out] event An empty event object.
624+ * @param[in] anchor The mapping anchor or @c NULL.
625+ * @param[in] tag The mapping tag or @c NULL.
626+ * @param[in] implicit If the tag may be omitted.
627+ * @param[in] style The mapping style.
628+ *
629+ * @returns @c 1 if the function succeeded, @c 0 on error.
630+ */
631+
632+YAML_DECLARE(int)
633+yaml_mapping_start_event_initialize(yaml_event_t *event,
634+ yaml_char_t *anchor, yaml_char_t *tag, int implicit,
635+ yaml_mapping_style_t style);
636+
637+/**
638+ * Create a MAPPING-END event.
639+ *
640+ * @param[out] event An empty event object.
641+ *
642+ * @returns @c 1 if the function succeeded, @c 0 on error.
643+ */
644+
645+YAML_DECLARE(int)
646+yaml_mapping_end_event_initialize(yaml_event_t *event);
647+
648+/**
649+ * Free any memory allocated for an event object.
650+ *
651+ * @param[in,out] event An event object.
652+ */
653+
654+YAML_DECLARE(void)
655+yaml_event_delete(yaml_event_t *event);
656+
657+/** @} */
658+
659+/**
660+ * @defgroup nodes Nodes
661+ * @{
662+ */
663+
664+/** The tag @c !!null with the only possible value: @c null. */
665+#define YAML_NULL_TAG "tag:yaml.org,2002:null"
666+/** The tag @c !!bool with the values: @c true and @c falce. */
667+#define YAML_BOOL_TAG "tag:yaml.org,2002:bool"
668+/** The tag @c !!str for string values. */
669+#define YAML_STR_TAG "tag:yaml.org,2002:str"
670+/** The tag @c !!int for integer values. */
671+#define YAML_INT_TAG "tag:yaml.org,2002:int"
672+/** The tag @c !!float for float values. */
673+#define YAML_FLOAT_TAG "tag:yaml.org,2002:float"
674+/** The tag @c !!timestamp for date and time values. */
675+#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp"
676+
677+/** The tag @c !!seq is used to denote sequences. */
678+#define YAML_SEQ_TAG "tag:yaml.org,2002:seq"
679+/** The tag @c !!map is used to denote mapping. */
680+#define YAML_MAP_TAG "tag:yaml.org,2002:map"
681+
682+/** The default scalar tag is @c !!str. */
683+#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG
684+/** The default sequence tag is @c !!seq. */
685+#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG
686+/** The default mapping tag is @c !!map. */
687+#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG
688+
689+/** Node types. */
690+typedef enum yaml_node_type_e {
691+ /** An empty node. */
692+ YAML_NO_NODE,
693+
694+ /** A scalar node. */
695+ YAML_SCALAR_NODE,
696+ /** A sequence node. */
697+ YAML_SEQUENCE_NODE,
698+ /** A mapping node. */
699+ YAML_MAPPING_NODE
700+} yaml_node_type_t;
701+
702+/** The forward definition of a document node structure. */
703+typedef struct yaml_node_s yaml_node_t;
704+
705+/** An element of a sequence node. */
706+typedef int yaml_node_item_t;
707+
708+/** An element of a mapping node. */
709+typedef struct yaml_node_pair_s {
710+ /** The key of the element. */
711+ int key;
712+ /** The value of the element. */
713+ int value;
714+} yaml_node_pair_t;
715+
716+/** The node structure. */
717+struct yaml_node_s {
718+
719+ /** The node type. */
720+ yaml_node_type_t type;
721+
722+ /** The node tag. */
723+ yaml_char_t *tag;
724+
725+ /** The node data. */
726+ union {
727+
728+ /** The scalar parameters (for @c YAML_SCALAR_NODE). */
729+ struct {
730+ /** The scalar value. */
731+ yaml_char_t *value;
732+ /** The length of the scalar value. */
733+ size_t length;
734+ /** The scalar style. */
735+ yaml_scalar_style_t style;
736+ } scalar;
737+
738+ /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */
739+ struct {
740+ /** The stack of sequence items. */
741+ struct {
742+ /** The beginning of the stack. */
743+ yaml_node_item_t *start;
744+ /** The end of the stack. */
745+ yaml_node_item_t *end;
746+ /** The top of the stack. */
747+ yaml_node_item_t *top;
748+ } items;
749+ /** The sequence style. */
750+ yaml_sequence_style_t style;
751+ } sequence;
752+
753+ /** The mapping parameters (for @c YAML_MAPPING_NODE). */
754+ struct {
755+ /** The stack of mapping pairs (key, value). */
756+ struct {
757+ /** The beginning of the stack. */
758+ yaml_node_pair_t *start;
759+ /** The end of the stack. */
760+ yaml_node_pair_t *end;
761+ /** The top of the stack. */
762+ yaml_node_pair_t *top;
763+ } pairs;
764+ /** The mapping style. */
765+ yaml_mapping_style_t style;
766+ } mapping;
767+
768+ } data;
769+
770+ /** The beginning of the node. */
771+ yaml_mark_t start_mark;
772+ /** The end of the node. */
773+ yaml_mark_t end_mark;
774+
775+};
776+
777+/** The document structure. */
778+typedef struct yaml_document_s {
779+
780+ /** The document nodes. */
781+ struct {
782+ /** The beginning of the stack. */
783+ yaml_node_t *start;
784+ /** The end of the stack. */
785+ yaml_node_t *end;
786+ /** The top of the stack. */
787+ yaml_node_t *top;
788+ } nodes;
789+
790+ /** The version directive. */
791+ yaml_version_directive_t *version_directive;
792+
793+ /** The list of tag directives. */
794+ struct {
795+ /** The beginning of the tag directives list. */
796+ yaml_tag_directive_t *start;
797+ /** The end of the tag directives list. */
798+ yaml_tag_directive_t *end;
799+ } tag_directives;
800+
801+ /** Is the document start indicator implicit? */
802+ int start_implicit;
803+ /** Is the document end indicator implicit? */
804+ int end_implicit;
805+
806+ /** The beginning of the document. */
807+ yaml_mark_t start_mark;
808+ /** The end of the document. */
809+ yaml_mark_t end_mark;
810+
811+} yaml_document_t;
812+
813+/**
814+ * Create a YAML document.
815+ *
816+ * @param[out] document An empty document object.
817+ * @param[in] version_directive The %YAML directive value or
818+ * @c NULL.
819+ * @param[in] tag_directives_start The beginning of the %TAG
820+ * directives list.
821+ * @param[in] tag_directives_end The end of the %TAG directives
822+ * list.
823+ * @param[in] start_implicit If the document start indicator is
824+ * implicit.
825+ * @param[in] end_implicit If the document end indicator is
826+ * implicit.
827+ *
828+ * @returns @c 1 if the function succeeded, @c 0 on error.
829+ */
830+
831+YAML_DECLARE(int)
832+yaml_document_initialize(yaml_document_t *document,
833+ yaml_version_directive_t *version_directive,
834+ yaml_tag_directive_t *tag_directives_start,
835+ yaml_tag_directive_t *tag_directives_end,
836+ int start_implicit, int end_implicit);
837+
838+/**
839+ * Delete a YAML document and all its nodes.
840+ *
841+ * @param[in,out] document A document object.
842+ */
843+
844+YAML_DECLARE(void)
845+yaml_document_delete(yaml_document_t *document);
846+
847+/**
848+ * Get a node of a YAML document.
849+ *
850+ * The pointer returned by this function is valid until any of the functions
851+ * modifying the documents are called.
852+ *
853+ * @param[in] document A document object.
854+ * @param[in] index The node id.
855+ *
856+ * @returns the node objct or @c NULL if @c node_id is out of range.
857+ */
858+
859+YAML_DECLARE(yaml_node_t *)
860+yaml_document_get_node(yaml_document_t *document, int index);
861+
862+/**
863+ * Get the root of a YAML document node.
864+ *
865+ * The root object is the first object added to the document.
866+ *
867+ * The pointer returned by this function is valid until any of the functions
868+ * modifying the documents are called.
869+ *
870+ * An empty document produced by the parser signifies the end of a YAML
871+ * stream.
872+ *
873+ * @param[in] document A document object.
874+ *
875+ * @returns the node object or @c NULL if the document is empty.
876+ */
877+
878+YAML_DECLARE(yaml_node_t *)
879+yaml_document_get_root_node(yaml_document_t *document);
880+
881+/**
882+ * Create a SCALAR node and attach it to the document.
883+ *
884+ * The @a style argument may be ignored by the emitter.
885+ *
886+ * @param[in,out] document A document object.
887+ * @param[in] tag The scalar tag.
888+ * @param[in] value The scalar value.
889+ * @param[in] length The length of the scalar value.
890+ * @param[in] style The scalar style.
891+ *
892+ * @returns the node id or @c 0 on error.
893+ */
894+
895+YAML_DECLARE(int)
896+yaml_document_add_scalar(yaml_document_t *document,
897+ yaml_char_t *tag, yaml_char_t *value, int length,
898+ yaml_scalar_style_t style);
899+
900+/**
901+ * Create a SEQUENCE node and attach it to the document.
902+ *
903+ * The @a style argument may be ignored by the emitter.
904+ *
905+ * @param[in,out] document A document object.
906+ * @param[in] tag The sequence tag.
907+ * @param[in] style The sequence style.
908+ *
909+ * @returns the node id or @c 0 on error.
910+ */
911+
912+YAML_DECLARE(int)
913+yaml_document_add_sequence(yaml_document_t *document,
914+ yaml_char_t *tag, yaml_sequence_style_t style);
915+
916+/**
917+ * Create a MAPPING node and attach it to the document.
918+ *
919+ * The @a style argument may be ignored by the emitter.
920+ *
921+ * @param[in,out] document A document object.
922+ * @param[in] tag The sequence tag.
923+ * @param[in] style The sequence style.
924+ *
925+ * @returns the node id or @c 0 on error.
926+ */
927+
928+YAML_DECLARE(int)
929+yaml_document_add_mapping(yaml_document_t *document,
930+ yaml_char_t *tag, yaml_mapping_style_t style);
931+
932+/**
933+ * Add an item to a SEQUENCE node.
934+ *
935+ * @param[in,out] document A document object.
936+ * @param[in] sequence The sequence node id.
937+ * @param[in] item The item node id.
938+*
939+ * @returns @c 1 if the function succeeded, @c 0 on error.
940+ */
941+
942+YAML_DECLARE(int)
943+yaml_document_append_sequence_item(yaml_document_t *document,
944+ int sequence, int item);
945+
946+/**
947+ * Add a pair of a key and a value to a MAPPING node.
948+ *
949+ * @param[in,out] document A document object.
950+ * @param[in] mapping The mapping node id.
951+ * @param[in] key The key node id.
952+ * @param[in] value The value node id.
953+*
954+ * @returns @c 1 if the function succeeded, @c 0 on error.
955+ */
956+
957+YAML_DECLARE(int)
958+yaml_document_append_mapping_pair(yaml_document_t *document,
959+ int mapping, int key, int value);
960+
961+/** @} */
962+
963+/**
964+ * @defgroup parser Parser Definitions
965+ * @{
966+ */
967+
968+/**
969+ * The prototype of a read handler.
970+ *
971+ * The read handler is called when the parser needs to read more bytes from the
972+ * source. The handler should write not more than @a size bytes to the @a
973+ * buffer. The number of written bytes should be set to the @a length variable.
974+ *
975+ * @param[in,out] data A pointer to an application data specified by
976+ * yaml_parser_set_input().
977+ * @param[out] buffer The buffer to write the data from the source.
978+ * @param[in] size The size of the buffer.
979+ * @param[out] size_read The actual number of bytes read from the source.
980+ *
981+ * @returns On success, the handler should return @c 1. If the handler failed,
982+ * the returned value should be @c 0. On EOF, the handler should set the
983+ * @a size_read to @c 0 and return @c 1.
984+ */
985+
986+typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size,
987+ size_t *size_read);
988+
989+/**
990+ * This structure holds information about a potential simple key.
991+ */
992+
993+typedef struct yaml_simple_key_s {
994+ /** Is a simple key possible? */
995+ int possible;
996+
997+ /** Is a simple key required? */
998+ int required;
999+
1000+ /** The number of the token. */
1001+ size_t token_number;
1002+
1003+ /** The position mark. */
1004+ yaml_mark_t mark;
1005+} yaml_simple_key_t;
1006+
1007+/**
1008+ * The states of the parser.
1009+ */
1010+typedef enum yaml_parser_state_e {
1011+ /** Expect STREAM-START. */
1012+ YAML_PARSE_STREAM_START_STATE,
1013+ /** Expect the beginning of an implicit document. */
1014+ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
1015+ /** Expect DOCUMENT-START. */
1016+ YAML_PARSE_DOCUMENT_START_STATE,
1017+ /** Expect the content of a document. */
1018+ YAML_PARSE_DOCUMENT_CONTENT_STATE,
1019+ /** Expect DOCUMENT-END. */
1020+ YAML_PARSE_DOCUMENT_END_STATE,
1021+ /** Expect a block node. */
1022+ YAML_PARSE_BLOCK_NODE_STATE,
1023+ /** Expect a block node or indentless sequence. */
1024+ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE,
1025+ /** Expect a flow node. */
1026+ YAML_PARSE_FLOW_NODE_STATE,
1027+ /** Expect the first entry of a block sequence. */
1028+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
1029+ /** Expect an entry of a block sequence. */
1030+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
1031+ /** Expect an entry of an indentless sequence. */
1032+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
1033+ /** Expect the first key of a block mapping. */
1034+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE,
1035+ /** Expect a block mapping key. */
1036+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE,
1037+ /** Expect a block mapping value. */
1038+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
1039+ /** Expect the first entry of a flow sequence. */
1040+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
1041+ /** Expect an entry of a flow sequence. */
1042+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
1043+ /** Expect a key of an ordered mapping. */
1044+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE,
1045+ /** Expect a value of an ordered mapping. */
1046+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE,
1047+ /** Expect the and of an ordered mapping entry. */
1048+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE,
1049+ /** Expect the first key of a flow mapping. */
1050+ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
1051+ /** Expect a key of a flow mapping. */
1052+ YAML_PARSE_FLOW_MAPPING_KEY_STATE,
1053+ /** Expect a value of a flow mapping. */
1054+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
1055+ /** Expect an empty value of a flow mapping. */
1056+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE,
1057+ /** Expect nothing. */
1058+ YAML_PARSE_END_STATE
1059+} yaml_parser_state_t;
1060+
1061+/**
1062+ * This structure holds aliases data.
1063+ */
1064+
1065+typedef struct yaml_alias_data_s {
1066+ /** The anchor. */
1067+ yaml_char_t *anchor;
1068+ /** The node id. */
1069+ int index;
1070+ /** The anchor mark. */
1071+ yaml_mark_t mark;
1072+} yaml_alias_data_t;
1073+
1074+/**
1075+ * The parser structure.
1076+ *
1077+ * All members are internal. Manage the structure using the @c yaml_parser_
1078+ * family of functions.
1079+ */
1080+
1081+typedef struct yaml_parser_s {
1082+
1083+ /**
1084+ * @name Error handling
1085+ * @{
1086+ */
1087+
1088+ /** Error type. */
1089+ yaml_error_type_t error;
1090+ /** Error description. */
1091+ const char *problem;
1092+ /** The byte about which the problem occured. */
1093+ size_t problem_offset;
1094+ /** The problematic value (@c -1 is none). */
1095+ int problem_value;
1096+ /** The problem position. */
1097+ yaml_mark_t problem_mark;
1098+ /** The error context. */
1099+ const char *context;
1100+ /** The context position. */
1101+ yaml_mark_t context_mark;
1102+
1103+ /**
1104+ * @}
1105+ */
1106+
1107+ /**
1108+ * @name Reader stuff
1109+ * @{
1110+ */
1111+
1112+ /** Read handler. */
1113+ yaml_read_handler_t *read_handler;
1114+
1115+ /** A pointer for passing to the read handler. */
1116+ void *read_handler_data;
1117+
1118+ /** Standard (string or file) input data. */
1119+ union {
1120+ /** String input data. */
1121+ struct {
1122+ /** The string start pointer. */
1123+ const unsigned char *start;
1124+ /** The string end pointer. */
1125+ const unsigned char *end;
1126+ /** The string current position. */
1127+ const unsigned char *current;
1128+ } string;
1129+
1130+ /** File input data. */
1131+ FILE *file;
1132+ } input;
1133+
1134+ /** EOF flag */
1135+ int eof;
1136+
1137+ /** The working buffer. */
1138+ struct {
1139+ /** The beginning of the buffer. */
1140+ yaml_char_t *start;
1141+ /** The end of the buffer. */
1142+ yaml_char_t *end;
1143+ /** The current position of the buffer. */
1144+ yaml_char_t *pointer;
1145+ /** The last filled position of the buffer. */
1146+ yaml_char_t *last;
1147+ } buffer;
1148+
1149+ /* The number of unread characters in the buffer. */
1150+ size_t unread;
1151+
1152+ /** The raw buffer. */
1153+ struct {
1154+ /** The beginning of the buffer. */
1155+ unsigned char *start;
1156+ /** The end of the buffer. */
1157+ unsigned char *end;
1158+ /** The current position of the buffer. */
1159+ unsigned char *pointer;
1160+ /** The last filled position of the buffer. */
1161+ unsigned char *last;
1162+ } raw_buffer;
1163+
1164+ /** The input encoding. */
1165+ yaml_encoding_t encoding;
1166+
1167+ /** The offset of the current position (in bytes). */
1168+ size_t offset;
1169+
1170+ /** The mark of the current position. */
1171+ yaml_mark_t mark;
1172+
1173+ /**
1174+ * @}
1175+ */
1176+
1177+ /**
1178+ * @name Scanner stuff
1179+ * @{
1180+ */
1181+
1182+ /** Have we started to scan the input stream? */
1183+ int stream_start_produced;
1184+
1185+ /** Have we reached the end of the input stream? */
1186+ int stream_end_produced;
1187+
1188+ /** The number of unclosed '[' and '{' indicators. */
1189+ int flow_level;
1190+
1191+ /** The tokens queue. */
1192+ struct {
1193+ /** The beginning of the tokens queue. */
1194+ yaml_token_t *start;
1195+ /** The end of the tokens queue. */
1196+ yaml_token_t *end;
1197+ /** The head of the tokens queue. */
1198+ yaml_token_t *head;
1199+ /** The tail of the tokens queue. */
1200+ yaml_token_t *tail;
1201+ } tokens;
1202+
1203+ /** The number of tokens fetched from the queue. */
1204+ size_t tokens_parsed;
1205+
1206+ /* Does the tokens queue contain a token ready for dequeueing. */
1207+ int token_available;
1208+
1209+ /** The indentation levels stack. */
1210+ struct {
1211+ /** The beginning of the stack. */
1212+ int *start;
1213+ /** The end of the stack. */
1214+ int *end;
1215+ /** The top of the stack. */
1216+ int *top;
1217+ } indents;
1218+
1219+ /** The current indentation level. */
1220+ int indent;
1221+
1222+ /** May a simple key occur at the current position? */
1223+ int simple_key_allowed;
1224+
1225+ /** The stack of simple keys. */
1226+ struct {
1227+ /** The beginning of the stack. */
1228+ yaml_simple_key_t *start;
1229+ /** The end of the stack. */
1230+ yaml_simple_key_t *end;
1231+ /** The top of the stack. */
1232+ yaml_simple_key_t *top;
1233+ } simple_keys;
1234+
1235+ /**
1236+ * @}
1237+ */
1238+
1239+ /**
1240+ * @name Parser stuff
1241+ * @{
1242+ */
1243+
1244+ /** The parser states stack. */
1245+ struct {
1246+ /** The beginning of the stack. */
1247+ yaml_parser_state_t *start;
1248+ /** The end of the stack. */
1249+ yaml_parser_state_t *end;
1250+ /** The top of the stack. */
1251+ yaml_parser_state_t *top;
1252+ } states;
1253+
1254+ /** The current parser state. */
1255+ yaml_parser_state_t state;
1256+
1257+ /** The stack of marks. */
1258+ struct {
1259+ /** The beginning of the stack. */
1260+ yaml_mark_t *start;
1261+ /** The end of the stack. */
1262+ yaml_mark_t *end;
1263+ /** The top of the stack. */
1264+ yaml_mark_t *top;
1265+ } marks;
1266+
1267+ /** The list of TAG directives. */
1268+ struct {
1269+ /** The beginning of the list. */
1270+ yaml_tag_directive_t *start;
1271+ /** The end of the list. */
1272+ yaml_tag_directive_t *end;
1273+ /** The top of the list. */
1274+ yaml_tag_directive_t *top;
1275+ } tag_directives;
1276+
1277+ /**
1278+ * @}
1279+ */
1280+
1281+ /**
1282+ * @name Dumper stuff
1283+ * @{
1284+ */
1285+
1286+ /** The alias data. */
1287+ struct {
1288+ /** The beginning of the list. */
1289+ yaml_alias_data_t *start;
1290+ /** The end of the list. */
1291+ yaml_alias_data_t *end;
1292+ /** The top of the list. */
1293+ yaml_alias_data_t *top;
1294+ } aliases;
1295+
1296+ /** The currently parsed document. */
1297+ yaml_document_t *document;
1298+
1299+ /**
1300+ * @}
1301+ */
1302+
1303+} yaml_parser_t;
1304+
1305+/**
1306+ * Initialize a parser.
1307+ *
1308+ * This function creates a new parser object. An application is responsible
1309+ * for destroying the object using the yaml_parser_delete() function.
1310+ *
1311+ * @param[out] parser An empty parser object.
1312+ *
1313+ * @returns @c 1 if the function succeeded, @c 0 on error.
1314+ */
1315+
1316+YAML_DECLARE(int)
1317+yaml_parser_initialize(yaml_parser_t *parser);
1318+
1319+/**
1320+ * Destroy a parser.
1321+ *
1322+ * @param[in,out] parser A parser object.
1323+ */
1324+
1325+YAML_DECLARE(void)
1326+yaml_parser_delete(yaml_parser_t *parser);
1327+
1328+/**
1329+ * Set a string input.
1330+ *
1331+ * Note that the @a input pointer must be valid while the @a parser object
1332+ * exists. The application is responsible for destroing @a input after
1333+ * destroying the @a parser.
1334+ *
1335+ * @param[in,out] parser A parser object.
1336+ * @param[in] input A source data.
1337+ * @param[in] size The length of the source data in bytes.
1338+ */
1339+
1340+YAML_DECLARE(void)
1341+yaml_parser_set_input_string(yaml_parser_t *parser,
1342+ const unsigned char *input, size_t size);
1343+
1344+/**
1345+ * Set a file input.
1346+ *
1347+ * @a file should be a file object open for reading. The application is
1348+ * responsible for closing the @a file.
1349+ *
1350+ * @param[in,out] parser A parser object.
1351+ * @param[in] file An open file.
1352+ */
1353+
1354+YAML_DECLARE(void)
1355+yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file);
1356+
1357+/**
1358+ * Set a generic input handler.
1359+ *
1360+ * @param[in,out] parser A parser object.
1361+ * @param[in] handler A read handler.
1362+ * @param[in] data Any application data for passing to the read
1363+ * handler.
1364+ */
1365+
1366+YAML_DECLARE(void)
1367+yaml_parser_set_input(yaml_parser_t *parser,
1368+ yaml_read_handler_t *handler, void *data);
1369+
1370+/**
1371+ * Set the source encoding.
1372+ *
1373+ * @param[in,out] parser A parser object.
1374+ * @param[in] encoding The source encoding.
1375+ */
1376+
1377+YAML_DECLARE(void)
1378+yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
1379+
1380+/**
1381+ * Scan the input stream and produce the next token.
1382+ *
1383+ * Call the function subsequently to produce a sequence of tokens corresponding
1384+ * to the input stream. The initial token has the type
1385+ * @c YAML_STREAM_START_TOKEN while the ending token has the type
1386+ * @c YAML_STREAM_END_TOKEN.
1387+ *
1388+ * An application is responsible for freeing any buffers associated with the
1389+ * produced token object using the @c yaml_token_delete function.
1390+ *
1391+ * An application must not alternate the calls of yaml_parser_scan() with the
1392+ * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break
1393+ * the parser.
1394+ *
1395+ * @param[in,out] parser A parser object.
1396+ * @param[out] token An empty token object.
1397+ *
1398+ * @returns @c 1 if the function succeeded, @c 0 on error.
1399+ */
1400+
1401+YAML_DECLARE(int)
1402+yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
1403+
1404+/**
1405+ * Parse the input stream and produce the next parsing event.
1406+ *
1407+ * Call the function subsequently to produce a sequence of events corresponding
1408+ * to the input stream. The initial event has the type
1409+ * @c YAML_STREAM_START_EVENT while the ending event has the type
1410+ * @c YAML_STREAM_END_EVENT.
1411+ *
1412+ * An application is responsible for freeing any buffers associated with the
1413+ * produced event object using the yaml_event_delete() function.
1414+ *
1415+ * An application must not alternate the calls of yaml_parser_parse() with the
1416+ * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the
1417+ * parser.
1418+ *
1419+ * @param[in,out] parser A parser object.
1420+ * @param[out] event An empty event object.
1421+ *
1422+ * @returns @c 1 if the function succeeded, @c 0 on error.
1423+ */
1424+
1425+YAML_DECLARE(int)
1426+yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
1427+
1428+/**
1429+ * Parse the input stream and produce the next YAML document.
1430+ *
1431+ * Call this function subsequently to produce a sequence of documents
1432+ * constituting the input stream.
1433+ *
1434+ * If the produced document has no root node, it means that the document
1435+ * end has been reached.
1436+ *
1437+ * An application is responsible for freeing any data associated with the
1438+ * produced document object using the yaml_document_delete() function.
1439+ *
1440+ * An application must not alternate the calls of yaml_parser_load() with the
1441+ * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
1442+ * the parser.
1443+ *
1444+ * @param[in,out] parser A parser object.
1445+ * @param[out] document An empty document object.
1446+ *
1447+ * @return @c 1 if the function succeeded, @c 0 on error.
1448+ */
1449+
1450+YAML_DECLARE(int)
1451+yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
1452+
1453+/** @} */
1454+
1455+/**
1456+ * @defgroup emitter Emitter Definitions
1457+ * @{
1458+ */
1459+
1460+/**
1461+ * The prototype of a write handler.
1462+ *
1463+ * The write handler is called when the emitter needs to flush the accumulated
1464+ * characters to the output. The handler should write @a size bytes of the
1465+ * @a buffer to the output.
1466+ *
1467+ * @param[in,out] data A pointer to an application data specified by
1468+ * yaml_emitter_set_output().
1469+ * @param[in] buffer The buffer with bytes to be written.
1470+ * @param[in] size The size of the buffer.
1471+ *
1472+ * @returns On success, the handler should return @c 1. If the handler failed,
1473+ * the returned value should be @c 0.
1474+ */
1475+
1476+typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size);
1477+
1478+/** The emitter states. */
1479+typedef enum yaml_emitter_state_e {
1480+ /** Expect STREAM-START. */
1481+ YAML_EMIT_STREAM_START_STATE,
1482+ /** Expect the first DOCUMENT-START or STREAM-END. */
1483+ YAML_EMIT_FIRST_DOCUMENT_START_STATE,
1484+ /** Expect DOCUMENT-START or STREAM-END. */
1485+ YAML_EMIT_DOCUMENT_START_STATE,
1486+ /** Expect the content of a document. */
1487+ YAML_EMIT_DOCUMENT_CONTENT_STATE,
1488+ /** Expect DOCUMENT-END. */
1489+ YAML_EMIT_DOCUMENT_END_STATE,
1490+ /** Expect the first item of a flow sequence. */
1491+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
1492+ /** Expect an item of a flow sequence. */
1493+ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
1494+ /** Expect the first key of a flow mapping. */
1495+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
1496+ /** Expect a key of a flow mapping. */
1497+ YAML_EMIT_FLOW_MAPPING_KEY_STATE,
1498+ /** Expect a value for a simple key of a flow mapping. */
1499+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
1500+ /** Expect a value of a flow mapping. */
1501+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
1502+ /** Expect the first item of a block sequence. */
1503+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
1504+ /** Expect an item of a block sequence. */
1505+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
1506+ /** Expect the first key of a block mapping. */
1507+ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
1508+ /** Expect the key of a block mapping. */
1509+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
1510+ /** Expect a value for a simple key of a block mapping. */
1511+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
1512+ /** Expect a value of a block mapping. */
1513+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
1514+ /** Expect nothing. */
1515+ YAML_EMIT_END_STATE
1516+} yaml_emitter_state_t;
1517+
1518+/**
1519+ * The emitter structure.
1520+ *
1521+ * All members are internal. Manage the structure using the @c yaml_emitter_
1522+ * family of functions.
1523+ */
1524+
1525+typedef struct yaml_emitter_s {
1526+
1527+ /**
1528+ * @name Error handling
1529+ * @{
1530+ */
1531+
1532+ /** Error type. */
1533+ yaml_error_type_t error;
1534+ /** Error description. */
1535+ const char *problem;
1536+
1537+ /**
1538+ * @}
1539+ */
1540+
1541+ /**
1542+ * @name Writer stuff
1543+ * @{
1544+ */
1545+
1546+ /** Write handler. */
1547+ yaml_write_handler_t *write_handler;
1548+
1549+ /** A pointer for passing to the white handler. */
1550+ void *write_handler_data;
1551+
1552+ /** Standard (string or file) output data. */
1553+ union {
1554+ /** String output data. */
1555+ struct {
1556+ /** The buffer pointer. */
1557+ unsigned char *buffer;
1558+ /** The buffer size. */
1559+ size_t size;
1560+ /** The number of written bytes. */
1561+ size_t *size_written;
1562+ } string;
1563+
1564+ /** File output data. */
1565+ FILE *file;
1566+ } output;
1567+
1568+ /** The working buffer. */
1569+ struct {
1570+ /** The beginning of the buffer. */
1571+ yaml_char_t *start;
1572+ /** The end of the buffer. */
1573+ yaml_char_t *end;
1574+ /** The current position of the buffer. */
1575+ yaml_char_t *pointer;
1576+ /** The last filled position of the buffer. */
1577+ yaml_char_t *last;
1578+ } buffer;
1579+
1580+ /** The raw buffer. */
1581+ struct {
1582+ /** The beginning of the buffer. */
1583+ unsigned char *start;
1584+ /** The end of the buffer. */
1585+ unsigned char *end;
1586+ /** The current position of the buffer. */
1587+ unsigned char *pointer;
1588+ /** The last filled position of the buffer. */
1589+ unsigned char *last;
1590+ } raw_buffer;
1591+
1592+ /** The stream encoding. */
1593+ yaml_encoding_t encoding;
1594+
1595+ /**
1596+ * @}
1597+ */
1598+
1599+ /**
1600+ * @name Emitter stuff
1601+ * @{
1602+ */
1603+
1604+ /** If the output is in the canonical style? */
1605+ int canonical;
1606+ /** The number of indentation spaces. */
1607+ int best_indent;
1608+ /** The preferred width of the output lines. */
1609+ int best_width;
1610+ /** Allow unescaped non-ASCII characters? */
1611+ int unicode;
1612+ /** The preferred line break. */
1613+ yaml_break_t line_break;
1614+
1615+ /** The stack of states. */
1616+ struct {
1617+ /** The beginning of the stack. */
1618+ yaml_emitter_state_t *start;
1619+ /** The end of the stack. */
1620+ yaml_emitter_state_t *end;
1621+ /** The top of the stack. */
1622+ yaml_emitter_state_t *top;
1623+ } states;
1624+
1625+ /** The current emitter state. */
1626+ yaml_emitter_state_t state;
1627+
1628+ /** The event queue. */
1629+ struct {
1630+ /** The beginning of the event queue. */
1631+ yaml_event_t *start;
1632+ /** The end of the event queue. */
1633+ yaml_event_t *end;
1634+ /** The head of the event queue. */
1635+ yaml_event_t *head;
1636+ /** The tail of the event queue. */
1637+ yaml_event_t *tail;
1638+ } events;
1639+
1640+ /** The stack of indentation levels. */
1641+ struct {
1642+ /** The beginning of the stack. */
1643+ int *start;
1644+ /** The end of the stack. */
1645+ int *end;
1646+ /** The top of the stack. */
1647+ int *top;
1648+ } indents;
1649+
1650+ /** The list of tag directives. */
1651+ struct {
1652+ /** The beginning of the list. */
1653+ yaml_tag_directive_t *start;
1654+ /** The end of the list. */
1655+ yaml_tag_directive_t *end;
1656+ /** The top of the list. */
1657+ yaml_tag_directive_t *top;
1658+ } tag_directives;
1659+
1660+ /** The current indentation level. */
1661+ int indent;
1662+
1663+ /** The current flow level. */
1664+ int flow_level;
1665+
1666+ /** Is it the document root context? */
1667+ int root_context;
1668+ /** Is it a sequence context? */
1669+ int sequence_context;
1670+ /** Is it a mapping context? */
1671+ int mapping_context;
1672+ /** Is it a simple mapping key context? */
1673+ int simple_key_context;
1674+
1675+ /** The current line. */
1676+ int line;
1677+ /** The current column. */
1678+ int column;
1679+ /** If the last character was a whitespace? */
1680+ int whitespace;
1681+ /** If the last character was an indentation character (' ', '-', '?', ':')? */
1682+ int indention;
1683+ /** If an explicit document end is required? */
1684+ int open_ended;
1685+
1686+ /** Anchor analysis. */
1687+ struct {
1688+ /** The anchor value. */
1689+ yaml_char_t *anchor;
1690+ /** The anchor length. */
1691+ size_t anchor_length;
1692+ /** Is it an alias? */
1693+ int alias;
1694+ } anchor_data;
1695+
1696+ /** Tag analysis. */
1697+ struct {
1698+ /** The tag handle. */
1699+ yaml_char_t *handle;
1700+ /** The tag handle length. */
1701+ size_t handle_length;
1702+ /** The tag suffix. */
1703+ yaml_char_t *suffix;
1704+ /** The tag suffix length. */
1705+ size_t suffix_length;
1706+ } tag_data;
1707+
1708+ /** Scalar analysis. */
1709+ struct {
1710+ /** The scalar value. */
1711+ yaml_char_t *value;
1712+ /** The scalar length. */
1713+ size_t length;
1714+ /** Does the scalar contain line breaks? */
1715+ int multiline;
1716+ /** Can the scalar be expessed in the flow plain style? */
1717+ int flow_plain_allowed;
1718+ /** Can the scalar be expressed in the block plain style? */
1719+ int block_plain_allowed;
1720+ /** Can the scalar be expressed in the single quoted style? */
1721+ int single_quoted_allowed;
1722+ /** Can the scalar be expressed in the literal or folded styles? */
1723+ int block_allowed;
1724+ /** The output style. */
1725+ yaml_scalar_style_t style;
1726+ } scalar_data;
1727+
1728+ /**
1729+ * @}
1730+ */
1731+
1732+ /**
1733+ * @name Dumper stuff
1734+ * @{
1735+ */
1736+
1737+ /** If the stream was already opened? */
1738+ int opened;
1739+ /** If the stream was already closed? */
1740+ int closed;
1741+
1742+ /** The information associated with the document nodes. */
1743+ struct {
1744+ /** The number of references. */
1745+ int references;
1746+ /** The anchor id. */
1747+ int anchor;
1748+ /** If the node has been emitted? */
1749+ int serialized;
1750+ } *anchors;
1751+
1752+ /** The last assigned anchor id. */
1753+ int last_anchor_id;
1754+
1755+ /** The currently emitted document. */
1756+ yaml_document_t *document;
1757+
1758+ /**
1759+ * @}
1760+ */
1761+
1762+} yaml_emitter_t;
1763+
1764+/**
1765+ * Initialize an emitter.
1766+ *
1767+ * This function creates a new emitter object. An application is responsible
1768+ * for destroying the object using the yaml_emitter_delete() function.
1769+ *
1770+ * @param[out] emitter An empty parser object.
1771+ *
1772+ * @returns @c 1 if the function succeeded, @c 0 on error.
1773+ */
1774+
1775+YAML_DECLARE(int)
1776+yaml_emitter_initialize(yaml_emitter_t *emitter);
1777+
1778+/**
1779+ * Destroy an emitter.
1780+ *
1781+ * @param[in,out] emitter An emitter object.
1782+ */
1783+
1784+YAML_DECLARE(void)
1785+yaml_emitter_delete(yaml_emitter_t *emitter);
1786+
1787+/**
1788+ * Set a string output.
1789+ *
1790+ * The emitter will write the output characters to the @a output buffer of the
1791+ * size @a size. The emitter will set @a size_written to the number of written
1792+ * bytes. If the buffer is smaller than required, the emitter produces the
1793+ * YAML_WRITE_ERROR error.
1794+ *
1795+ * @param[in,out] emitter An emitter object.
1796+ * @param[in] output An output buffer.
1797+ * @param[in] size The buffer size.
1798+ * @param[in] size_written The pointer to save the number of written
1799+ * bytes.
1800+ */
1801+
1802+YAML_DECLARE(void)
1803+yaml_emitter_set_output_string(yaml_emitter_t *emitter,
1804+ unsigned char *output, size_t size, size_t *size_written);
1805+
1806+/**
1807+ * Set a file output.
1808+ *
1809+ * @a file should be a file object open for writing. The application is
1810+ * responsible for closing the @a file.
1811+ *
1812+ * @param[in,out] emitter An emitter object.
1813+ * @param[in] file An open file.
1814+ */
1815+
1816+YAML_DECLARE(void)
1817+yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
1818+
1819+/**
1820+ * Set a generic output handler.
1821+ *
1822+ * @param[in,out] emitter An emitter object.
1823+ * @param[in] handler A write handler.
1824+ * @param[in] data Any application data for passing to the write
1825+ * handler.
1826+ */
1827+
1828+YAML_DECLARE(void)
1829+yaml_emitter_set_output(yaml_emitter_t *emitter,
1830+ yaml_write_handler_t *handler, void *data);
1831+
1832+/**
1833+ * Set the output encoding.
1834+ *
1835+ * @param[in,out] emitter An emitter object.
1836+ * @param[in] encoding The output encoding.
1837+ */
1838+
1839+YAML_DECLARE(void)
1840+yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
1841+
1842+/**
1843+ * Set if the output should be in the "canonical" format as in the YAML
1844+ * specification.
1845+ *
1846+ * @param[in,out] emitter An emitter object.
1847+ * @param[in] canonical If the output is canonical.
1848+ */
1849+
1850+YAML_DECLARE(void)
1851+yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
1852+
1853+/**
1854+ * Set the intendation increment.
1855+ *
1856+ * @param[in,out] emitter An emitter object.
1857+ * @param[in] indent The indentation increment (1 < . < 10).
1858+ */
1859+
1860+YAML_DECLARE(void)
1861+yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
1862+
1863+/**
1864+ * Set the preferred line width. @c -1 means unlimited.
1865+ *
1866+ * @param[in,out] emitter An emitter object.
1867+ * @param[in] width The preferred line width.
1868+ */
1869+
1870+YAML_DECLARE(void)
1871+yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
1872+
1873+/**
1874+ * Set if unescaped non-ASCII characters are allowed.
1875+ *
1876+ * @param[in,out] emitter An emitter object.
1877+ * @param[in] unicode If unescaped Unicode characters are allowed.
1878+ */
1879+
1880+YAML_DECLARE(void)
1881+yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
1882+
1883+/**
1884+ * Set the preferred line break.
1885+ *
1886+ * @param[in,out] emitter An emitter object.
1887+ * @param[in] line_break The preferred line break.
1888+ */
1889+
1890+YAML_DECLARE(void)
1891+yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
1892+
1893+/**
1894+ * Emit an event.
1895+ *
1896+ * The event object may be generated using the yaml_parser_parse() function.
1897+ * The emitter takes the responsibility for the event object and destroys its
1898+ * content after it is emitted. The event object is destroyed even if the
1899+ * function fails.
1900+ *
1901+ * @param[in,out] emitter An emitter object.
1902+ * @param[in,out] event An event object.
1903+ *
1904+ * @returns @c 1 if the function succeeded, @c 0 on error.
1905+ */
1906+
1907+YAML_DECLARE(int)
1908+yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
1909+
1910+/**
1911+ * Start a YAML stream.
1912+ *
1913+ * This function should be used before yaml_emitter_dump() is called.
1914+ *
1915+ * @param[in,out] emitter An emitter object.
1916+ *
1917+ * @returns @c 1 if the function succeeded, @c 0 on error.
1918+ */
1919+
1920+YAML_DECLARE(int)
1921+yaml_emitter_open(yaml_emitter_t *emitter);
1922+
1923+/**
1924+ * Finish a YAML stream.
1925+ *
1926+ * This function should be used after yaml_emitter_dump() is called.
1927+ *
1928+ * @param[in,out] emitter An emitter object.
1929+ *
1930+ * @returns @c 1 if the function succeeded, @c 0 on error.
1931+ */
1932+
1933+YAML_DECLARE(int)
1934+yaml_emitter_close(yaml_emitter_t *emitter);
1935+
1936+/**
1937+ * Emit a YAML document.
1938+ *
1939+ * The documen object may be generated using the yaml_parser_load() function
1940+ * or the yaml_document_initialize() function. The emitter takes the
1941+ * responsibility for the document object and destoys its content after
1942+ * it is emitted. The document object is destroyedeven if the function fails.
1943+ *
1944+ * @param[in,out] emitter An emitter object.
1945+ * @param[in,out] document A document object.
1946+ *
1947+ * @returns @c 1 if the function succeeded, @c 0 on error.
1948+ */
1949+
1950+YAML_DECLARE(int)
1951+yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
1952+
1953+/**
1954+ * Flush the accumulated characters to the output.
1955+ *
1956+ * @param[in,out] emitter An emitter object.
1957+ *
1958+ * @returns @c 1 if the function succeeded, @c 0 on error.
1959+ */
1960+
1961+YAML_DECLARE(int)
1962+yaml_emitter_flush(yaml_emitter_t *emitter);
1963+
1964+/** @} */
1965+
1966+#ifdef __cplusplus
1967+}
1968+#endif
1969+
1970+#endif /* #ifndef YAML_H */
1971+
c/yaml_private.hnew file+639
@@ -0,0 +1,639 @@
1+
2+#if HAVE_CONFIG_H
3+#include <config.h>
4+#endif
5+
6+#include <yaml.h>
7+
8+#include <assert.h>
9+#include <limits.h>
10+
11+/*
12+ * Memory management.
13+ */
14+
15+YAML_DECLARE(void *)
16+yaml_malloc(size_t size);
17+
18+YAML_DECLARE(void *)
19+yaml_realloc(void *ptr, size_t size);
20+
21+YAML_DECLARE(void)
22+yaml_free(void *ptr);
23+
24+YAML_DECLARE(yaml_char_t *)
25+yaml_strdup(const yaml_char_t *);
26+
27+/*
28+ * Reader: Ensure that the buffer contains at least `length` characters.
29+ */
30+
31+YAML_DECLARE(int)
32+yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
33+
34+/*
35+ * Scanner: Ensure that the token stack contains at least one token ready.
36+ */
37+
38+YAML_DECLARE(int)
39+yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
40+
41+/*
42+ * The size of the input raw buffer.
43+ */
44+
45+#define INPUT_RAW_BUFFER_SIZE 16384
46+
47+/*
48+ * The size of the input buffer.
49+ *
50+ * It should be possible to decode the whole raw buffer.
51+ */
52+
53+#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
54+
55+/*
56+ * The size of the output buffer.
57+ */
58+
59+#define OUTPUT_BUFFER_SIZE 16384
60+
61+/*
62+ * The size of the output raw buffer.
63+ *
64+ * It should be possible to encode the whole output buffer.
65+ */
66+
67+#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
68+
69+/*
70+ * The size of other stacks and queues.
71+ */
72+
73+#define INITIAL_STACK_SIZE 16
74+#define INITIAL_QUEUE_SIZE 16
75+#define INITIAL_STRING_SIZE 16
76+
77+/*
78+ * Buffer management.
79+ */
80+
81+#define BUFFER_INIT(context,buffer,size) \
82+ (((buffer).start = yaml_malloc(size)) ? \
83+ ((buffer).last = (buffer).pointer = (buffer).start, \
84+ (buffer).end = (buffer).start+(size), \
85+ 1) : \
86+ ((context)->error = YAML_MEMORY_ERROR, \
87+ 0))
88+
89+#define BUFFER_DEL(context,buffer) \
90+ (yaml_free((buffer).start), \
91+ (buffer).start = (buffer).pointer = (buffer).end = 0)
92+
93+/*
94+ * String management.
95+ */
96+
97+typedef struct {
98+ yaml_char_t *start;
99+ yaml_char_t *end;
100+ yaml_char_t *pointer;
101+} yaml_string_t;
102+
103+YAML_DECLARE(int)
104+yaml_string_extend(yaml_char_t **start,
105+ yaml_char_t **pointer, yaml_char_t **end);
106+
107+YAML_DECLARE(int)
108+yaml_string_join(
109+ yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
110+ yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
111+
112+#define NULL_STRING { NULL, NULL, NULL }
113+
114+#define STRING(string,length) { (string), (string)+(length), (string) }
115+
116+#define STRING_INIT(context,string,size) \
117+ (((string).start = yaml_malloc(size)) ? \
118+ ((string).pointer = (string).start, \
119+ (string).end = (string).start+(size), \
120+ memset((string).start, 0, (size)), \
121+ 1) : \
122+ ((context)->error = YAML_MEMORY_ERROR, \
123+ 0))
124+
125+#define STRING_DEL(context,string) \
126+ (yaml_free((string).start), \
127+ (string).start = (string).pointer = (string).end = 0)
128+
129+#define STRING_EXTEND(context,string) \
130+ (((string).pointer+5 < (string).end) \
131+ || yaml_string_extend(&(string).start, \
132+ &(string).pointer, &(string).end))
133+
134+#define CLEAR(context,string) \
135+ ((string).pointer = (string).start, \
136+ memset((string).start, 0, (string).end-(string).start))
137+
138+#define JOIN(context,string_a,string_b) \
139+ ((yaml_string_join(&(string_a).start, &(string_a).pointer, \
140+ &(string_a).end, &(string_b).start, \
141+ &(string_b).pointer, &(string_b).end)) ? \
142+ ((string_b).pointer = (string_b).start, \
143+ 1) : \
144+ ((context)->error = YAML_MEMORY_ERROR, \
145+ 0))
146+
147+/*
148+ * String check operations.
149+ */
150+
151+/*
152+ * Check the octet at the specified position.
153+ */
154+
155+#define CHECK_AT(string,octet,offset) \
156+ ((string).pointer[offset] == (yaml_char_t)(octet))
157+
158+/*
159+ * Check the current octet in the buffer.
160+ */
161+
162+#define CHECK(string,octet) CHECK_AT((string),(octet),0)
163+
164+/*
165+ * Check if the character at the specified position is an alphabetical
166+ * character, a digit, '_', or '-'.
167+ */
168+
169+#define IS_ALPHA_AT(string,offset) \
170+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
171+ (string).pointer[offset] <= (yaml_char_t) '9') || \
172+ ((string).pointer[offset] >= (yaml_char_t) 'A' && \
173+ (string).pointer[offset] <= (yaml_char_t) 'Z') || \
174+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
175+ (string).pointer[offset] <= (yaml_char_t) 'z') || \
176+ (string).pointer[offset] == '_' || \
177+ (string).pointer[offset] == '-')
178+
179+#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
180+
181+/*
182+ * Check if the character at the specified position is a digit.
183+ */
184+
185+#define IS_DIGIT_AT(string,offset) \
186+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
187+ (string).pointer[offset] <= (yaml_char_t) '9'))
188+
189+#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
190+
191+/*
192+ * Get the value of a digit.
193+ */
194+
195+#define AS_DIGIT_AT(string,offset) \
196+ ((string).pointer[offset] - (yaml_char_t) '0')
197+
198+#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
199+
200+/*
201+ * Check if the character at the specified position is a hex-digit.
202+ */
203+
204+#define IS_HEX_AT(string,offset) \
205+ (((string).pointer[offset] >= (yaml_char_t) '0' && \
206+ (string).pointer[offset] <= (yaml_char_t) '9') || \
207+ ((string).pointer[offset] >= (yaml_char_t) 'A' && \
208+ (string).pointer[offset] <= (yaml_char_t) 'F') || \
209+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
210+ (string).pointer[offset] <= (yaml_char_t) 'f'))
211+
212+#define IS_HEX(string) IS_HEX_AT((string),0)
213+
214+/*
215+ * Get the value of a hex-digit.
216+ */
217+
218+#define AS_HEX_AT(string,offset) \
219+ (((string).pointer[offset] >= (yaml_char_t) 'A' && \
220+ (string).pointer[offset] <= (yaml_char_t) 'F') ? \
221+ ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
222+ ((string).pointer[offset] >= (yaml_char_t) 'a' && \
223+ (string).pointer[offset] <= (yaml_char_t) 'f') ? \
224+ ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
225+ ((string).pointer[offset] - (yaml_char_t) '0'))
226+
227+#define AS_HEX(string) AS_HEX_AT((string),0)
228+
229+/*
230+ * Check if the character is ASCII.
231+ */
232+
233+#define IS_ASCII_AT(string,offset) \
234+ ((string).pointer[offset] <= (yaml_char_t) '\x7F')
235+
236+#define IS_ASCII(string) IS_ASCII_AT((string),0)
237+
238+/*
239+ * Check if the character can be printed unescaped.
240+ */
241+
242+#define IS_PRINTABLE_AT(string,offset) \
243+ (((string).pointer[offset] == 0x0A) /* . == #x0A */ \
244+ || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
245+ && (string).pointer[offset] <= 0x7E) \
246+ || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
247+ && (string).pointer[offset+1] >= 0xA0) \
248+ || ((string).pointer[offset] > 0xC2 \
249+ && (string).pointer[offset] < 0xED) \
250+ || ((string).pointer[offset] == 0xED \
251+ && (string).pointer[offset+1] < 0xA0) \
252+ || ((string).pointer[offset] == 0xEE) \
253+ || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
254+ && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
255+ && (string).pointer[offset+2] == 0xBF) \
256+ && !((string).pointer[offset+1] == 0xBF \
257+ && ((string).pointer[offset+2] == 0xBE \
258+ || (string).pointer[offset+2] == 0xBF))))
259+
260+#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
261+
262+/*
263+ * Check if the character at the specified position is NUL.
264+ */
265+
266+#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset))
267+
268+#define IS_Z(string) IS_Z_AT((string),0)
269+
270+/*
271+ * Check if the character at the specified position is BOM.
272+ */
273+
274+#define IS_BOM_AT(string,offset) \
275+ (CHECK_AT((string),'\xEF',(offset)) \
276+ && CHECK_AT((string),'\xBB',(offset)+1) \
277+ && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */
278+
279+#define IS_BOM(string) IS_BOM_AT(string,0)
280+
281+/*
282+ * Check if the character at the specified position is space.
283+ */
284+
285+#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset))
286+
287+#define IS_SPACE(string) IS_SPACE_AT((string),0)
288+
289+/*
290+ * Check if the character at the specified position is tab.
291+ */
292+
293+#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset))
294+
295+#define IS_TAB(string) IS_TAB_AT((string),0)
296+
297+/*
298+ * Check if the character at the specified position is blank (space or tab).
299+ */
300+
301+#define IS_BLANK_AT(string,offset) \
302+ (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset)))
303+
304+#define IS_BLANK(string) IS_BLANK_AT((string),0)
305+
306+/*
307+ * Check if the character at the specified position is a line break.
308+ */
309+
310+#define IS_BREAK_AT(string,offset) \
311+ (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \
312+ || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \
313+ || (CHECK_AT((string),'\xC2',(offset)) \
314+ && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \
315+ || (CHECK_AT((string),'\xE2',(offset)) \
316+ && CHECK_AT((string),'\x80',(offset)+1) \
317+ && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \
318+ || (CHECK_AT((string),'\xE2',(offset)) \
319+ && CHECK_AT((string),'\x80',(offset)+1) \
320+ && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */
321+
322+#define IS_BREAK(string) IS_BREAK_AT((string),0)
323+
324+#define IS_CRLF_AT(string,offset) \
325+ (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1))
326+
327+#define IS_CRLF(string) IS_CRLF_AT((string),0)
328+
329+/*
330+ * Check if the character is a line break or NUL.
331+ */
332+
333+#define IS_BREAKZ_AT(string,offset) \
334+ (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset)))
335+
336+#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0)
337+
338+/*
339+ * Check if the character is a line break, space, or NUL.
340+ */
341+
342+#define IS_SPACEZ_AT(string,offset) \
343+ (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
344+
345+#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0)
346+
347+/*
348+ * Check if the character is a line break, space, tab, or NUL.
349+ */
350+
351+#define IS_BLANKZ_AT(string,offset) \
352+ (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
353+
354+#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0)
355+
356+/*
357+ * Determine the width of the character.
358+ */
359+
360+#define WIDTH_AT(string,offset) \
361+ (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
362+ ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
363+ ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
364+ ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
365+
366+#define WIDTH(string) WIDTH_AT((string),0)
367+
368+/*
369+ * Move the string pointer to the next character.
370+ */
371+
372+#define MOVE(string) ((string).pointer += WIDTH((string)))
373+
374+/*
375+ * Copy a character and move the pointers of both strings.
376+ */
377+
378+#define COPY(string_a,string_b) \
379+ ((*(string_b).pointer & 0x80) == 0x00 ? \
380+ (*((string_a).pointer++) = *((string_b).pointer++)) : \
381+ (*(string_b).pointer & 0xE0) == 0xC0 ? \
382+ (*((string_a).pointer++) = *((string_b).pointer++), \
383+ *((string_a).pointer++) = *((string_b).pointer++)) : \
384+ (*(string_b).pointer & 0xF0) == 0xE0 ? \
385+ (*((string_a).pointer++) = *((string_b).pointer++), \
386+ *((string_a).pointer++) = *((string_b).pointer++), \
387+ *((string_a).pointer++) = *((string_b).pointer++)) : \
388+ (*(string_b).pointer & 0xF8) == 0xF0 ? \
389+ (*((string_a).pointer++) = *((string_b).pointer++), \
390+ *((string_a).pointer++) = *((string_b).pointer++), \
391+ *((string_a).pointer++) = *((string_b).pointer++), \
392+ *((string_a).pointer++) = *((string_b).pointer++)) : 0)
393+
394+/*
395+ * Stack and queue management.
396+ */
397+
398+YAML_DECLARE(int)
399+yaml_stack_extend(void **start, void **top, void **end);
400+
401+YAML_DECLARE(int)
402+yaml_queue_extend(void **start, void **head, void **tail, void **end);
403+
404+#define STACK_INIT(context,stack,size) \
405+ (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
406+ ((stack).top = (stack).start, \
407+ (stack).end = (stack).start+(size), \
408+ 1) : \
409+ ((context)->error = YAML_MEMORY_ERROR, \
410+ 0))
411+
412+#define STACK_DEL(context,stack) \
413+ (yaml_free((stack).start), \
414+ (stack).start = (stack).top = (stack).end = 0)
415+
416+#define STACK_EMPTY(context,stack) \
417+ ((stack).start == (stack).top)
418+
419+#define PUSH(context,stack,value) \
420+ (((stack).top != (stack).end \
421+ || yaml_stack_extend((void **)&(stack).start, \
422+ (void **)&(stack).top, (void **)&(stack).end)) ? \
423+ (*((stack).top++) = value, \
424+ 1) : \
425+ ((context)->error = YAML_MEMORY_ERROR, \
426+ 0))
427+
428+#define POP(context,stack) \
429+ (*(--(stack).top))
430+
431+#define QUEUE_INIT(context,queue,size) \
432+ (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
433+ ((queue).head = (queue).tail = (queue).start, \
434+ (queue).end = (queue).start+(size), \
435+ 1) : \
436+ ((context)->error = YAML_MEMORY_ERROR, \
437+ 0))
438+
439+#define QUEUE_DEL(context,queue) \
440+ (yaml_free((queue).start), \
441+ (queue).start = (queue).head = (queue).tail = (queue).end = 0)
442+
443+#define QUEUE_EMPTY(context,queue) \
444+ ((queue).head == (queue).tail)
445+
446+#define ENQUEUE(context,queue,value) \
447+ (((queue).tail != (queue).end \
448+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
449+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
450+ (*((queue).tail++) = value, \
451+ 1) : \
452+ ((context)->error = YAML_MEMORY_ERROR, \
453+ 0))
454+
455+#define DEQUEUE(context,queue) \
456+ (*((queue).head++))
457+
458+#define QUEUE_INSERT(context,queue,index,value) \
459+ (((queue).tail != (queue).end \
460+ || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
461+ (void **)&(queue).tail, (void **)&(queue).end)) ? \
462+ (memmove((queue).head+(index)+1,(queue).head+(index), \
463+ ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
464+ *((queue).head+(index)) = value, \
465+ (queue).tail++, \
466+ 1) : \
467+ ((context)->error = YAML_MEMORY_ERROR, \
468+ 0))
469+
470+/*
471+ * Token initializers.
472+ */
473+
474+#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
475+ (memset(&(token), 0, sizeof(yaml_token_t)), \
476+ (token).type = (token_type), \
477+ (token).start_mark = (token_start_mark), \
478+ (token).end_mark = (token_end_mark))
479+
480+#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
481+ (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
482+ (token).data.stream_start.encoding = (token_encoding))
483+
484+#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
485+ (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
486+
487+#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
488+ (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
489+ (token).data.alias.value = (token_value))
490+
491+#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
492+ (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
493+ (token).data.anchor.value = (token_value))
494+
495+#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
496+ (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
497+ (token).data.tag.handle = (token_handle), \
498+ (token).data.tag.suffix = (token_suffix))
499+
500+#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
501+ (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
502+ (token).data.scalar.value = (token_value), \
503+ (token).data.scalar.length = (token_length), \
504+ (token).data.scalar.style = (token_style))
505+
506+#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
507+ (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
508+ (token).data.version_directive.major = (token_major), \
509+ (token).data.version_directive.minor = (token_minor))
510+
511+#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
512+ (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
513+ (token).data.tag_directive.handle = (token_handle), \
514+ (token).data.tag_directive.prefix = (token_prefix))
515+
516+/*
517+ * Event initializers.
518+ */
519+
520+#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
521+ (memset(&(event), 0, sizeof(yaml_event_t)), \
522+ (event).type = (event_type), \
523+ (event).start_mark = (event_start_mark), \
524+ (event).end_mark = (event_end_mark))
525+
526+#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
527+ (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
528+ (event).data.stream_start.encoding = (event_encoding))
529+
530+#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
531+ (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
532+
533+#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \
534+ event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
535+ (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
536+ (event).data.document_start.version_directive = (event_version_directive), \
537+ (event).data.document_start.tag_directives.start = (event_tag_directives_start), \
538+ (event).data.document_start.tag_directives.end = (event_tag_directives_end), \
539+ (event).data.document_start.implicit = (event_implicit))
540+
541+#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
542+ (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
543+ (event).data.document_end.implicit = (event_implicit))
544+
545+#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
546+ (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
547+ (event).data.alias.anchor = (event_anchor))
548+
549+#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
550+ event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
551+ (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
552+ (event).data.scalar.anchor = (event_anchor), \
553+ (event).data.scalar.tag = (event_tag), \
554+ (event).data.scalar.value = (event_value), \
555+ (event).data.scalar.length = (event_length), \
556+ (event).data.scalar.plain_implicit = (event_plain_implicit), \
557+ (event).data.scalar.quoted_implicit = (event_quoted_implicit), \
558+ (event).data.scalar.style = (event_style))
559+
560+#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
561+ event_implicit,event_style,start_mark,end_mark) \
562+ (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
563+ (event).data.sequence_start.anchor = (event_anchor), \
564+ (event).data.sequence_start.tag = (event_tag), \
565+ (event).data.sequence_start.implicit = (event_implicit), \
566+ (event).data.sequence_start.style = (event_style))
567+
568+#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
569+ (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
570+
571+#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
572+ event_implicit,event_style,start_mark,end_mark) \
573+ (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
574+ (event).data.mapping_start.anchor = (event_anchor), \
575+ (event).data.mapping_start.tag = (event_tag), \
576+ (event).data.mapping_start.implicit = (event_implicit), \
577+ (event).data.mapping_start.style = (event_style))
578+
579+#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
580+ (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
581+
582+/*
583+ * Document initializer.
584+ */
585+
586+#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \
587+ document_version_directive,document_tag_directives_start, \
588+ document_tag_directives_end,document_start_implicit, \
589+ document_end_implicit,document_start_mark,document_end_mark) \
590+ (memset(&(document), 0, sizeof(yaml_document_t)), \
591+ (document).nodes.start = (document_nodes_start), \
592+ (document).nodes.end = (document_nodes_end), \
593+ (document).nodes.top = (document_nodes_start), \
594+ (document).version_directive = (document_version_directive), \
595+ (document).tag_directives.start = (document_tag_directives_start), \
596+ (document).tag_directives.end = (document_tag_directives_end), \
597+ (document).start_implicit = (document_start_implicit), \
598+ (document).end_implicit = (document_end_implicit), \
599+ (document).start_mark = (document_start_mark), \
600+ (document).end_mark = (document_end_mark))
601+
602+/*
603+ * Node initializers.
604+ */
605+
606+#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \
607+ (memset(&(node), 0, sizeof(yaml_node_t)), \
608+ (node).type = (node_type), \
609+ (node).tag = (node_tag), \
610+ (node).start_mark = (node_start_mark), \
611+ (node).end_mark = (node_end_mark))
612+
613+#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \
614+ node_style,start_mark,end_mark) \
615+ (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \
616+ (node).data.scalar.value = (node_value), \
617+ (node).data.scalar.length = (node_length), \
618+ (node).data.scalar.style = (node_style))
619+
620+#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \
621+ node_style,start_mark,end_mark) \
622+ (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \
623+ (node).data.sequence.items.start = (node_items_start), \
624+ (node).data.sequence.items.end = (node_items_end), \
625+ (node).data.sequence.items.top = (node_items_start), \
626+ (node).data.sequence.style = (node_style))
627+
628+#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \
629+ node_style,start_mark,end_mark) \
630+ (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \
631+ (node).data.mapping.pairs.start = (node_pairs_start), \
632+ (node).data.mapping.pairs.end = (node_pairs_end), \
633+ (node).data.mapping.pairs.top = (node_pairs_start), \
634+ (node).data.mapping.style = (node_style))
635+
636+#define YAML_VERSION_STRING "0.1.2"
637+#define YAML_VERSION_MAJOR 0
638+#define YAML_VERSION_MINOR 1
639+#define YAML_VERSION_PATCH 2
yaml.cabal+12−3
@@ -11,6 +11,9 @@ stability: unstable
11cabal-version: >= 1.2
11cabal-version: >= 1.2
12build-type: Simple
12build-type: Simple
13homepage: http://github.com/snoyberg/yaml/tree/master
13homepage: http://github.com/snoyberg/yaml/tree/master
14+extra-source-files: c/helper.h,
15+ c/yaml_private.h,
16+ c/yaml.h
14
17
15library
18library
16 build-depends: base >= 4 && < 5,
19 build-depends: base >= 4 && < 5,
@@ -22,8 +25,14 @@ library
22 other-modules: Text.Libyaml,
25 other-modules: Text.Libyaml,
23 C2HS
26 C2HS
24 ghc-options: -Wall
27 ghc-options: -Wall
25− c-sources: c/helper.c
28+ c-sources: c/helper.c,
29+ c/api.c,
30+ c/dumper.c,
31+ c/emitter.c,
32+ c/loader.c,
33+ c/parser.c,
34+ c/reader.c,
35+ c/scanner.c,
36+ c/writer.c
26 include-dirs: c
37 include-dirs: c
27− includes: c/helper.h
28− extra-libraries: yaml
29 build-tools: c2hs
38 build-tools: c2hs