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