root/libyaml/trunk/tests/run-emitter.c

Revision 265, 8.5 kB (checked in by xi, 1 year ago)

Fixed bugs and updated tests.

Line 
1 #include <yaml.h>
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6
7 #ifdef NDEBUG
8 #undef NDEBUG
9 #endif
10 #include <assert.h>
11
12 #define BUFFER_SIZE 65536
13 #define MAX_EVENTS  1024
14
15 int compare_events(const yaml_event_t *event, const yaml_event_t *model)
16 {
17     yaml_char_t *event_anchor = NULL;
18     yaml_char_t *model_anchor = NULL;
19     yaml_char_t *event_tag = NULL;
20     yaml_char_t *model_tag = NULL;
21     yaml_char_t *event_value = NULL;
22     yaml_char_t *model_value = NULL;
23     size_t event_length = 0;
24     size_t model_length = 0;
25     int idx;
26
27     if (event->type != model->type)
28         return 0;
29
30     switch (event->type)
31     {
32         case YAML_DOCUMENT_START_EVENT:
33             if (!event->data.document_start.version_directive !=
34                     !model->data.document_start.version_directive)
35                 return 0;
36             if (event->data.document_start.version_directive) {
37                 yaml_version_directive_t *event_version_directive =
38                     event->data.document_start.version_directive;
39                 yaml_version_directive_t *model_version_directive =
40                     model->data.document_start.version_directive;
41                 if (event_version_directive->major !=
42                         model_version_directive->major ||
43                         event_version_directive->minor !=
44                         model_version_directive->minor)
45                     return 0;
46             }
47             if (event->data.document_start.tag_directives.length !=
48                     model->data.document_start.tag_directives.length)
49                 return 0;
50             for (idx = 0; idx < event->data.document_start.tag_directives.length; idx++) {
51                 yaml_tag_directive_t *event_tag_directive =
52                     event->data.document_start.tag_directives.list + idx;
53                 yaml_tag_directive_t *model_tag_directive =
54                     model->data.document_start.tag_directives.list + idx;
55                 if (strcmp(event_tag_directive->handle, model_tag_directive->handle))
56                     return 0;
57                 if (strcmp(event_tag_directive->prefix, model_tag_directive->prefix))
58                     return 0;
59             }
60             break;
61
62         case YAML_ALIAS_EVENT:
63             event_anchor = event->data.alias.anchor;
64             model_anchor = model->data.alias.anchor;
65             break;
66
67         case YAML_SCALAR_EVENT:
68             event_anchor = event->data.scalar.anchor;
69             model_anchor = model->data.scalar.anchor;
70             event_tag = event->data.scalar.tag;
71             model_tag = model->data.scalar.tag;
72             event_value = event->data.scalar.value;
73             model_value = model->data.scalar.value;
74             event_length = event->data.scalar.length;
75             model_length = model->data.scalar.length;
76             if (event->data.scalar.is_plain_implicit !=
77                     model->data.scalar.is_plain_implicit)
78                 return 0;
79             if (event->data.scalar.is_quoted_implicit !=
80                     model->data.scalar.is_quoted_implicit)
81                 return 0;
82             break;
83
84         case YAML_SEQUENCE_START_EVENT:
85             event_anchor = event->data.sequence_start.anchor;
86             model_anchor = model->data.sequence_start.anchor;
87             event_tag = event->data.sequence_start.tag;
88             model_tag = model->data.sequence_start.tag;
89             if (event->data.sequence_start.is_implicit !=
90                     model->data.sequence_start.is_implicit)
91                 return 0;
92             break;
93
94         case YAML_MAPPING_START_EVENT:
95             event_anchor = event->data.mapping_start.anchor;
96             model_anchor = model->data.mapping_start.anchor;
97             event_tag = event->data.mapping_start.tag;
98             model_tag = model->data.mapping_start.tag;
99             if (event->data.mapping_start.is_implicit !=
100                     model->data.mapping_start.is_implicit)
101                 return 0;
102             break;
103
104         default:
105             break;
106     }
107
108     if (!event_anchor != !model_anchor)
109         return 0;
110     if (event_anchor && strcmp(event_anchor, model_anchor))
111         return 0;
112
113     if (event_tag && !strcmp(event_tag, "!"))
114         event_tag = NULL;
115     if (model_tag && !strcmp(model_tag, "!"))
116         model_tag = NULL;
117     if (!event_tag != !model_tag)
118         return 0;
119     if (event_tag && strcmp(event_tag, model_tag))
120         return 0;
121
122     if (event_length != model_length)
123         return 0;
124     if (event_length && memcmp(event_value, model_value, event_length))
125         return 0;
126
127     return 1;
128 }
129
130 int print_output(char *name, unsigned char *buffer, size_t size, int count)
131 {
132     FILE *file;
133     char data[BUFFER_SIZE];
134     size_t data_size = 1;
135     size_t total_size = 0;
136     if (count >= 0) {
137         printf("FAILED (at the event #%d)\nSOURCE:\n", count+1);
138     }
139     file = fopen(name, "rb");
140     assert(file);
141     while (data_size > 0) {
142         data_size = fread(data, 1, BUFFER_SIZE, file);
143         assert(!ferror(file));
144         if (!data_size) break;
145         assert(fwrite(data, 1, data_size, stdout) == data_size);
146         total_size += data_size;
147         if (feof(file)) break;
148     }
149     fclose(file);
150     printf("#### (length: %d)\n", total_size);
151     printf("OUTPUT:\n%s#### (length: %d)\n", buffer, size);
152     return 0;
153 }
154
155 int
156 main(int argc, char *argv[])
157 {
158     int idx;
159     int is_canonical = 0;
160     int is_unicode = 0;
161
162     idx = 1;
163     while (idx < argc) {
164         if (strcmp(argv[idx], "-c") == 0) {
165             is_canonical = 1;
166         }
167         else if (strcmp(argv[idx], "-u") == 0) {
168             is_unicode = 1;
169         }
170         else if (argv[idx][0] == '-') {
171             printf("Unknown option: '%s'\n", argv[idx]);
172             return 0;
173         }
174         if (argv[idx][0] == '-') {
175             if (idx < argc-1) {
176                 memmove(argv+idx, argv+idx+1, (argc-idx-1)*sizeof(char *));
177             }
178             argc --;
179         }
180         else {
181             idx ++;
182         }
183     }
184
185     if (argc < 2) {
186         printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
187         return 0;
188     }
189
190     for (idx = 1; idx < argc; idx ++)
191     {
192         FILE *file;
193         yaml_parser_t *parser;
194         yaml_emitter_t *emitter;
195         yaml_event_t event;
196         unsigned char buffer[BUFFER_SIZE];
197         size_t written = 0;
198         yaml_event_t events[MAX_EVENTS];
199         size_t event_number = 0;
200         int count = 0;
201         int failed = 0;
202
203         memset(buffer, 0, BUFFER_SIZE);
204         memset(events, 0, MAX_EVENTS*sizeof(yaml_event_t));
205
206         printf("[%d] Parsing, emitting, and parsing again '%s': ", idx, argv[idx]);
207         fflush(stdout);
208
209         file = fopen(argv[idx], "rb");
210         assert(file);
211
212         parser = yaml_parser_new();
213         assert(parser);
214
215         yaml_parser_set_file_reader(parser, file);
216
217         emitter = yaml_emitter_new();
218         assert(emitter);
219
220         if (is_canonical) {
221             yaml_emitter_set_canonical(emitter, 1);
222         }
223         if (is_unicode) {
224             yaml_emitter_set_unicode(emitter, 1);
225         }
226         yaml_emitter_set_string_writer(emitter, buffer, BUFFER_SIZE, &written);
227
228         while (1)
229         {
230             if (!yaml_parser_parse_event(parser, &event))
231                 failed = 1;
232
233             if (!event.type)
234                 break;
235
236             assert(event_number < MAX_EVENTS);
237             yaml_event_duplicate(&(events[event_number++]), &event);
238             assert(yaml_emitter_emit_event(emitter, &event) ||
239                     (yaml_emitter_flush(emitter) &&
240                      print_output(argv[idx], buffer, written, count)));
241             count ++;
242         }
243
244         yaml_parser_delete(parser);
245         fclose(file);
246         yaml_emitter_delete(emitter);
247
248         if (!failed)
249         {
250             count = 0;
251             parser = yaml_parser_new();
252             yaml_parser_set_string_reader(parser, buffer, written);
253
254             while (1)
255             {
256                 assert(yaml_parser_parse_event(parser, &event) ||
257                         print_output(argv[idx], buffer, written, count));
258                 if (!event.type)
259                     break;
260                 assert(compare_events(events+count, &event) ||
261                         print_output(argv[idx], buffer, written, count));
262                 yaml_event_destroy(&event);
263                 count ++;
264             }
265             yaml_parser_delete(parser);
266         }
267
268         while(event_number) {
269             yaml_event_destroy(events+(--event_number));
270         }
271
272         printf("PASSED (length: %d)\n", written);
273         print_output(argv[idx], buffer, written, -1);
274     }
275
276     return 0;
277 }
Note: See TracBrowser for help on using the browser.