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