aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
m---------reqs/simple-opt0
-rw-r--r--src/gen-consts.h4
-rw-r--r--src/gen.c36
-rw-r--r--src/opt.c72
-rw-r--r--src/opt.h2
-rw-r--r--src/parse.c20
-rw-r--r--src/parse.h4
-rw-r--r--src/tok.c4
-rw-r--r--src/tok.h2
10 files changed, 113 insertions, 33 deletions
diff --git a/.gitmodules b/.gitmodules
index 760cb64..2a251eb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "reqs/simple-opt"]
path = reqs/simple-opt
- url = https://github.com/shmibs/simple-opt
+ url = https://git.airen-no-jikken.icu/k/simple-opt.git
[submodule "reqs/uthash"]
path = reqs/uthash
url = https://github.com/troydhanson/uthash.git
diff --git a/reqs/simple-opt b/reqs/simple-opt
-Subproject 879d526d7ee7ee7a876f284dac76075e7a7267a
+Subproject 197d36e32ddf85b49e82d5b84b9170f25f844ec
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"
diff --git a/src/gen.c b/src/gen.c
index 1283119..846f122 100644
--- a/src/gen.c
+++ b/src/gen.c
@@ -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,
diff --git a/src/opt.c b/src/opt.c
index a856c74..a50f4ca 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -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);
+}
diff --git a/src/opt.h b/src/opt.h
index ec328e6..a944929 100644
--- a/src/opt.h
+++ b/src/opt.h
@@ -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;
};
diff --git a/src/tok.c b/src/tok.c
index bae9285..9b57459 100644
--- a/src/tok.c
+++ b/src/tok.c
@@ -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;
diff --git a/src/tok.h b/src/tok.h
index fdf3cbc..5653f85 100644
--- a/src/tok.h
+++ b/src/tok.h
@@ -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,