From 85456307365f470378df2f5e7fc3a355bc3d4ace Mon Sep 17 00:00:00 2001 From: katherine Date: Thu, 30 May 2019 07:34:25 -0700 Subject: add configurable uthash header location --- src/gen-consts.h | 2 +- src/gen.c | 5 ++-- src/parse.c | 43 ++++++++++++++++++++++++++++- src/parse.h | 4 ++- src/tok.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/tok.h | 5 +++- 6 files changed, 131 insertions(+), 11 deletions(-) diff --git a/src/gen-consts.h b/src/gen-consts.h index e3b1b16..9179c0b 100644 --- a/src/gen-consts.h +++ b/src/gen-consts.h @@ -817,7 +817,7 @@ static const char shash[] = "#ifndef CONFCONF_HASH_H\n" "#define CONFCONF_HASH_H\n" "\n" -"#include \n" +"#include %s\n" "\n" "#define CONFCONF_PRIV_GET_HASH_main(h, htmp, fun, mem) \\\n" " do { \\\n" diff --git a/src/gen.c b/src/gen.c index e427b7c..1283119 100644 --- a/src/gen.c +++ b/src/gen.c @@ -55,7 +55,7 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar) fprintf(f, sdoublel); if (ar.uses_hash) - fprintf(f, shash); + fprintf(f, shash, pr.location); /******** * BODY * @@ -140,11 +140,12 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar) /* hash */ if (ar.uses_hash) { fprintf(f, - "#include \n\n" + "#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", + pr.location, pr.suffix, (ar.uses_type[PARSE_TYPE_HASH_BOOL] ? " bool b;\n" : ""), diff --git a/src/parse.c b/src/parse.c index 6ec3ade..752e0b8 100644 --- a/src/parse.c +++ b/src/parse.c @@ -18,6 +18,13 @@ static const char *curfname; ERR(__VA_ARGS__); \ } while (0) +#define ERR_LONG(t) \ + do { \ + if ((t).type == TOK_LONG) { \ + ERR_AT((t).line, (t).col, "token too long"); \ + } \ + } while (0) + #define ERR_END(t, m) \ do { \ if ((t).type == TOK_END) { \ @@ -53,6 +60,7 @@ static enum parse_type_e sub_parse_type(void) } ERR_END(t, "type"); + ERR_LONG(t); if (t.type != TOK_ID) { if (type >= PARSE_TYPE_HASH_BOOL) @@ -129,6 +137,7 @@ static void sub_parse_deftype(size_t line, size_t col, ) ) ); + ERR_LONG(t); if (t.type != TOK_ID) { ERR_AT(t.line, t.col, "unexpected token `%s` (expected %s name)", t.val, @@ -221,6 +230,7 @@ static void sub_parse_deftype(size_t line, size_t col, ERR_END(t, (dt.type == PARSE_DEFTYPE_ENUM ? "id or `}`" : "member name")); + ERR_LONG(t); if (t.type != TOK_ID) { if (t.type == TOK_RBRACE || t.type == TOK_COMMA) { @@ -295,7 +305,7 @@ static bool sub_parse_op(void) sub_parse_deftype(t.line, t.col, PARSE_DEFTYPE_ENUM); return true; - case TOK_OP_SUFFIX: + case TOK_OP_NAMING_SUFFIX: if (r.suffix_seen) { WARN_AT(t.line, t.col, "naming suffix redefined (previous value was `%s`)", @@ -304,6 +314,7 @@ static bool sub_parse_op(void) t = tok_get(); ERR_END(t, "naming suffix"); + ERR_LONG(t); if (t.type != TOK_ID) ERR_AT(t.line, t.col, "invalid naming suffix `%s`", t.val); @@ -313,6 +324,28 @@ static bool sub_parse_op(void) return true; + case TOK_OP_UTHASH_LOCATION: + if (r.location_seen) { + WARN_AT(t.line, t.col, + "uthash location redefined (previous value was %s)", + r.location); + } + + t = tok_get(); + ERR_END(t, "uthash header"); + ERR_LONG(t); + if (t.type != TOK_HEADER) + ERR_AT(t.line, t.col, "invalid uthash header `%s`", t.val); + + strcpy(r.location, t.val); + + r.location_seen = true; + + return true; + + case TOK_LONG: + ERR_LONG(t); + default: tok_unget(t); return false; @@ -340,6 +373,7 @@ static bool sub_parse_rule(void) t = tok_get(); ERR_END(t, "variable name"); + ERR_LONG(t); if (t.type != TOK_ID) { ERR_AT(t.line, t.col, "unexpected token `%s`, (expected variable name)", t.val); @@ -396,6 +430,7 @@ struct parse_result_s parse(FILE *f, const char *fname) struct parse_deftype_s *dcur, *dtmp; r.suffix_seen = false; + r.location_seen = false; r.deftypes = NULL; r.vars = NULL; curfname = fname; @@ -447,6 +482,12 @@ struct parse_result_s parse(FILE *f, const char *fname) } } + if (!r.location_seen) { + fprintf(stderr, "\x1B[1m%s:\x1B[0m ", fname); + WARN("no uthash location header specified. using ``"); + strcpy(r.location, ""); + } + if (!r.suffix_seen) { j = 0; diff --git a/src/parse.h b/src/parse.h index 754462f..771b1a6 100644 --- a/src/parse.h +++ b/src/parse.h @@ -86,8 +86,10 @@ struct parse_var_s { }; struct parse_result_s { - char suffix[TOK_MAX_LEN]; bool suffix_seen; + char suffix[TOK_MAX_LEN]; + bool location_seen; + char location[TOK_MAX_LEN]; struct parse_deftype_s *deftypes; struct parse_var_s *vars; }; diff --git a/src/tok.c b/src/tok.c index c80d397..bae9285 100644 --- a/src/tok.c +++ b/src/tok.c @@ -1,5 +1,6 @@ #include "tok.h" +#include #include #include @@ -68,12 +69,13 @@ static void sub_match_op(void) struct { bool possible; enum tok_type_e type; - char name[(32 < TOK_MAX_LEN ? 32 : TOK_MAX_LEN)]; + char name[32]; } ops[] = { - { true, TOK_OP_SUFFIX, ".suffix" }, { true, TOK_OP_STRUCT, ".struct" }, { true, TOK_OP_UNION, ".union" }, { true, TOK_OP_ENUM, ".enum" }, + { true, TOK_OP_NAMING_SUFFIX, ".naming-suffix" }, + { true, TOK_OP_UTHASH_LOCATION, ".uthash-location" }, }; unsigned i, j; bool again; @@ -96,7 +98,7 @@ static void sub_match_op(void) val[vlen] = c; vlen++; - for (j = 0; j < 4; j++) { + for (j = 0; j < 5; j++) { if (!ops[j].possible) continue; @@ -121,6 +123,14 @@ static void sub_match_op(void) vlen++; c = getc(curf); } while (c != EOF && !isspace(c) && vlen < TOK_MAX_LEN - 1); + + if (vlen + 2 == TOK_MAX_LEN) { + vlen = 0; + val[0] = '\0'; + curtok.type = TOK_LONG; + return; + } + ungetc(c, curf); val[vlen] = '\0'; curtok.type = TOK_UNKNWN; @@ -136,6 +146,7 @@ static void sub_match_uint(void) curtok.type = TOK_UINT; while (true) { + c = getc(curf); if (!isdigit(c)) { @@ -144,6 +155,13 @@ static void sub_match_uint(void) return; } + if (vlen + 2 == TOK_MAX_LEN) { + vlen = 0; + val[0] = '\0'; + curtok.type = TOK_LONG; + return; + } + val[vlen] = c; vlen++; } @@ -164,11 +182,58 @@ static void sub_match_id(void) return; } + if (vlen + 2 == TOK_MAX_LEN) { + vlen = 0; + val[0] = '\0'; + curtok.type = TOK_LONG; + return; + } + val[vlen] = c; vlen++; } } +static void sub_match_header(void) +{ + int c, cend; + + curtok.type = TOK_END; + + cend = (val[0] == '"' ? '"' : '>'); + + while (true) { + c = getc(curf); + + if (c == EOF) + return; + + if (c == '\n') { + val[vlen] = '\0'; + curtok.type = TOK_UNKNWN; + return; + } + + if (vlen + 2 == TOK_MAX_LEN) { + vlen = 0; + val[0] = '\0'; + curtok.type = TOK_LONG; + return; + } + + val[vlen] = c; + vlen++; + + if (c == cend) + break; + } + + curtok.type = TOK_HEADER; + + val[vlen] = '\0'; + vlen++; +} + void tok_reset(FILE *f) { curf = f; @@ -182,11 +247,12 @@ struct tok_s tok_get(void) { int c; + assert(TOK_MAX_LEN >= 32); + if (unget) { unget = false; return curtok; - } - + } curtok.col += vlen; vlen = 0; @@ -256,6 +322,13 @@ struct tok_s tok_get(void) return curtok; default: + if (c == '"' || c == '<') { + val[0] = c; + vlen = 1; + sub_match_header(); + return curtok; + } + if (isdigit(c)) { val[0] = c; vlen = 1; diff --git a/src/tok.h b/src/tok.h index 488c5ad..fdf3cbc 100644 --- a/src/tok.h +++ b/src/tok.h @@ -13,14 +13,17 @@ enum tok_type_e { TOK_BANG, TOK_QMARK, TOK_ASTERISK, - TOK_OP_SUFFIX, TOK_OP_STRUCT, TOK_OP_UNION, TOK_OP_ENUM, + TOK_OP_NAMING_SUFFIX, + TOK_OP_UTHASH_LOCATION, TOK_UINT, TOK_ID, + TOK_HEADER, TOK_UNKNWN, TOK_END, + TOK_LONG, }; struct tok_s { -- cgit v1.2.3