I am using argp C-library with these options:
struct argp_option options[]=
{
{"quiet",'q',0,0,"Decrease logging, can be used multiple times (default=LOG_ERR)"},
{"verbose",'v',0,0,"Increase logging, can be used multiple times (default=LOG_ERR)"},
{"R0",10,"BOOL",0,"Set ALL relais on or off (true/false)"},
[...]
{0}
};
My parse_opt()
function uses the usual switch
statement:
switch(key)
{
case 'q':
{ /* One loglevel quieter */
loglevel--;
loglevel=minmax(loglevel,0,7);
setlogmask(LOG_UPTO (loglevel));
break;
}
[...] // further options to be processed
}
Is it possible to force somehow the processing of the "-q" and "-v" switches before the other options are getting processed? Even if these two might have been use multiple times (i.e. myprogram -aqqqqv
)?
You can do this via the struct argp_state *
argument passed to parse_opt()
: define a state with a boolean field and set it to true
or false
depending on whether you want to only parse -q
and -v
or everything else. Then and call argp_parse()
twice and switch the boolean between the two calls.
Alternatively you can define two separate parse_opt()
functions: one that only looks at -v
and -q
, and one that looks at everything else. Then, call argp_parse()
twice: first with the first function, then with the second one.
This second method seems simpler to me. Here's an example:
static error_t parse_opt_verbosity(int key, char *arg, struct argp_state *state) {
if (key == 'q' || key == 'v') {
/* logic here */
}
return 0;
}
static error_t parse_opt_rest(int key, char *arg, struct argp_state *state) {
switch (key) {
case 'q':
case 'v':
/* ignore these, already handled */
break;
case 'a':
/* ... */
break;
case 'b':
/* ... */
break;
case 'c':
/* ... */
break;
case ARGP_KEY_ARG:
/* ... */
break;
case ARGP_KEY_END:
/* ... */
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
int main(int argc, char **argv) {
struct argp argp = {
.options = options,
.parser = &parse_opt_verbosity
};
argp_parse(&argp, argc, argv, 0, 0, &your_args_struct);
argp.parser = &parse_opt_rest;
argp_parse(&argp, argc, argv, 0, 0, &your_args_struct);
/* ... */
return 0;
}