1247738Sbapt
2247738Sbapt#include <yaml.h>
3247738Sbapt
4247738Sbapt#include <stdlib.h>
5247738Sbapt#include <stdio.h>
6247738Sbapt
7247738Sbaptint
8247738Sbaptmain(int argc, char *argv[])
9247738Sbapt{
10247738Sbapt    int help = 0;
11247738Sbapt    int canonical = 0;
12247738Sbapt    int unicode = 0;
13247738Sbapt    int k;
14247738Sbapt    int done = 0;
15247738Sbapt
16247738Sbapt    yaml_parser_t parser;
17247738Sbapt    yaml_emitter_t emitter;
18247738Sbapt    yaml_document_t document;
19247738Sbapt
20247738Sbapt    /* Clear the objects. */
21247738Sbapt
22247738Sbapt    memset(&parser, 0, sizeof(parser));
23247738Sbapt    memset(&emitter, 0, sizeof(emitter));
24247738Sbapt    memset(&document, 0, sizeof(document));
25247738Sbapt
26247738Sbapt    /* Analyze command line options. */
27247738Sbapt
28247738Sbapt    for (k = 1; k < argc; k ++)
29247738Sbapt    {
30247738Sbapt        if (strcmp(argv[k], "-h") == 0
31247738Sbapt                || strcmp(argv[k], "--help") == 0) {
32247738Sbapt            help = 1;
33247738Sbapt        }
34247738Sbapt
35247738Sbapt        else if (strcmp(argv[k], "-c") == 0
36247738Sbapt                || strcmp(argv[k], "--canonical") == 0) {
37247738Sbapt            canonical = 1;
38247738Sbapt        }
39247738Sbapt
40247738Sbapt        else if (strcmp(argv[k], "-u") == 0
41247738Sbapt                || strcmp(argv[k], "--unicode") == 0) {
42247738Sbapt            unicode = 1;
43247738Sbapt        }
44247738Sbapt
45247738Sbapt        else {
46247738Sbapt            fprintf(stderr, "Unrecognized option: %s\n"
47247738Sbapt                    "Try `%s --help` for more information.\n",
48247738Sbapt                    argv[k], argv[0]);
49247738Sbapt            return 1;
50247738Sbapt        }
51247738Sbapt    }
52247738Sbapt
53247738Sbapt    /* Display the help string. */
54247738Sbapt
55247738Sbapt    if (help)
56247738Sbapt    {
57247738Sbapt        printf("%s [--canonical] [--unicode] <input >output\n"
58247738Sbapt                "or\n%s -h | --help\nReformat a YAML stream\n\nOptions:\n"
59247738Sbapt                "-h, --help\t\tdisplay this help and exit\n"
60247738Sbapt                "-c, --canonical\t\toutput in the canonical YAML format\n"
61247738Sbapt                "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
62247738Sbapt                argv[0], argv[0]);
63247738Sbapt        return 0;
64247738Sbapt    }
65247738Sbapt
66247738Sbapt    /* Initialize the parser and emitter objects. */
67247738Sbapt
68247738Sbapt    if (!yaml_parser_initialize(&parser))
69247738Sbapt        goto parser_error;
70247738Sbapt
71247738Sbapt    if (!yaml_emitter_initialize(&emitter))
72247738Sbapt        goto emitter_error;
73247738Sbapt
74247738Sbapt    /* Set the parser parameters. */
75247738Sbapt
76247738Sbapt    yaml_parser_set_input_file(&parser, stdin);
77247738Sbapt
78247738Sbapt    /* Set the emitter parameters. */
79247738Sbapt
80247738Sbapt    yaml_emitter_set_output_file(&emitter, stdout);
81247738Sbapt
82247738Sbapt    yaml_emitter_set_canonical(&emitter, canonical);
83247738Sbapt    yaml_emitter_set_unicode(&emitter, unicode);
84247738Sbapt
85247738Sbapt    /* The main loop. */
86247738Sbapt
87247738Sbapt    while (!done)
88247738Sbapt    {
89247738Sbapt        /* Get the next event. */
90247738Sbapt
91247738Sbapt        if (!yaml_parser_load(&parser, &document))
92247738Sbapt            goto parser_error;
93247738Sbapt
94247738Sbapt        /* Check if this is the stream end. */
95247738Sbapt
96247738Sbapt        if (!yaml_document_get_root_node(&document)) {
97247738Sbapt            done = 1;
98247738Sbapt        }
99247738Sbapt
100247738Sbapt        /* Emit the event. */
101247738Sbapt
102247738Sbapt        if (!yaml_emitter_dump(&emitter, &document))
103247738Sbapt            goto emitter_error;
104247738Sbapt    }
105247738Sbapt
106247738Sbapt    yaml_parser_delete(&parser);
107247738Sbapt    yaml_emitter_delete(&emitter);
108247738Sbapt
109247738Sbapt    return 0;
110247738Sbapt
111247738Sbaptparser_error:
112247738Sbapt
113247738Sbapt    /* Display a parser error message. */
114247738Sbapt
115247738Sbapt    switch (parser.error)
116247738Sbapt    {
117247738Sbapt        case YAML_MEMORY_ERROR:
118247738Sbapt            fprintf(stderr, "Memory error: Not enough memory for parsing\n");
119247738Sbapt            break;
120247738Sbapt
121247738Sbapt        case YAML_READER_ERROR:
122247738Sbapt            if (parser.problem_value != -1) {
123247738Sbapt                fprintf(stderr, "Reader error: %s: #%X at %d\n", parser.problem,
124247738Sbapt                        parser.problem_value, parser.problem_offset);
125247738Sbapt            }
126247738Sbapt            else {
127247738Sbapt                fprintf(stderr, "Reader error: %s at %d\n", parser.problem,
128247738Sbapt                        parser.problem_offset);
129247738Sbapt            }
130247738Sbapt            break;
131247738Sbapt
132247738Sbapt        case YAML_SCANNER_ERROR:
133247738Sbapt            if (parser.context) {
134247738Sbapt                fprintf(stderr, "Scanner error: %s at line %d, column %d\n"
135247738Sbapt                        "%s at line %d, column %d\n", parser.context,
136247738Sbapt                        parser.context_mark.line+1, parser.context_mark.column+1,
137247738Sbapt                        parser.problem, parser.problem_mark.line+1,
138247738Sbapt                        parser.problem_mark.column+1);
139247738Sbapt            }
140247738Sbapt            else {
141247738Sbapt                fprintf(stderr, "Scanner error: %s at line %d, column %d\n",
142247738Sbapt                        parser.problem, parser.problem_mark.line+1,
143247738Sbapt                        parser.problem_mark.column+1);
144247738Sbapt            }
145247738Sbapt            break;
146247738Sbapt
147247738Sbapt        case YAML_PARSER_ERROR:
148247738Sbapt            if (parser.context) {
149247738Sbapt                fprintf(stderr, "Parser error: %s at line %d, column %d\n"
150247738Sbapt                        "%s at line %d, column %d\n", parser.context,
151247738Sbapt                        parser.context_mark.line+1, parser.context_mark.column+1,
152247738Sbapt                        parser.problem, parser.problem_mark.line+1,
153247738Sbapt                        parser.problem_mark.column+1);
154247738Sbapt            }
155247738Sbapt            else {
156247738Sbapt                fprintf(stderr, "Parser error: %s at line %d, column %d\n",
157247738Sbapt                        parser.problem, parser.problem_mark.line+1,
158247738Sbapt                        parser.problem_mark.column+1);
159247738Sbapt            }
160247738Sbapt            break;
161247738Sbapt
162247738Sbapt        case YAML_COMPOSER_ERROR:
163247738Sbapt            if (parser.context) {
164247738Sbapt                fprintf(stderr, "Composer error: %s at line %d, column %d\n"
165247738Sbapt                        "%s at line %d, column %d\n", parser.context,
166247738Sbapt                        parser.context_mark.line+1, parser.context_mark.column+1,
167247738Sbapt                        parser.problem, parser.problem_mark.line+1,
168247738Sbapt                        parser.problem_mark.column+1);
169247738Sbapt            }
170247738Sbapt            else {
171247738Sbapt                fprintf(stderr, "Composer error: %s at line %d, column %d\n",
172247738Sbapt                        parser.problem, parser.problem_mark.line+1,
173247738Sbapt                        parser.problem_mark.column+1);
174247738Sbapt            }
175247738Sbapt            break;
176247738Sbapt
177247738Sbapt        default:
178247738Sbapt            /* Couldn't happen. */
179247738Sbapt            fprintf(stderr, "Internal error\n");
180247738Sbapt            break;
181247738Sbapt    }
182247738Sbapt
183247738Sbapt    yaml_parser_delete(&parser);
184247738Sbapt    yaml_emitter_delete(&emitter);
185247738Sbapt
186247738Sbapt    return 1;
187247738Sbapt
188247738Sbaptemitter_error:
189247738Sbapt
190247738Sbapt    /* Display an emitter error message. */
191247738Sbapt
192247738Sbapt    switch (emitter.error)
193247738Sbapt    {
194247738Sbapt        case YAML_MEMORY_ERROR:
195247738Sbapt            fprintf(stderr, "Memory error: Not enough memory for emitting\n");
196247738Sbapt            break;
197247738Sbapt
198247738Sbapt        case YAML_WRITER_ERROR:
199247738Sbapt            fprintf(stderr, "Writer error: %s\n", emitter.problem);
200247738Sbapt            break;
201247738Sbapt
202247738Sbapt        case YAML_EMITTER_ERROR:
203247738Sbapt            fprintf(stderr, "Emitter error: %s\n", emitter.problem);
204247738Sbapt            break;
205247738Sbapt
206247738Sbapt        default:
207247738Sbapt            /* Couldn't happen. */
208247738Sbapt            fprintf(stderr, "Internal error\n");
209247738Sbapt            break;
210247738Sbapt    }
211247738Sbapt
212247738Sbapt    yaml_parser_delete(&parser);
213247738Sbapt    yaml_emitter_delete(&emitter);
214247738Sbapt
215247738Sbapt    return 1;
216247738Sbapt}
217247738Sbapt
218