diff options
| author | katherine <k@airen-no-jikken.icu> | 2019-05-30 07:34:25 -0700 | 
|---|---|---|
| committer | katherine <k@airen-no-jikken.icu> | 2019-05-30 07:34:25 -0700 | 
| commit | 85456307365f470378df2f5e7fc3a355bc3d4ace (patch) | |
| tree | 52bf3f24741399237bd99ea3fde253a3b8d83b0c | |
| parent | 00d99b082162e287d481577915be73d5bf1dc483 (diff) | |
| download | confconf-85456307365f470378df2f5e7fc3a355bc3d4ace.tar.gz | |
add configurable uthash header location
| -rw-r--r-- | src/gen-consts.h | 2 | ||||
| -rw-r--r-- | src/gen.c | 5 | ||||
| -rw-r--r-- | src/parse.c | 43 | ||||
| -rw-r--r-- | src/parse.h | 4 | ||||
| -rw-r--r-- | src/tok.c | 83 | ||||
| -rw-r--r-- | 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 <uthash.h>\n" +"#include %s\n"  "\n"  "#define CONFCONF_PRIV_GET_HASH_main(h, htmp, fun, mem) \\\n"  "	do { \\\n" @@ -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;  }; @@ -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; @@ -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 { | 
