1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2023 James Simmons <jsimmons@infradead.org>
5 * Writing libyaml C code can be very difficult to get right. So I wrote
6 * this application that takes a YAML file and creates pseudo user land
7 * libyaml C code. This will speed up development greatly. Note its not
8 * 100% promised that the YAML config file that works with the libyaml
9 * is valid. Please always test your YAML file with http://www.yamllint.com
11 * To build this application just run : gcc -lyaml yaml-event-dump.c
13 * This application just takes one argument which is the file path to
14 * the YAML config file. Example ./a.out lnet.conf
16 * Once you run this application against the YAML config file you will
17 * see C libyaml pseudocode that using the libyaml API will build
18 * a proper YAML document. You can then cut and paste the C code
19 * ouput to your C function, thus saving time. At the end of the
20 * pseudo code we also prints out the YAML document in the style
26 int main(int argc, char **argv)
28 yaml_emitter_t output;
36 fprintf(stderr, "usage: %s /path/to/yaml.conf\n", argv[0]);
40 file = fopen(argv[1], "r");
44 /* Initialize configuration parser */
45 rc = yaml_parser_initialize(&setup);
49 yaml_parser_set_input_file(&setup, file);
51 rc = yaml_emitter_initialize(&output);
55 yaml_emitter_set_output_file(&output, stdout);
57 puts("\tyaml_emitter_t request;");
58 puts("\tyaml_event_t event;\n");
61 /* Get the next event. */
62 if (!yaml_parser_parse(&setup, &event))
66 case YAML_STREAM_START_EVENT:
67 puts("\tyaml_emitter_open(&request);");
69 case YAML_DOCUMENT_START_EVENT:
70 puts("\tyaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);");
71 puts("\trc = yaml_emitter_emit(&request, &event);");
72 puts("\tif (rc == 0)");
73 puts("\t\tgoto emitter_error;");
76 case YAML_DOCUMENT_END_EVENT:
77 puts("\tyaml_document_end_event_initialize(&event, 0);");
78 /* YAML_STREAM_END_EVENT will be next */
79 puts("\trc = yaml_emitter_close(&request);");
80 puts("\tif (rc == 0)");
81 puts("\t\tgoto emitter_error;");
84 case YAML_ALIAS_EVENT:
86 case YAML_SCALAR_EVENT: {
87 char *value = (char *)event.data.scalar.value;
89 puts("\tyaml_scalar_event_initialize(&event, NULL,");
91 puts("\t\t\t\t (yaml_char_t *)YAML_NULL_TAG,");
92 } else if (strcasecmp(value, "yes") == 0 ||
93 strcasecmp(value, "no") == 0 ||
94 strcasecmp(value, "true") == 0 ||
95 strcasecmp(value, "false") == 0 ||
96 strcasecmp(value, "on") == 0 ||
97 strcasecmp(value, "off") == 0 ||
98 strcasecmp(value, "y") == 0 ||
99 strcasecmp(value, "n") == 0) {
100 puts("\t\t\t\t (yaml_char_t *)YAML_BOOL_TAG,");
101 } else if (strspn(value, "0123456789abcdefABCDEF") ==
103 puts("\t\t\t\t (yaml_char_t *)YAML_INT_TAG,");
105 puts("\t\t\t\t (yaml_char_t *)YAML_STR_TAG,");
107 //printf("\t\t\t\t (yaml_char_t *)\"%s\",\n",
108 // event.data.scalar.tag);
109 printf("\t\t\t\t (yaml_char_t *)\"%s\",\n", value);
110 printf("\t\t\t\t strlen(\"%s\"), 1, 0,\n", value);
112 switch (event.data.scalar.style) {
113 case YAML_PLAIN_SCALAR_STYLE:
114 puts("\t\t\t\t YAML_PLAIN_SCALAR_STYLE);");
116 case YAML_SINGLE_QUOTED_SCALAR_STYLE:
117 puts("\t\t\t\t YAML_SINGLE_QUOTED_SCALAR_STYLE);");
119 case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
120 puts("\t\t\t\t YAML_DOUBLE_QUOTED_SCALAR_STYLE);");
122 case YAML_LITERAL_SCALAR_STYLE:
123 puts("\t\t\t\t YAML_LITERAL_SCALAR_STYLE);");
125 case YAML_FOLDED_SCALAR_STYLE:
126 puts("\t\t\t\t YAML_FOLDER_SCALAR_STYLE);");
128 case YAML_ANY_SCALAR_STYLE:
130 puts("\t\t\t\t YAML_ANY_SCALAR_STYLE);");
133 puts("\trc = yaml_emitter_emit(&request, &event);");
134 puts("\tif (rc == 0)");
135 puts("\t\tgoto emitter_error;");
139 case YAML_SEQUENCE_START_EVENT:
140 puts("\tyaml_sequence_start_event_initialize(&event, NULL,");
141 puts("\t\t\t\t\t (yaml_char_t *)YAML_SEQ_TAG,");
142 printf("\t\t\t\t\t 1, %s);\n",
143 (event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE) ?
144 "YAML_BLOCK_SEQUENCE_STYLE" : "YAML_FLOW_SEQUENCE_STYLE");
145 puts("\trc = yaml_emitter_emit(&request, &event);");
146 puts("\tif (rc == 0)");
147 puts("\t\tgoto emitter_error;");
150 case YAML_SEQUENCE_END_EVENT:
151 puts("\tyaml_sequence_end_event_initialize(&event);");
152 puts("\trc = yaml_emitter_emit(&request, &event);");
153 puts("\tif (rc == 0)");
154 puts("\t\tgoto emitter_error;");
157 case YAML_MAPPING_START_EVENT:
158 puts("\tyaml_mapping_start_event_initialize(&event, NULL,");
159 puts("\t\t\t\t\t (yaml_char_t *)YAML_MAP_TAG,"),
160 printf("\t\t\t\t\t 1, %s);\n",
161 (event.data.mapping_start.style == YAML_BLOCK_MAPPING_STYLE) ?
162 "YAML_BLOCK_MAPPING_STYLE" : "YAML_FLOW_MAPPING_STYLE");
163 puts("\trc = yaml_emitter_emit(&request, &event);");
164 puts("\tif (rc == 0)");
165 puts("\t\tgoto emitter_error;");
168 case YAML_MAPPING_END_EVENT:
169 puts("\tyaml_mapping_end_event_initialize(&event);");
170 puts("\trc = yaml_emitter_emit(&request, &event);");
171 puts("\tif (rc == 0)");
172 puts("\t\tgoto emitter_error;");
178 /* Emit the event. */
179 if (!yaml_emitter_emit(&output, &event))
181 } while (event.type != YAML_STREAM_END_EVENT);
183 rc = yaml_emitter_flush(&output);
185 fprintf(stderr, "dump failed\n");
188 yaml_emitter_delete(&output);
190 yaml_parser_delete(&setup);