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

Submodule changed.

stack.yaml+1−4
@@ -1,4 +1,4 @@
1−resolver: lts-22.13
1+resolver: lts-20.25
22
33flags:
44 yaml:
@@ -7,6 +7,3 @@ flags:
77packages:
88 - yaml
99 - libyaml
10−
11−extra-deps:
12− - libyaml-clib-0.2.5
yaml/ChangeLog.md−4
@@ -1,9 +1,5 @@
11# ChangeLog for yaml
22
3−## 0.11.11.2
4−
5−* Compat with aeson 2.2
6−
73## 0.11.11.1
84
95* For optparse-applicative-0.18: use `pretty` instead of `text` [#216](https://github.com/snoyberg/yaml/pull/216)
yaml/package.yaml+2−4
@@ -1,5 +1,5 @@
11name: yaml
2−version: 0.11.11.2
2+version: 0.11.11.1
33synopsis: Support for parsing and rendering YAML documents.
44description: README and API documentation are available at <https://www.stackage.org/package/yaml>
55category: Data
@@ -34,7 +34,7 @@ flags:
3434 default: true
3535
3636dependencies:
37−- base >=4.14 && <5 # GHC 8.10.1 and later
37+- base >=4.9.1 && <5 # GHC 8.0.2 and later, meaning that Data.Semigroup is in base
3838- bytestring >=0.9.1.4
3939- transformers >=0.1
4040- mtl
@@ -109,5 +109,3 @@ tests:
109109 - base-compat
110110 - temporary
111111 - raw-strings-qq
112− build-tools:
113− - hspec-discover
yaml/src/Data/Yaml/Config.hs+1−6
@@ -5,7 +5,7 @@
55-- In particular, merging environment variables with yaml values
66--
77-- 'loadYamlSettings' is a high-level API for loading YAML and merging environment variables.
8−-- A yaml value of @_env:ENV_VAR:default@ or just @_env:ENV_VAR@ will lookup the environment variable @ENV_VAR@.
8+-- A yaml value of @_env:ENV_VAR:default@ will lookup the environment variable @ENV_VAR@.
99--
1010-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
1111module Data.Yaml.Config
@@ -185,11 +185,6 @@ requireCustomEnv = RequireCustomEnv
185185--
186186-- > loadYamlSettings ["config/foo.yaml"] [] useEnv
187187--
188−-- Alternatively you can configure settings through the Yaml @Value@ directly in Haskell.
189−-- For example, to load up settings from only from environment variables, you can use:
190−--
191−-- > loadYamlSettings [] [object ["connectionString" .= ("_env:DATABASE_URL" :: String)]] requireEnv
192−--
193188-- @since 0.8.16
194189loadYamlSettings
195190 :: FromJSON settings
yaml/src/Data/Yaml/Internal.hs+1−1
@@ -50,7 +50,7 @@ import qualified Data.HashMap.Strict as M
5050import Data.Aeson.Types hiding (AesonException, parse)
5151#else
5252import Data.Aeson.Types hiding (parse)
53−import Data.Aeson.Internal (JSONPath, JSONPathElement(..), formatError)
53+import Data.Aeson.Internal (formatError)
5454#endif
5555import qualified Data.Attoparsec.Text as Atto
5656import Data.Bits (shiftL, (.|.))
yaml/test/Data/Yaml/IncludeSpec.hs−5
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
21{-# LANGUAGE QuasiQuotes #-}
32{-# LANGUAGE OverloadedStrings #-}
43module Data.Yaml.IncludeSpec (main, spec) where
@@ -7,11 +6,7 @@ import Test.Hspec
76import Data.List (isPrefixOf)
87import qualified Data.ByteString.Lazy as LB
98import Data.Aeson
10−#if MIN_VERSION_aeson(2,2,0)
119import Data.Aeson.Types (JSONPathElement(..))
12−#else
13−import Data.Aeson.Internal (JSONPathElement(..))
14−#endif
1510import Data.Yaml (ParseException(InvalidYaml))
1611import Data.Yaml.Include
1712import Data.Yaml.Internal
yaml/test/Data/YamlSpec.hs+2−2
@@ -822,9 +822,9 @@ casePreservesScientificPrecision = do
822822 -- However, it didn't work (and still doesn't work with aeson < 0.7)
823823 -- for two reasons:
824824 --
825− -- - We use 'Data.Text.Read.double', which is not as accurate as it
825+ -- * We use 'Data.Text.Read.double', which is not as accurate as it
826826 -- can be;
827− -- - Even if we used 'Data.Text.Read.rational' we would not get good
827+ -- * Even if we used 'Data.Text.Read.rational' we would not get good
828828 -- results, because of <https://github.com/bos/text/issues/34>.
829829 "x: 9.78159610558926e-5" `shouldDecode` object
830830 [ "x" .= D.Number (read "9.78159610558926e-5") ]
yaml/yaml.cabal+1−3
@@ -5,7 +5,7 @@ cabal-version: 1.12
55-- see: https://github.com/sol/hpack
66
77name: yaml
8−version: 0.11.11.2
8+version: 0.11.11.1
99synopsis: Support for parsing and rendering YAML documents.
1010description: README and API documentation are available at <https://www.stackage.org/package/yaml>
1111category: Data
@@ -198,8 +198,6 @@ test-suite spec
198198 test
199199 ghc-options: -Wall -Wcompat -with-rtsopts=-K1K
200200 cpp-options: -DTEST
201− build-tool-depends:
202− hspec-discover:hspec-discover
203201 build-depends:
204202 HUnit
205203 , aeson >=0.11