0

I think I'm trying to figure out to arrange things so that getopt_long skips an argument.

I wrote a shared library / dll and I use it from C or from a lua script. The bit of code that parses the CLI is in the shared library / dll, which is in C (see below) I can get access to argc and argv from the shared library / dll file in C.

When I start my program, it can be either of:

$ my_c_app --buddy moe --buddy larry --buddy curly

$ interpreter my_script.scr --buddy moe --buddy larry --buddy curly

When I parse from my_c_app, everything works fine. But when I pass in the argc and argv from the lua script, things go awry.

I think it gets tripped by because the whole thing starts with lua my_script.lua. I think this needs to skip that part (aka, treat the two terms as the name of the starting program)

Here's the parsing code:

static struct option long_options[] = {
    {"buddy", required_argument, NULL, 'b'},
    {"version", optional_argument, NULL, 'v'},
    {NULL, 0, NULL, 0}
};

void parse_cli(int argc, char *const *argv)
{
    char ch;

    // show me what you see
    for (int i = 0; i < argc; i++) {
        printf("%s\n", argv[i]);
    }

    print("--------\n");

    while ((ch = getopt_long(argc, argv, "p:v:", long_options, NULL)) != -1) {
        switch (ch) {
        case 'b':
            printf("buddy %s\n", optarg);
            break;
        case 'v':
            printf("version 1.0\n");
        default:
            break;
        }
    }
}

Here's what you see:

works

$ my_c_app --buddy moe --buddy larry --buddy curly
my_c_app
--buddy
moe
--buddy
larry
--buddy
curly
--------
moe
larry
curly

fails

interpreter
my_script.scr
--buddy
moe
--buddy
larry
--buddy
curly
--------
(null)
(null)
(null)

NOTES:

  • I experimented with setting optind to different values, nope.
  • My interpreter is really lua.
  • I don't think this is a lua thing. It may as well be python my_script.py
101010
  • 14,866
  • 30
  • 95
  • 172

1 Answers1

0

A quick fix you can do is to check if argv[1] exists and does not start with -. If so, start the parsing from argv + 1.

void parse_cli(int argc, char *const *argv)
{
    if (argc > 1 && argv[1][0] != '-') {
        argv++;
        argc--;
    }
    ...
dbush
  • 205,898
  • 23
  • 218
  • 273
  • This solution is giving me some issues when I go to use `optarg`. It's no longer consistently equal to the argument's value. I experimented with `argv[optind]` which also behaved inconsistently between the two ways that I start my app. – 101010 Jul 31 '20 at 17:23