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

Last change on this file since 1247 was 898, checked in by hartmans, 16 years ago

Add pyyaml and libyaml packages
backported from lenny.
There is discussion about how these should go in the repository; these are added in this form
in order to make forward progress.

File size: 12.9 KB
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 copy_event(yaml_event_t *event_to, yaml_event_t *event_from)
16{
17    switch (event_from->type)
18    {
19        case YAML_STREAM_START_EVENT:
20            return yaml_stream_start_event_initialize(event_to,
21                    event_from->data.stream_start.encoding);
22
23        case YAML_STREAM_END_EVENT:
24            return yaml_stream_end_event_initialize(event_to);
25
26        case YAML_DOCUMENT_START_EVENT:
27            return yaml_document_start_event_initialize(event_to,
28                    event_from->data.document_start.version_directive,
29                    event_from->data.document_start.tag_directives.start,
30                    event_from->data.document_start.tag_directives.end,
31                    event_from->data.document_start.implicit);
32
33        case YAML_DOCUMENT_END_EVENT:
34            return yaml_document_end_event_initialize(event_to,
35                    event_from->data.document_end.implicit);
36
37        case YAML_ALIAS_EVENT:
38            return yaml_alias_event_initialize(event_to,
39                    event_from->data.alias.anchor);
40
41        case YAML_SCALAR_EVENT:
42            return yaml_scalar_event_initialize(event_to,
43                    event_from->data.scalar.anchor,
44                    event_from->data.scalar.tag,
45                    event_from->data.scalar.value,
46                    event_from->data.scalar.length,
47                    event_from->data.scalar.plain_implicit,
48                    event_from->data.scalar.quoted_implicit,
49                    event_from->data.scalar.style);
50
51        case YAML_SEQUENCE_START_EVENT:
52            return yaml_sequence_start_event_initialize(event_to,
53                    event_from->data.sequence_start.anchor,
54                    event_from->data.sequence_start.tag,
55                    event_from->data.sequence_start.implicit,
56                    event_from->data.sequence_start.style);
57
58        case YAML_SEQUENCE_END_EVENT:
59            return yaml_sequence_end_event_initialize(event_to);
60
61        case YAML_MAPPING_START_EVENT:
62            return yaml_mapping_start_event_initialize(event_to,
63                    event_from->data.mapping_start.anchor,
64                    event_from->data.mapping_start.tag,
65                    event_from->data.mapping_start.implicit,
66                    event_from->data.mapping_start.style);
67
68        case YAML_MAPPING_END_EVENT:
69            return yaml_mapping_end_event_initialize(event_to);
70
71        default:
72            assert(1);
73    }
74
75    return 0;
76}
77
78int compare_events(yaml_event_t *event1, yaml_event_t *event2)
79{
80    int k;
81
82    if (event1->type != event2->type)
83        return 0;
84
85    switch (event1->type)
86    {
87        case YAML_STREAM_START_EVENT:
88            return 1;
89            /* return (event1->data.stream_start.encoding ==
90                    event2->data.stream_start.encoding); */
91
92        case YAML_DOCUMENT_START_EVENT:
93            if ((event1->data.document_start.version_directive && !event2->data.document_start.version_directive)
94                    || (!event1->data.document_start.version_directive && event2->data.document_start.version_directive)
95                    || (event1->data.document_start.version_directive && event2->data.document_start.version_directive
96                        && (event1->data.document_start.version_directive->major != event2->data.document_start.version_directive->major
97                            || event1->data.document_start.version_directive->minor != event2->data.document_start.version_directive->minor)))
98                return 0;
99            if ((event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start) !=
100                    (event2->data.document_start.tag_directives.end - event2->data.document_start.tag_directives.start))
101                return 0;
102            for (k = 0; k < (event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start); k ++) {
103                if ((strcmp((char *)event1->data.document_start.tag_directives.start[k].handle,
104                                (char *)event2->data.document_start.tag_directives.start[k].handle) != 0)
105                        || (strcmp((char *)event1->data.document_start.tag_directives.start[k].prefix,
106                            (char *)event2->data.document_start.tag_directives.start[k].prefix) != 0))
107                    return 0;
108            }
109            /* if (event1->data.document_start.implicit != event2->data.document_start.implicit)
110                return 0; */
111            return 1;
112
113        case YAML_DOCUMENT_END_EVENT:
114            return 1;
115            /* return (event1->data.document_end.implicit ==
116                    event2->data.document_end.implicit); */
117
118        case YAML_ALIAS_EVENT:
119            return (strcmp((char *)event1->data.alias.anchor,
120                        (char *)event2->data.alias.anchor) == 0);
121
122        case YAML_SCALAR_EVENT:
123            if ((event1->data.scalar.anchor && !event2->data.scalar.anchor)
124                    || (!event1->data.scalar.anchor && event2->data.scalar.anchor)
125                    || (event1->data.scalar.anchor && event2->data.scalar.anchor
126                        && strcmp((char *)event1->data.scalar.anchor,
127                            (char *)event2->data.scalar.anchor) != 0))
128                return 0;
129            if ((event1->data.scalar.tag && !event2->data.scalar.tag
130                        && strcmp((char *)event1->data.scalar.tag, "!") != 0)
131                    || (!event1->data.scalar.tag && event2->data.scalar.tag
132                        && strcmp((char *)event2->data.scalar.tag, "!") != 0)
133                    || (event1->data.scalar.tag && event2->data.scalar.tag
134                        && strcmp((char *)event1->data.scalar.tag,
135                            (char *)event2->data.scalar.tag) != 0))
136                return 0;
137            if ((event1->data.scalar.length != event2->data.scalar.length)
138                    || memcmp(event1->data.scalar.value, event2->data.scalar.value,
139                        event1->data.scalar.length) != 0)
140                return 0;
141            if ((event1->data.scalar.plain_implicit != event2->data.scalar.plain_implicit)
142                    || (event2->data.scalar.quoted_implicit != event2->data.scalar.quoted_implicit)
143                    /* || (event2->data.scalar.style != event2->data.scalar.style) */)
144                return 0;
145            return 1;
146
147        case YAML_SEQUENCE_START_EVENT:
148            if ((event1->data.sequence_start.anchor && !event2->data.sequence_start.anchor)
149                    || (!event1->data.sequence_start.anchor && event2->data.sequence_start.anchor)
150                    || (event1->data.sequence_start.anchor && event2->data.sequence_start.anchor
151                        && strcmp((char *)event1->data.sequence_start.anchor,
152                            (char *)event2->data.sequence_start.anchor) != 0))
153                return 0;
154            if ((event1->data.sequence_start.tag && !event2->data.sequence_start.tag)
155                    || (!event1->data.sequence_start.tag && event2->data.sequence_start.tag)
156                    || (event1->data.sequence_start.tag && event2->data.sequence_start.tag
157                        && strcmp((char *)event1->data.sequence_start.tag,
158                            (char *)event2->data.sequence_start.tag) != 0))
159                return 0;
160            if ((event1->data.sequence_start.implicit != event2->data.sequence_start.implicit)
161                    /* || (event2->data.sequence_start.style != event2->data.sequence_start.style) */)
162                return 0;
163            return 1;
164
165        case YAML_MAPPING_START_EVENT:
166            if ((event1->data.mapping_start.anchor && !event2->data.mapping_start.anchor)
167                    || (!event1->data.mapping_start.anchor && event2->data.mapping_start.anchor)
168                    || (event1->data.mapping_start.anchor && event2->data.mapping_start.anchor
169                        && strcmp((char *)event1->data.mapping_start.anchor,
170                            (char *)event2->data.mapping_start.anchor) != 0))
171                return 0;
172            if ((event1->data.mapping_start.tag && !event2->data.mapping_start.tag)
173                    || (!event1->data.mapping_start.tag && event2->data.mapping_start.tag)
174                    || (event1->data.mapping_start.tag && event2->data.mapping_start.tag
175                        && strcmp((char *)event1->data.mapping_start.tag,
176                            (char *)event2->data.mapping_start.tag) != 0))
177                return 0;
178            if ((event1->data.mapping_start.implicit != event2->data.mapping_start.implicit)
179                    /* || (event2->data.mapping_start.style != event2->data.mapping_start.style) */)
180                return 0;
181            return 1;
182
183        default:
184            return 1;
185    }
186}
187
188int print_output(char *name, unsigned char *buffer, size_t size, int count)
189{
190    FILE *file;
191    char data[BUFFER_SIZE];
192    size_t data_size = 1;
193    size_t total_size = 0;
194    if (count >= 0) {
195        printf("FAILED (at the event #%d)\nSOURCE:\n", count+1);
196    }
197    file = fopen(name, "rb");
198    assert(file);
199    while (data_size > 0) {
200        data_size = fread(data, 1, BUFFER_SIZE, file);
201        assert(!ferror(file));
202        if (!data_size) break;
203        assert(fwrite(data, 1, data_size, stdout) == data_size);
204        total_size += data_size;
205        if (feof(file)) break;
206    }
207    fclose(file);
208    printf("#### (length: %d)\n", total_size);
209    printf("OUTPUT:\n%s#### (length: %d)\n", buffer, size);
210    return 0;
211}
212
213int
214main(int argc, char *argv[])
215{
216    int number;
217    int canonical = 0;
218    int unicode = 0;
219
220    number = 1;
221    while (number < argc) {
222        if (strcmp(argv[number], "-c") == 0) {
223            canonical = 1;
224        }
225        else if (strcmp(argv[number], "-u") == 0) {
226            unicode = 1;
227        }
228        else if (argv[number][0] == '-') {
229            printf("Unknown option: '%s'\n", argv[number]);
230            return 0;
231        }
232        if (argv[number][0] == '-') {
233            if (number < argc-1) {
234                memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
235            }
236            argc --;
237        }
238        else {
239            number ++;
240        }
241    }
242
243    if (argc < 2) {
244        printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
245        return 0;
246    }
247
248    for (number = 1; number < argc; number ++)
249    {
250        FILE *file;
251        yaml_parser_t parser;
252        yaml_emitter_t emitter;
253        yaml_event_t event;
254        unsigned char buffer[BUFFER_SIZE];
255        size_t written = 0;
256        yaml_event_t events[MAX_EVENTS];
257        size_t event_number = 0;
258        int done = 0;
259        int count = 0;
260        int error = 0;
261        int k;
262        memset(buffer, 0, BUFFER_SIZE);
263        memset(events, 0, MAX_EVENTS*sizeof(yaml_event_t));
264
265        printf("[%d] Parsing, emitting, and parsing again '%s': ", number, argv[number]);
266        fflush(stdout);
267
268        file = fopen(argv[number], "rb");
269        assert(file);
270
271        assert(yaml_parser_initialize(&parser));
272        yaml_parser_set_input_file(&parser, file);
273        assert(yaml_emitter_initialize(&emitter));
274        if (canonical) {
275            yaml_emitter_set_canonical(&emitter, 1);
276        }
277        if (unicode) {
278            yaml_emitter_set_unicode(&emitter, 1);
279        }
280        yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
281
282        while (!done)
283        {
284            if (!yaml_parser_parse(&parser, &event)) {
285                error = 1;
286                break;
287            }
288
289            done = (event.type == YAML_STREAM_END_EVENT);
290            assert(event_number < MAX_EVENTS);
291            assert(copy_event(&(events[event_number++]), &event));
292            assert(yaml_emitter_emit(&emitter, &event) || 
293                    (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
294            count ++;
295        }
296
297        yaml_parser_delete(&parser);
298        assert(!fclose(file));
299        yaml_emitter_delete(&emitter);
300
301        if (!error)
302        {
303            count = done = 0;
304            assert(yaml_parser_initialize(&parser));
305            yaml_parser_set_input_string(&parser, buffer, written);
306
307            while (!done)
308            {
309                assert(yaml_parser_parse(&parser, &event) || print_output(argv[number], buffer, written, count));
310                done = (event.type == YAML_STREAM_END_EVENT);
311                assert(compare_events(events+count, &event) || print_output(argv[number], buffer, written, count));
312                yaml_event_delete(&event);
313                count ++;
314            }
315            yaml_parser_delete(&parser);
316        }
317
318        for (k = 0; k < event_number; k ++) {
319            yaml_event_delete(events+k);
320        }
321
322        printf("PASSED (length: %d)\n", written);
323        print_output(argv[number], buffer, written, -1);
324    }
325
326    return 0;
327}
Note: See TracBrowser for help on using the repository browser.