diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gen-consts.h | 4 | ||||
| -rw-r--r-- | src/gen.c | 36 | ||||
| -rw-r--r-- | src/opt.c | 72 | ||||
| -rw-r--r-- | src/opt.h | 2 | ||||
| -rw-r--r-- | src/parse.c | 20 | ||||
| -rw-r--r-- | src/parse.h | 4 | ||||
| -rw-r--r-- | src/tok.c | 4 | ||||
| -rw-r--r-- | src/tok.h | 2 | 
8 files changed, 112 insertions, 32 deletions
| diff --git a/src/gen-consts.h b/src/gen-consts.h index 9179c0b..72c1a46 100644 --- a/src/gen-consts.h +++ b/src/gen-consts.h @@ -1,4 +1,4 @@ -static const char sheaderp1[] = +static const char sheadp1[] =  "#ifndef CONFCONF_HEAD_H\n"  "#define CONFCONF_HEAD_H\n"  "\n" @@ -113,7 +113,7 @@ static const char sheaderp1[] =  "\n"  ; -static const char sheaderp2[] = +static const char sheadp2[] =  "static enum confconf_result_type confconf_priv_get_tok(\n"  "		struct confconf_priv_state *st)\n"  "{\n" @@ -2,6 +2,7 @@  #include "version.h"  #include "parse.h" +#include "opt.h"  #include <time.h>  #include <assert.h> @@ -28,8 +29,8 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  	fprintf(f, "/* generated by %s on %04d-%02d-%02d */\n",   			VERSION, ti->tm_year + 1900, ti->tm_mon + 1, ti->tm_mday); -	fprintf(f, sheaderp1); -	fprintf(f, sheaderp2); +	fprintf(f, sheadp1); +	fprintf(f, sheadp2);  	if (ar.uses_type[PARSE_TYPE_BOOL])  		fprintf(f, sbool); @@ -54,8 +55,10 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  	if (ar.uses_type[PARSE_TYPE_DOUBLEL])  		fprintf(f, sdoublel); +	/* if (ar.uses_array) */ +	/* 	fprintf(f, sarray); */  	if (ar.uses_hash) -		fprintf(f, shash, pr.location); +		fprintf(f, shash, (opt_header_str() ? opt_header_str() : pr.header));  	/********  	 * BODY * @@ -64,10 +67,11 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  	fprintf(f,  			"#ifndef CONFCONF_BODY_%s_H\n"  			"#define CONFCONF_BODY_%s_H\n\n", -			pr.suffix, pr.suffix -		   ); +			(opt_suffix_str() ? opt_suffix_str() : pr.suffix), +			(opt_suffix_str() ? opt_suffix_str() : pr.suffix) +	); -	/* types */ +	/* deftypes */  	HASH_ITER(hh, pr.deftypes, dcur, dtmp) {  		if (!dcur->is_used)  			continue; @@ -77,14 +81,17 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  					 (dcur->type == PARSE_DEFTYPE_UNION ?  					  "union" : "struct")  				), -				dcur->name, pr.suffix); +				dcur->name, +				(opt_suffix_str() ? opt_suffix_str() : pr.suffix) +		);  		for (i = 0; i < dcur->member_list_len; i++) {  			if (dcur->type == PARSE_DEFTYPE_ENUM) {  				fprintf(f, "	CONFCONF_TYPE_%s_%s_%s,\n",  						dcur->name,  						dcur->member_name_list[i], -						pr.suffix); +						(opt_suffix_str() ? opt_suffix_str() : pr.suffix) +				);  				continue;  			} @@ -135,9 +142,7 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  		fprintf(f, "};\n\n");  	} -	/* array */ - -	/* hash */ +	/* hash type */  	if (ar.uses_hash) {  		fprintf(f,  				"#include %s\n\n" @@ -145,8 +150,8 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  				"	char *key;\n"  				"	union {\n"  				"%s%s%s%s%s%s%s%s%s%s%s", -				pr.location, -				pr.suffix, +				(opt_header_str() ? opt_header_str() : pr.header), +				(opt_suffix_str() ? opt_suffix_str() : pr.suffix),  				(ar.uses_type[PARSE_TYPE_HASH_BOOL]  				 ? "		bool b;\n" : ""),  				(ar.uses_type[PARSE_TYPE_HASH_STRING] @@ -177,7 +182,10 @@ void gen(FILE *f, struct parse_result_s pr, struct analyse_result_s ar)  							 (dcur->type == PARSE_DEFTYPE_UNION ?  							  "union" : "struct")  						), -						dcur->name, pr.suffix, dcur->name); +						dcur->name, +						(opt_suffix_str() ? opt_suffix_str() : pr.suffix), +						dcur->name +				);  			}  		}  		fprintf(f, @@ -1,11 +1,14 @@  #include "version.h"  #include "opt.h" +#include "tok.h"  #include "../reqs/simple-opt/simple-opt.h"  #include <stdbool.h>  #include <stdlib.h>  #include <stdio.h> +#include <ctype.h> +#include <string.h>  static struct simple_opt options[] = {  	{ SIMPLE_OPT_FLAG, 'h', "help", false, @@ -16,12 +19,18 @@ static struct simple_opt options[] = {  		"specify file to read from (default is stdin)", "<file>" },  	{ SIMPLE_OPT_STRING, 'o', "output", true,  		"specify file to write to (default is stdout)", "<file>" }, +	{ SIMPLE_OPT_STRING, 'u', "uthash-header", true, +		"specify location header for uthash in the output (default is <uthash.h>)", "<file>" }, +	{ SIMPLE_OPT_STRING, 'n', "name-suffix", true, +		"specify unique suffix to append to generated functions and types", "<file>" },  	{ SIMPLE_OPT_END }  };  void opt_parse(int argc, char **argv)  {  	struct simple_opt_result result; +	size_t i; +	char c, cend;  	result = simple_opt_parse(argc, argv, options); @@ -33,7 +42,7 @@ void opt_parse(int argc, char **argv)  	/* help */  	if (options[0].was_seen) { -		simple_opt_print_usage(stdout, 70, argv[0], +		simple_opt_print_usage(stdout, 80, argv[0],  				"[-i input.confconf] [-o output.h]",  				"confconf is a config file parser generator for C",  				options); @@ -45,6 +54,53 @@ void opt_parse(int argc, char **argv)  		puts(VERSION);  		exit(EXIT_SUCCESS);  	} + +	/* check header */ +	if (options[4].was_seen) { +		cend = options[4].val.v_string[0]; + +		if (cend != '"' && cend != '<') { +			fprintf(stderr, "%s: err: badly-formatted uthash header `%s`\n", +					argv[0], options[4].val.v_string); +			exit(EXIT_FAILURE); +		} + +		if (cend == '<') +			cend = '>'; + +		for (i = 1, c = options[4].val.v_string[1]; +				c && c != cend && c != '\n'; +				c = options[4].val.v_string[++i] +		); + +		if (c != cend +				|| options[4].val.v_string[i+1] != '\0' +				|| strlen(options[4].val.v_string) > TOK_MAX_LEN +				|| options[4].val.v_string[2] == '\0' +		) { +			fprintf(stderr, "%s: err: badly-formatted uthash header `%s`\n", +					argv[0], options[4].val.v_string); +			exit(EXIT_FAILURE); +		} +	} + +	/* check suffix */ +	if (options[5].was_seen) { +		if (options[5].val.v_string[i] == '\0') { +			fprintf(stderr, "%s: err: badly-formatted name suffix ``\n", +					argv[0]); +			exit(EXIT_FAILURE); +		} + +		for (i = 0; options[5].val.v_string[i] != '\0'; i++) { +			if (!isalnum(options[5].val.v_string[i]) ) { +				fprintf(stderr, "%s: err: badly-formatted name suffix `%s`\n", +						argv[0], options[5].val.v_string); +				exit(EXIT_FAILURE); +			} +		} +	} +  }  const char* opt_infile_str(void) @@ -60,3 +116,17 @@ const char* opt_outfile_str(void)  			? options[3].val.v_string  			: NULL);  } + +const char* opt_header_str(void) +{ +	return (options[4].was_seen +			? options[4].val.v_string +			: NULL); +} + +const char* opt_suffix_str(void) +{ +	return (options[5].was_seen +			? options[5].val.v_string +			: NULL); +} @@ -5,5 +5,7 @@ void opt_parse(int argc, char **argv);  const char* opt_infile_str(void);  const char* opt_outfile_str(void); +const char* opt_header_str(void); +const char* opt_suffix_str(void);  #endif diff --git a/src/parse.c b/src/parse.c index 8b8f699..9e0a29b 100644 --- a/src/parse.c +++ b/src/parse.c @@ -324,11 +324,11 @@ static bool sub_parse_op(void)  		return true; -	case TOK_OP_UTHASH_LOCATION: -		if (r.location_seen) { +	case TOK_OP_UTHASH_HEADER: +		if (r.header_seen) {  			WARN_AT(t.line, t.col, -					"uthash location redefined (previous value was %s)", -					r.location); +					"uthash header redefined (previous value was %s)", +					r.header);  		}  		t = tok_get(); @@ -337,9 +337,9 @@ static bool sub_parse_op(void)  		if (t.type != TOK_HEADER)  			ERR_AT(t.line, t.col, "invalid uthash header `%s`", t.val); -		strcpy(r.location, t.val); +		strcpy(r.header, t.val); -		r.location_seen = true; +		r.header_seen = true;  		return true; @@ -430,7 +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.header_seen = false;  	r.deftypes = NULL;  	r.vars = NULL;  	curfname = fname; @@ -485,12 +485,12 @@ struct parse_result_s parse(FILE *f, const char *fname)  		}  	} -	/* warn hash location */ +	/* warn hash header */  	HASH_ITER(hh, r.vars, vcur, vtmp) { -		if (vcur->type >= PARSE_TYPE_HASH_BOOL && !r.location_seen) { +		if (vcur->type >= PARSE_TYPE_HASH_BOOL && !r.header_seen) {  			fprintf(stderr, "\x1B[1m%s:\x1B[0m ", fname);  			WARN("no uthash location header specified. using `<uthash.h>`"); -			strcpy(r.location, "<uthash.h>"); +			strcpy(r.header, "<uthash.h>");  			break;  		}  	} diff --git a/src/parse.h b/src/parse.h index 771b1a6..4f2645d 100644 --- a/src/parse.h +++ b/src/parse.h @@ -88,8 +88,8 @@ struct parse_var_s {  struct parse_result_s {  	bool suffix_seen;  	char suffix[TOK_MAX_LEN]; -	bool location_seen; -	char location[TOK_MAX_LEN]; +	bool header_seen; +	char header[TOK_MAX_LEN];  	struct parse_deftype_s *deftypes;  	struct parse_var_s *vars;  }; @@ -74,8 +74,8 @@ static void sub_match_op(void)  		{ 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" }, +		{ true, TOK_OP_NAMING_SUFFIX,   ".name-suffix"   }, +		{ true, TOK_OP_UTHASH_HEADER, ".uthash-header" },  	};  	unsigned i, j;  	bool again; @@ -17,7 +17,7 @@ enum tok_type_e {  	TOK_OP_UNION,  	TOK_OP_ENUM,  	TOK_OP_NAMING_SUFFIX, -	TOK_OP_UTHASH_LOCATION, +	TOK_OP_UTHASH_HEADER,  	TOK_UINT,  	TOK_ID,  	TOK_HEADER, | 
