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 event;
19
20    /* Clear the objects. */
21
22    memset(&parser, 0, sizeof(parser));
23    memset(&emitter, 0, sizeof(emitter));
24    memset(&event, 0, sizeof(event));
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_parse(&parser, &event))
92            goto parser_error;
93
94        /* Check if this is the stream end. */
95
96        if (event.type == YAML_STREAM_END_EVENT) {
97            done = 1;
98        }
99
100        /* Emit the event. */
101
102        if (!yaml_emitter_emit(&emitter, &event))
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        default:
163            /* Couldn't happen. */
164            fprintf(stderr, "Internal error\n");
165            break;
166    }
167
168    yaml_parser_delete(&parser);
169    yaml_emitter_delete(&emitter);
170
171    return 1;
172
173emitter_error:
174
175    /* Display an emitter error message. */
176
177    switch (emitter.error)
178    {
179        case YAML_MEMORY_ERROR:
180            fprintf(stderr, "Memory error: Not enough memory for emitting\n");
181            break;
182
183        case YAML_WRITER_ERROR:
184            fprintf(stderr, "Writer error: %s\n", emitter.problem);
185            break;
186
187        case YAML_EMITTER_ERROR:
188            fprintf(stderr, "Emitter error: %s\n", emitter.problem);
189            break;
190
191        default:
192            /* Couldn't happen. */
193            fprintf(stderr, "Internal error\n");
194            break;
195    }
196
197    yaml_parser_delete(&parser);
198    yaml_emitter_delete(&emitter);
199
200    return 1;
201}
202
203