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, |