source: trunk/sandbox/syck-parser/syck-parser.c @ 2

Revision 2, 4.6 KB checked in by xi, 9 years ago (diff)

Add command-line syck parser (see #1).

RevLine 
[2]1
2#include <stdlib.h>
3#include <stdio.h>
4#include <stdarg.h>
5#include <error.h>
6#include <string.h>
7
8#include <syck.h>
9
10#define USAGE   \
11    "Usage:\n"  \
12    "\tsyck-parser filename [implicit_typing [taguri_expansion]]\n"   \
13    "where implicit_typing and taguri_expansion equal 1 or 0 (default: 1)\n"
14
15#define INDENT "  "
16
17SyckNode *copy_node(SyckNode *n)
18{
19    SyckNode *m;
20    long i;
21
22    switch (n->kind) {
23        case syck_str_kind:
24            m = syck_new_str2(n->data.str->ptr, n->data.str->len, n->data.str->style);
25            break;
26        case syck_seq_kind:
27            m = syck_alloc_seq();
28            for (i = 0; i < syck_seq_count(n); i++) {
29                syck_seq_add(m, syck_seq_read(n, i));
30            }
31            break;
32        case syck_map_kind:
33            m = syck_alloc_map();
34            for (i = 0; i < syck_map_count(n); i++) {
35                syck_map_add(m, syck_map_read(n, map_key, i), syck_map_read(n, map_value, i));
36            }
37            break;
38    }
39
40    if (n->type_id) {
41        m->type_id = strdup(n->type_id);
42    }
43    else {
44        m->type_id = strdup("");
45    }
46    if (n->anchor) {
47        m->anchor = strdup(n->anchor);
48    }
49    else {
50        m->anchor = strdup("");
51    }
52
53    return m;
54}
55
56void release(SyckParser *p, SYMID id)
57{
58    SyckNode *n;
59    int i;
60   
61    syck_lookup_sym(p, id, (char **)&n);
62
63    switch (n->kind) {
64        case syck_seq_kind:
65            for (i = 0; i < syck_seq_count(n); i++) {
66                release(p, syck_seq_read(n, i));
67            }
68            break;
69        case syck_map_kind:
70            for (i = 0; i < syck_map_count(n); i++) {
71                release(p, syck_map_read(n, map_key, i));
72                release(p, syck_map_read(n, map_value, i));
73            }
74            break;
75    }
76    syck_free_node(n);
77}
78
79SYMID node_handler(SyckParser *p, SyckNode *n)
80{
81    SyckNode *m = copy_node(n);
82    SYMID id = syck_add_sym(p, (char *)m);
83   
84    m->id = id;
85    return id;
86}
87
88void error_handler(SyckParser *p, char *str)
89{
90    errx(1, "Error handler is not implemented");
91}
92
93SyckNode *bad_anchor_handler(SyckParser *p, char *anchor)
94{
95    errx(1, "Bad anchor handler is not implemented");
96    return NULL;
97}
98
99void output(int indent, const char *template, ...)
100{
101    va_list ap;
102    int k;
103
104    for (k = 0; k < indent; k++) {
105        printf(INDENT);
106    }
107
108    va_start(ap, template);
109    vprintf(template, ap);
110    va_end(ap);
111
112    printf("\n");
113}
114
115void traverse(SyckParser *p, int indent, SYMID id)
116{
117    SyckNode *n;
118
119    int i;
120   
121    syck_lookup_sym(p, id, (char **)&n);
122
123    switch (n->kind) {
124        case syck_str_kind:
125            output(indent, "Node Scalar (%s):", n->type_id);
126            output(indent+1, "Value: '%s'", n->data.str->ptr);
127            break;
128        case syck_seq_kind:
129            output(indent, "Node Sequence (%s):", n->type_id);
130            for (i = 0; i < syck_seq_count(n); i++) {
131                output(indent+1, "Item #%d:", i+1);
132                traverse(p, indent+2, syck_seq_read(n, i));
133            }
134            break;
135        case syck_map_kind:
136            output(indent, "Node Mapping (%s):", n->type_id);
137            for (i = 0; i < syck_map_count(n); i++) {
138                output(indent+1, "Key #%d:", i+1);
139                traverse(p, indent+2, syck_map_read(n, map_key, i));
140                output(indent+1, "Value #%d:", i+1);
141                traverse(p, indent+2, syck_map_read(n, map_value, i));
142            }
143            break;
144    }
145}
146
147int main(int argc, char *argv[])
148{
149    FILE *stream;
150    SyckParser *p;
151    char *filename;
152    int implicit_typing;
153    int taguri_expansion;
154    SYMID document;
155    int document_number = 0;
156
157    if (argc <= 1 || argc > 4) {
158        fprintf(stderr, USAGE);
159        exit(1);
160    }
161    filename = argv[1];
162    implicit_typing = !(argc >= 3 && strcmp(argv[2], "0") == 0);
163    taguri_expansion = !(argc >= 4 && strcmp(argv[3], "0") == 0);
164
165    p = syck_new_parser();
166
167    syck_parser_implicit_typing(p, implicit_typing);
168    syck_parser_taguri_expansion(p, taguri_expansion);
169
170    stream = fopen(argv[1], "r");
171    if (!stream) err(1, "Cannot open file");
172    syck_parser_file(p, stream, NULL);
173
174    syck_parser_handler(p, node_handler);
175    syck_parser_error_handler(p, error_handler);
176    syck_parser_bad_anchor_handler(p, bad_anchor_handler);
177
178    output(0, "Stream '%s':", argv[1]);
179    document = syck_parse(p);
180    document_number ++;
181    while (!p->eof) {
182        output(1, "Document #%d:", document_number);
183        traverse(p, 2, document);
184        release(p, document);
185        document = syck_parse(p);
186        document_number ++;
187    }
188    output(0, "DONE.");
189
190    return 0;
191}
192
Note: See TracBrowser for help on using the repository browser.