summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2016-12-25 12:22:05 -0500
committermidipix <writeonce@midipix.org>2016-12-25 13:53:59 -0500
commita6ad51943c98c3f075d527a9d2a84a3b613655d2 (patch)
tree100916999a20df003a0a576dfa8777cf9275c40b /src
parentc774e5ee3b57a33564e1824fe7bca3526d7e783f (diff)
downloadapimagic-a6ad51943c98c3f075d527a9d2a84a3b613655d2.tar.bz2
apimagic-a6ad51943c98c3f075d527a9d2a84a3b613655d2.tar.xz
argv.h: use an option vector rather than a direct pointer to the option table.
Diffstat (limited to 'src')
-rw-r--r--src/driver/amgc_driver_ctx.c19
-rw-r--r--src/internal/apimagic_driver_impl.h2
-rw-r--r--src/internal/argv/argv.h83
3 files changed, 65 insertions, 39 deletions
diff --git a/src/driver/amgc_driver_ctx.c b/src/driver/amgc_driver_ctx.c
index d287008..e5b218e 100644
--- a/src/driver/amgc_driver_ctx.c
+++ b/src/driver/amgc_driver_ctx.c
@@ -61,7 +61,7 @@ static uint32_t amgc_argv_flags(uint32_t flags)
static int amgc_driver_usage(
const char * program,
const char * arg,
- const struct argv_option * options,
+ const struct argv_option ** optv,
struct argv_meta * meta)
{
char header[512];
@@ -70,7 +70,7 @@ static int amgc_driver_usage(
"Usage: %s [options] <file>...\n" "Options:\n",
program);
- argv_usage(stdout,header,options,arg);
+ argv_usage(stdout,header,optv,arg);
argv_free(meta);
return AMGC_USAGE;
@@ -151,7 +151,7 @@ int amgc_get_driver_ctx(
{
struct amgc_driver_ctx_impl * ctx;
struct amgc_common_ctx cctx;
- const struct argv_option * options;
+ const struct argv_option * optv[AMGC_OPTV_ELEMENTS];
struct argv_meta * meta;
struct argv_entry * entry;
size_t nunits;
@@ -160,9 +160,9 @@ int amgc_get_driver_ctx(
(void)envp;
- options = amgc_default_options;
+ argv_optv_init(amgc_default_options,optv);
- if (!(meta = argv_get(argv,options,amgc_argv_flags(flags))))
+ if (!(meta = argv_get(argv,optv,amgc_argv_flags(flags))))
return -1;
nunits = 0;
@@ -172,7 +172,7 @@ int amgc_get_driver_ctx(
cctx.drvflags = flags;
if (!argv[1] && (flags & AMGC_DRIVER_VERBOSITY_USAGE))
- return amgc_driver_usage(program,0,options,meta);
+ return amgc_driver_usage(program,0,optv,meta);
/* compiler defaults */
cctx.std = STANDARD_C99;
@@ -183,7 +183,7 @@ int amgc_get_driver_ctx(
switch (entry->tag) {
case TAG_HELP:
if (flags & AMGC_DRIVER_VERBOSITY_USAGE)
- return amgc_driver_usage(program,entry->arg,options,meta);
+ return amgc_driver_usage(program,entry->arg,optv,meta);
case TAG_VERSION:
cctx.drvflags |= AMGC_DRIVER_VERSION;
@@ -253,11 +253,14 @@ int amgc_create_driver_ctx(
const struct amgc_common_ctx * cctx,
struct amgc_driver_ctx ** pctx)
{
+ const struct argv_option * optv[AMGC_OPTV_ELEMENTS];
struct argv_meta * meta;
struct amgc_driver_ctx_impl * ctx;
char * argv[] = {"apimagic_driver",0};
- if (!(meta = argv_get(argv,amgc_default_options,0)))
+ argv_optv_init(amgc_default_options,optv);
+
+ if (!(meta = argv_get(argv,optv,0)))
return -1;
if (!(ctx = amgc_driver_ctx_alloc(meta,cctx,0,0)))
diff --git a/src/internal/apimagic_driver_impl.h b/src/internal/apimagic_driver_impl.h
index a2c9a5e..d2a6819 100644
--- a/src/internal/apimagic_driver_impl.h
+++ b/src/internal/apimagic_driver_impl.h
@@ -12,6 +12,8 @@
#define AMGC_TAB_WIDTH 8
#endif
+#define AMGC_OPTV_ELEMENTS 64
+
extern const struct argv_option amgc_default_options[];
enum app_tags {
diff --git a/src/internal/argv/argv.h b/src/internal/argv/argv.h
index 4bd1480..89f5407 100644
--- a/src/internal/argv/argv.h
+++ b/src/internal/argv/argv.h
@@ -139,17 +139,21 @@ struct argv_ctx {
#ifdef ARGV_DRIVER
+static int argv_optv_init(
+ const struct argv_option[],
+ const struct argv_option **);
+
static const char * argv_program_name(const char *);
static void argv_usage(
FILE *,
const char * header,
- const struct argv_option[],
+ const struct argv_option **,
const char * mode);
static struct argv_meta * argv_get(
char **,
- const struct argv_option[],
+ const struct argv_option **,
int flags);
static void argv_free(struct argv_meta *);
@@ -161,14 +165,30 @@ static void argv_free(struct argv_meta *);
/* implementation of static functions */
/*------------------------------------*/
+static int argv_optv_init(
+ const struct argv_option options[],
+ const struct argv_option ** optv)
+{
+ const struct argv_option * option;
+ int i;
+
+ for (option=options,i=0; option->long_name || option->short_name; option++)
+ optv[i++] = option;
+
+ optv[i] = 0;
+ return i;
+}
+
static const struct argv_option * argv_short_option(
const char * ch,
- const struct argv_option options[],
+ const struct argv_option ** optv,
struct argv_entry * entry)
{
const struct argv_option * option;
- for (option=options; option->long_name || option->short_name; option++) {
+ for (; *optv; optv++) {
+ option = *optv;
+
if (option->short_name == *ch) {
entry->tag = option->tag;
entry->fopt = true;
@@ -181,15 +201,16 @@ static const struct argv_option * argv_short_option(
static const struct argv_option * argv_long_option(
const char * ch,
- const struct argv_option options[],
+ const struct argv_option ** optv,
struct argv_entry * entry)
{
const struct argv_option * option;
const char * arg;
size_t len;
- for (option=options; option->long_name || option->short_name; option++) {
- len = option->long_name ? strlen(option->long_name) : 0;
+ for (; *optv; optv++) {
+ option = *optv;
+ len = option->long_name ? strlen(option->long_name) : 0;
if (len && !(strncmp(option->long_name,ch,len))) {
arg = ch + len;
@@ -226,7 +247,7 @@ static inline bool is_last_option(const char * arg)
static inline bool is_hybrid_option(
const char * arg,
- const struct argv_option options[])
+ const struct argv_option ** optv)
{
const struct argv_option * option;
struct argv_entry entry;
@@ -234,11 +255,11 @@ static inline bool is_hybrid_option(
if (!is_short_option(arg))
return false;
- if (!(option = argv_long_option(++arg,options,&entry)))
+ if (!(option = argv_long_option(++arg,optv,&entry)))
return false;
if (!(option->flags & ARGV_OPTION_HYBRID_SWITCH))
- if (argv_short_option(arg,options,&entry))
+ if (argv_short_option(arg,optv,&entry))
return false;
return true;
@@ -265,20 +286,18 @@ static inline bool is_arg_in_paradigm(const char * arg, const char * paradigm)
}
static inline const struct argv_option * option_from_tag(
- const struct argv_option options[],
+ const struct argv_option ** optv,
int tag)
{
- const struct argv_option * option;
-
- for (option=options; option->short_name || option->long_name; option++)
- if (option->tag == tag)
- return option;
+ for (; *optv; optv++)
+ if (optv[0]->tag == tag)
+ return optv[0];
return 0;
}
static void argv_scan(
char ** argv,
- const struct argv_option options[],
+ const struct argv_option ** optv,
struct argv_ctx * ctx,
struct argv_meta * meta)
{
@@ -316,14 +335,14 @@ static void argv_scan(
else if (is_last_option(ch))
fnoscan = true;
- else if (!fshort && is_hybrid_option(ch,options))
+ else if (!fshort && is_hybrid_option(ch,optv))
fhybrid = true;
if (!fnoscan && !fhybrid && (fshort || is_short_option(ch))) {
if (!fshort)
ch++;
- if ((option = argv_short_option(ch,options,&entry))) {
+ if ((option = argv_short_option(ch,optv,&entry))) {
if (ch[1]) {
ch++;
fnext = false;
@@ -370,7 +389,7 @@ static void argv_scan(
} else if (!fnoscan && (fhybrid || is_long_option(ch))) {
ch += (fhybrid ? 1 : 2);
- if ((option = argv_long_option(ch,options,&entry))) {
+ if ((option = argv_long_option(ch,optv,&entry))) {
val = ch + strlen(option->long_name);
/* val[0] is either '=' (or ',') or '\0' */
@@ -584,7 +603,7 @@ static void argv_show_error(struct argv_ctx * ctx)
}
static void argv_show_status(
- const struct argv_option options[],
+ const struct argv_option ** optv,
struct argv_ctx * ctx,
struct argv_meta * meta)
{
@@ -610,7 +629,7 @@ static void argv_show_status(
fputs("\n\nparsed entries:\n",stderr);
for (entry=meta->entries; entry->arg || entry->fopt; entry++)
if (entry->fopt) {
- option = option_from_tag(options,entry->tag);
+ option = option_from_tag(optv,entry->tag);
short_name[0] = option->short_name;
if (entry->fval)
@@ -683,13 +702,13 @@ static struct argv_meta * argv_alloc(char ** argv, struct argv_ctx * ctx)
static struct argv_meta * argv_get(
char * argv[],
- const struct argv_option options[],
+ const struct argv_option ** optv,
int flags)
{
struct argv_meta * meta;
struct argv_ctx ctx = {flags,ARGV_MODE_SCAN,0,0,0,0,0,0,0};
- argv_scan(argv,options,&ctx,0);
+ argv_scan(argv,optv,&ctx,0);
if (ctx.errcode != ARGV_ERROR_OK) {
ctx.program = argv_program_name(argv[0]);
@@ -704,7 +723,7 @@ static struct argv_meta * argv_get(
return 0;
ctx.mode = ARGV_MODE_COPY;
- argv_scan(meta->argv,options,&ctx,meta);
+ argv_scan(meta->argv,optv,&ctx,meta);
if (ctx.errcode != ARGV_ERROR_OK) {
ctx.program = argv[0];
@@ -716,7 +735,7 @@ static struct argv_meta * argv_get(
}
if (ctx.flags & ARGV_VERBOSITY_STATUS)
- argv_show_status(options,&ctx,meta);
+ argv_show_status(optv,&ctx,meta);
return meta;
}
@@ -736,9 +755,10 @@ static void argv_free(struct argv_meta * xmeta)
static void argv_usage(
FILE * file,
const char * header,
- const struct argv_option options[],
+ const struct argv_option ** options,
const char * mode)
{
+ const struct argv_option ** optv;
const struct argv_option * option;
bool fshort,flong,fboth;
size_t len,optlen,desclen;
@@ -771,10 +791,9 @@ static void argv_usage(
if (header)
fprintf(file,"%s",header);
- option = options;
- optlen = 0;
+ for (optlen=0,optv=options; *optv; optv++) {
+ option = *optv;
- for (; option->short_name || option->long_name; option++) {
/* indent + comma */
len = fboth ? sizeof(indent) + 1 : sizeof(indent);
@@ -805,7 +824,9 @@ static void argv_usage(
optlen &= (~(ARGV_TAB_WIDTH-1));
desclen = (optlen < width / 2) ? width - optlen : optlen;
- for (option=options; option->short_name || option->long_name; option++) {
+ for (optv=options; *optv; optv++) {
+ option = *optv;
+
/* color */
if (fcolor) {
color = (color == ccyan) ? cblue : ccyan;