summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/driver/slbt_driver_ctx.c43
-rw-r--r--src/internal/argv/argv.h83
-rw-r--r--src/internal/slibtool_driver_impl.h2
-rw-r--r--src/logic/slbt_exec_install.c13
-rw-r--r--src/logic/slbt_exec_uninstall.c15
5 files changed, 95 insertions, 61 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 40be65f..0abbf85 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -128,7 +128,7 @@ static uint32_t slbt_argv_flags(uint32_t flags)
static int slbt_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];
@@ -137,7 +137,7 @@ static int slbt_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 SLBT_USAGE;
@@ -191,8 +191,9 @@ static int slbt_split_argv(
struct argv_entry * mode;
struct argv_entry * config;
struct argv_entry * finish;
- const struct argv_option * option;
- const struct argv_option * options = slbt_default_options;
+ const struct argv_option ** popt;
+ const struct argv_option ** optout;
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
struct argv_ctx ctx = {ARGV_VERBOSITY_NONE,
ARGV_MODE_SCAN,
0,0,0,0,0,0,0};
@@ -200,17 +201,19 @@ static int slbt_split_argv(
program = argv_program_name(argv[0]);
/* missing arguments? */
+ argv_optv_init(slbt_default_options,optv);
+
if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
- return slbt_driver_usage(program,0,options,0);
+ return slbt_driver_usage(program,0,optv,0);
/* initial argv scan: ... --mode=xxx ... <compiler> ... */
- argv_scan(argv,options,&ctx,0);
+ argv_scan(argv,optv,&ctx,0);
/* invalid slibtool arguments? */
if (ctx.erridx && !ctx.unitidx) {
if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
argv_get(
- argv,options,
+ argv,optv,
slbt_argv_flags(flags));
return -1;
}
@@ -219,7 +222,7 @@ static int slbt_split_argv(
compiler = argv[ctx.unitidx];
argv[ctx.unitidx] = 0;
- meta = argv_get(argv,options,ARGV_VERBOSITY_NONE);
+ meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE);
argv[ctx.unitidx] = compiler;
/* missing all of --mode, --config, and --finish? */
@@ -263,9 +266,8 @@ static int slbt_split_argv(
sargv->targv[i] = argv[i];
/* split vectors: legacy mixture */
- options = option_from_tag(
- slbt_default_options,
- TAG_OUTPUT);
+ for (optout=optv; optout[0]->tag != TAG_OUTPUT; optout++)
+ (void)0;
targv = sargv->targv + i;
cargv = sargv->cargv;
@@ -345,11 +347,11 @@ static int slbt_split_argv(
*targv++ = argv[i];
} else {
- for (option=options; option->long_name; option++)
- if (!(strcmp(option->long_name,&argv[i][1])))
+ for (popt=optout; popt[0] && popt[0]->long_name; popt++)
+ if (!(strcmp(popt[0]->long_name,&argv[i][1])))
break;
- if (option->long_name)
+ if (popt[0] && popt[0]->long_name)
*targv++ = argv[i];
else
*cargv++ = argv[i];
@@ -797,17 +799,17 @@ int slbt_get_driver_ctx(
struct slbt_split_vector sargv;
struct slbt_driver_ctx_impl * ctx;
struct slbt_common_ctx cctx;
- const struct argv_option * options;
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
struct argv_meta * meta;
struct argv_entry * entry;
const char * program;
- options = slbt_default_options;
+ argv_optv_init(slbt_default_options,optv);
if (slbt_split_argv(argv,flags,&sargv))
return -1;
- if (!(meta = argv_get(sargv.targv,options,slbt_argv_flags(flags))))
+ if (!(meta = argv_get(sargv.targv,optv,slbt_argv_flags(flags))))
return -1;
program = argv_program_name(argv[0]);
@@ -826,7 +828,7 @@ int slbt_get_driver_ctx(
case TAG_HELP:
case TAG_HELP_ALL:
if (flags & SLBT_DRIVER_VERBOSITY_USAGE)
- return slbt_driver_usage(program,entry->arg,options,meta);
+ return slbt_driver_usage(program,entry->arg,optv,meta);
case TAG_VERSION:
cctx.drvflags |= SLBT_DRIVER_VERSION;
@@ -1122,11 +1124,14 @@ int slbt_create_driver_ctx(
const struct slbt_common_ctx * cctx,
struct slbt_driver_ctx ** pctx)
{
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
struct argv_meta * meta;
struct slbt_driver_ctx_impl * ctx;
char * argv[] = {"slibtool_driver",0};
- if (!(meta = argv_get(argv,slbt_default_options,0)))
+ argv_optv_init(slbt_default_options,optv);
+
+ if (!(meta = argv_get(argv,optv,0)))
return -1;
if (!(ctx = slbt_driver_ctx_alloc(meta,cctx)))
diff --git a/src/internal/argv/argv.h b/src/internal/argv/argv.h
index ca1ceba..60806a2 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;
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index 72f86b0..738f308 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -8,6 +8,8 @@
#include <slibtool/slibtool.h>
#include "argv/argv.h"
+#define SLBT_OPTV_ELEMENTS 64
+
extern const struct argv_option slbt_default_options[];
enum app_tags {
diff --git a/src/logic/slbt_exec_install.c b/src/logic/slbt_exec_install.c
index 7dc2b72..311fc3c 100644
--- a/src/logic/slbt_exec_install.c
+++ b/src/logic/slbt_exec_install.c
@@ -14,6 +14,7 @@
#define ARGV_DRIVER
#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
#include "slibtool_install_impl.h"
#include "slibtool_readlink_impl.h"
#include "slibtool_spawn_impl.h"
@@ -24,7 +25,7 @@
static int slbt_install_usage(
const char * program,
const char * arg,
- const struct argv_option * options,
+ const struct argv_option ** optv,
struct argv_meta * meta)
{
char header[512];
@@ -34,7 +35,7 @@ static int slbt_install_usage(
"Options:\n",
program);
- argv_usage(stdout,header,options,arg);
+ argv_usage(stdout,header,optv,arg);
argv_free(meta);
return SLBT_USAGE;
@@ -545,8 +546,8 @@ int slbt_exec_install(
struct argv_entry * copy;
struct argv_entry * dest;
struct argv_entry * last;
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
char dstdir[PATH_MAX];
- const struct argv_option * options = slbt_install_options;
/* dry run */
if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN)
@@ -570,13 +571,15 @@ int slbt_exec_install(
iargv++;
/* missing arguments? */
+ argv_optv_init(slbt_install_options,optv);
+
if (!iargv[1] && (dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_USAGE))
- return slbt_install_usage(dctx->program,0,options,0);
+ return slbt_install_usage(dctx->program,0,optv,0);
/* <install> argv meta */
if (!(meta = argv_get(
iargv,
- options,
+ optv,
dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS
? ARGV_VERBOSITY_ERRORS
: ARGV_VERBOSITY_NONE)))
diff --git a/src/logic/slbt_exec_uninstall.c b/src/logic/slbt_exec_uninstall.c
index cc27911..0dafa81 100644
--- a/src/logic/slbt_exec_uninstall.c
+++ b/src/logic/slbt_exec_uninstall.c
@@ -14,6 +14,7 @@
#define ARGV_DRIVER
#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
#include "slibtool_uninstall_impl.h"
#include "slibtool_readlink_impl.h"
#include "slibtool_errinfo_impl.h"
@@ -22,7 +23,7 @@
static int slbt_uninstall_usage(
const char * program,
const char * arg,
- const struct argv_option * options,
+ const struct argv_option ** optv,
struct argv_meta * meta)
{
char header[512];
@@ -32,7 +33,7 @@ static int slbt_uninstall_usage(
"Options:\n",
program);
- argv_usage(stdout,header,options,arg);
+ argv_usage(stdout,header,optv,arg);
argv_free(meta);
return SLBT_USAGE;
@@ -250,7 +251,7 @@ int slbt_exec_uninstall(
struct slbt_exec_ctx * actx;
struct argv_meta * meta;
struct argv_entry * entry;
- const struct argv_option * options = slbt_uninstall_options;
+ const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
/* dry run */
if (dctx->cctx->drvflags & SLBT_DRIVER_DRY_RUN)
@@ -274,13 +275,15 @@ int slbt_exec_uninstall(
iargv++;
/* missing arguments? */
+ argv_optv_init(slbt_uninstall_options,optv);
+
if (!iargv[1] && (dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_USAGE))
- return slbt_uninstall_usage(dctx->program,0,options,0);
+ return slbt_uninstall_usage(dctx->program,0,optv,0);
/* <uninstall> argv meta */
if (!(meta = argv_get(
iargv,
- options,
+ optv,
dctx->cctx->drvflags & SLBT_DRIVER_VERBOSITY_ERRORS
? ARGV_VERBOSITY_ERRORS
: ARGV_VERBOSITY_NONE)))
@@ -325,7 +328,7 @@ int slbt_exec_uninstall(
/* --help */
if (flags & SLBT_UNINSTALL_HELP) {
- slbt_uninstall_usage(dctx->program,0,options,meta);
+ slbt_uninstall_usage(dctx->program,0,optv,meta);
return 0;
}