1*0f5c86ddSBaptiste Daroussin #include <yaml.h>
2*0f5c86ddSBaptiste Daroussin
3*0f5c86ddSBaptiste Daroussin #include <stdlib.h>
4*0f5c86ddSBaptiste Daroussin #include <stdio.h>
5*0f5c86ddSBaptiste Daroussin #include <assert.h>
6*0f5c86ddSBaptiste Daroussin #include "../src/yaml_private.h"
7*0f5c86ddSBaptiste Daroussin
8*0f5c86ddSBaptiste Daroussin int get_line(FILE * input, char *line);
9*0f5c86ddSBaptiste Daroussin char *get_anchor(char sigil, char *line, char *anchor);
10*0f5c86ddSBaptiste Daroussin char *get_tag(char *line, char *tag);
11*0f5c86ddSBaptiste Daroussin void get_value(char *line, char *value, int *style);
12*0f5c86ddSBaptiste Daroussin int usage(int ret);
13*0f5c86ddSBaptiste Daroussin
main(int argc,char * argv[])14*0f5c86ddSBaptiste Daroussin int main(int argc, char *argv[])
15*0f5c86ddSBaptiste Daroussin {
16*0f5c86ddSBaptiste Daroussin FILE *input;
17*0f5c86ddSBaptiste Daroussin yaml_emitter_t emitter;
18*0f5c86ddSBaptiste Daroussin yaml_event_t event;
19*0f5c86ddSBaptiste Daroussin yaml_version_directive_t *version_directive = NULL;
20*0f5c86ddSBaptiste Daroussin
21*0f5c86ddSBaptiste Daroussin int canonical = 0;
22*0f5c86ddSBaptiste Daroussin int unicode = 0;
23*0f5c86ddSBaptiste Daroussin char line[1024];
24*0f5c86ddSBaptiste Daroussin int foundfile = 0;
25*0f5c86ddSBaptiste Daroussin int i = 0;
26*0f5c86ddSBaptiste Daroussin int minor = 0;
27*0f5c86ddSBaptiste Daroussin int flow = -1; /** default no flow style collections */
28*0f5c86ddSBaptiste Daroussin
29*0f5c86ddSBaptiste Daroussin for (i = 1; i < argc; i++) {
30*0f5c86ddSBaptiste Daroussin if (strncmp(argv[i], "--help", 6) == 0)
31*0f5c86ddSBaptiste Daroussin return usage(0);
32*0f5c86ddSBaptiste Daroussin if (strncmp(argv[i], "-h", 2) == 0)
33*0f5c86ddSBaptiste Daroussin return usage(0);
34*0f5c86ddSBaptiste Daroussin if (strncmp(argv[i], "--flow", 6) == 0) {
35*0f5c86ddSBaptiste Daroussin if (i+1 == argc)
36*0f5c86ddSBaptiste Daroussin return usage(1);
37*0f5c86ddSBaptiste Daroussin i++;
38*0f5c86ddSBaptiste Daroussin if (strncmp(argv[i], "keep", 4) == 0)
39*0f5c86ddSBaptiste Daroussin flow = 0;
40*0f5c86ddSBaptiste Daroussin else if (strncmp(argv[i], "on", 2) == 0)
41*0f5c86ddSBaptiste Daroussin flow = 1;
42*0f5c86ddSBaptiste Daroussin else if (strncmp(argv[i], "off", 3) == 0)
43*0f5c86ddSBaptiste Daroussin flow = -1;
44*0f5c86ddSBaptiste Daroussin else
45*0f5c86ddSBaptiste Daroussin return usage(1);
46*0f5c86ddSBaptiste Daroussin }
47*0f5c86ddSBaptiste Daroussin else if (strncmp(argv[i], "--directive", 11) == 0) {
48*0f5c86ddSBaptiste Daroussin if (i+1 == argc)
49*0f5c86ddSBaptiste Daroussin return usage(1);
50*0f5c86ddSBaptiste Daroussin i++;
51*0f5c86ddSBaptiste Daroussin if (strncmp(argv[i], "1.1", 3) == 0)
52*0f5c86ddSBaptiste Daroussin minor = 1;
53*0f5c86ddSBaptiste Daroussin else if (strncmp(argv[i], "1.2", 3) == 0)
54*0f5c86ddSBaptiste Daroussin minor = 2;
55*0f5c86ddSBaptiste Daroussin else
56*0f5c86ddSBaptiste Daroussin return usage(1);
57*0f5c86ddSBaptiste Daroussin }
58*0f5c86ddSBaptiste Daroussin else if (!foundfile) {
59*0f5c86ddSBaptiste Daroussin input = fopen(argv[i], "rb");
60*0f5c86ddSBaptiste Daroussin foundfile = 1;
61*0f5c86ddSBaptiste Daroussin }
62*0f5c86ddSBaptiste Daroussin
63*0f5c86ddSBaptiste Daroussin }
64*0f5c86ddSBaptiste Daroussin if (minor) {
65*0f5c86ddSBaptiste Daroussin version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
66*0f5c86ddSBaptiste Daroussin version_directive->major = 1;
67*0f5c86ddSBaptiste Daroussin version_directive->minor = minor;
68*0f5c86ddSBaptiste Daroussin }
69*0f5c86ddSBaptiste Daroussin if (!foundfile)
70*0f5c86ddSBaptiste Daroussin input = stdin;
71*0f5c86ddSBaptiste Daroussin
72*0f5c86ddSBaptiste Daroussin assert(input);
73*0f5c86ddSBaptiste Daroussin
74*0f5c86ddSBaptiste Daroussin if (!yaml_emitter_initialize(&emitter)) {
75*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Could not initalize the emitter object\n");
76*0f5c86ddSBaptiste Daroussin return 1;
77*0f5c86ddSBaptiste Daroussin }
78*0f5c86ddSBaptiste Daroussin yaml_emitter_set_output_file(&emitter, stdout);
79*0f5c86ddSBaptiste Daroussin yaml_emitter_set_canonical(&emitter, canonical);
80*0f5c86ddSBaptiste Daroussin yaml_emitter_set_unicode(&emitter, unicode);
81*0f5c86ddSBaptiste Daroussin
82*0f5c86ddSBaptiste Daroussin
83*0f5c86ddSBaptiste Daroussin while (get_line(input, line)) {
84*0f5c86ddSBaptiste Daroussin int ok;
85*0f5c86ddSBaptiste Daroussin char anchor[256];
86*0f5c86ddSBaptiste Daroussin char tag[256];
87*0f5c86ddSBaptiste Daroussin int implicit;
88*0f5c86ddSBaptiste Daroussin int style;
89*0f5c86ddSBaptiste Daroussin
90*0f5c86ddSBaptiste Daroussin if (strncmp(line, "+STR", 4) == 0) {
91*0f5c86ddSBaptiste Daroussin ok = yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
92*0f5c86ddSBaptiste Daroussin }
93*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "-STR", 4) == 0) {
94*0f5c86ddSBaptiste Daroussin ok = yaml_stream_end_event_initialize(&event);
95*0f5c86ddSBaptiste Daroussin }
96*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "+DOC", 4) == 0) {
97*0f5c86ddSBaptiste Daroussin implicit = strncmp(line+4, " ---", 4) != 0;
98*0f5c86ddSBaptiste Daroussin ok = yaml_document_start_event_initialize(&event, version_directive, NULL, NULL, implicit);
99*0f5c86ddSBaptiste Daroussin }
100*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "-DOC", 4) == 0) {
101*0f5c86ddSBaptiste Daroussin implicit = strncmp(line+4, " ...", 4) != 0;
102*0f5c86ddSBaptiste Daroussin ok = yaml_document_end_event_initialize(&event, implicit);
103*0f5c86ddSBaptiste Daroussin }
104*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "+MAP", 4) == 0) {
105*0f5c86ddSBaptiste Daroussin style = YAML_BLOCK_MAPPING_STYLE;
106*0f5c86ddSBaptiste Daroussin if (flow == 1)
107*0f5c86ddSBaptiste Daroussin style = YAML_FLOW_MAPPING_STYLE;
108*0f5c86ddSBaptiste Daroussin else if (flow == 0 && strncmp(line+5, "{}", 2) == 0)
109*0f5c86ddSBaptiste Daroussin style = YAML_FLOW_MAPPING_STYLE;
110*0f5c86ddSBaptiste Daroussin ok = yaml_mapping_start_event_initialize(&event, (yaml_char_t *)
111*0f5c86ddSBaptiste Daroussin get_anchor('&', line, anchor), (yaml_char_t *)
112*0f5c86ddSBaptiste Daroussin get_tag(line, tag), 0, style);
113*0f5c86ddSBaptiste Daroussin }
114*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "-MAP", 4) == 0) {
115*0f5c86ddSBaptiste Daroussin ok = yaml_mapping_end_event_initialize(&event);
116*0f5c86ddSBaptiste Daroussin }
117*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "+SEQ", 4) == 0) {
118*0f5c86ddSBaptiste Daroussin style = YAML_BLOCK_SEQUENCE_STYLE;
119*0f5c86ddSBaptiste Daroussin if (flow == 1)
120*0f5c86ddSBaptiste Daroussin style = YAML_FLOW_MAPPING_STYLE;
121*0f5c86ddSBaptiste Daroussin else if (flow == 0 && strncmp(line+5, "[]", 2) == 0)
122*0f5c86ddSBaptiste Daroussin style = YAML_FLOW_SEQUENCE_STYLE;
123*0f5c86ddSBaptiste Daroussin ok = yaml_sequence_start_event_initialize(&event, (yaml_char_t *)
124*0f5c86ddSBaptiste Daroussin get_anchor('&', line, anchor), (yaml_char_t *)
125*0f5c86ddSBaptiste Daroussin get_tag(line, tag), 0, style);
126*0f5c86ddSBaptiste Daroussin }
127*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "-SEQ", 4) == 0) {
128*0f5c86ddSBaptiste Daroussin ok = yaml_sequence_end_event_initialize(&event);
129*0f5c86ddSBaptiste Daroussin }
130*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "=VAL", 4) == 0) {
131*0f5c86ddSBaptiste Daroussin char value[1024];
132*0f5c86ddSBaptiste Daroussin int style;
133*0f5c86ddSBaptiste Daroussin
134*0f5c86ddSBaptiste Daroussin get_value(line, value, &style);
135*0f5c86ddSBaptiste Daroussin implicit = (get_tag(line, tag) == NULL);
136*0f5c86ddSBaptiste Daroussin
137*0f5c86ddSBaptiste Daroussin ok = yaml_scalar_event_initialize(&event, (yaml_char_t *)
138*0f5c86ddSBaptiste Daroussin get_anchor('&', line, anchor), (yaml_char_t *) get_tag(line, tag), (yaml_char_t *) value, -1, implicit, implicit, style);
139*0f5c86ddSBaptiste Daroussin }
140*0f5c86ddSBaptiste Daroussin else if (strncmp(line, "=ALI", 4) == 0) {
141*0f5c86ddSBaptiste Daroussin ok = yaml_alias_event_initialize(&event, (yaml_char_t *)
142*0f5c86ddSBaptiste Daroussin get_anchor('*', line, anchor)
143*0f5c86ddSBaptiste Daroussin );
144*0f5c86ddSBaptiste Daroussin }
145*0f5c86ddSBaptiste Daroussin else {
146*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Unknown event: '%s'\n", line);
147*0f5c86ddSBaptiste Daroussin fflush(stdout);
148*0f5c86ddSBaptiste Daroussin return 1;
149*0f5c86ddSBaptiste Daroussin }
150*0f5c86ddSBaptiste Daroussin
151*0f5c86ddSBaptiste Daroussin if (!ok)
152*0f5c86ddSBaptiste Daroussin goto event_error;
153*0f5c86ddSBaptiste Daroussin if (!yaml_emitter_emit(&emitter, &event))
154*0f5c86ddSBaptiste Daroussin goto emitter_error;
155*0f5c86ddSBaptiste Daroussin }
156*0f5c86ddSBaptiste Daroussin
157*0f5c86ddSBaptiste Daroussin assert(!fclose(input));
158*0f5c86ddSBaptiste Daroussin yaml_emitter_delete(&emitter);
159*0f5c86ddSBaptiste Daroussin fflush(stdout);
160*0f5c86ddSBaptiste Daroussin
161*0f5c86ddSBaptiste Daroussin return 0;
162*0f5c86ddSBaptiste Daroussin
163*0f5c86ddSBaptiste Daroussin emitter_error:
164*0f5c86ddSBaptiste Daroussin switch (emitter.error) {
165*0f5c86ddSBaptiste Daroussin case YAML_MEMORY_ERROR:
166*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Memory error: Not enough memory for emitting\n");
167*0f5c86ddSBaptiste Daroussin break;
168*0f5c86ddSBaptiste Daroussin case YAML_WRITER_ERROR:
169*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Writer error: %s\n", emitter.problem);
170*0f5c86ddSBaptiste Daroussin break;
171*0f5c86ddSBaptiste Daroussin case YAML_EMITTER_ERROR:
172*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Emitter error: %s\n", emitter.problem);
173*0f5c86ddSBaptiste Daroussin break;
174*0f5c86ddSBaptiste Daroussin default:
175*0f5c86ddSBaptiste Daroussin /*
176*0f5c86ddSBaptiste Daroussin * Couldn't happen.
177*0f5c86ddSBaptiste Daroussin */
178*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Internal error\n");
179*0f5c86ddSBaptiste Daroussin break;
180*0f5c86ddSBaptiste Daroussin }
181*0f5c86ddSBaptiste Daroussin yaml_emitter_delete(&emitter);
182*0f5c86ddSBaptiste Daroussin return 1;
183*0f5c86ddSBaptiste Daroussin
184*0f5c86ddSBaptiste Daroussin event_error:
185*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Memory error: Not enough memory for creating an event\n");
186*0f5c86ddSBaptiste Daroussin yaml_emitter_delete(&emitter);
187*0f5c86ddSBaptiste Daroussin return 1;
188*0f5c86ddSBaptiste Daroussin }
189*0f5c86ddSBaptiste Daroussin
get_line(FILE * input,char * line)190*0f5c86ddSBaptiste Daroussin int get_line(FILE * input, char *line)
191*0f5c86ddSBaptiste Daroussin {
192*0f5c86ddSBaptiste Daroussin char *newline;
193*0f5c86ddSBaptiste Daroussin
194*0f5c86ddSBaptiste Daroussin if (!fgets(line, 1024 - 1, input))
195*0f5c86ddSBaptiste Daroussin return 0;
196*0f5c86ddSBaptiste Daroussin
197*0f5c86ddSBaptiste Daroussin if ((newline = strchr(line, '\n')) == NULL) {
198*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Line too long: '%s'", line);
199*0f5c86ddSBaptiste Daroussin abort();
200*0f5c86ddSBaptiste Daroussin }
201*0f5c86ddSBaptiste Daroussin *newline = '\0';
202*0f5c86ddSBaptiste Daroussin
203*0f5c86ddSBaptiste Daroussin return 1;
204*0f5c86ddSBaptiste Daroussin }
205*0f5c86ddSBaptiste Daroussin
get_anchor(char sigil,char * line,char * anchor)206*0f5c86ddSBaptiste Daroussin char *get_anchor(char sigil, char *line, char *anchor)
207*0f5c86ddSBaptiste Daroussin {
208*0f5c86ddSBaptiste Daroussin char *start;
209*0f5c86ddSBaptiste Daroussin char *end;
210*0f5c86ddSBaptiste Daroussin if ((start = strchr(line, sigil)) == NULL)
211*0f5c86ddSBaptiste Daroussin return NULL;
212*0f5c86ddSBaptiste Daroussin start++;
213*0f5c86ddSBaptiste Daroussin if ((end = strchr(start, ' ')) == NULL)
214*0f5c86ddSBaptiste Daroussin end = line + strlen(line);
215*0f5c86ddSBaptiste Daroussin memcpy(anchor, start, end - start);
216*0f5c86ddSBaptiste Daroussin anchor[end - start] = '\0';
217*0f5c86ddSBaptiste Daroussin return anchor;
218*0f5c86ddSBaptiste Daroussin }
219*0f5c86ddSBaptiste Daroussin
get_tag(char * line,char * tag)220*0f5c86ddSBaptiste Daroussin char *get_tag(char *line, char *tag)
221*0f5c86ddSBaptiste Daroussin {
222*0f5c86ddSBaptiste Daroussin char *start;
223*0f5c86ddSBaptiste Daroussin char *end;
224*0f5c86ddSBaptiste Daroussin if ((start = strchr(line, '<')) == NULL)
225*0f5c86ddSBaptiste Daroussin return NULL;
226*0f5c86ddSBaptiste Daroussin if ((end = strchr(line, '>')) == NULL)
227*0f5c86ddSBaptiste Daroussin return NULL;
228*0f5c86ddSBaptiste Daroussin memcpy(tag, start + 1, end - start - 1);
229*0f5c86ddSBaptiste Daroussin tag[end - start - 1] = '\0';
230*0f5c86ddSBaptiste Daroussin return tag;
231*0f5c86ddSBaptiste Daroussin }
232*0f5c86ddSBaptiste Daroussin
get_value(char * line,char * value,int * style)233*0f5c86ddSBaptiste Daroussin void get_value(char *line, char *value, int *style)
234*0f5c86ddSBaptiste Daroussin {
235*0f5c86ddSBaptiste Daroussin int i = 0;
236*0f5c86ddSBaptiste Daroussin char *c;
237*0f5c86ddSBaptiste Daroussin char *start = NULL;
238*0f5c86ddSBaptiste Daroussin char *end = line + strlen(line);
239*0f5c86ddSBaptiste Daroussin
240*0f5c86ddSBaptiste Daroussin for (c = line + 4; c < end; c++) {
241*0f5c86ddSBaptiste Daroussin if (*c == ' ') {
242*0f5c86ddSBaptiste Daroussin start = c + 1;
243*0f5c86ddSBaptiste Daroussin if (*start == ':')
244*0f5c86ddSBaptiste Daroussin *style = YAML_PLAIN_SCALAR_STYLE;
245*0f5c86ddSBaptiste Daroussin else if (*start == '\'')
246*0f5c86ddSBaptiste Daroussin *style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
247*0f5c86ddSBaptiste Daroussin else if (*start == '"')
248*0f5c86ddSBaptiste Daroussin *style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
249*0f5c86ddSBaptiste Daroussin else if (*start == '|')
250*0f5c86ddSBaptiste Daroussin *style = YAML_LITERAL_SCALAR_STYLE;
251*0f5c86ddSBaptiste Daroussin else if (*start == '>')
252*0f5c86ddSBaptiste Daroussin *style = YAML_FOLDED_SCALAR_STYLE;
253*0f5c86ddSBaptiste Daroussin else {
254*0f5c86ddSBaptiste Daroussin start = NULL;
255*0f5c86ddSBaptiste Daroussin continue;
256*0f5c86ddSBaptiste Daroussin }
257*0f5c86ddSBaptiste Daroussin start++;
258*0f5c86ddSBaptiste Daroussin break;
259*0f5c86ddSBaptiste Daroussin }
260*0f5c86ddSBaptiste Daroussin }
261*0f5c86ddSBaptiste Daroussin if (!start)
262*0f5c86ddSBaptiste Daroussin abort();
263*0f5c86ddSBaptiste Daroussin
264*0f5c86ddSBaptiste Daroussin for (c = start; c < end; c++) {
265*0f5c86ddSBaptiste Daroussin if (*c == '\\') {
266*0f5c86ddSBaptiste Daroussin if (*++c == '\\')
267*0f5c86ddSBaptiste Daroussin value[i++] = '\\';
268*0f5c86ddSBaptiste Daroussin else if (*c == '0')
269*0f5c86ddSBaptiste Daroussin value[i++] = '\0';
270*0f5c86ddSBaptiste Daroussin else if (*c == 'b')
271*0f5c86ddSBaptiste Daroussin value[i++] = '\b';
272*0f5c86ddSBaptiste Daroussin else if (*c == 'n')
273*0f5c86ddSBaptiste Daroussin value[i++] = '\n';
274*0f5c86ddSBaptiste Daroussin else if (*c == 'r')
275*0f5c86ddSBaptiste Daroussin value[i++] = '\r';
276*0f5c86ddSBaptiste Daroussin else if (*c == 't')
277*0f5c86ddSBaptiste Daroussin value[i++] = '\t';
278*0f5c86ddSBaptiste Daroussin else
279*0f5c86ddSBaptiste Daroussin abort();
280*0f5c86ddSBaptiste Daroussin }
281*0f5c86ddSBaptiste Daroussin else
282*0f5c86ddSBaptiste Daroussin value[i++] = *c;
283*0f5c86ddSBaptiste Daroussin }
284*0f5c86ddSBaptiste Daroussin value[i] = '\0';
285*0f5c86ddSBaptiste Daroussin }
286*0f5c86ddSBaptiste Daroussin
usage(int ret)287*0f5c86ddSBaptiste Daroussin int usage(int ret) {
288*0f5c86ddSBaptiste Daroussin fprintf(stderr, "Usage: run-emitter-test-suite [--directive (1.1|1.2)] [--flow (on|off|keep)] [<input-file>]\n");
289*0f5c86ddSBaptiste Daroussin return ret;
290*0f5c86ddSBaptiste Daroussin }
291