From 31423d1ce9d902b988c9b38f996718c7095d4315 Mon Sep 17 00:00:00 2001 From: katherine Date: Mon, 27 May 2019 16:29:08 -0700 Subject: implement hash parsing generation --- src/analyse.c | 65 ++++++---- src/analyse.h | 3 + src/gen-consts.h | 380 +++++++++++++++++++++++++++++++++++-------------------- src/gen.c | 121 +++++++++++++++++- src/main.c | 6 +- src/parse.c | 83 +++--------- src/parse.h | 8 +- src/tok.c | 10 +- src/tok.h | 4 +- 9 files changed, 433 insertions(+), 247 deletions(-) (limited to 'src') diff --git a/src/analyse.c b/src/analyse.c index e454f6c..e0e5fa6 100644 --- a/src/analyse.c +++ b/src/analyse.c @@ -7,6 +7,8 @@ struct analyse_result_s analyse(struct parse_result_s pr) { struct analyse_result_s ar = { + .uses_array = false, + .uses_hash = false, .uses_bool = false, .uses_string = false, .uses_id = false, @@ -20,8 +22,8 @@ struct analyse_result_s analyse(struct parse_result_s pr) .uses_double = false, .uses_doublel = false, }; - struct parse_deftype_s *dtp, *tmp_dtp; - struct parse_var_s *vtp, *tmp_vtp; + struct parse_deftype_s *dcur, *dtmp; + struct parse_var_s *vcur, *vtmp; struct analyse_tree_s *cur; unsigned i; @@ -29,17 +31,17 @@ struct analyse_result_s analyse(struct parse_result_s pr) ar.deftype_tree.is_terminal = false; if (pr.deftypes != NULL) { - HASH_ITER(hh, pr.deftypes, dtp, tmp_dtp) { + HASH_ITER(hh, pr.deftypes, dcur, dtmp) { cur = &(ar.deftype_tree); /* walk down the tree, creating nodes when necessary */ - for (i = 0; dtp->name[i] != '\0'; i++) { + for (i = 0; dcur->name[i] != '\0'; i++) { if (cur->branch_count == 0 || cur->branch_chars[cur->branch_count - 1] - != dtp->name[i] + != dcur->name[i] ) { cur->branch_count++; - cur->branch_chars[cur->branch_count - 1] = dtp->name[i]; + cur->branch_chars[cur->branch_count - 1] = dcur->name[i]; TRYALLOC(cur->branches[cur->branch_count - 1], 1); cur = cur->branches[cur->branch_count - 1]; cur->branch_count = 0; @@ -50,7 +52,7 @@ struct analyse_result_s analyse(struct parse_result_s pr) } cur->is_terminal = true; - strcpy(cur->name, dtp->name); + strcpy(cur->name, dcur->name); } } @@ -58,17 +60,17 @@ struct analyse_result_s analyse(struct parse_result_s pr) ar.var_tree.is_terminal = false; if (pr.vars != NULL) { - HASH_ITER(hh, pr.vars, vtp, tmp_vtp) { + HASH_ITER(hh, pr.vars, vcur, vtmp) { cur = &(ar.var_tree); /* walk down the tree, creating nodes when necessary */ - for (i = 0; vtp->name[i] != '\0'; i++) { + for (i = 0; vcur->name[i] != '\0'; i++) { if (cur->branch_count == 0 || cur->branch_chars[cur->branch_count - 1] - != vtp->name[i] + != vcur->name[i] ) { cur->branch_count++; - cur->branch_chars[cur->branch_count - 1] = vtp->name[i]; + cur->branch_chars[cur->branch_count - 1] = vcur->name[i]; TRYALLOC(cur->branches[cur->branch_count - 1], 1); cur = cur->branches[cur->branch_count - 1]; cur->branch_count = 0; @@ -79,14 +81,25 @@ struct analyse_result_s analyse(struct parse_result_s pr) } cur->is_terminal = true; - strcpy(cur->name, vtp->name); + strcpy(cur->name, vcur->name); } } - HASH_ITER(hh, pr.vars, vtp, tmp_vtp) { - switch (vtp->type - - (PARSE_TYPE_ARRAY_BOOL * (vtp->type >= PARSE_TYPE_ARRAY_BOOL)) - - (PARSE_TYPE_ARRAY_BOOL * (vtp->type >= PARSE_TYPE_HASH_BOOL)) + for (i = 0; i < PARSE_TYPE_ARRAY_BOOL; i++) + ar.hash_types[i] = false; + + HASH_ITER(hh, pr.vars, vcur, vtmp) { + if (vcur->type >= PARSE_TYPE_HASH_BOOL) { + ar.uses_hash = true; + ar.uses_id = true; + ar.hash_types[vcur->type - PARSE_TYPE_HASH_BOOL] = true; + } else if (vcur->type >= PARSE_TYPE_ARRAY_BOOL) { + ar.uses_array = true; + } + + switch (vcur->type + - (PARSE_TYPE_ARRAY_BOOL * (vcur->type >= PARSE_TYPE_ARRAY_BOOL)) + - (PARSE_TYPE_ARRAY_BOOL * (vcur->type >= PARSE_TYPE_HASH_BOOL)) ) { case PARSE_TYPE_BOOL: ar.uses_bool = true; @@ -125,16 +138,16 @@ struct analyse_result_s analyse(struct parse_result_s pr) ar.uses_doublel = true; break; default: - HASH_FIND_STR(pr.deftypes, vtp->deftype_name, dtp); - assert(dtp != NULL); - for (i = 0; i < dtp->member_list_len; i++) { - switch (dtp->member_type_list[i] - - (PARSE_TYPE_ARRAY_BOOL * - (dtp->member_type_list[i] >= PARSE_TYPE_ARRAY_BOOL) - ) - - (PARSE_TYPE_ARRAY_BOOL * - (dtp->member_type_list[i] >= PARSE_TYPE_HASH_BOOL) - ) + HASH_FIND_STR(pr.deftypes, vcur->deftype_name, dcur); + assert(dcur != NULL); + for (i = 0; i < dcur->member_list_len; i++) { + switch (dcur->member_type_list[i] + - (PARSE_TYPE_ARRAY_BOOL * + (dcur->member_type_list[i] >= PARSE_TYPE_ARRAY_BOOL) + ) + - (PARSE_TYPE_ARRAY_BOOL * + (dcur->member_type_list[i] >= PARSE_TYPE_HASH_BOOL) + ) ) { case PARSE_TYPE_BOOL: ar.uses_bool = true; diff --git a/src/analyse.h b/src/analyse.h index 19f1b96..77594c2 100644 --- a/src/analyse.h +++ b/src/analyse.h @@ -18,6 +18,8 @@ struct analyse_tree_s { }; struct analyse_result_s { + bool uses_array; + bool uses_hash; bool uses_bool; bool uses_string; bool uses_id; @@ -30,6 +32,7 @@ struct analyse_result_s { bool uses_float; bool uses_double; bool uses_doublel; + bool hash_types[PARSE_TYPE_ARRAY_BOOL]; struct analyse_tree_s deftype_tree; struct analyse_tree_s var_tree; }; diff --git a/src/gen-consts.h b/src/gen-consts.h index 035e3d2..e3b1b16 100644 --- a/src/gen-consts.h +++ b/src/gen-consts.h @@ -1,4 +1,4 @@ -static const char sheader[] = +static const char sheaderp1[] = "#ifndef CONFCONF_HEAD_H\n" "#define CONFCONF_HEAD_H\n" "\n" @@ -14,7 +14,7 @@ static const char sheader[] = " CONFCONF_SUCCESS = 0,\n" " CONFCONF_ERR_UNEXPECTED_EOF,\n" " CONFCONF_ERR_UNEXPECTED_TOKEN,\n" -" CONFCONF_ERR_HASH_KEY_TOO_LONG,\n" +" CONFCONF_ERR_HASH_DUPLICATE_KEY,\n" " CONFCONF_ERR_RANGE,\n" " CONFCONF_ERR_MISSING_VARIABLE,\n" " CONFCONF_ERR_MEMORY,\n" @@ -40,7 +40,7 @@ static const char sheader[] = " float f;\n" " double d;\n" " long double dl;\n" -" };\n" +" } val;\n" "};\n" "\n" "static int confconf_priv_gcp_file(void *fp)\n" @@ -111,72 +111,108 @@ static const char sheader[] = " }\n" "}\n" "\n" +; + +static const char sheaderp2[] = "static enum confconf_result_type confconf_priv_get_tok(\n" " struct confconf_priv_state *st)\n" "{\n" -" size_t len = 0, mlen = 0;\n" +" size_t len = 0, mlen = CONFCONF_ALLOCWIDTH;\n" " char *stmp;\n" " int c;\n" "\n" -" st->s = NULL;\n" +" st->val.s = NULL;\n" "\n" " c = (*(st->gcp))(st->fp);\n" "\n" " if (c == EOF)\n" " return CONFCONF_ERR_UNEXPECTED_EOF;\n" "\n" +" st->val.s = realloc(st->val.s, mlen);\n" +" if (st->val.s == NULL)\n" +" return CONFCONF_ERR_MEMORY;\n" +" st->val.s[0] = '\\0';\n" +"\n" " while (c != ' ' && c != '\\f' && c != '\\n'\n" " && c != '\\r' && c != '\\t' && c != '\\v'\n" -" && c != ']' && c != '}' && c != ','\n" +" && c != ']' && c != '}'\n" +" && c != '[' && c != '{'\n" +" && c != ',' && c != ':'\n" " && c != EOF) {\n" " if (len == mlen) {\n" " mlen += CONFCONF_ALLOCWIDTH;\n" "\n" " if (mlen < len) {\n" -" if (st->s != NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " }\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" "\n" -" stmp = realloc(st->s, mlen);\n" +" stmp = realloc(st->val.s, mlen);\n" " if (stmp == NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" -" st->s = stmp;\n" +" st->val.s = stmp;\n" " }\n" "\n" -" st->s[len] = c;\n" +" st->val.s[len] = c;\n" " len++;\n" " c = (*(st->gcp))(st->fp);\n" " }\n" "\n" +" if (st->val.s[0] == '\\0') {\n" +" st->val.s[0] = c;\n" +" len++;\n" +" if (len == mlen) {\n" +" mlen += CONFCONF_ALLOCWIDTH;\n" +"\n" +" if (mlen < len) {\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" +" }\n" +" return CONFCONF_ERR_MEMORY;\n" +" }\n" +"\n" +" stmp = realloc(st->val.s, mlen);\n" +" if (stmp == NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" +" return CONFCONF_ERR_MEMORY;\n" +" }\n" +" st->val.s = stmp;\n" +" }\n" +" st->val.s[1] = '\\0';\n" +" return CONFCONF_SUCCESS;\n" +" }\n" +"\n" " if (len == mlen) {\n" " mlen += CONFCONF_ALLOCWIDTH;\n" "\n" " if (mlen < len) {\n" -" if (st->s != NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " }\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" "\n" -" stmp = realloc(st->s, mlen);\n" +" stmp = realloc(st->val.s, mlen);\n" " if (stmp == NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" -" st->s = stmp;\n" +" st->val.s = stmp;\n" " }\n" "\n" " (*(st->ugcp))(c, st->fp);\n" "\n" -" st->s[len] = '\\0';\n" +" st->val.s[len] = '\\0';\n" "\n" " st->col += len;\n" " st->byte += len;\n" @@ -184,6 +220,50 @@ static const char sheader[] = " return CONFCONF_SUCCESS;\n" "}\n" "\n" +"static enum confconf_result_type confconf_priv_get_id(\n" +" struct confconf_priv_state *st)\n" +"{\n" +" enum confconf_result_type r;\n" +" char *off;\n" +"\n" +" r = confconf_priv_get_tok(st);\n" +"\n" +" if (r != CONFCONF_SUCCESS)\n" +" return r;\n" +"\n" +" for (off = st->val.s; *off != '\\0'; off++) {\n" +" if (*off >= '0' && *off <= '9')\n" +" continue;\n" +" if (\n" +" *off == 'a' || *off == 'b' || *off == 'c' ||\n" +" *off == 'd' || *off == 'e' || *off == 'f' ||\n" +" *off == 'g' || *off == 'h' || *off == 'i' ||\n" +" *off == 'j' || *off == 'k' || *off == 'l' ||\n" +" *off == 'm' || *off == 'n' || *off == 'o' ||\n" +" *off == 'p' || *off == 'q' || *off == 'r' ||\n" +" *off == 's' || *off == 't' || *off == 'u' ||\n" +" *off == 'v' || *off == 'w' || *off == 'x' ||\n" +" *off == 'y' || *off == 'z' ||\n" +" *off == 'A' || *off == 'B' || *off == 'C' ||\n" +" *off == 'D' || *off == 'E' || *off == 'F' ||\n" +" *off == 'G' || *off == 'H' || *off == 'I' ||\n" +" *off == 'J' || *off == 'K' || *off == 'L' ||\n" +" *off == 'M' || *off == 'N' || *off == 'O' ||\n" +" *off == 'P' || *off == 'Q' || *off == 'R' ||\n" +" *off == 'S' || *off == 'T' || *off == 'U' ||\n" +" *off == 'V' || *off == 'W' || *off == 'X' ||\n" +" *off == 'Y' || *off == 'Z' ||\n" +" *off == '-' || *off == '_'\n" +" ) {\n" +" continue;\n" +" }\n" +" \n" +" return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" +" }\n" +"\n" +" return CONFCONF_SUCCESS;\n" +"}\n" +"\n" "#endif\n" "\n" ; @@ -203,7 +283,7 @@ static const char sbool[] = " if (r != CONFCONF_SUCCESS)\n" " return r;\n" "\n" -" off = st->s;\n" +" off = st->val.s;\n" "\n" " if (*off == 't' || *off == 'T') {\n" " if (\n" @@ -212,8 +292,8 @@ static const char sbool[] = " (*(++off) == 'e' || *off == 'E') &&\n" " (*(++off) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = true;\n" +" free(st->val.s);\n" +" st->val.b = true;\n" " return CONFCONF_SUCCESS;\n" " } else {\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" @@ -226,8 +306,8 @@ static const char sbool[] = " (*(++off) == 's' || *off == 'S') &&\n" " (*(++off) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = true;\n" +" free(st->val.s);\n" +" st->val.b = true;\n" " return CONFCONF_SUCCESS;\n" " } else {\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" @@ -239,8 +319,8 @@ static const char sbool[] = " (*(++off) == 'o' || *off == 'O') &&\n" " (*(++off) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = false;\n" +" free(st->val.s);\n" +" st->val.b = false;\n" " return CONFCONF_SUCCESS;\n" " } else {\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" @@ -255,8 +335,8 @@ static const char sbool[] = " (*(++off) == 'e' || *off == 'E') &&\n" " (*(++off) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = false;\n" +" free(st->val.s);\n" +" st->val.b = false;\n" " return CONFCONF_SUCCESS;\n" " } else {\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" @@ -268,8 +348,8 @@ static const char sbool[] = " (*(off+1) == 'n' || *(off+1) == 'N') &&\n" " (*(off+2) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = true;\n" +" free(st->val.s);\n" +" st->val.b = true;\n" " return CONFCONF_SUCCESS;\n" " }\n" "\n" @@ -278,8 +358,8 @@ static const char sbool[] = " (*(++off) == 'f' || *off == 'F') &&\n" " (*(++off) == '\\0')\n" " ) {\n" -" free(st->s);\n" -" st->b = false;\n" +" free(st->val.s);\n" +" st->val.b = false;\n" " return CONFCONF_SUCCESS;\n" " } else {\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" @@ -305,7 +385,7 @@ static const char sstring[] = " int c, endc;\n" " bool escape = false;\n" "\n" -" st->s = NULL;\n" +" st->val.s = NULL;\n" "\n" " c = (*(st->gcp))(st->fp);\n" " if (c == EOF)\n" @@ -342,9 +422,9 @@ static const char sstring[] = " }\n" "\n" " if (c == EOF) {\n" -" if (st->s != NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " }\n" " return CONFCONF_ERR_UNEXPECTED_EOF;\n" " }\n" @@ -353,23 +433,23 @@ static const char sstring[] = " mlen += CONFCONF_ALLOCWIDTH;\n" "\n" " if (mlen < len) {\n" -" if (st->s != NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " }\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" "\n" -" stmp = realloc(st->s, mlen);\n" +" stmp = realloc(st->val.s, mlen);\n" " if (stmp == NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" -" st->s = stmp;\n" +" st->val.s = stmp;\n" " }\n" "\n" -" st->s[len] = c;\n" +" st->val.s[len] = c;\n" " len++;\n" " }\n" "\n" @@ -377,75 +457,23 @@ static const char sstring[] = " mlen += CONFCONF_ALLOCWIDTH;\n" "\n" " if (mlen < len) {\n" -" if (st->s != NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" if (st->val.s != NULL) {\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " }\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" "\n" -" stmp = realloc(st->s, mlen);\n" +" stmp = realloc(st->val.s, mlen);\n" " if (stmp == NULL) {\n" -" free(st->s);\n" -" st->s = NULL;\n" +" free(st->val.s);\n" +" st->val.s = NULL;\n" " return CONFCONF_ERR_MEMORY;\n" " }\n" -" st->s = stmp;\n" -" }\n" -"\n" -" st->s[len] = '\\0';\n" -" return CONFCONF_SUCCESS;\n" -"}\n" -"\n" -"#endif\n" -"\n" -; - -static const char sid[] = -"#ifndef CONFCONF_ID_H\n" -"#define CONFCONF_ID_H\n" -"\n" -"static enum confconf_result_type confconf_priv_get_id(\n" -" struct confconf_priv_state *st)\n" -"{\n" -" enum confconf_result_type r;\n" -" char *off;\n" -"\n" -" r = confconf_priv_get_tok(st);\n" -"\n" -" if (r != CONFCONF_SUCCESS)\n" -" return r;\n" -"\n" -" for (off = st->s; *off != '\\0'; off++) {\n" -" if (*off >= '0' && *off <= '9')\n" -" continue;\n" -" if (\n" -" *off == 'a' || *off == 'b' || *off == 'c' ||\n" -" *off == 'd' || *off == 'e' || *off == 'f' ||\n" -" *off == 'g' || *off == 'h' || *off == 'i' ||\n" -" *off == 'j' || *off == 'k' || *off == 'l' ||\n" -" *off == 'm' || *off == 'n' || *off == 'o' ||\n" -" *off == 'p' || *off == 'q' || *off == 'r' ||\n" -" *off == 's' || *off == 't' || *off == 'u' ||\n" -" *off == 'v' || *off == 'w' || *off == 'x' ||\n" -" *off == 'y' || *off == 'z' ||\n" -" *off == 'A' || *off == 'B' || *off == 'C' ||\n" -" *off == 'D' || *off == 'E' || *off == 'F' ||\n" -" *off == 'G' || *off == 'H' || *off == 'I' ||\n" -" *off == 'J' || *off == 'K' || *off == 'L' ||\n" -" *off == 'M' || *off == 'N' || *off == 'O' ||\n" -" *off == 'P' || *off == 'Q' || *off == 'R' ||\n" -" *off == 'S' || *off == 'T' || *off == 'U' ||\n" -" *off == 'V' || *off == 'W' || *off == 'X' ||\n" -" *off == 'Y' || *off == 'Z' ||\n" -" *off == '-' || *off == '_'\n" -" ) {\n" -" continue;\n" -" }\n" -" \n" -" return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" +" st->val.s = stmp;\n" " }\n" "\n" +" st->val.s[len] = '\\0';\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -473,7 +501,7 @@ static const char sint[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" i = strtol(st->s, &check, 0);\n" +" i = strtol(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -484,8 +512,8 @@ static const char sint[] = " if (i > INT_MAX || i < INT_MIN)\n" " return CONFCONF_ERR_RANGE;\n" "\n" -" free(st->s);\n" -" st->i = (int)i;\n" +" free(st->val.s);\n" +" st->val.i = (int)i;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -512,7 +540,7 @@ static const char sintl[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" il = strtol(st->s, &check, 0);\n" +" il = strtol(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -520,8 +548,8 @@ static const char sintl[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->il = il;\n" +" free(st->val.s);\n" +" st->val.il = il;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -548,7 +576,7 @@ static const char sintll[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" ill = strtoll(st->s, &check, 0);\n" +" ill = strtoll(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -556,8 +584,8 @@ static const char sintll[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->ill = ill;\n" +" free(st->val.s);\n" +" st->val.ill = ill;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -585,7 +613,7 @@ static const char suint[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" u = strtoul(st->s, &check, 0);\n" +" u = strtoul(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -596,8 +624,8 @@ static const char suint[] = " if (u > UINT_MAX)\n" " return CONFCONF_ERR_RANGE;\n" "\n" -" free(st->s);\n" -" st->u = (unsigned)u;\n" +" free(st->val.s);\n" +" st->val.u = (unsigned)u;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -624,7 +652,7 @@ static const char suintl[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" ul = strtoul(st->s, &check, 0);\n" +" ul = strtoul(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -632,8 +660,8 @@ static const char suintl[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->ul = ul;\n" +" free(st->val.s);\n" +" st->val.ul = ul;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -660,7 +688,7 @@ static const char suintll[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" ull = strtoull(st->s, &check, 0);\n" +" ull = strtoull(st->val.s, &check, 0);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -668,8 +696,8 @@ static const char suintll[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->ull = ull;\n" +" free(st->val.s);\n" +" st->val.ull = ull;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -696,7 +724,7 @@ static const char sfloat[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" f = strtof(st->s, &check);\n" +" f = strtof(st->val.s, &check);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -704,8 +732,8 @@ static const char sfloat[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->f = f;\n" +" free(st->val.s);\n" +" st->val.f = f;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -732,7 +760,7 @@ static const char sdouble[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" d = strtod(st->s, &check);\n" +" d = strtod(st->val.s, &check);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -740,8 +768,8 @@ static const char sdouble[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->d = d;\n" +" free(st->val.s);\n" +" st->val.d = d;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" @@ -768,7 +796,7 @@ static const char sdoublel[] = " return r;\n" "\n" " errno = EILSEQ;\n" -" dl = strtold(st->s, &check);\n" +" dl = strtold(st->val.s, &check);\n" "\n" " if (errno == ERANGE)\n" " return CONFCONF_ERR_RANGE;\n" @@ -776,11 +804,95 @@ static const char sdoublel[] = " if (*check != '\\0')\n" " return CONFCONF_ERR_UNEXPECTED_TOKEN;\n" "\n" -" free(st->s);\n" -" st->dl = dl;\n" +" free(st->val.s);\n" +" st->val.dl = dl;\n" " return CONFCONF_SUCCESS;\n" "}\n" "\n" "#endif\n" "\n" ; + +static const char shash[] = +"#ifndef CONFCONF_HASH_H\n" +"#define CONFCONF_HASH_H\n" +"\n" +"#include \n" +"\n" +"#define CONFCONF_PRIV_GET_HASH_main(h, htmp, fun, mem) \\\n" +" do { \\\n" +" int c; \\\n" +" char *hash_swp; \\\n" +" (h) = NULL; \\\n" +" c = (*(st.gcp))(st.fp); \\\n" +" if (c != '[') { \\\n" +" if (c == EOF) { \\\n" +" r = CONFCONF_ERR_UNEXPECTED_EOF; \\\n" +" st.val.s = NULL; \\\n" +" break; \\\n" +" } \\\n" +" (*(st.ugcp))(c, st.fp); \\\n" +" confconf_priv_get_tok(&st); \\\n" +" r = CONFCONF_ERR_UNEXPECTED_TOKEN; \\\n" +" } \\\n" +" st.col++; \\\n" +" st.byte++; \\\n" +" while (1) { \\\n" +" confconf_priv_eat_space(&st); \\\n" +" r = confconf_priv_get_id(&st); \\\n" +" if (r != CONFCONF_SUCCESS) \\\n" +" break; \\\n" +" HASH_FIND_STR((h), st.val.s, (htmp)); \\\n" +" if ((htmp) != NULL) { \\\n" +" r = CONFCONF_ERR_HASH_DUPLICATE_KEY; \\\n" +" break; \\\n" +" } \\\n" +" hash_swp = st.val.s; \\\n" +" confconf_priv_eat_space(&st); \\\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" +" free(hash_swp); \\\n" +" r = confconf_priv_get_tok(&st); \\\n" +" if (r == CONFCONF_SUCCESS) \\\n" +" r = CONFCONF_ERR_UNEXPECTED_TOKEN; \\\n" +" break; \\\n" +" } \\\n" +" r = confconf_priv_get_ ## fun (&st); \\\n" +" if (r != CONFCONF_SUCCESS) { \\\n" +" free(hash_swp); \\\n" +" break; \\\n" +" } \\\n" +" (htmp) = malloc(sizeof(*(htmp))); \\\n" +" if ((htmp) == NULL) { \\\n" +" free(hash_swp); \\\n" +" r = CONFCONF_ERR_MEMORY; \\\n" +" break; \\\n" +" } \\\n" +" (htmp)->key = hash_swp; \\\n" +" (htmp)->val.mem = st.val.mem; \\\n" +" HASH_ADD_STR((h), key, (htmp)); \\\n" +" confconf_priv_eat_space(&st); \\\n" +" c = (*(st.gcp))(st.fp); \\\n" +" if (c == ',') { \\\n" +" st.col++; \\\n" +" st.byte++; \\\n" +" confconf_priv_eat_space(&st); \\\n" +" } else if (c == ']') { \\\n" +" st.col++; \\\n" +" st.byte++; \\\n" +" r = CONFCONF_SUCCESS; \\\n" +" break; \\\n" +" } else { \\\n" +" (*(st.ugcp))(c, st.fp); \\\n" +" } \\\n" +" } \\\n" +" } while (0)\n" +"\n" +"#endif\n" +"\n" +; 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 +#include #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 \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"); } diff --git a/src/main.c b/src/main.c index 4ec0e75..16fd3d7 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,6 @@ int main(int argc, char **argv) FILE *fo = stdout; FILE *fi = stdin; const char *finame = "stdin"; - const char *foname; struct parse_result_s pr; struct analyse_result_s ar; @@ -42,9 +41,8 @@ int main(int argc, char **argv) } if (opt_outfile_str() != NULL) { - foname = opt_infile_str(); - fo = fopen(foname, "w"); - TRY(fo != NULL, "could not write to file `%s`", foname); + fo = fopen(opt_outfile_str(), "w"); + TRY(fo != NULL, "could not write to file `%s`", opt_outfile_str()); } pr = parse(fi, finame); diff --git a/src/parse.c b/src/parse.c index cb459e5..57db35c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -172,10 +172,11 @@ static void sub_parse_deftype(size_t line, size_t col, bool is_union) type = sub_parse_type(); - if (type == PARSE_TYPE_DEFTYPE - || type == PARSE_TYPE_ARRAY_DEFTYPE - || type == PARSE_TYPE_HASH_DEFTYPE - ) { + if (type >= PARSE_TYPE_ARRAY_BOOL) { + ERR_AT(t.line, t.col, "defined types may not contain arrays or hashes"); + } + + if (type == PARSE_TYPE_DEFTYPE) { t = tok_get(); ERR_AT(t.line, t.col, "defined types may not contain other defined types"); } @@ -231,11 +232,11 @@ static bool sub_parse_op(void) sub_parse_deftype(t.line, t.col, true); return true; - case TOK_OP_FUN_SUF: - if (r.fun_suf_seen) { + case TOK_OP_SUFFIX: + if (r.suffix_seen) { WARN_AT(t.line, t.col, "function-suffix redefined (previous value was `%s`)", - r.fun_suf); + r.suffix); } t = tok_get(); @@ -243,52 +244,9 @@ static bool sub_parse_op(void) if (t.type != TOK_ID) ERR_AT(t.line, t.col, "invalid function-suffix `%s`", t.val); - strcpy(r.fun_suf, t.val); - - r.fun_suf_seen = true; - - return true; - - case TOK_OP_HKEY_SIZE: - if (r.hkey_size_seen) { - WARN_AT(t.line, t.col, - "hkey_size redefined (previous value was %lu)", - r.hkey_size); - } - - t = tok_get(); - ERR_END(t); - if (t.type != TOK_UINT) - ERR_AT(t.line, t.col, "invalid hkey_size `%s`", t.val); - - errno = EILSEQ; - r.hkey_size = strtoul(t.val, NULL, 10); - - if (errno == ERANGE) - ERR_AT(t.line, t.col, "hkey_size `%s` too large", t.val); - - if (r.hkey_size == 0) - ERR_AT(t.line, t.col, "hkey_size cannot be 0"); - - r.hkey_size_seen = true; - - return true; - - case TOK_OP_HKEY_NAME: - if (r.hkey_name_seen) { - ERR_AT(t.line, t.col, - "hkey_name redefined (previous value was `%s`)", - r.hkey_name); - } - - t = tok_get(); - ERR_END(t); - if (t.type != TOK_ID) - ERR_AT(t.line, t.col, "invalid hkey_name `%s`", t.val); - - strcpy(r.hkey_name, t.val); + strcpy(r.suffix, t.val); - r.hkey_name_seen = true; + r.suffix_seen = true; return true; @@ -374,11 +332,7 @@ struct parse_result_s parse(FILE *f, const char *fname) struct parse_var_s *vcur, *vtmp; struct parse_deftype_s *dcur, *dtmp; - r.hkey_size = 16; - strcpy(r.hkey_name, "key"); - r.hkey_name_seen = false; - r.hkey_size_seen = false; - r.fun_suf_seen = false; + r.suffix_seen = false; r.deftypes = NULL; r.vars = NULL; curfname = fname; @@ -420,12 +374,12 @@ struct parse_result_s parse(FILE *f, const char *fname) HASH_ITER(hh, r.deftypes, dcur, dtmp) { if (!dcur->is_used) { WARN_AT(dcur->line, dcur->col, - "struct `%s` defined but not used", + "type `%s` defined but not used", dcur->name); } } - if (!r.fun_suf_seen) { + if (!r.suffix_seen) { j = 0; @@ -434,24 +388,23 @@ struct parse_result_s parse(FILE *f, const char *fname) j = i + (fname[i] == '/' || fname[i] == '\\'); - for (i = j; fname[i] != '\0' && fname[i] != '.' - && i - j < r.hkey_size; i++) { + for (i = j; fname[i] != '\0' && fname[i] != '.'; i++) { if (!isalnum(fname[i]) && fname[i] != '_') { fprintf(stderr, "\x1B[1m%s:\x1B[0m ", fname); ERR("no function suffix specified, and could not generate one"); } - r.fun_suf[i - j] = fname[i]; + r.suffix[i - j] = fname[i]; } - r.fun_suf[i - j] = '\0'; + r.suffix[i - j] = '\0'; - if (r.fun_suf[0] == '\0') { + if (r.suffix[0] == '\0') { fprintf(stderr, "\x1B[1m%s:\x1B[0m ", fname); ERR("no function suffix specified, and could not generate one"); } fprintf(stderr, "\x1B[1m%s:\x1B[0m ", fname); - WARN("no function suffix specified. using `%s`...", r.fun_suf); + WARN("no function suffix specified. using `%s`...", r.suffix); } HASH_SORT(r.deftypes, sub_sort_deftypes); diff --git a/src/parse.h b/src/parse.h index b9f2ceb..094d808 100644 --- a/src/parse.h +++ b/src/parse.h @@ -78,12 +78,8 @@ struct parse_var_s { }; struct parse_result_s { - unsigned long hkey_size; - bool hkey_size_seen; - char hkey_name[TOK_MAX_LEN]; - bool hkey_name_seen; - char fun_suf[TOK_MAX_LEN]; - bool fun_suf_seen; + char suffix[TOK_MAX_LEN]; + bool suffix_seen; struct parse_deftype_s *deftypes; struct parse_var_s *vars; }; diff --git a/src/tok.c b/src/tok.c index 04d1eb8..177507a 100644 --- a/src/tok.c +++ b/src/tok.c @@ -70,11 +70,9 @@ static void sub_match_op(void) enum tok_type_e type; char name[(32 < TOK_MAX_LEN ? 32 : TOK_MAX_LEN)]; } ops[] = { - { true, TOK_OP_STRUCT, ".struct" }, - { true, TOK_OP_UNION, ".union" }, - { true, TOK_OP_HKEY_SIZE, ".hash-key-size" }, - { true, TOK_OP_HKEY_NAME, ".hash-key-name" }, - { true, TOK_OP_FUN_SUF, ".function-suffix" }, + { true, TOK_OP_SUFFIX, ".suffix" }, + { true, TOK_OP_STRUCT, ".struct" }, + { true, TOK_OP_UNION, ".union" }, }; unsigned i, j; bool again; @@ -97,7 +95,7 @@ static void sub_match_op(void) val[vlen] = c; vlen++; - for (j = 0; j < 5; j++) { + for (j = 0; j < 3; j++) { if (!ops[j].possible) continue; diff --git a/src/tok.h b/src/tok.h index 08099b3..7558508 100644 --- a/src/tok.h +++ b/src/tok.h @@ -13,11 +13,9 @@ enum tok_type_e { TOK_BANG, TOK_QMARK, TOK_ASTERISK, + TOK_OP_SUFFIX, TOK_OP_STRUCT, TOK_OP_UNION, - TOK_OP_HKEY_SIZE, - TOK_OP_HKEY_NAME, - TOK_OP_FUN_SUF, TOK_UINT, TOK_ID, TOK_UNKNWN, -- cgit v1.2.3