From 6646ce83fecafedd8a264ec95e8eb064b5258957 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 13 Apr 2024 18:22:00 +0200 Subject: [PATCH] remove dependency on recutils and libjansson --- src/include/Makefile.am | 13 +- src/include/options-generator.c | 457 ++++++++++++++++++++------------ 2 files changed, 294 insertions(+), 176 deletions(-) diff --git a/src/include/Makefile.am b/src/include/Makefile.am index d3a94b4d..266b0f85 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -1,17 +1,11 @@ # This Makefile.am is in the public domain SUBDIRS = . -d_options.json: options.tmpl d_options.rec - recfmt -f options.tmpl < d_options.rec | sed -e "s/,*]/]/g" -e "s/\(,\"\"\)*]/]/" -e "s/\[\"\"\]/\[\]/" -e '0,/./i{' -e '$$a"end":""}' -e 's/\"\"/null/' | gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "\\n") } { printf("%s%s", $$0, RT) }' | jq 'del(..|nulls)' > d_options.json - -r_options.json: options.tmpl r_options.rec - recfmt -f options.tmpl < r_options.rec | sed -e "s/,*]/]/g" -e "s/\(,\"\"\)*]/]/" -e "s/\[\"\"\]/\[\]/" -e '0,/./i{' -e '$$a"end":""}' -e 's/\"\"/null/' | gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "\\n") } { printf("%s%s", $$0, RT) }' | jq 'del(..|nulls)' > r_options.json - -microhttpd2_inline_daemon_documentation.h.in microhttpd2_generated_daemon_options.h: d_options.json options-generator +microhttpd2_inline_daemon_documentation.h.in microhttpd2_generated_daemon_options.h: d_options.rec options-generator rm -f microhttpd2_inline_daemon_documentation.h.in microhttpd2_generated_daemon_options.h ./options-generator daemon > microhttpd2_generated_daemon_options.h chmod -w $@ -microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h: r_options.json options-generator +microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h: r_options.rec options-generator rm -f microhttpd2_inline_response_documentation.h.in microhttpd2_generated_response_options.h ./options-generator response > microhttpd2_generated_response_options.h chmod -w $@ @@ -21,14 +15,11 @@ microhttpd2.h: microhttpd2_preamble.h.in microhttpd2_inline_daemon_documentation cat $^ >$@ chmod -w $@ -# TODO: make conditional on 'libjansson' being available! noinst_PROGRAMS = \ options-generator options_generator_SOURCES = \ options-generator.c -options_generator_LDADD = \ - -ljansson mhd2includedir = $(includedir)/mhd2 diff --git a/src/include/options-generator.c b/src/include/options-generator.c index 01141793..f0376a28 100644 --- a/src/include/options-generator.c +++ b/src/include/options-generator.c @@ -23,12 +23,28 @@ */ #define _GNU_SOURCE #include +#include #include #include #include -#include #include +#define MAX_ARGS 3 + +struct Option +{ + struct Option *next; + char *name; + unsigned int value; + char *type; + char *comment; + unsigned int argc; + char *arguments[MAX_ARGS]; + unsigned int desc; + char *descriptions[MAX_ARGS]; + char *conditional; +}; + static FILE *f; static char *category; @@ -39,48 +55,30 @@ typedef void const char *comment, const char *type, const char *conditional, - json_t *args, - json_t *descs); + unsigned int argc, + char **arguments, + unsigned int desc, + char **descriptions); static void -iterate (json_t *input, +iterate (struct Option *head, Callback cb) { - const char *name; - json_t *obj; - - json_object_foreach (input, name, obj) + for (struct Option *o = head; NULL != o; o = o->next) { - unsigned int value - = json_integer_value (json_object_get (obj, - "Value")); - const char *comment - = json_string_value (json_object_get (obj, - "Comment")); - const char *type - = json_string_value (json_object_get (obj, - "Type")); - const char *conditional - = json_string_value (json_object_get (obj, - "Conditional")); - json_t *args - = json_object_get (obj, - "Arguments"); - json_t *descs - = json_object_get (obj, - "Descriptions"); - if (0 == strcmp ("end", - name)) + o->name)) continue; - cb (name, - value, - comment, - type, - conditional, - args, - descs); + cb (o->name, + o->value, + o->comment, + o->type, + o->conditional, + o->argc, + o->arguments, + o->desc, + o->descriptions); } } @@ -91,10 +89,12 @@ check (const char *name, const char *comment, const char *type, const char *conditional, - json_t *args, - json_t *descs) + unsigned int argc, + char **arguments, + unsigned int desc, + char **descriptions) { - if (json_array_size (args) != json_array_size (descs)) + if (argc != desc) { fprintf (stderr, "Mismatch between descriptions and arguments for `%s'\n", @@ -102,18 +102,17 @@ check (const char *name, exit (2); } if ( (NULL == type) && - ( (NULL == args) || - (1 != json_array_size (args)) ) ) + ( (0 == argc) || + (1 != argc) ) ) { fprintf (stderr, "Type and argument missing for `%s' and not exactly 1 argument\n", name); exit (2); } - for (unsigned int i = 0; i= json_array_size (args)) + if (1 >= argc) return; printf ("/**\n * Data for #MHD_%c_O_%s\n */\n%s\n{\n", (char) toupper (*category), uppercase (name), type); - for (unsigned int i = 0; isettings.%s = option->val.%s;\n", category, lowercase (name), lowercase (name)); else - for (unsigned int i = 0; isettings.%s.v_%s = option->val.%s.v_%s;\n", category, @@ -640,12 +620,26 @@ dump_option_set_switch (const char *name, } +static char ** +parse (char **target, + const char *prefix, + const char *input) +{ + if (0 != strncasecmp (prefix, + input, + strlen (prefix))) + return NULL; + *target = strdup (input + strlen (prefix)); + return target; +} + + int main (int argc, char **argv) { - json_t *j; - json_error_t err; + static char *dummy; + struct Option *head = NULL; if (argc < 2) { @@ -657,25 +651,160 @@ main (int argc, { char *fn; + char *line = NULL; + char **larg = NULL; + unsigned int off; + size_t len; + struct Option *last = NULL; asprintf (&fn, - "%c_options.json", + "%c_options.rec", *category); - j = json_load_file (fn, 0, &err); - if (NULL == j) + f = fopen (fn, "r"); + if (NULL == f) { fprintf (stderr, - "Failed to parse %s: %s at %d:%d\n", - fn, - err.text, - err.line, - err.column); + "Failed to open %s\n", + fn); free (fn); return 2; } + off = 0; +TOP: + while (1) + { + ssize_t r; + + free (line); + line = NULL; + len = 0; + r = getline (&line, + &len, + f); + off++; + if (r <= 0) + break; + while ( (r > 0) && + ( (isspace (line[r - 1])) || + (line[r - 1] == '\n') ) ) + line[--r] = '\0'; /* remove new line */ + if (0 == r) + { + larg = NULL; + continue; + } + if ( (NULL != larg) && + ( (0 == strncmp ("+ ", + line, + 2) ) || + (0 == strcmp ("+", + line) ) ) ) + { + if (larg == &dummy) + { + fprintf (stderr, + "Continuation after 'Value:' not supported on line %u\n", + off); + exit (2); + } + + *larg = realloc (*larg, + strlen (*larg) + r + 2); + strcat (*larg, + "\n"); + if (0 != strcmp ("+", + line) ) + strcat (*larg, + line + 2); + continue; + } + if ( ('%' == line[0]) || + ('#' == line[0]) ) + continue; + if (NULL == larg) + { + struct Option *o = malloc (sizeof (struct Option)); + + memset (o, 0, sizeof (*o)); + if (NULL == head) + head = o; + else + last->next = o; + last = o; + } + if (NULL != (larg = parse (&last->name, + "Name: ", + line))) + continue; + if (NULL != (larg = parse (&last->comment, + "Comment: ", + line))) + continue; + if (NULL != (larg = parse (&last->type, + "Type: ", + line))) + continue; + if (NULL != (larg = parse (&last->conditional, + "Conditional: ", + line))) + continue; + if (0 == strncasecmp (line, + "Value: ", + strlen ("Value: "))) + { + char xdummy; + + if (1 == sscanf (line + strlen ("Value: "), + "%u%c", + &last->value, + &xdummy)) + { + larg = &dummy; + continue; + } + fprintf (stderr, + "Value on line %d not a number\n", + off); + return 2; + } + for (unsigned int i = 0; iarguments[i], + name, + line))) + { + last->argc = i + 1; + goto TOP; + } + snprintf (name, + sizeof (name), + "Description%u: ", + i + 1); + if (NULL != (larg = parse (&last->descriptions[i], + name, + line))) + { + last->desc = i + 1; + goto TOP; + } + } + fprintf (stderr, + "Could not parse line %u: `%s'\n", + off, + line); + exit (2); + } free (fn); + free (line); } - iterate (j, + + iterate (head, &check); /* Generate enum MHD_${CATEGORY}Option */ @@ -694,7 +823,7 @@ main (int argc, " MHD_%c_O_END = 0\n" " ,\n\n", (char) toupper (*category)); - iterate (j, + iterate (head, &dump_enum); printf (" /**\n" " * The sentinel value.\n" @@ -704,7 +833,7 @@ main (int argc, " MHD_%c_O_SENTINEL = 65535\n\n", (char) toupper (*category)); printf ("};\n\n"); - iterate (j, + iterate (head, &dump_union_members); /* Generate union MHD_${CATEGORY}OptionValue */ @@ -716,7 +845,7 @@ main (int argc, category, capitalize (category)); f = stdout; - iterate (j, + iterate (head, &dump_union); f = NULL; printf ("};\n\n"); @@ -739,7 +868,7 @@ main (int argc, capitalize (category)); printf ( "#if defined(MHD_USE_COMPOUND_LITERALS) && defined(MHD_USE_DESIG_NEST_INIT)\n"); - iterate (j, + iterate (head, &dump_option_macros); printf ( "\n" @@ -762,7 +891,7 @@ main (int argc, printf ( "#else /* !MHD_USE_COMPOUND_LITERALS || !MHD_USE_DESIG_NEST_INIT */\n"); printf ("MHD_NOWARN_UNUSED_FUNC_"); - iterate (j, &dump_option_static_functions); + iterate (head, &dump_option_static_functions); printf ("\n/**\n" " * Terminate the list of the options\n" " * @return the terminating object of struct MHD_%sOptionAndValue\n" @@ -806,7 +935,7 @@ main (int argc, " complex, so these here are just for documentation!\n" " We do not actually *build* this code... */\n" "#if 0\n\n"); - iterate (j, + iterate (head, &dump_option_documentation_functions); fprintf (f, "/* End of generated code documenting how to use options */\n#endif\n\n"); @@ -855,7 +984,7 @@ main (int argc, " for (size_t i=0;i