cgliboptional-parameters

How to make command-line options mandatory with GLib?


I use GLib to parse some command-line options. The problem is that I want to make two of those options mandatory so that the program terminates with the help screen if the user omits them.

My code looks like this:

static gint line   = -1;
static gint column = -1;

static GOptionEntry options[] =
{
    {"line", 'l', 0, G_OPTION_ARG_INT, &line, "The line", "L"},
    {"column", 'c', 0, G_OPTION_ARG_INT, &column, "The column", "C"},
    {NULL}
};

...

int main(int argc, char** argv)
{
    GError *error = NULL;
    GOptionContext *context;

    context = g_option_context_new ("- test");
    g_option_context_add_main_entries (context, options, NULL);

    if (!g_option_context_parse(context, &argc, &argv, &error))
    {
        usage(error->message, context);
    }

    ...

    return 0;
}

If I omit one of those parameters or both on the command-line g_option_context_parse() still succeeds and the values in question (line and or column) are still -1. How can I tell GLib to fail parsing if the user doesn't pass both options on the command-line? Maybe I'm just blind but I couldn't find a flag I can put into my GOptionEntry data structure to tell it to make those fields mandatory.

Of course I could check if one of those variables is still -1 but then the user could just have passed this value on the command-line and I want to print a separate error message if the values are out of range.


Solution

  • It's up to you to check argument sanity (beyond parsing), that goes for getopt as well. The problem is, when making things 'mandatory', you will often run into cases where 'mandatory' applies only in the absence of other arguments.

    For instance, ./program --help should require no additional arguments, likewise for ./program --version. Putting the logic of "require --foo and --bar unless --version OR --help" in the parser itself would border on bloat and overcomplexity.

    You simply must check the value of line and column after arguments are parsed to ensure that they were set to something. It's entirely possible to put all of that logic into a function (e.g. check_sanity()) if you are worried about clutter in main().

    In summary, the behavior that you are seeing is by design, I don't think it's likely to change. If either variable remains as it was initialized after the parser runs, the user forgot to specify the respective option.