From 06cb82a8ccc3587dff728321dff5416b18090483 Mon Sep 17 00:00:00 2001 From: katherine Date: Wed, 10 Jul 2019 20:24:08 -0700 Subject: implement deftype get --- src/gen.c | 788 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 643 insertions(+), 145 deletions(-) (limited to 'src/gen.c') diff --git a/src/gen.c b/src/gen.c index 846f122..ff93dd5 100644 --- a/src/gen.c +++ b/src/gen.c @@ -4,197 +4,695 @@ #include "parse.h" #include "opt.h" +#include "../reqs/uthash/include/uthash.h" + #include #include #include "gen-consts.h" -void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar) +static inline void sub_head(FILE *f, struct analyse_result_s *ar) { - time_t t; - struct tm *ti; - - struct parse_deftype_s *dcur, *dtmp; - struct parse_var_s *vcur, *vtmp; - - unsigned i; - - time(&t); - ti = localtime(&t); - - /******** - * HEAD * - ********/ - - fprintf(f, "/* generated by %s on %04d-%02d-%02d */\n", - VERSION, ti->tm_year + 1900, ti->tm_mon + 1, ti->tm_mday); - fprintf(f, sheadp1); fprintf(f, sheadp2); - if (ar.uses_type[PARSE_TYPE_BOOL]) + if (ar->uses_type[PARSE_TYPE_BOOL]) fprintf(f, sbool); - if (ar.uses_type[PARSE_TYPE_STRING]) + if (ar->uses_type[PARSE_TYPE_STRING]) fprintf(f, sstring); - if (ar.uses_type[PARSE_TYPE_INT]) + if (ar->uses_type[PARSE_TYPE_INT]) fprintf(f, sint); - if (ar.uses_type[PARSE_TYPE_INTL]) + if (ar->uses_type[PARSE_TYPE_INTL]) fprintf(f, sintl); - if (ar.uses_type[PARSE_TYPE_INTLL]) + if (ar->uses_type[PARSE_TYPE_INTLL]) fprintf(f, sintll); - if (ar.uses_type[PARSE_TYPE_UINT]) + if (ar->uses_type[PARSE_TYPE_UINT]) fprintf(f, suint); - if (ar.uses_type[PARSE_TYPE_UINTL]) + if (ar->uses_type[PARSE_TYPE_UINTL]) fprintf(f, suintl); - if (ar.uses_type[PARSE_TYPE_UINTLL]) + if (ar->uses_type[PARSE_TYPE_UINTLL]) fprintf(f, suintll); - if (ar.uses_type[PARSE_TYPE_FLOAT]) + if (ar->uses_type[PARSE_TYPE_FLOAT]) fprintf(f, sfloat); - if (ar.uses_type[PARSE_TYPE_DOUBLE]) + if (ar->uses_type[PARSE_TYPE_DOUBLE]) fprintf(f, sdouble); - if (ar.uses_type[PARSE_TYPE_DOUBLEL]) + if (ar->uses_type[PARSE_TYPE_DOUBLEL]) fprintf(f, sdoublel); +} - /* if (ar.uses_array) */ - /* fprintf(f, sarray); */ - if (ar.uses_hash) - fprintf(f, shash, (opt_header_str() ? opt_header_str() : pr.header)); +static inline void sub_deftypes_type(FILE *f, struct parse_result_s *pr, + struct parse_deftype_s *dcur) +{ + unsigned i; - /******** - * BODY * - ********/ + /* enum for indicating which union elem is used */ + if (dcur->type == PARSE_DEFTYPE_UNION) { + fprintf(f, + "enum confconf_utype_%s_%s {\n", + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + + for (i = 0; i < dcur->member_list_len; i++) { + fprintf(f, + " CONFCONF_UTYPE_%s_%s_%s,\n", + dcur->name, + dcur->member_name_list[i], + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + } + + fprintf(f, "};\n\n"); + } fprintf(f, - "#ifndef CONFCONF_BODY_%s_H\n" - "#define CONFCONF_BODY_%s_H\n\n", - (opt_suffix_str() ? opt_suffix_str() : pr.suffix), - (opt_suffix_str() ? opt_suffix_str() : pr.suffix) + "%s confconf_type_%s_%s {\n", + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : "struct"), + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) ); - /* deftypes */ - HASH_ITER(hh, pr.deftypes, dcur, dtmp) { - if (!dcur->is_used) - continue; + if (dcur->type == PARSE_DEFTYPE_UNION) { + fprintf(f, + " enum confconf_utype_%s_%s type;\n" + " union {\n", + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + } - fprintf(f, "%s confconf_type_%s_%s {\n", - (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : - (dcur->type == PARSE_DEFTYPE_UNION ? - "union" : "struct") - ), + for (i = 0; i < dcur->member_list_len; i++) { + if (dcur->type == PARSE_DEFTYPE_UNION) { + fprintf(f, " "); + } + + if (dcur->type == PARSE_DEFTYPE_ENUM) { + fprintf(f, + " CONFCONF_TYPE_%s_%s_%s,\n", dcur->name, - (opt_suffix_str() ? opt_suffix_str() : pr.suffix) - ); + dcur->member_name_list[i], + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + continue; + } + + switch (dcur->member_type_list[i]) { + case PARSE_TYPE_BOOL: + fprintf(f, " bool "); + break; + case PARSE_TYPE_STRING: + fprintf(f, " char *"); + break; + case PARSE_TYPE_ID: + fprintf(f, " char *"); + break; + case PARSE_TYPE_INT: + fprintf(f, " int "); + break; + case PARSE_TYPE_INTL: + fprintf(f, " long int "); + break; + case PARSE_TYPE_INTLL: + fprintf(f, " long long int "); + break; + case PARSE_TYPE_UINT: + fprintf(f, " unsigned "); + break; + case PARSE_TYPE_UINTL: + fprintf(f, " long unsigned "); + break; + case PARSE_TYPE_UINTLL: + fprintf(f, " long long unsigned "); + break; + case PARSE_TYPE_FLOAT: + fprintf(f, " float "); + break; + case PARSE_TYPE_DOUBLE: + fprintf(f, " double "); + break; + case PARSE_TYPE_DOUBLEL: + fprintf(f, " long double "); + break; + default: + assert(0); + } + fprintf(f, "%s;\n", dcur->member_name_list[i]); + } + if (dcur->type == PARSE_DEFTYPE_UNION) { + fprintf(f, " } val;\n"); + } + + fprintf(f, "};\n\n"); +} + +static inline void sub_deftypes_get_struct(FILE *f, + struct parse_deftype_s *dcur) +{ + unsigned i; + + fprintf(f, " int c;\n"); + + /* add stmp for alloc-swap and set all string elements to NULL */ + if (dcur->contains_heap) { + fprintf(f, " char *stmp;\n"); for (i = 0; i < dcur->member_list_len; i++) { - if (dcur->type == PARSE_DEFTYPE_ENUM) { - fprintf(f, " CONFCONF_TYPE_%s_%s_%s,\n", - dcur->name, - dcur->member_name_list[i], - (opt_suffix_str() ? opt_suffix_str() : pr.suffix) + if (dcur->member_type_list[i] == PARSE_TYPE_STRING) { + fprintf(f, + "\n" + " t->%s = NULL;\n", + dcur->member_name_list[i] ); - continue; } + } + } - switch (dcur->member_type_list[i]) { - case PARSE_TYPE_BOOL: - fprintf(f, " bool "); - break; - case PARSE_TYPE_STRING: - fprintf(f, " char *"); - break; - case PARSE_TYPE_ID: - fprintf(f, " char *"); - break; - case PARSE_TYPE_INT: - fprintf(f, " int "); - break; - case PARSE_TYPE_INTL: - fprintf(f, " long int "); - break; - case PARSE_TYPE_INTLL: - fprintf(f, " long long int "); - break; - case PARSE_TYPE_UINT: - fprintf(f, " unsigned "); - break; - case PARSE_TYPE_UINTL: - fprintf(f, " long unsigned "); - break; - case PARSE_TYPE_UINTLL: - fprintf(f, " long long unsigned "); - break; - case PARSE_TYPE_FLOAT: - fprintf(f, " float "); - break; - case PARSE_TYPE_DOUBLE: - fprintf(f, " double "); - break; - case PARSE_TYPE_DOUBLEL: - fprintf(f, " long double "); - break; - default: - assert(0); - } + fprintf(f, + "\n" + " c = (*(st->gcp))(st->fp);\n" + "\n" + " if (c == EOF)\n" + " return CONFCONF_ERR_UNEXPECTED_EOF;\n" + "\n" + " if (c != '{') {\n" + " (*(st->ugcp))(c, st->fp);\n" + " pos = confconf_priv_pos_get(st);\n" + " r = confconf_priv_get_tok(st);\n" + " if (r != CONFCONF_SUCCESS)\n" + " return r;\n" + " confconf_priv_pos_set(st, pos);\n" + " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" + " }\n" + "\n" + " st->col++;\n" + " st->byte++;\n" + "\n" + " confconf_priv_eat_space(st);\n" + ); - fprintf(f, "%s;\n", dcur->member_name_list[i]); + for (i = 0; i < dcur->member_list_len; i++) { + if (i != 0) { + fprintf(f, + "\n" + " confconf_priv_eat_space(st);\n" + "\n" + " c = (*(st->gcp))(st->fp);\n" + " if (c == ',') {\n" + " st->col++;\n" + " st->byte++;\n" + " confconf_priv_eat_space(st);\n" + " } else {\n" + " (*(st->ugcp))(c, st->fp);\n" + " }\n" + ); } - fprintf(f, "};\n\n"); - } + fprintf(f, "\n"); + + if (dcur->member_type_list[i] != PARSE_TYPE_STRING) { + fprintf(f, + " st->vp = &(t->%s);\n", + dcur->member_name_list[i] + ); + } + + switch (dcur->member_type_list[i]) { + case PARSE_TYPE_BOOL: + fprintf(f, " r = confconf_priv_get_bool(st);\n"); + break; + case PARSE_TYPE_STRING: + fprintf(f, " r = confconf_priv_get_str(st);\n"); + break; + case PARSE_TYPE_ID: + fprintf(f, " r = confconf_priv_get_id(st);\n"); + break; + case PARSE_TYPE_INT: + fprintf(f, " r = confconf_priv_get_int(st);\n"); + break; + case PARSE_TYPE_INTL: + fprintf(f, " r = confconf_priv_get_intl(st);\n"); + break; + case PARSE_TYPE_INTLL: + fprintf(f, " r = confconf_priv_get_intll(st);\n"); + break; + case PARSE_TYPE_UINT: + fprintf(f, " r = confconf_priv_get_uint(st);\n"); + break; + case PARSE_TYPE_UINTL: + fprintf(f, " r = confconf_priv_get_uintl(st);\n"); + break; + case PARSE_TYPE_UINTLL: + fprintf(f, " r = confconf_priv_get_uintll(st);\n"); + break; + case PARSE_TYPE_FLOAT: + fprintf(f, " r = confconf_priv_get_float(st);\n"); + break; + case PARSE_TYPE_DOUBLE: + fprintf(f, " r = confconf_priv_get_double(st);\n"); + break; + case PARSE_TYPE_DOUBLEL: + fprintf(f, " r = confconf_priv_get_doublel(st);\n"); + break; + default: + assert(0); + } - /* hash type */ - if (ar.uses_hash) { fprintf(f, - "#include %s\n\n" - "struct confconf_hash_%s {\n" - " char *key;\n" - " union {\n" - "%s%s%s%s%s%s%s%s%s%s%s", - (opt_header_str() ? opt_header_str() : pr.header), - (opt_suffix_str() ? opt_suffix_str() : pr.suffix), - (ar.uses_type[PARSE_TYPE_HASH_BOOL] - ? " bool b;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_STRING] - ? " char *s;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_INT] - ? " int i;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_INTL] - ? " long int il;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_INTLL] - ? " long long int ill;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_UINT] - ? " unsigned u;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_UINTL] - ? " long unsigned ul;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_UINTLL] - ? " long long unsigned ull;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_FLOAT] - ? " float f;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_DOUBLE] - ? " double d;\n" : ""), - (ar.uses_type[PARSE_TYPE_HASH_DOUBLEL] - ? " long double dl;\n" : "") + " if (r != CONFCONF_SUCCESS)\n" + " %s;\n", + (dcur->contains_heap ? "goto err" : "return r") ); - HASH_ITER(hh, pr.deftypes, dcur, dtmp) { - if (dcur->is_used && dcur->is_in_hash) { - fprintf(f, " %s confconf_type_%s_%s type_%s;\n", - (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : - (dcur->type == PARSE_DEFTYPE_UNION ? - "union" : "struct") - ), - dcur->name, - (opt_suffix_str() ? opt_suffix_str() : pr.suffix), - dcur->name + + if (dcur->member_type_list[i] == PARSE_TYPE_STRING) { + fprintf(f, + "\n" + " stmp = confconf_priv_dup_sbuf(st);\n" + " if (stmp == NULL)\n" + " goto err;\n" + " t->%s = stmp;\n", + dcur->member_name_list[i] + ); + } + } + + fprintf(f, + "\n" + " c = (*(st->gcp))(st->fp);\n" + "\n" + " if (c == EOF)\n" + " return CONFCONF_ERR_UNEXPECTED_EOF;\n" + "\n" + " if (c != '}') {\n" + " (*(st->ugcp))(c, st->fp);\n" + " pos = confconf_priv_pos_get(st);\n" + " r = confconf_priv_get_tok(st);\n" + " if (r != CONFCONF_SUCCESS)\n" + " %s;\n" + " confconf_priv_pos_set(st, pos);\n" + " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" + " %s;\n" + " }\n" + "\n" + " return CONFCONF_SUCCESS;\n", + (dcur->contains_heap ? "goto err" : "return r"), + (dcur->contains_heap ? "goto err" : "return r") + ); + + if (dcur->contains_heap) { + fprintf(f, "\nerr:\n"); + for (i = 0; i < dcur->member_list_len; i++) { + if (dcur->member_type_list[i] == PARSE_TYPE_STRING + || dcur->member_type_list[i] == PARSE_TYPE_ID + ) { + fprintf(f, + " if (t->%s != NULL)\n" + " free(t->%s);\n" + "\n", + dcur->member_name_list[i], + dcur->member_name_list[i] ); } } + fprintf(f, " return r;\n"); + } +} + +/* emit a switch statement dfa to char-by-char recognise a string */ +static void sub_print_switch(FILE *f, struct analyse_trie_s *cur, + unsigned depth, const char *dest, const char *stmt) +{ + unsigned i; + + cur->idx = 0; + do { + /* skip leaves */ + if (cur->branch_count == 0) { + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "if (*stmp == '\\0') {\n"); + for (i = 0; i < depth + 1; i++) + fprintf(f, "\t"); + fprintf(f, "%s = %s;\n", dest, cur->sval); + for (i = 0; i < depth + 1; i++) + fprintf(f, "\t"); + fprintf(f, "%s;\n", stmt); + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "}\n"); + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "break;\n"); + depth--; + } else { + if (cur->idx == 0) { + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "switch ( *(stmp++) ) {\n"); + } + + if (cur->idx == cur->branch_count) { + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "}\n"); + /* skip break for final '}' */ + if (cur->parent != NULL || cur->idx != cur->branch_count) { + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "break;\n"); + } + depth--; + } else { + /* match prefix terminals */ + if (cur->idx == 0 && cur->sval != NULL) { + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "case '\\0':\n"); + for (i = 0; i < depth + 1; i++) + fprintf(f, "\t"); + fprintf(f, "%s = %s;\n", dest, cur->sval); + for (i = 0; i < depth + 1; i++) + fprintf(f, "\t"); + fprintf(f, "%s;\n", stmt); + for (i = 0; i < depth + 1; i++) + fprintf(f, "\t"); + fprintf(f, "break;\n"); + } + for (i = 0; i < depth; i++) + fprintf(f, "\t"); + fprintf(f, "case '%c':\n", cur->branch_chars[cur->idx]); + depth++; + } + } + + /* next node in the trie, iterating depth-first */ + if (cur->idx == cur->branch_count) { + cur = cur->parent; + } else { + cur->idx++; + cur = cur->branches[cur->idx - 1]; + cur->idx = 0; + } + } while (cur != NULL); + +} + +static inline void sub_deftypes_get_union(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar, struct parse_deftype_s *dcur, unsigned idx) +{ + struct analyse_trie_s *t = &(ar->deftype_mem_tries[idx]); + unsigned i; + + fprintf(f, + " char *stmp;\n" + " unsigned mem;\n" + "\n" + " confconf_priv_eat_space(st);\n" + "\n" + " pos = confconf_priv_pos_get(st);\n" + " r = confconf_priv_get_tok(st);\n" + " if (r != CONFCONF_SUCCESS)\n" + " return r;\n" + " stmp = st->sbuf;\n" + "\n" + ); + + sub_print_switch(f, t, 1, "mem", "goto match"); + + fprintf(f, + "\n" + " confconf_priv_pos_set(st, pos);\n" + " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" + "\n" + "match:\n" + " pos = confconf_priv_pos_get(st);\n" + "\n" + " switch (mem) {\n" + ); + + for (i = 0; i < dcur->member_list_len; i++) { fprintf(f, - " } val;\n" - " UT_hash_handle hh;\n" - "};\n\n" + " case %u:\n" + " st->vp = &(t->val.%s);\n" + " r = confconf_priv_get_%s(st);\n" + " t->type = CONFCONF_UTYPE_%s_%s_%s;\n" + " break;\n", + i, + dcur->member_name_list[i], + parse_typestrs[dcur->member_type_list[i]], + dcur->name, + dcur->member_name_list[i], + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) ); + } + + fprintf(f, + " }\n" + "\n" + " if (r != CONFCONF_SUCCESS)\n" + " return r;\n" + "\n" + " return CONFCONF_SUCCESS;\n" + ); +} + +static inline void sub_deftypes_get_enum(FILE *f, struct analyse_result_s *ar, + struct parse_deftype_s *dcur, unsigned idx) +{ + struct analyse_trie_s *t = &(ar->deftype_mem_tries[idx]); + + fprintf(f, + " char *stmp;\n" + "\n" + " confconf_priv_eat_space(st);\n" + "\n" + " pos = confconf_priv_pos_get(st);\n" + " r = confconf_priv_get_tok(st);\n" + " if (r != CONFCONF_SUCCESS)\n" + " return r;\n" + " stmp = st->sbuf;\n" + "\n" + ); + + sub_print_switch(f, t, 1, "*t", "return CONFCONF_SUCCESS"); + + fprintf(f, + "\n" + " confconf_priv_pos_set(st, pos);\n" + " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" + ); +} + +static inline void sub_deftypes_get(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar, struct parse_deftype_s *dcur, unsigned idx) +{ + fprintf(f, + "static enum confconf_result_type\n" + "confconf_priv_get_%s_%s(struct confconf_priv_state *st)\n" + "{\n" + " enum confconf_result_type r;\n" + " %s confconf_type_%s_%s *t = st->vp;\n" + " struct confconf_priv_pos pos;\n", + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix), + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : "struct"), + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + + switch (dcur->type) { + case PARSE_DEFTYPE_STRUCT: + sub_deftypes_get_struct(f, dcur); + break; + + case PARSE_DEFTYPE_UNION: + sub_deftypes_get_union(f, pr, ar, dcur, idx); + break; + + case PARSE_DEFTYPE_ENUM: + sub_deftypes_get_enum(f, ar, dcur, idx); + break; + + default: + assert(0); + } + + fprintf(f, "}\n\n"); +} + +static inline void sub_deftypes(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar) +{ + struct parse_deftype_s *dcur, *dtmp; + unsigned i = 0; + + HASH_ITER(hh, pr->deftypes, dcur, dtmp) { + + if (!dcur->is_used) { + i++; + continue; + } + + /* print the type definition */ + sub_deftypes_type(f, pr, dcur); + /* print it's get function */ + sub_deftypes_get(f, pr, ar, dcur, i); + i++; + } + +} + +static inline void sub_arraytype(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar) +{ + struct parse_deftype_s *dcur, *dtmp; + + fprintf(f, + "struct confconf_array_%s {\n" + " size_t len;\n" + " union {\n" + "%s%s%s%s%s%s%s%s%s%s%s", + (opt_suffix_str() ? opt_suffix_str() : pr->suffix), + (ar->uses_type[PARSE_TYPE_ARRAY_BOOL] + ? " bool b;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_STRING] + ? " char *s;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_INT] + ? " int i;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_INTL] + ? " long int il;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_INTLL] + ? " long long int ill;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_UINT] + ? " unsigned u;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_UINTL] + ? " long unsigned ul;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_UINTLL] + ? " long long unsigned ull;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_FLOAT] + ? " float f;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_DOUBLE] + ? " double d;\n" : ""), + (ar->uses_type[PARSE_TYPE_ARRAY_DOUBLEL] + ? " long double dl;\n" : "") + ); + + HASH_ITER(hh, pr->deftypes, dcur, dtmp) { + if (dcur->is_used && dcur->is_in_array) { + fprintf(f, + " %s confconf_type_%s_%s type_%s;\n", + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : + (dcur->type == PARSE_DEFTYPE_UNION ? "union" : "struct") + ), + dcur->name, pr->suffix, dcur->name + ); + } + } + + fprintf(f, + " } *arr;\n" + "};\n\n" + ); +} + +static inline void sub_hashtype(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar) +{ + struct parse_deftype_s *dcur, *dtmp; + + fprintf(f, + "#include %s\n\n" + "struct confconf_hash_%s {\n" + " char *key;\n" + " union {\n" + "%s%s%s%s%s%s%s%s%s%s%s", + (opt_header_str() ? opt_header_str() : pr->header), + (opt_suffix_str() ? opt_suffix_str() : pr->suffix), + (ar->uses_type[PARSE_TYPE_HASH_BOOL] + ? " bool b;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_STRING] + ? " char *s;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_INT] + ? " int i;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_INTL] + ? " long int il;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_INTLL] + ? " long long int ill;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_UINT] + ? " unsigned u;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_UINTL] + ? " long unsigned ul;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_UINTLL] + ? " long long unsigned ull;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_FLOAT] + ? " float f;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_DOUBLE] + ? " double d;\n" : ""), + (ar->uses_type[PARSE_TYPE_HASH_DOUBLEL] + ? " long double dl;\n" : "") + ); + HASH_ITER(hh, pr->deftypes, dcur, dtmp) { + if (dcur->is_used && dcur->is_in_hash) { + fprintf(f, + " %s confconf_type_%s_%s type_%s;\n", + (dcur->type == PARSE_DEFTYPE_ENUM ? "enum" : + (dcur->type == PARSE_DEFTYPE_UNION ? "union" : "struct") + ), + dcur->name, + (opt_suffix_str() ? opt_suffix_str() : pr->suffix), + dcur->name + ); + } } + fprintf(f, + " } val;\n" + " UT_hash_handle hh;\n" + "};\n\n" + ); +} + +static inline void sub_body(FILE *f, struct parse_result_s *pr, + struct analyse_result_s *ar) +{ + struct parse_var_s *vcur, *vtmp; + +} + +void gen(FILE *f, struct parse_result_s *pr, struct analyse_result_s *ar) +{ + time_t t; + struct tm *ti; + + assert(pr != NULL); + assert(ar != NULL); + + time(&t); + ti = localtime(&t); + + fprintf(f, "/* generated by %s on %04d-%02d-%02d */\n\n", + VERSION, ti->tm_year + 1900, ti->tm_mon + 1, ti->tm_mday); + + /* conditionally include static subroutines from gen-consts.h */ + sub_head(f, ar); + + fprintf(f, + "#ifndef CONFCONF_BODY_%s_H\n" + "#define CONFCONF_BODY_%s_H\n\n", + (opt_suffix_str() ? opt_suffix_str() : pr->suffix), + (opt_suffix_str() ? opt_suffix_str() : pr->suffix) + ); + + /* define struct/enum/unions and their get functions */ + sub_deftypes(f, pr, ar); + + if (ar->uses_array) + sub_arraytype(f, pr, ar); + + if (ar->uses_hash) + sub_hashtype(f, pr, ar); + + sub_body(f, pr, ar); + fprintf(f, "#endif\n"); } -- cgit v1.2.3