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 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 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 186 int usage(int ret) { 187 fprintf(stderr, "Usage: libyaml-parser [--flow (on|off|keep)] [<input-file>]\n"); 188 return ret; 189 } 190