-
Notifications
You must be signed in to change notification settings - Fork 1
This portion of API presents basic extopts library functionality. Here 'basic' means simpliest CLI use case - parsing command line arguments, extracting their parameters, leaving the rest to be handeled by programmer directly.
To use basic extopts
#include <extopts/extopts.h>
should be inserted into source files.
int extopts_get(int *argc, char *argv[], struct extopt *opts);
This is main extopts function which parses command line arguments according to passed extopts description structures array.
It takes standard command line arguments starting from executable path in argv[0].
After processing argv will be rearranged so that:
- all non-option arguments will be moved to the beginning of argv starting from 0th argument;
- 0th argument, path to application will be moved right after all non-option arguments followed by options and their arguments. It also will be stored to extpath variable.
- Short form of application name (its basename) will be stored at 'extname'. In case of module execution it will be changed to format -.
- value by argc address will contain number of these non-option arguments.
Example of argv organization before extopts_get():
[./a.out] [--int] [42] [--flag] [--string] ["/some/string"] [arg-0] [arg-1]`
|_________________________________argc=8__________________________________|
and after:
[some-arg-0] [some-arg-1] [./a.out]`
|________argc=2_________|
This example can be implemented using following extopts description:
bool opts_flag;
int opts_int;
const char *opts_str;
struct extopt opts[] = {
{
.name_long = "int",
.name_short = 'i',
EXTOPT_ARG_INT("INT", &opts_myint),
.desc = "int option",
}, {
.name_long = "string",
EXTOPT_ARG_STR("STR", &opts_mystr),
.desc = "string option",
}, {
.name_long = "flag",
.name_short = 'f',
EXTOPT_NO_ARG(&opts_flag),
.desc = "boolean flag",
},
EXTOPTS_END
};
void extopts_usage(struct extopt *opts);
struct extopt *extopt_find(char *opt_str, struct extopt *opts);
static char extopt_is_end(struct extopt opt);
struct extopt {
char *name_long;
char name_short;
char *desc;
/* Option argument */
int has_arg;
char *arg_name;
enum extopt_argtype arg_type;
union {
void *addr;
const char **const_str;
bool *flag;
int (*setter)(struct extopt *opt, const char *arg);
} arg;
};
enum extopt_argtype {
/* Field 'arg' will be used as 'flag' pointing to flag for whether
* parameter was met in command line or not */
EXTOPT_ARGTYPE_NO_ARG,
/* Field 'arg' will be used as 'setter' handler which will be
* called for argument parsing */
EXTOPT_ARGTYPE_SPECIAL,
/* Field 'arg' will be used as 'addr' pointing to the variable of
* corresponding size where parsed parameter argument value will
* be stored */
/* Signed integers */
EXTOPT_ARGTYPE_INT,
EXTOPT_ARGTYPE_LINT,
EXTOPT_ARGTYPE_LLINT,
/* Unsigned integers */
EXTOPT_ARGTYPE_UINT,
EXTOPT_ARGTYPE_ULINT,
EXTOPT_ARGTYPE_ULLINT,
/* Floating-point */
EXTOPT_ARGTYPE_FLOAT,
EXTOPT_ARGTYPE_DOUBLE,
EXTOPT_ARGTYPE_LDOUBLE,
/* Strings */
EXTOPT_ARGTYPE_STR, /* Field 'const_str' is used instead of 'addr' */
EXTOPT_ARGTYPE_CHAR,
};
enum {
no_extarg,
required_extarg,
};
- EXTOPT_ARG_INT
- EXTOPT_ARG_LINT
- EXTOPT_ARG_LLINT
#define EXTOPT_ARG_INT(NAME, ADDR)
#define EXTOPT_ARG_LINT(NAME, ADDR)
#define EXTOPT_ARG_LLINT(NAME, ADDR)
- EXTOPT_ARG_UINT
- EXTOPT_ARG_ULINT
- EXTOPT_ARG_ULLINT
#define EXTOPT_ARG_UINT(NAME, ADDR)
#define EXTOPT_ARG_ULINT(NAME, ADDR)
#define EXTOPT_ARG_ULLINT(NAME, ADDR)
- EXTOPT_ARG_FLOAT
- EXTOPT_ARG_DOUBLE
- EXTOPT_ARG_LDOUBLE
#define EXTOPT_ARG_FLOAT(NAME, ADDR)
#define EXTOPT_ARG_DOUBLE(NAME, ADDR)
#define EXTOPT_ARG_LDOUBLE(NAME, ADDR)
- EXTOPT_ARG_STR
- EXTOPT_ARG_CHAR
#define EXTOPT_ARG_STR(NAME, ADDR)
#define EXTOPT_ARG_CHAR(NAME, ADDR)
#define EXTOPT_NO_ARG(FLAG_ADDR)
#define EXTOPT_ARG_SPECIAL(NAME, SETTER_FUNC)
- EXTOPTS_HELP
#define EXTOPTS_HELP(FLAG_ADDR)
- EXTOPTS_VERSION
#define EXTOPTS_VERSION(FLAG_ADDR)
- EXTOPTS_END
char *extname;
char *extpath;
Extmods API allows to create CLI utility based on commands system: application firstly receives command name, then - arguments for it. Nearest example is git: 'git' utility with commands 'commit', 'pull', 'push' etc.
Functions of 'extmods' group allow to easily implement such command operation. Main utility can set its own policy of extracting command name from command line arguments, parse arguments related to this command and pass rest of arguments to main function of module, which is basically usual:
int func(int argc, char *argv[])
To use extmods functionality insert
#include <extopts/extmods.h>
into source files.
struct extmod *extmod_find(char *name);
struct extmod *extmod_extract(int *argc, char *argv[]);
int extmod_exec(int argc, char *argv[], struct extmod *module);
void extmod_print_desc(struct extmod *module);
void extmod_print_opts(struct extmod *module);
char extmod_has_name(struct extmod *module);
char extmod_has_desc(struct extmod *module);
char extmod_has_opts(struct extmod *module);
void extmods_usage_list(void);
struct extmod {
char *name;
int (*exec)(int argc, char *argv[]);
struct extopt *opts;
char *desc_short;
char *desc;
};
#define EXTMOD_DECL(NAME, EXEC, OPTS, DESC_SHORT, DESC) \
struct extmod *extmod_##NAME; \
void extmod_constr_##NAME() __attribute__ ((constructor)); \
void extmod_constr_##NAME() \
{ \
extmod_##NAME = &extmods[extmods_num++]; \
extmod_##NAME->name = #NAME; \
extmod_##NAME->exec = EXEC; \
extmod_##NAME->opts = OPTS; \
extmod_##NAME->desc_short = DESC_SHORT; \
extmod_##NAME->desc = DESC; \
}
- extmods
struct extmod extmods[];
- extmods_num
int extmods_num;
- extmod
struct extmod *extmod;
- extmodname
char extmodname[];