From: James Simmons Date: Mon, 24 Jul 2023 16:10:17 +0000 (-0400) Subject: LU-9680 contrib: share libyaml C code generator X-Git-Tag: 2.15.57~14 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=ebcfe25232387c894d8284e76f8fe6011364f25e;p=fs%2Flustre-release.git LU-9680 contrib: share libyaml C code generator Writing proper libyaml C code is not easy. So I wrote an application that generates the C code to help the developer not struggle starting from scratch. It wouldn't be a one to one copy and paste but it greatly helps. The build the application just do gcc -lyaml yaml-event-dump.c Test-Parameters: trivial Change-Id: I1b570dbfc3ea2e6a7ec77b3743aa4cd80aba2acb Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51508 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Timothy Day Reviewed-by: Alex Deiter Reviewed-by: Oleg Drokin --- diff --git a/contrib/yaml-event-dump.c b/contrib/yaml-event-dump.c new file mode 100644 index 0000000..780c586d --- /dev/null +++ b/contrib/yaml-event-dump.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023 James Simmons + * + * Writing libyaml C code can be very difficult to get right. So I wrote + * this application that takes a YAML file and creates pseudo user land + * libyaml C code. This will speed up development greatly. Note its not + * 100% promised that the YAML config file that works with the libyaml + * is valid. Please always test your YAML file with http://www.yamllint.com + * + * To build this application just run : gcc -lyaml yaml-event-dump.c + * + * This application just takes one argument which is the file path to + * the YAML config file. Example ./a.out lnet.conf + * + * Once you run this application against the YAML config file you will + * see C libyaml pseudocode that using the libyaml API will build + * a proper YAML document. You can then cut and paste the C code + * ouput to your C function, thus saving time. At the end of the + * pseudo code we also prints out the YAML document in the style + * of the libyaml API. + */ +#include +#include + +int main(int argc, char **argv) +{ + yaml_emitter_t output; + yaml_parser_t setup; + yaml_event_t event; + FILE *file; + int i = 1; + int rc; + + if (argc != 2) { + fprintf(stderr, "usage: %s /path/to/yaml.conf\n", argv[0]); + return -1; + } + + file = fopen(argv[1], "r"); + if (!file) + return -errno; + + /* Initialize configuration parser */ + rc = yaml_parser_initialize(&setup); + if (rc == 0) + return -EINVAL; + + yaml_parser_set_input_file(&setup, file); + + rc = yaml_emitter_initialize(&output); + if (rc == 0) + goto free_results; + + yaml_emitter_set_output_file(&output, stdout); + + puts("\tyaml_emitter_t request;"); + puts("\tyaml_event_t event;\n"); + + do { + /* Get the next event. */ + if (!yaml_parser_parse(&setup, &event)) + goto emitter_error; + + switch (event.type) { + case YAML_STREAM_START_EVENT: + puts("\tyaml_emitter_open(&request);"); + break; + case YAML_DOCUMENT_START_EVENT: + puts("\tyaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);"); + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + break; + case YAML_DOCUMENT_END_EVENT: + puts("\tyaml_document_end_event_initialize(&event, 0);"); + /* YAML_STREAM_END_EVENT will be next */ + puts("\trc = yaml_emitter_close(&request);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + break; + case YAML_ALIAS_EVENT: + break; + case YAML_SCALAR_EVENT: { + char *value = (char *)event.data.scalar.value; + + puts("\tyaml_scalar_event_initialize(&event, NULL,"); + if (!strlen(value)) { + puts("\t\t\t\t (yaml_char_t *)YAML_NULL_TAG,"); + } else if (strcasecmp(value, "yes") == 0 || + strcasecmp(value, "no") == 0 || + strcasecmp(value, "true") == 0 || + strcasecmp(value, "false") == 0 || + strcasecmp(value, "on") == 0 || + strcasecmp(value, "off") == 0 || + strcasecmp(value, "y") == 0 || + strcasecmp(value, "n") == 0) { + puts("\t\t\t\t (yaml_char_t *)YAML_BOOL_TAG,"); + } else if (strspn(value, "0123456789abcdefABCDEF") == + strlen(value)) { + puts("\t\t\t\t (yaml_char_t *)YAML_INT_TAG,"); + } else { + puts("\t\t\t\t (yaml_char_t *)YAML_STR_TAG,"); + } + //printf("\t\t\t\t (yaml_char_t *)\"%s\",\n", + // event.data.scalar.tag); + printf("\t\t\t\t (yaml_char_t *)\"%s\",\n", value); + printf("\t\t\t\t strlen(\"%s\"), 1, 0,\n", value); + + switch (event.data.scalar.style) { + case YAML_PLAIN_SCALAR_STYLE: + puts("\t\t\t\t YAML_PLAIN_SCALAR_STYLE);"); + break; + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + puts("\t\t\t\t YAML_SINGLE_QUOTED_SCALAR_STYLE);"); + break; + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + puts("\t\t\t\t YAML_DOUBLE_QUOTED_SCALAR_STYLE);"); + break; + case YAML_LITERAL_SCALAR_STYLE: + puts("\t\t\t\t YAML_LITERAL_SCALAR_STYLE);"); + break; + case YAML_FOLDED_SCALAR_STYLE: + puts("\t\t\t\t YAML_FOLDER_SCALAR_STYLE);"); + break; + case YAML_ANY_SCALAR_STYLE: + default: + puts("\t\t\t\t YAML_ANY_SCALAR_STYLE);"); + break; + } + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + } + break; + case YAML_SEQUENCE_START_EVENT: + puts("\tyaml_sequence_start_event_initialize(&event, NULL,"); + puts("\t\t\t\t\t (yaml_char_t *)YAML_SEQ_TAG,"); + printf("\t\t\t\t\t 1, %s);\n", + (event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE) ? + "YAML_BLOCK_SEQUENCE_STYLE" : "YAML_FLOW_SEQUENCE_STYLE"); + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + break; + case YAML_SEQUENCE_END_EVENT: + puts("\tyaml_sequence_end_event_initialize(&event);"); + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + break; + case YAML_MAPPING_START_EVENT: + puts("\tyaml_mapping_start_event_initialize(&event, NULL,"); + puts("\t\t\t\t\t (yaml_char_t *)YAML_MAP_TAG,"), + printf("\t\t\t\t\t 1, %s);\n", + (event.data.mapping_start.style == YAML_BLOCK_MAPPING_STYLE) ? + "YAML_BLOCK_MAPPING_STYLE" : "YAML_FLOW_MAPPING_STYLE"); + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + break; + case YAML_MAPPING_END_EVENT: + puts("\tyaml_mapping_end_event_initialize(&event);"); + puts("\trc = yaml_emitter_emit(&request, &event);"); + puts("\tif (rc == 0)"); + puts("\t\tgoto emitter_error;"); + puts(""); + default: + break; + } + + /* Emit the event. */ + if (!yaml_emitter_emit(&output, &event)) + goto emitter_error; + } while (event.type != YAML_STREAM_END_EVENT); + + rc = yaml_emitter_flush(&output); + if (rc == 0) + fprintf(stderr, "dump failed\n"); + +emitter_error: + yaml_emitter_delete(&output); +free_results: + yaml_parser_delete(&setup); + return 0; +}