1
2#include <yaml.h>
3
4#include <stdlib.h>
5#include <stdio.h>
6
7int
8main(int argc, char *argv[])
9{
10    int help = 0;
11    int canonical = 0;
12    int unicode = 0;
13    int k;
14    int done = 0;
15
16    yaml_parser_t parser;
17    yaml_emitter_t emitter;
18    yaml_event_t input_event;
19    yaml_document_t output_document;
20
21    int root;
22
23    /* Clear the objects. */
24
25    memset(&parser, 0, sizeof(parser));
26    memset(&emitter, 0, sizeof(emitter));
27    memset(&input_event, 0, sizeof(input_event));
28    memset(&output_document, 0, sizeof(output_document));
29
30    /* Analyze command line options. */
31
32    for (k = 1; k < argc; k ++)
33    {
34        if (strcmp(argv[k], "-h") == 0
35                || strcmp(argv[k], "--help") == 0) {
36            help = 1;
37        }
38
39        else if (strcmp(argv[k], "-c") == 0
40                || strcmp(argv[k], "--canonical") == 0) {
41            canonical = 1;
42        }
43
44        else if (strcmp(argv[k], "-u") == 0
45                || strcmp(argv[k], "--unicode") == 0) {
46            unicode = 1;
47        }
48
49        else {
50            fprintf(stderr, "Unrecognized option: %s\n"
51                    "Try `%s --help` for more information.\n",
52                    argv[k], argv[0]);
53            return 1;
54        }
55    }
56
57    /* Display the help string. */
58
59    if (help)
60    {
61        printf("%s <input\n"
62                "or\n%s -h | --help\nDeconstruct a YAML stream\n\nOptions:\n"
63                "-h, --help\t\tdisplay this help and exit\n"
64                "-c, --canonical\t\toutput in the canonical YAML format\n"
65                "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
66                argv[0], argv[0]);
67        return 0;
68    }
69
70    /* Initialize the parser and emitter objects. */
71
72    if (!yaml_parser_initialize(&parser)) {
73        fprintf(stderr, "Could not initialize the parser object\n");
74        return 1;
75    }
76
77    if (!yaml_emitter_initialize(&emitter)) {
78        yaml_parser_delete(&parser);
79        fprintf(stderr, "Could not inialize the emitter object\n");
80        return 1;
81    }
82
83    /* Set the parser parameters. */
84
85    yaml_parser_set_input_file(&parser, stdin);
86
87    /* Set the emitter parameters. */
88
89    yaml_emitter_set_output_file(&emitter, stdout);
90
91    yaml_emitter_set_canonical(&emitter, canonical);
92    yaml_emitter_set_unicode(&emitter, unicode);
93
94    /* Create and emit the STREAM-START event. */
95
96    if (!yaml_emitter_open(&emitter))
97        goto emitter_error;
98
99    /* Create a output_document object. */
100
101    if (!yaml_document_initialize(&output_document, NULL, NULL, NULL, 0, 0))
102        goto document_error;
103
104    /* Create the root sequence. */
105
106    root = yaml_document_add_sequence(&output_document, NULL,
107            YAML_BLOCK_SEQUENCE_STYLE);
108    if (!root) goto document_error;
109
110    /* Loop through the input events. */
111
112    while (!done)
113    {
114        int properties, key, value, map, seq;
115
116        /* Get the next event. */
117
118        if (!yaml_parser_parse(&parser, &input_event))
119            goto parser_error;
120
121        /* Check if this is the stream end. */
122
123        if (input_event.type == YAML_STREAM_END_EVENT) {
124            done = 1;
125        }
126
127        /* Create a mapping node and attach it to the root sequence. */
128
129        properties = yaml_document_add_mapping(&output_document, NULL,
130                YAML_BLOCK_MAPPING_STYLE);
131        if (!properties) goto document_error;
132        if (!yaml_document_append_sequence_item(&output_document,
133                    root, properties)) goto document_error;
134
135        /* Analyze the event. */
136
137        switch (input_event.type)
138        {
139            case YAML_STREAM_START_EVENT:
140
141                /* Add 'type': 'STREAM-START'. */
142
143                key = yaml_document_add_scalar(&output_document, NULL,
144                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
145                if (!key) goto document_error;
146                value = yaml_document_add_scalar(&output_document, NULL,
147                    "STREAM-START", -1, YAML_PLAIN_SCALAR_STYLE);
148                if (!value) goto document_error;
149                if (!yaml_document_append_mapping_pair(&output_document,
150                            properties, key, value)) goto document_error;
151
152                /* Add 'encoding': <encoding>. */
153
154                if (input_event.data.stream_start.encoding)
155                {
156                    yaml_encoding_t encoding
157                        = input_event.data.stream_start.encoding;
158
159                    key = yaml_document_add_scalar(&output_document, NULL,
160                        "encoding", -1, YAML_PLAIN_SCALAR_STYLE);
161                    if (!key) goto document_error;
162                    value = yaml_document_add_scalar(&output_document, NULL,
163                            (encoding == YAML_UTF8_ENCODING ? "utf-8" :
164                             encoding == YAML_UTF16LE_ENCODING ? "utf-16-le" :
165                             encoding == YAML_UTF16BE_ENCODING ? "utf-16-be" :
166                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
167                    if (!value) goto document_error;
168                    if (!yaml_document_append_mapping_pair(&output_document,
169                                properties, key, value)) goto document_error;
170                }
171
172                break;
173
174            case YAML_STREAM_END_EVENT:
175
176                /* Add 'type': 'STREAM-END'. */
177
178                key = yaml_document_add_scalar(&output_document, NULL,
179                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
180                if (!key) goto document_error;
181                value = yaml_document_add_scalar(&output_document, NULL,
182                    "STREAM-END", -1, YAML_PLAIN_SCALAR_STYLE);
183                if (!value) goto document_error;
184                if (!yaml_document_append_mapping_pair(&output_document,
185                            properties, key, value)) goto document_error;
186
187                break;
188
189            case YAML_DOCUMENT_START_EVENT:
190
191                /* Add 'type': 'DOCUMENT-START'. */
192
193                key = yaml_document_add_scalar(&output_document, NULL,
194                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
195                if (!key) goto document_error;
196                value = yaml_document_add_scalar(&output_document, NULL,
197                    "DOCUMENT-START", -1, YAML_PLAIN_SCALAR_STYLE);
198                if (!value) goto document_error;
199                if (!yaml_document_append_mapping_pair(&output_document,
200                            properties, key, value)) goto document_error;
201
202                /* Display the output_document version numbers. */
203
204                if (input_event.data.document_start.version_directive)
205                {
206                    yaml_version_directive_t *version
207                        = input_event.data.document_start.version_directive;
208                    char number[64];
209
210                    /* Add 'version': {}. */
211
212                    key = yaml_document_add_scalar(&output_document, NULL,
213                        "version", -1, YAML_PLAIN_SCALAR_STYLE);
214                    if (!key) goto document_error;
215                    map = yaml_document_add_mapping(&output_document, NULL,
216                            YAML_FLOW_MAPPING_STYLE);
217                    if (!map) goto document_error;
218                    if (!yaml_document_append_mapping_pair(&output_document,
219                                properties, key, map)) goto document_error;
220
221                    /* Add 'major': <number>. */
222
223                    key = yaml_document_add_scalar(&output_document, NULL,
224                        "major", -1, YAML_PLAIN_SCALAR_STYLE);
225                    if (!key) goto document_error;
226                    sprintf(number, "%d", version->major);
227                    value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
228                        number, -1, YAML_PLAIN_SCALAR_STYLE);
229                    if (!value) goto document_error;
230                    if (!yaml_document_append_mapping_pair(&output_document,
231                                map, key, value)) goto document_error;
232
233                    /* Add 'minor': <number>. */
234
235                    key = yaml_document_add_scalar(&output_document, NULL,
236                        "minor", -1, YAML_PLAIN_SCALAR_STYLE);
237                    if (!key) goto document_error;
238                    sprintf(number, "%d", version->minor);
239                    value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
240                        number, -1, YAML_PLAIN_SCALAR_STYLE);
241                    if (!value) goto document_error;
242                    if (!yaml_document_append_mapping_pair(&output_document,
243                                map, key, value)) goto document_error;
244                }
245
246                /* Display the output_document tag directives. */
247
248                if (input_event.data.document_start.tag_directives.start
249                        != input_event.data.document_start.tag_directives.end)
250                {
251                    yaml_tag_directive_t *tag;
252
253                    /* Add 'tags': []. */
254
255                    key = yaml_document_add_scalar(&output_document, NULL,
256                        "tags", -1, YAML_PLAIN_SCALAR_STYLE);
257                    if (!key) goto document_error;
258                    seq = yaml_document_add_sequence(&output_document, NULL,
259                            YAML_BLOCK_SEQUENCE_STYLE);
260                    if (!seq) goto document_error;
261                    if (!yaml_document_append_mapping_pair(&output_document,
262                                properties, key, seq)) goto document_error;
263
264                    for (tag = input_event.data.document_start.tag_directives.start;
265                            tag != input_event.data.document_start.tag_directives.end;
266                            tag ++)
267                    {
268                        /* Add {}. */
269
270                        map = yaml_document_add_mapping(&output_document, NULL,
271                                YAML_FLOW_MAPPING_STYLE);
272                        if (!map) goto document_error;
273                        if (!yaml_document_append_sequence_item(&output_document,
274                                    seq, map)) goto document_error;
275
276                        /* Add 'handle': <handle>. */
277
278                        key = yaml_document_add_scalar(&output_document, NULL,
279                            "handle", -1, YAML_PLAIN_SCALAR_STYLE);
280                        if (!key) goto document_error;
281                        value = yaml_document_add_scalar(&output_document, NULL,
282                            tag->handle, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
283                        if (!value) goto document_error;
284                        if (!yaml_document_append_mapping_pair(&output_document,
285                                    map, key, value)) goto document_error;
286
287                        /* Add 'prefix': <prefix>. */
288
289                        key = yaml_document_add_scalar(&output_document, NULL,
290                            "prefix", -1, YAML_PLAIN_SCALAR_STYLE);
291                        if (!key) goto document_error;
292                        value = yaml_document_add_scalar(&output_document, NULL,
293                            tag->prefix, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
294                        if (!value) goto document_error;
295                        if (!yaml_document_append_mapping_pair(&output_document,
296                                    map, key, value)) goto document_error;
297                    }
298                }
299
300                /* Add 'implicit': <flag>. */
301
302                key = yaml_document_add_scalar(&output_document, NULL,
303                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
304                if (!key) goto document_error;
305                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
306                        (input_event.data.document_start.implicit ?
307                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
308                if (!value) goto document_error;
309                if (!yaml_document_append_mapping_pair(&output_document,
310                            properties, key, value)) goto document_error;
311
312                break;
313
314            case YAML_DOCUMENT_END_EVENT:
315
316                /* Add 'type': 'DOCUMENT-END'. */
317
318                key = yaml_document_add_scalar(&output_document, NULL,
319                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
320                if (!key) goto document_error;
321                value = yaml_document_add_scalar(&output_document, NULL,
322                    "DOCUMENT-END", -1, YAML_PLAIN_SCALAR_STYLE);
323                if (!value) goto document_error;
324                if (!yaml_document_append_mapping_pair(&output_document,
325                            properties, key, value)) goto document_error;
326
327                /* Add 'implicit': <flag>. */
328
329                key = yaml_document_add_scalar(&output_document, NULL,
330                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
331                if (!key) goto document_error;
332                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
333                        (input_event.data.document_end.implicit ?
334                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
335                if (!value) goto document_error;
336                if (!yaml_document_append_mapping_pair(&output_document,
337                            properties, key, value)) goto document_error;
338
339                break;
340
341            case YAML_ALIAS_EVENT:
342
343                /* Add 'type': 'ALIAS'. */
344
345                key = yaml_document_add_scalar(&output_document, NULL,
346                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
347                if (!key) goto document_error;
348                value = yaml_document_add_scalar(&output_document, NULL,
349                    "ALIAS", -1, YAML_PLAIN_SCALAR_STYLE);
350                if (!value) goto document_error;
351                if (!yaml_document_append_mapping_pair(&output_document,
352                            properties, key, value)) goto document_error;
353
354                /* Add 'anchor': <anchor>. */
355
356                key = yaml_document_add_scalar(&output_document, NULL,
357                    "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
358                if (!key) goto document_error;
359                value = yaml_document_add_scalar(&output_document, NULL,
360                        input_event.data.alias.anchor, -1,
361                        YAML_DOUBLE_QUOTED_SCALAR_STYLE);
362                if (!value) goto document_error;
363                if (!yaml_document_append_mapping_pair(&output_document,
364                            properties, key, value)) goto document_error;
365
366                break;
367
368            case YAML_SCALAR_EVENT:
369
370                /* Add 'type': 'SCALAR'. */
371
372                key = yaml_document_add_scalar(&output_document, NULL,
373                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
374                if (!key) goto document_error;
375                value = yaml_document_add_scalar(&output_document, NULL,
376                    "SCALAR", -1, YAML_PLAIN_SCALAR_STYLE);
377                if (!value) goto document_error;
378                if (!yaml_document_append_mapping_pair(&output_document,
379                            properties, key, value)) goto document_error;
380
381                /* Add 'anchor': <anchor>. */
382
383                if (input_event.data.scalar.anchor)
384                {
385                    key = yaml_document_add_scalar(&output_document, NULL,
386                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
387                    if (!key) goto document_error;
388                    value = yaml_document_add_scalar(&output_document, NULL,
389                            input_event.data.scalar.anchor, -1,
390                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
391                    if (!value) goto document_error;
392                    if (!yaml_document_append_mapping_pair(&output_document,
393                                properties, key, value)) goto document_error;
394                }
395
396                /* Add 'tag': <tag>. */
397
398                if (input_event.data.scalar.tag)
399                {
400                    key = yaml_document_add_scalar(&output_document, NULL,
401                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
402                    if (!key) goto document_error;
403                    value = yaml_document_add_scalar(&output_document, NULL,
404                            input_event.data.scalar.tag, -1,
405                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
406                    if (!value) goto document_error;
407                    if (!yaml_document_append_mapping_pair(&output_document,
408                                properties, key, value)) goto document_error;
409                }
410
411                /* Add 'value': <value>. */
412
413                key = yaml_document_add_scalar(&output_document, NULL,
414                    "value", -1, YAML_PLAIN_SCALAR_STYLE);
415                if (!key) goto document_error;
416                value = yaml_document_add_scalar(&output_document, NULL,
417                        input_event.data.scalar.value,
418                        input_event.data.scalar.length,
419                        YAML_DOUBLE_QUOTED_SCALAR_STYLE);
420                if (!value) goto document_error;
421                if (!yaml_document_append_mapping_pair(&output_document,
422                            properties, key, value)) goto document_error;
423
424                /* Display if the scalar tag is implicit. */
425
426                /* Add 'implicit': {} */
427
428                key = yaml_document_add_scalar(&output_document, NULL,
429                    "version", -1, YAML_PLAIN_SCALAR_STYLE);
430                if (!key) goto document_error;
431                map = yaml_document_add_mapping(&output_document, NULL,
432                        YAML_FLOW_MAPPING_STYLE);
433                if (!map) goto document_error;
434                if (!yaml_document_append_mapping_pair(&output_document,
435                            properties, key, map)) goto document_error;
436
437                /* Add 'plain': <flag>. */
438
439                key = yaml_document_add_scalar(&output_document, NULL,
440                    "plain", -1, YAML_PLAIN_SCALAR_STYLE);
441                if (!key) goto document_error;
442                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
443                        (input_event.data.scalar.plain_implicit ?
444                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
445                if (!value) goto document_error;
446                if (!yaml_document_append_mapping_pair(&output_document,
447                            map, key, value)) goto document_error;
448
449                /* Add 'quoted': <flag>. */
450
451                key = yaml_document_add_scalar(&output_document, NULL,
452                    "quoted", -1, YAML_PLAIN_SCALAR_STYLE);
453                if (!key) goto document_error;
454                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
455                        (input_event.data.scalar.quoted_implicit ?
456                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
457                if (!value) goto document_error;
458                if (!yaml_document_append_mapping_pair(&output_document,
459                            map, key, value)) goto document_error;
460
461                /* Display the style information. */
462
463                if (input_event.data.scalar.style)
464                {
465                    yaml_scalar_style_t style = input_event.data.scalar.style;
466
467                    /* Add 'style': <style>. */
468
469                    key = yaml_document_add_scalar(&output_document, NULL,
470                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
471                    if (!key) goto document_error;
472                    value = yaml_document_add_scalar(&output_document, NULL,
473                            (style == YAML_PLAIN_SCALAR_STYLE ? "plain" :
474                             style == YAML_SINGLE_QUOTED_SCALAR_STYLE ?
475                                    "single-quoted" :
476                             style == YAML_DOUBLE_QUOTED_SCALAR_STYLE ?
477                                    "double-quoted" :
478                             style == YAML_LITERAL_SCALAR_STYLE ? "literal" :
479                             style == YAML_FOLDED_SCALAR_STYLE ? "folded" :
480                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
481                    if (!value) goto document_error;
482                    if (!yaml_document_append_mapping_pair(&output_document,
483                                properties, key, value)) goto document_error;
484                }
485
486                break;
487
488            case YAML_SEQUENCE_START_EVENT:
489
490                /* Add 'type': 'SEQUENCE-START'. */
491
492                key = yaml_document_add_scalar(&output_document, NULL,
493                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
494                if (!key) goto document_error;
495                value = yaml_document_add_scalar(&output_document, NULL,
496                    "SEQUENCE-START", -1, YAML_PLAIN_SCALAR_STYLE);
497                if (!value) goto document_error;
498                if (!yaml_document_append_mapping_pair(&output_document,
499                            properties, key, value)) goto document_error;
500
501                /* Add 'anchor': <anchor>. */
502
503                if (input_event.data.sequence_start.anchor)
504                {
505                    key = yaml_document_add_scalar(&output_document, NULL,
506                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
507                    if (!key) goto document_error;
508                    value = yaml_document_add_scalar(&output_document, NULL,
509                            input_event.data.sequence_start.anchor, -1,
510                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
511                    if (!value) goto document_error;
512                    if (!yaml_document_append_mapping_pair(&output_document,
513                                properties, key, value)) goto document_error;
514                }
515
516                /* Add 'tag': <tag>. */
517
518                if (input_event.data.sequence_start.tag)
519                {
520                    key = yaml_document_add_scalar(&output_document, NULL,
521                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
522                    if (!key) goto document_error;
523                    value = yaml_document_add_scalar(&output_document, NULL,
524                            input_event.data.sequence_start.tag, -1,
525                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
526                    if (!value) goto document_error;
527                    if (!yaml_document_append_mapping_pair(&output_document,
528                                properties, key, value)) goto document_error;
529                }
530
531                /* Add 'implicit': <flag>. */
532
533                key = yaml_document_add_scalar(&output_document, NULL,
534                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
535                if (!key) goto document_error;
536                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
537                        (input_event.data.sequence_start.implicit ?
538                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
539                if (!value) goto document_error;
540                if (!yaml_document_append_mapping_pair(&output_document,
541                            properties, key, value)) goto document_error;
542
543                /* Display the style information. */
544
545                if (input_event.data.sequence_start.style)
546                {
547                    yaml_sequence_style_t style
548                        = input_event.data.sequence_start.style;
549
550                    /* Add 'style': <style>. */
551
552                    key = yaml_document_add_scalar(&output_document, NULL,
553                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
554                    if (!key) goto document_error;
555                    value = yaml_document_add_scalar(&output_document, NULL,
556                            (style == YAML_BLOCK_SEQUENCE_STYLE ? "block" :
557                             style == YAML_FLOW_SEQUENCE_STYLE ? "flow" :
558                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
559                    if (!value) goto document_error;
560                    if (!yaml_document_append_mapping_pair(&output_document,
561                                properties, key, value)) goto document_error;
562                }
563
564                break;
565
566            case YAML_SEQUENCE_END_EVENT:
567
568                /* Add 'type': 'SEQUENCE-END'. */
569
570                key = yaml_document_add_scalar(&output_document, NULL,
571                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
572                if (!key) goto document_error;
573                value = yaml_document_add_scalar(&output_document, NULL,
574                    "SEQUENCE-END", -1, YAML_PLAIN_SCALAR_STYLE);
575                if (!value) goto document_error;
576                if (!yaml_document_append_mapping_pair(&output_document,
577                            properties, key, value)) goto document_error;
578
579                break;
580
581            case YAML_MAPPING_START_EVENT:
582
583                /* Add 'type': 'MAPPING-START'. */
584
585                key = yaml_document_add_scalar(&output_document, NULL,
586                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
587                if (!key) goto document_error;
588                value = yaml_document_add_scalar(&output_document, NULL,
589                    "MAPPING-START", -1, YAML_PLAIN_SCALAR_STYLE);
590                if (!value) goto document_error;
591                if (!yaml_document_append_mapping_pair(&output_document,
592                            properties, key, value)) goto document_error;
593
594                /* Add 'anchor': <anchor>. */
595
596                if (input_event.data.mapping_start.anchor)
597                {
598                    key = yaml_document_add_scalar(&output_document, NULL,
599                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
600                    if (!key) goto document_error;
601                    value = yaml_document_add_scalar(&output_document, NULL,
602                            input_event.data.mapping_start.anchor, -1,
603                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
604                    if (!value) goto document_error;
605                    if (!yaml_document_append_mapping_pair(&output_document,
606                                properties, key, value)) goto document_error;
607                }
608
609                /* Add 'tag': <tag>. */
610
611                if (input_event.data.mapping_start.tag)
612                {
613                    key = yaml_document_add_scalar(&output_document, NULL,
614                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
615                    if (!key) goto document_error;
616                    value = yaml_document_add_scalar(&output_document, NULL,
617                            input_event.data.mapping_start.tag, -1,
618                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
619                    if (!value) goto document_error;
620                    if (!yaml_document_append_mapping_pair(&output_document,
621                                properties, key, value)) goto document_error;
622                }
623
624                /* Add 'implicit': <flag>. */
625
626                key = yaml_document_add_scalar(&output_document, NULL,
627                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
628                if (!key) goto document_error;
629                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
630                        (input_event.data.mapping_start.implicit ?
631                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
632                if (!value) goto document_error;
633                if (!yaml_document_append_mapping_pair(&output_document,
634                            properties, key, value)) goto document_error;
635
636                /* Display the style information. */
637
638                if (input_event.data.sequence_start.style)
639                {
640                    yaml_sequence_style_t style
641                        = input_event.data.mapping_start.style;
642
643                    /* Add 'style': <style>. */
644
645                    key = yaml_document_add_scalar(&output_document, NULL,
646                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
647                    if (!key) goto document_error;
648                    value = yaml_document_add_scalar(&output_document, NULL,
649                            (style == YAML_BLOCK_MAPPING_STYLE ? "block" :
650                             style == YAML_FLOW_MAPPING_STYLE ? "flow" :
651                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
652                    if (!value) goto document_error;
653                    if (!yaml_document_append_mapping_pair(&output_document,
654                                properties, key, value)) goto document_error;
655                }
656
657                break;
658
659            case YAML_MAPPING_END_EVENT:
660
661                /* Add 'type': 'MAPPING-END'. */
662
663                key = yaml_document_add_scalar(&output_document, NULL,
664                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
665                if (!key) goto document_error;
666                value = yaml_document_add_scalar(&output_document, NULL,
667                    "MAPPING-END", -1, YAML_PLAIN_SCALAR_STYLE);
668                if (!value) goto document_error;
669                if (!yaml_document_append_mapping_pair(&output_document,
670                            properties, key, value)) goto document_error;
671
672                break;
673
674            default:
675                /* It couldn't really happen. */
676                break;
677        }
678
679        /* Delete the event object. */
680
681        yaml_event_delete(&input_event);
682    }
683
684    if (!yaml_emitter_dump(&emitter, &output_document))
685        goto emitter_error;
686    if (!yaml_emitter_close(&emitter))
687        goto emitter_error;
688
689    yaml_parser_delete(&parser);
690    yaml_emitter_delete(&emitter);
691
692    return 0;
693
694parser_error:
695
696    /* Display a parser error message. */
697
698    switch (parser.error)
699    {
700        case YAML_MEMORY_ERROR:
701            fprintf(stderr, "Memory error: Not enough memory for parsing\n");
702            break;
703
704        case YAML_READER_ERROR:
705            if (parser.problem_value != -1) {
706                fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
707                        parser.problem_value, parser.problem_offset);
708            }
709            else {
710                fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
711                        parser.problem_offset);
712            }
713            break;
714
715        case YAML_SCANNER_ERROR:
716            if (parser.context) {
717                fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
718                        "%s at line %d, column %d\n", parser.context,
719                        parser.context_mark.line+1, parser.context_mark.column+1,
720                        parser.problem, parser.problem_mark.line+1,
721                        parser.problem_mark.column+1);
722            }
723            else {
724                fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
725                        parser.problem, parser.problem_mark.line+1,
726                        parser.problem_mark.column+1);
727            }
728            break;
729
730        case YAML_PARSER_ERROR:
731            if (parser.context) {
732                fprintf(stderr, "Parser error: %s at line %d, column %d\n"
733                        "%s at line %d, column %d\n", parser.context,
734                        parser.context_mark.line+1, parser.context_mark.column+1,
735                        parser.problem, parser.problem_mark.line+1,
736                        parser.problem_mark.column+1);
737            }
738            else {
739                fprintf(stderr, "Parser error: %s at line %d, column %d\n",
740                        parser.problem, parser.problem_mark.line+1,
741                        parser.problem_mark.column+1);
742            }
743            break;
744
745        default:
746            /* Couldn't happen. */
747            fprintf(stderr, "Internal error\n");
748            break;
749    }
750
751    yaml_event_delete(&input_event);
752    yaml_document_delete(&output_document);
753    yaml_parser_delete(&parser);
754    yaml_emitter_delete(&emitter);
755
756    return 1;
757
758emitter_error:
759
760    /* Display an emitter error message. */
761
762    switch (emitter.error)
763    {
764        case YAML_MEMORY_ERROR:
765            fprintf(stderr, "Memory error: Not enough memory for emitting\n");
766            break;
767
768        case YAML_WRITER_ERROR:
769            fprintf(stderr, "Writer error: %s\n", emitter.problem);
770            break;
771
772        case YAML_EMITTER_ERROR:
773            fprintf(stderr, "Emitter error: %s\n", emitter.problem);
774            break;
775
776        default:
777            /* Couldn't happen. */
778            fprintf(stderr, "Internal error\n");
779            break;
780    }
781
782    yaml_event_delete(&input_event);
783    yaml_document_delete(&output_document);
784    yaml_parser_delete(&parser);
785    yaml_emitter_delete(&emitter);
786
787    return 1;
788
789document_error:
790
791    fprintf(stderr, "Memory error: Not enough memory for creating a document\n");
792
793    yaml_event_delete(&input_event);
794    yaml_document_delete(&output_document);
795    yaml_parser_delete(&parser);
796    yaml_emitter_delete(&emitter);
797
798    return 1;
799}
800
801