1 #include <yaml.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <assert.h>
5
6 void print_escaped(yaml_char_t * str, size_t length);
7 int usage(int ret);
8
main(int argc,char * argv[])9 int main(int argc, char *argv[])
10 {
11 FILE *input;
12 yaml_parser_t parser;
13 yaml_event_t event;
14 int flow = -1; /** default no flow style collections */
15 int i = 0;
16 int foundfile = 0;
17
18 for (i = 1; i < argc; i++) {
19 if (strncmp(argv[i], "--flow", 6) == 0) {
20 if (i+1 == argc)
21 return usage(1);
22 i++;
23 if (strncmp(argv[i], "keep", 4) == 0)
24 flow = 0;
25 else if (strncmp(argv[i], "on", 2) == 0)
26 flow = 1;
27 else if (strncmp(argv[i], "off", 3) == 0)
28 flow = -1;
29 else
30 return usage(1);
31 }
32 else if (strncmp(argv[i], "--help", 6) == 0)
33 return usage(0);
34 else if (strncmp(argv[i], "-h", 2) == 0)
35 return usage(0);
36 else if (!foundfile) {
37 input = fopen(argv[i], "rb");
38 foundfile = 1;
39 }
40 else
41 return usage(1);
42 }
43 if (!foundfile) {
44 input = stdin;
45 }
46 assert(input);
47
48 if (!yaml_parser_initialize(&parser)) {
49 fprintf(stderr, "Could not initialize the parser object\n");
50 return 1;
51 }
52 yaml_parser_set_input_file(&parser, input);
53
54 while (1) {
55 yaml_event_type_t type;
56 if (!yaml_parser_parse(&parser, &event)) {
57 if ( parser.problem_mark.line || parser.problem_mark.column ) {
58 fprintf(stderr, "Parse error: %s\nLine: %lu Column: %lu\n",
59 parser.problem,
60 (unsigned long)parser.problem_mark.line + 1,
61 (unsigned long)parser.problem_mark.column + 1);
62 }
63 else {
64 fprintf(stderr, "Parse error: %s\n", parser.problem);
65 }
66 return 1;
67 }
68 type = event.type;
69
70 if (type == YAML_NO_EVENT)
71 printf("???\n");
72 else if (type == YAML_STREAM_START_EVENT)
73 printf("+STR\n");
74 else if (type == YAML_STREAM_END_EVENT)
75 printf("-STR\n");
76 else if (type == YAML_DOCUMENT_START_EVENT) {
77 printf("+DOC");
78 if (!event.data.document_start.implicit)
79 printf(" ---");
80 printf("\n");
81 }
82 else if (type == YAML_DOCUMENT_END_EVENT) {
83 printf("-DOC");
84 if (!event.data.document_end.implicit)
85 printf(" ...");
86 printf("\n");
87 }
88 else if (type == YAML_MAPPING_START_EVENT) {
89 printf("+MAP");
90 if (flow == 0 && event.data.mapping_start.style == YAML_FLOW_MAPPING_STYLE)
91 printf(" {}");
92 else if (flow == 1)
93 printf(" {}");
94 if (event.data.mapping_start.anchor)
95 printf(" &%s", event.data.mapping_start.anchor);
96 if (event.data.mapping_start.tag)
97 printf(" <%s>", event.data.mapping_start.tag);
98 printf("\n");
99 }
100 else if (type == YAML_MAPPING_END_EVENT)
101 printf("-MAP\n");
102 else if (type == YAML_SEQUENCE_START_EVENT) {
103 printf("+SEQ");
104 if (flow == 0 && event.data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE)
105 printf(" []");
106 else if (flow == 1)
107 printf(" []");
108 if (event.data.sequence_start.anchor)
109 printf(" &%s", event.data.sequence_start.anchor);
110 if (event.data.sequence_start.tag)
111 printf(" <%s>", event.data.sequence_start.tag);
112 printf("\n");
113 }
114 else if (type == YAML_SEQUENCE_END_EVENT)
115 printf("-SEQ\n");
116 else if (type == YAML_SCALAR_EVENT) {
117 printf("=VAL");
118 if (event.data.scalar.anchor)
119 printf(" &%s", event.data.scalar.anchor);
120 if (event.data.scalar.tag)
121 printf(" <%s>", event.data.scalar.tag);
122 switch (event.data.scalar.style) {
123 case YAML_PLAIN_SCALAR_STYLE:
124 printf(" :");
125 break;
126 case YAML_SINGLE_QUOTED_SCALAR_STYLE:
127 printf(" '");
128 break;
129 case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
130 printf(" \"");
131 break;
132 case YAML_LITERAL_SCALAR_STYLE:
133 printf(" |");
134 break;
135 case YAML_FOLDED_SCALAR_STYLE:
136 printf(" >");
137 break;
138 case YAML_ANY_SCALAR_STYLE:
139 abort();
140 }
141 print_escaped(event.data.scalar.value, event.data.scalar.length);
142 printf("\n");
143 }
144 else if (type == YAML_ALIAS_EVENT)
145 printf("=ALI *%s\n", event.data.alias.anchor);
146 else
147 abort();
148
149 yaml_event_delete(&event);
150
151 if (type == YAML_STREAM_END_EVENT)
152 break;
153 }
154
155 assert(!fclose(input));
156 yaml_parser_delete(&parser);
157 fflush(stdout);
158
159 return 0;
160 }
161
print_escaped(yaml_char_t * str,size_t length)162 void print_escaped(yaml_char_t * str, size_t length)
163 {
164 int i;
165 char c;
166
167 for (i = 0; i < length; i++) {
168 c = *(str + i);
169 if (c == '\\')
170 printf("\\\\");
171 else if (c == '\0')
172 printf("\\0");
173 else if (c == '\b')
174 printf("\\b");
175 else if (c == '\n')
176 printf("\\n");
177 else if (c == '\r')
178 printf("\\r");
179 else if (c == '\t')
180 printf("\\t");
181 else
182 printf("%c", c);
183 }
184 }
185
usage(int ret)186 int usage(int ret) {
187 fprintf(stderr, "Usage: libyaml-parser [--flow (on|off|keep)] [<input-file>]\n");
188 return ret;
189 }
190