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_document_t document;
19 
20     /* Clear the objects. */
21 
22     memset(&parser, 0, sizeof(parser));
23     memset(&emitter, 0, sizeof(emitter));
24     memset(&document, 0, sizeof(document));
25 
26     /* Analyze command line options. */
27 
28     for (k = 1; k < argc; k ++)
29     {
30         if (strcmp(argv[k], "-h") == 0
31                 || strcmp(argv[k], "--help") == 0) {
32             help = 1;
33         }
34 
35         else if (strcmp(argv[k], "-c") == 0
36                 || strcmp(argv[k], "--canonical") == 0) {
37             canonical = 1;
38         }
39 
40         else if (strcmp(argv[k], "-u") == 0
41                 || strcmp(argv[k], "--unicode") == 0) {
42             unicode = 1;
43         }
44 
45         else {
46             fprintf(stderr, "Unrecognized option: %s\n"
47                     "Try `%s --help` for more information.\n",
48                     argv[k], argv[0]);
49             return 1;
50         }
51     }
52 
53     /* Display the help string. */
54 
55     if (help)
56     {
57         printf("%s [--canonical] [--unicode] <input >output\n"
58                 "or\n%s -h | --help\nReformat a YAML stream\n\nOptions:\n"
59                 "-h, --help\t\tdisplay this help and exit\n"
60                 "-c, --canonical\t\toutput in the canonical YAML format\n"
61                 "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
62                 argv[0], argv[0]);
63         return 0;
64     }
65 
66     /* Initialize the parser and emitter objects. */
67 
68     if (!yaml_parser_initialize(&parser))
69         goto parser_error;
70 
71     if (!yaml_emitter_initialize(&emitter))
72         goto emitter_error;
73 
74     /* Set the parser parameters. */
75 
76     yaml_parser_set_input_file(&parser, stdin);
77 
78     /* Set the emitter parameters. */
79 
80     yaml_emitter_set_output_file(&emitter, stdout);
81 
82     yaml_emitter_set_canonical(&emitter, canonical);
83     yaml_emitter_set_unicode(&emitter, unicode);
84 
85     /* The main loop. */
86 
87     while (!done)
88     {
89         /* Get the next event. */
90 
91         if (!yaml_parser_load(&parser, &document))
92             goto parser_error;
93 
94         /* Check if this is the stream end. */
95 
96         if (!yaml_document_get_root_node(&document)) {
97             done = 1;
98         }
99 
100         /* Emit the event. */
101 
102         if (!yaml_emitter_dump(&emitter, &document))
103             goto emitter_error;
104     }
105 
106     yaml_parser_delete(&parser);
107     yaml_emitter_delete(&emitter);
108 
109     return 0;
110 
111 parser_error:
112 
113     /* Display a parser error message. */
114 
115     switch (parser.error)
116     {
117         case YAML_MEMORY_ERROR:
118             fprintf(stderr, "Memory error: Not enough memory for parsing\n");
119             break;
120 
121         case YAML_READER_ERROR:
122             if (parser.problem_value != -1) {
123                 fprintf(stderr, "Reader error: %s: #%X at %zd\n", parser.problem,
124                         parser.problem_value, parser.problem_offset);
125             }
126             else {
127                 fprintf(stderr, "Reader error: %s at %lu\n", parser.problem,
128                         parser.problem_offset);
129             }
130             break;
131 
132         case YAML_SCANNER_ERROR:
133             if (parser.context) {
134                 fprintf(stderr, "Scanner error: %s at line %lu, column %lu\n"
135                         "%s at line %lu, column %lu\n", parser.context,
136                         parser.context_mark.line+1, parser.context_mark.column+1,
137                         parser.problem, parser.problem_mark.line+1,
138                         parser.problem_mark.column+1);
139             }
140             else {
141                 fprintf(stderr, "Scanner error: %s at line %lu, column %lu\n",
142                         parser.problem, parser.problem_mark.line+1,
143                         parser.problem_mark.column+1);
144             }
145             break;
146 
147         case YAML_PARSER_ERROR:
148             if (parser.context) {
149                 fprintf(stderr, "Parser error: %s at line %lu, column %lu\n"
150                         "%s at line %lu, column %lu\n", parser.context,
151                         parser.context_mark.line+1, parser.context_mark.column+1,
152                         parser.problem, parser.problem_mark.line+1,
153                         parser.problem_mark.column+1);
154             }
155             else {
156                 fprintf(stderr, "Parser error: %s at line %lu, column %lu\n",
157                         parser.problem, parser.problem_mark.line+1,
158                         parser.problem_mark.column+1);
159             }
160             break;
161 
162         case YAML_COMPOSER_ERROR:
163             if (parser.context) {
164                 fprintf(stderr, "Composer error: %s at line %lu, column %lu\n"
165                         "%s at line %lu, column %lu\n", parser.context,
166                         parser.context_mark.line+1, parser.context_mark.column+1,
167                         parser.problem, parser.problem_mark.line+1,
168                         parser.problem_mark.column+1);
169             }
170             else {
171                 fprintf(stderr, "Composer error: %s at line %lu, column %lu\n",
172                         parser.problem, parser.problem_mark.line+1,
173                         parser.problem_mark.column+1);
174             }
175             break;
176 
177         default:
178             /* Couldn't happen. */
179             fprintf(stderr, "Internal error\n");
180             break;
181     }
182 
183     yaml_parser_delete(&parser);
184     yaml_emitter_delete(&emitter);
185 
186     return 1;
187 
188 emitter_error:
189 
190     /* Display an emitter error message. */
191 
192     switch (emitter.error)
193     {
194         case YAML_MEMORY_ERROR:
195             fprintf(stderr, "Memory error: Not enough memory for emitting\n");
196             break;
197 
198         case YAML_WRITER_ERROR:
199             fprintf(stderr, "Writer error: %s\n", emitter.problem);
200             break;
201 
202         case YAML_EMITTER_ERROR:
203             fprintf(stderr, "Emitter error: %s\n", emitter.problem);
204             break;
205 
206         default:
207             /* Couldn't happen. */
208             fprintf(stderr, "Internal error\n");
209             break;
210     }
211 
212     yaml_parser_delete(&parser);
213     yaml_emitter_delete(&emitter);
214 
215     return 1;
216 }
217 
218