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_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
111parser_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 %d\n", parser.problem,
124                        parser.problem_value, parser.problem_offset);
125            }
126            else {
127                fprintf(stderr, "Reader error: %s at %d\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 %d, column %d\n"
135                        "%s at line %d, column %d\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 %d, column %d\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 %d, column %d\n"
150                        "%s at line %d, column %d\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 %d, column %d\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 %d, column %d\n"
165                        "%s at line %d, column %d\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 %d, column %d\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
188emitter_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