1 
2 #include <yaml.h>
3 
4 #include <stdlib.h>
5 #include <stdio.h>
6 
7 int
main(int argc,char * argv[])8 main(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
145                 if (!key) goto document_error;
146                 value = yaml_document_add_scalar(&output_document, NULL,
147                     (yaml_char_t *)"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                         (yaml_char_t *)"encoding", -1, YAML_PLAIN_SCALAR_STYLE);
161                     if (!key) goto document_error;
162                     value = yaml_document_add_scalar(&output_document, NULL,
163                             (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
180                 if (!key) goto document_error;
181                 value = yaml_document_add_scalar(&output_document, NULL,
182                     (yaml_char_t *)"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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
195                 if (!key) goto document_error;
196                 value = yaml_document_add_scalar(&output_document, NULL,
197                     (yaml_char_t *)"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                         (yaml_char_t *)"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                         (yaml_char_t *)"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_char_t *)YAML_INT_TAG,
228                         (yaml_char_t *)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                         (yaml_char_t *)"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_char_t *)YAML_INT_TAG,
240                         (yaml_char_t *)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                         (yaml_char_t *)"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                             (yaml_char_t *)"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                             (yaml_char_t *)"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                     (yaml_char_t *)"implicit", -1, YAML_PLAIN_SCALAR_STYLE);
304                 if (!key) goto document_error;
305                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
306                         (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
320                 if (!key) goto document_error;
321                 value = yaml_document_add_scalar(&output_document, NULL,
322                     (yaml_char_t *)"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                     (yaml_char_t *)"implicit", -1, YAML_PLAIN_SCALAR_STYLE);
331                 if (!key) goto document_error;
332                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
333                         (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
347                 if (!key) goto document_error;
348                 value = yaml_document_add_scalar(&output_document, NULL,
349                     (yaml_char_t *)"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                     (yaml_char_t *)"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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
374                 if (!key) goto document_error;
375                 value = yaml_document_add_scalar(&output_document, NULL,
376                     (yaml_char_t *)"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                         (yaml_char_t *)"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                         (yaml_char_t *)"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                     (yaml_char_t *)"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                     (yaml_char_t *)"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                     (yaml_char_t *)"plain", -1, YAML_PLAIN_SCALAR_STYLE);
441                 if (!key) goto document_error;
442                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
443                         (yaml_char_t *)(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                     (yaml_char_t *)"quoted", -1, YAML_PLAIN_SCALAR_STYLE);
453                 if (!key) goto document_error;
454                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
455                         (yaml_char_t *)(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                         (yaml_char_t *)"style", -1, YAML_PLAIN_SCALAR_STYLE);
471                     if (!key) goto document_error;
472                     value = yaml_document_add_scalar(&output_document, NULL,
473                             (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
494                 if (!key) goto document_error;
495                 value = yaml_document_add_scalar(&output_document, NULL,
496                     (yaml_char_t *)"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                         (yaml_char_t *)"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                         (yaml_char_t *)"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                     (yaml_char_t *)"implicit", -1, YAML_PLAIN_SCALAR_STYLE);
535                 if (!key) goto document_error;
536                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
537                         (yaml_char_t *)(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                         (yaml_char_t *)"style", -1, YAML_PLAIN_SCALAR_STYLE);
554                     if (!key) goto document_error;
555                     value = yaml_document_add_scalar(&output_document, NULL,
556                             (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
572                 if (!key) goto document_error;
573                 value = yaml_document_add_scalar(&output_document, NULL,
574                     (yaml_char_t *)"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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
587                 if (!key) goto document_error;
588                 value = yaml_document_add_scalar(&output_document, NULL,
589                     (yaml_char_t *)"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                         (yaml_char_t *)"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                         (yaml_char_t *)"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                     (yaml_char_t *)"implicit", -1, YAML_PLAIN_SCALAR_STYLE);
628                 if (!key) goto document_error;
629                 value = yaml_document_add_scalar(&output_document, (yaml_char_t *)YAML_BOOL_TAG,
630                         (yaml_char_t *)(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                         = (yaml_sequence_style_t) input_event.data.mapping_start.style;
642 
643                     /* Add 'style': <style>. */
644 
645                     key = yaml_document_add_scalar(&output_document, NULL,
646                         (yaml_char_t *)"style", -1, YAML_PLAIN_SCALAR_STYLE);
647                     if (!key) goto document_error;
648                     value = yaml_document_add_scalar(&output_document, NULL,
649                             (yaml_char_t *)(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                     (yaml_char_t *)"type", -1, YAML_PLAIN_SCALAR_STYLE);
665                 if (!key) goto document_error;
666                 value = yaml_document_add_scalar(&output_document, NULL,
667                     (yaml_char_t *)"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 
694 parser_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 %zd\n", parser.problem,
707                         parser.problem_value, parser.problem_offset);
708             }
709             else {
710                 fprintf(stderr, "Reader error: %s at %zd\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 %lu, column %lu\n"
718                         "%s at line %lu, column %lu\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 %lu, column %lu\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 %lu, column %lu\n"
733                         "%s at line %lu, column %lu\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 %lu, column %lu\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 
758 emitter_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 
789 document_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