aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gen-consts.h2
-rw-r--r--src/gen.c5
-rw-r--r--src/parse.c43
-rw-r--r--src/parse.h4
-rw-r--r--src/tok.c83
-rw-r--r--src/tok.h5
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 <uthash.h>\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 <uthash.h>\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 `<uthash.h>`");
+ strcpy(r.location, "<uthash.h>");
+ }
+
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 <assert.h>
#include <stdbool.h>
#include <ctype.h>
@@ -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 {