aboutsummaryrefslogtreecommitdiffstats
path: root/src/gen.c
diff options
context:
space:
mode:
authorkatherine <shmibs@airen-no-jikken.icu>2019-05-27 16:29:08 -0700
committerkatherine <shmibs@airen-no-jikken.icu>2019-05-27 16:29:08 -0700
commit31423d1ce9d902b988c9b38f996718c7095d4315 (patch)
treed247172e33dc04f194456ba2498287185b5528fb /src/gen.c
parent79985ce2ecc8630a2c1ca48a8eef61e3a69c3fdd (diff)
downloadconfconf-31423d1ce9d902b988c9b38f996718c7095d4315.tar.gz
implement hash parsing generation
Diffstat (limited to 'src/gen.c')
-rw-r--r--src/gen.c121
1 files changed, 118 insertions, 3 deletions
diff --git a/src/gen.c b/src/gen.c
index fdad6e8..d2c1aeb 100644
--- a/src/gen.c
+++ b/src/gen.c
@@ -1,8 +1,10 @@
#include "gen.h"
#include "version.h"
+#include "parse.h"
#include <time.h>
+#include <assert.h>
#include "gen-consts.h"
@@ -11,20 +13,29 @@ void gen(FILE *f, struct parse_result_s pr, 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, sheader);
+ fprintf(f, sheaderp1);
+ fprintf(f, sheaderp2);
+ /* built-in types */
if (ar.uses_bool)
fprintf(f, sbool);
if (ar.uses_string)
fprintf(f, sstring);
- if (ar.uses_id)
- fprintf(f, sid);
if (ar.uses_int)
fprintf(f, sint);
if (ar.uses_intl)
@@ -43,5 +54,109 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)
fprintf(f, sdouble);
if (ar.uses_doublel)
fprintf(f, sdoublel);
+ if (ar.uses_hash)
+ fprintf(f, shash);
+
+ /********
+ * BODY *
+ ********/
+
+ fprintf(f,
+ "#ifndef CONFCONF_BODY_%s_H\n"
+ "#define CONFCONF_BODY_%s_H\n\n",
+ pr.suffix, pr.suffix
+ );
+
+ /* structs */
+ HASH_ITER(hh, pr.deftypes, dcur, dtmp) {
+ fprintf(f, "struct confconf_type_%s_%s {\n",
+ dcur->name, pr.suffix);
+
+ for (i = 0; i < dcur->member_list_len; i++) {
+ 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]);
+ }
+
+ fprintf(f, "};\n\n");
+ }
+
+ /* array */
+
+ /* hash */
+ if (ar.uses_hash) {
+ fprintf(f,
+ "#include <uthash.h>\n\n"
+ "struct confconf_hash_%s {\n"
+ " char *key;\n"
+ " union {\n"
+ "%s%s%s%s%s%s%s%s%s%s%s",
+ pr.suffix,
+ (ar.uses_bool ? " bool b;\n" : ""),
+ (ar.uses_string ? " char *s;\n" : ""),
+ (ar.uses_int ? " int i;\n" : ""),
+ (ar.uses_intl ? " long int il;\n" : ""),
+ (ar.uses_intll ? " long long int ill;\n" : ""),
+ (ar.uses_uint ? " unsigned u;\n" : ""),
+ (ar.uses_uintl ? " long unsigned ul;\n" : ""),
+ (ar.uses_uintll ? " long long unsigned ull;\n" : ""),
+ (ar.uses_float ? " float f;\n" : ""),
+ (ar.uses_double ? " double d;\n" : ""),
+ (ar.uses_doublel ? " long double dl;\n" : "")
+ );
+ HASH_ITER(hh, pr.deftypes, dcur, dtmp) {
+ if (dcur->is_used) {
+ fprintf(f, " %s confconf_type_%s_%s type_%s;\n",
+ (dcur->is_union ? "union" : "struct"),
+ dcur->name, pr.suffix, dcur->name);
+ }
+ }
+ fprintf(f,
+ " } val;\n"
+ " UT_hash_handle hh;\n"
+ "};\n\n"
+ );
+
+ }
+ fprintf(f, "#endif\n");
}