summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/driver/ptyc_driver_ctx.c21
-rw-r--r--src/internal/argv/argv.h83
-rw-r--r--src/internal/ptycon_driver_impl.h2
3 files changed, 66 insertions, 40 deletions
diff --git a/src/driver/ptyc_driver_ctx.c b/src/driver/ptyc_driver_ctx.c
index 1a79c79..a30063b 100644
--- a/src/driver/ptyc_driver_ctx.c
+++ b/src/driver/ptyc_driver_ctx.c
@@ -127,7 +127,7 @@ static uint32_t ptyc_argv_flags(uint32_t flags)
static int ptyc_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];
@@ -136,7 +136,7 @@ static int ptyc_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 PTYC_USAGE;
@@ -229,7 +229,7 @@ int ptyc_get_driver_ctx(
struct ptyc_driver_ctx_impl * ctx;
struct ptyc_common_ctx cctx;
struct ptyc_split_vector sargv;
- const struct argv_option * options;
+ const struct argv_option * optv[PTYC_OPTV_ELEMENTS];
struct argv_meta * meta;
struct argv_entry * entry;
size_t nunits;
@@ -244,7 +244,7 @@ int ptyc_get_driver_ctx(
if (ptyc_vtbl_init())
return -1;
- options = ptyc_default_options;
+ argv_optv_init(ptyc_default_options,optv);
sargv.targv = targv;
sargv.eargv = 0;
@@ -252,7 +252,7 @@ int ptyc_get_driver_ctx(
if (ptyc_split_argv(argv,&sargv))
return -1;
- if (!(meta = argv_get(sargv.targv,options,ptyc_argv_flags(flags))))
+ if (!(meta = argv_get(sargv.targv,optv,ptyc_argv_flags(flags))))
return -1;
nunits = 0;
@@ -262,7 +262,7 @@ int ptyc_get_driver_ctx(
cctx.eargv = sargv.eargv;
if (!argv[1] && (flags & PTYC_DRIVER_VERBOSITY_USAGE))
- return ptyc_driver_usage(program,0,options,meta);
+ return ptyc_driver_usage(program,0,optv,meta);
/* get options, count units */
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
@@ -270,7 +270,7 @@ int ptyc_get_driver_ctx(
switch (entry->tag) {
case TAG_HELP:
if (flags & PTYC_DRIVER_VERBOSITY_USAGE)
- return ptyc_driver_usage(program,entry->arg,options,meta);
+ return ptyc_driver_usage(program,entry->arg,optv,meta);
case TAG_VERSION:
cctx.drvflags |= PTYC_DRIVER_VERSION;
@@ -322,7 +322,7 @@ int ptyc_get_driver_ctx(
}
} else
/* strict */
- return ptyc_driver_usage(program,0,options,meta);
+ return ptyc_driver_usage(program,0,optv,meta);
}
if (cctx.sysroot && ptyc_open_dir(&cctx.hroot,0,cctx.sysroot,false)) {
@@ -350,6 +350,7 @@ int ptyc_create_driver_ctx(
const struct ptyc_common_ctx * cctx,
struct ptyc_driver_ctx ** pctx)
{
+ const struct argv_option * optv[PTYC_OPTV_ELEMENTS];
struct argv_meta * meta;
struct ptyc_driver_ctx_impl * ctx;
char * argv[] = {"ptycon_driver",0};
@@ -360,7 +361,9 @@ int ptyc_create_driver_ctx(
if (ptyc_vtbl_init())
return -1;
- if (!(meta = argv_get(argv,ptyc_default_options,0)))
+ argv_optv_init(ptyc_default_options,optv);
+
+ if (!(meta = argv_get(argv,optv,0)))
return -1;
if (!(ctx = ptyc_driver_ctx_alloc(meta,cctx,0)))
diff --git a/src/internal/argv/argv.h b/src/internal/argv/argv.h
index b03761c..82d7546 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/ptycon_driver_impl.h b/src/internal/ptycon_driver_impl.h
index 438c178..486def3 100644
--- a/src/internal/ptycon_driver_impl.h
+++ b/src/internal/ptycon_driver_impl.h
@@ -12,6 +12,8 @@
#include "ptycon_bridge_impl.h"
#include "argv/argv.h"
+#define PTYC_OPTV_ELEMENTS 64
+
extern const struct argv_option ptyc_default_options[];
extern const ntapi_vtbl * ptyc_ntapi;
extern const ntcon_vtbl * const ptyc_ntcon;