最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Argument ordering for processing with argp? - Stack Overflow

programmeradmin4浏览0评论

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 switchstatement:

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)?

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 switchstatement:

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)?

Share asked Mar 11 at 7:14 ChristianChristian 3673 silver badges12 bronze badges 3
  • Call argp_parse twice, but tell parse_opt to ignore the other flags on the first run through. Or have two distinct parser functions... – Botje Commented Mar 11 at 7:49
  • You could just do loglevel=minmax(loglevel,0,7); (and the setlogmask call) after option processing instead of doing it during option processing. Then the -q and -v options would simply decrement or increment loglevel and the order they are processed wouldn't matter. – Ian Abbott Commented Mar 11 at 17:49
  • That's (more or less) the way I did it now. Created a structure action.xy where it sets flags in parse_opt, but does nothing. After full parsing I check the values of the action_struct and perform the actions. Works for me. – Christian Commented Mar 11 at 21:18
Add a comment  | 

1 Answer 1

Reset to default 3

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;
}
发布评论

评论列表(0)

  1. 暂无评论