How to make command line options mandatory for GLib?

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

My code is as follows:

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 these parameters, either as on the command line (g_option_context_parse) is still successful and the values ​​in question (row and column) or still -1. How can I tell GLib about parsing failure if the user does not pass both options on the command line? Maybe I'm just blind, but I could not find a flag that I can add to my GOptionEntry data structure to report this so that these fields are required.

Of course, I could check if one of these variables is still -1, but then the user can simply pass this value on the command line, and I want to print a separate error message if the values ​​are out of range.

+4
source share
3 answers

It is up to you to check the reasonableness of the argument (other than parsing), which is also suitable for getopt . The problem is that when you make things “mandatory,” you often encounter situations where “mandatory” applies only in the absence of other arguments.

For example, ./program --help does not require additional arguments, similarly for ./program --version . Assuming the logic "require -foo and -bar, unless the -version OR -help" in the parser itself is not limited to bloat and overflow.

You just have to check the line and column values ​​after parsing the arguments to make sure they are set to something. It is possible to include all this logic in a function (e.g. check_sanity() ) if you are worried about the mess in main() .

In general, the behavior that you see by design, I do not think that it can change. If any variable remains the same as it was initialized after starting the parser, the user forgot to specify the corresponding option.

+8
source

Impossible to achieve with GLib, I checked the documentation and source code. You can send a request for a function and / or live with the proposed solution, despite the mentioned drawback.

+1
source

Recently, I encountered a similar problem, and I think (I don’t know for sure yet, but it looks doable), this can be done with two callbacks. The argument processing callback will do whatever you want to indicate that the argument entered has been entered (bitmask?, ...). It will also save the analyzed value (see below). Configure this callback as GOptionArgFunc and specify it in the GOptionEntry array using the G_OPTION_ARG_CALLBACK flag.

The message parser checks to see if all the necessary requirements have been entered. Configure this callback as GOptionParseFunc and point to it using g_option_group_set_parse_hooks .

If you use g_option_group_new , you can pass it to user_data (address of your bitmask?, ...) for use in both callbacks. Use g_option_group_add_entries and g_option_context_set_main_group instead of g_option_context_add_main_entries to get group entries related to GOptionContext .

The only thing I see so far is that you need to set up your own record pointer array in order to use the actual values ​​of the parsed records, since the GOptionEntry arg_data field will be used to point to the arg callback function.

+1
source

Source: https://habr.com/ru/post/1307867/


All Articles