source: trunk/packages/libyaml/tests/run-dumper.c @ 898

Last change on this file since 898 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: 10.4 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_DOCUMENTS  16
14
15int copy_document(yaml_document_t *document_to, yaml_document_t *document_from)
16{
17    yaml_node_t *node;
18    yaml_node_item_t *item;
19    yaml_node_pair_t *pair;
20
21    if (!yaml_document_initialize(document_to, document_from->version_directive,
22                document_from->tag_directives.start,
23                document_from->tag_directives.end,
24                document_from->start_implicit, document_from->end_implicit))
25        return 0;
26
27    for (node = document_from->nodes.start;
28            node < document_from->nodes.top; node ++) {
29        switch (node->type) {
30            case YAML_SCALAR_NODE:
31                if (!yaml_document_add_scalar(document_to, node->tag,
32                            node->data.scalar.value, node->data.scalar.length,
33                            node->data.scalar.style)) goto error;
34                break;
35            case YAML_SEQUENCE_NODE:
36                if (!yaml_document_add_sequence(document_to, node->tag,
37                            node->data.sequence.style)) goto error;
38                break;
39            case YAML_MAPPING_NODE:
40                if (!yaml_document_add_mapping(document_to, node->tag,
41                            node->data.mapping.style)) goto error;
42                break;
43            default:
44                assert(0);
45                break;
46        }
47    }
48
49    for (node = document_from->nodes.start;
50            node < document_from->nodes.top; node ++) {
51        switch (node->type) {
52            case YAML_SEQUENCE_NODE:
53                for (item = node->data.sequence.items.start;
54                        item < node->data.sequence.items.top; item ++) {
55                    if (!yaml_document_append_sequence_item(document_to,
56                                node - document_from->nodes.start + 1,
57                                *item)) goto error;
58                }
59                break;
60            case YAML_MAPPING_NODE:
61                for (pair = node->data.mapping.pairs.start;
62                        pair < node->data.mapping.pairs.top; pair ++) {
63                    if (!yaml_document_append_mapping_pair(document_to,
64                                node - document_from->nodes.start + 1,
65                                pair->key, pair->value)) goto error;
66                }
67                break;
68            default:
69                break;
70        }
71    }
72    return 1;
73
74error:
75    yaml_document_delete(document_to);
76    return 0;
77}
78
79int compare_nodes(yaml_document_t *document1, int index1,
80        yaml_document_t *document2, int index2)
81{
82    yaml_node_t *node1 = yaml_document_get_node(document1, index1);
83    yaml_node_t *node2 = yaml_document_get_node(document2, index2);
84    int k;
85
86    assert(node1);
87    assert(node2);
88
89    if (node1->type != node2->type)
90        return 0;
91
92    if (strcmp((char *)node1->tag, (char *)node2->tag) != 0) return 0;
93
94    switch (node1->type) {
95        case YAML_SCALAR_NODE:
96            if (node1->data.scalar.length != node2->data.scalar.length)
97                return 0;
98            if (strncmp((char *)node1->data.scalar.value, (char *)node2->data.scalar.value,
99                        node1->data.scalar.length) != 0) return 0;
100            break;
101        case YAML_SEQUENCE_NODE:
102            if ((node1->data.sequence.items.top - node1->data.sequence.items.start) !=
103                    (node2->data.sequence.items.top - node2->data.sequence.items.start))
104                return 0;
105            for (k = 0; k < (node1->data.sequence.items.top - node1->data.sequence.items.start); k ++) {
106                if (!compare_nodes(document1, node1->data.sequence.items.start[k],
107                            document2, node2->data.sequence.items.start[k])) return 0;
108            }
109            break;
110        case YAML_MAPPING_NODE:
111            if ((node1->data.mapping.pairs.top - node1->data.mapping.pairs.start) !=
112                    (node2->data.mapping.pairs.top - node2->data.mapping.pairs.start))
113                return 0;
114            for (k = 0; k < (node1->data.mapping.pairs.top - node1->data.mapping.pairs.start); k ++) {
115                if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].key,
116                            document2, node2->data.mapping.pairs.start[k].key)) return 0;
117                if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].value,
118                            document2, node2->data.mapping.pairs.start[k].value)) return 0;
119            }
120            break;
121        default:
122            assert(0);
123            break;
124    }
125    return 1;
126}
127
128int compare_documents(yaml_document_t *document1, yaml_document_t *document2)
129{
130    int k;
131
132    if ((document1->version_directive && !document2->version_directive)
133            || (!document1->version_directive && document2->version_directive)
134            || (document1->version_directive && document2->version_directive
135                && (document1->version_directive->major != document2->version_directive->major
136                    || document1->version_directive->minor != document2->version_directive->minor)))
137        return 0;
138
139    if ((document1->tag_directives.end - document1->tag_directives.start) !=
140            (document2->tag_directives.end - document2->tag_directives.start))
141        return 0;
142    for (k = 0; k < (document1->tag_directives.end - document1->tag_directives.start); k ++) {
143        if ((strcmp((char *)document1->tag_directives.start[k].handle,
144                        (char *)document2->tag_directives.start[k].handle) != 0)
145                || (strcmp((char *)document1->tag_directives.start[k].prefix,
146                    (char *)document2->tag_directives.start[k].prefix) != 0))
147            return 0;
148    }
149
150    if ((document1->nodes.top - document1->nodes.start) !=
151            (document2->nodes.top - document2->nodes.start))
152        return 0;
153
154    if (document1->nodes.top != document1->nodes.start) {
155        if (!compare_nodes(document1, 1, document2, 1))
156            return 0;
157    }
158
159    return 1;
160}
161
162int print_output(char *name, unsigned char *buffer, size_t size, int count)
163{
164    FILE *file;
165    char data[BUFFER_SIZE];
166    size_t data_size = 1;
167    size_t total_size = 0;
168    if (count >= 0) {
169        printf("FAILED (at the document #%d)\nSOURCE:\n", count+1);
170    }
171    file = fopen(name, "rb");
172    assert(file);
173    while (data_size > 0) {
174        data_size = fread(data, 1, BUFFER_SIZE, file);
175        assert(!ferror(file));
176        if (!data_size) break;
177        assert(fwrite(data, 1, data_size, stdout) == data_size);
178        total_size += data_size;
179        if (feof(file)) break;
180    }
181    fclose(file);
182    printf("#### (length: %d)\n", total_size);
183    printf("OUTPUT:\n%s#### (length: %d)\n", buffer, size);
184    return 0;
185}
186
187int
188main(int argc, char *argv[])
189{
190    int number;
191    int canonical = 0;
192    int unicode = 0;
193
194    number = 1;
195    while (number < argc) {
196        if (strcmp(argv[number], "-c") == 0) {
197            canonical = 1;
198        }
199        else if (strcmp(argv[number], "-u") == 0) {
200            unicode = 1;
201        }
202        else if (argv[number][0] == '-') {
203            printf("Unknown option: '%s'\n", argv[number]);
204            return 0;
205        }
206        if (argv[number][0] == '-') {
207            if (number < argc-1) {
208                memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
209            }
210            argc --;
211        }
212        else {
213            number ++;
214        }
215    }
216
217    if (argc < 2) {
218        printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
219        return 0;
220    }
221
222    for (number = 1; number < argc; number ++)
223    {
224        FILE *file;
225        yaml_parser_t parser;
226        yaml_emitter_t emitter;
227
228        yaml_document_t document;
229        unsigned char buffer[BUFFER_SIZE];
230        size_t written = 0;
231        yaml_document_t documents[MAX_DOCUMENTS];
232        size_t document_number = 0;
233        int done = 0;
234        int count = 0;
235        int error = 0;
236        int k;
237        memset(buffer, 0, BUFFER_SIZE);
238        memset(documents, 0, MAX_DOCUMENTS*sizeof(yaml_document_t));
239
240        printf("[%d] Loading, dumping, and loading again '%s': ", number, argv[number]);
241        fflush(stdout);
242
243        file = fopen(argv[number], "rb");
244        assert(file);
245
246        assert(yaml_parser_initialize(&parser));
247        yaml_parser_set_input_file(&parser, file);
248        assert(yaml_emitter_initialize(&emitter));
249        if (canonical) {
250            yaml_emitter_set_canonical(&emitter, 1);
251        }
252        if (unicode) {
253            yaml_emitter_set_unicode(&emitter, 1);
254        }
255        yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
256        yaml_emitter_open(&emitter);
257
258        while (!done)
259        {
260            if (!yaml_parser_load(&parser, &document)) {
261                error = 1;
262                break;
263            }
264
265            done = (!yaml_document_get_root_node(&document));
266            if (!done) {
267                assert(document_number < MAX_DOCUMENTS);
268                assert(copy_document(&(documents[document_number++]), &document));
269                assert(yaml_emitter_dump(&emitter, &document) || 
270                        (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
271                count ++;
272            }
273            else {
274                yaml_document_delete(&document);
275            }
276        }
277
278        yaml_parser_delete(&parser);
279        assert(!fclose(file));
280        yaml_emitter_close(&emitter);
281        yaml_emitter_delete(&emitter);
282
283        if (!error)
284        {
285            count = done = 0;
286            assert(yaml_parser_initialize(&parser));
287            yaml_parser_set_input_string(&parser, buffer, written);
288
289            while (!done)
290            {
291                assert(yaml_parser_load(&parser, &document) || print_output(argv[number], buffer, written, count));
292                done = (!yaml_document_get_root_node(&document));
293                if (!done) {
294                    assert(compare_documents(documents+count, &document) || print_output(argv[number], buffer, written, count));
295                    count ++;
296                }
297                yaml_document_delete(&document);
298            }
299            yaml_parser_delete(&parser);
300        }
301
302        for (k = 0; k < document_number; k ++) {
303            yaml_document_delete(documents+k);
304        }
305
306        printf("PASSED (length: %d)\n", written);
307        print_output(argv[number], buffer, written, -1);
308    }
309
310    return 0;
311}
Note: See TracBrowser for help on using the repository browser.