source: libyaml/trunk/tests/run-emitter.c @ 265

Revision 265, 8.5 KB checked in by xi, 6 years ago (diff)

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
15int 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
130int 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
155int
156main(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 repository browser.