The 'getopt-gnu' module is one of the most heavily used modules
of Gnulib (more than 50 packages use it) and it, together with
'xalloc' and 'regex', one of the first three modules a package
typically uses.

So, I thought, I can use it in my packages, without expecting problems.
Today, I wrote this code:

 --------------------------------------------------------------------
    /* Long options.  */
    static const struct option long_options[] =
    {
      { "context", required_argument, NULL, 'c' },
      { "help", no_argument, NULL, 'h' },
      { "version", no_argument, NULL, 'V' },
      { NULL, 0, NULL, 0 }
    };

    int optchar;

    while ((optchar = getopt_long (argc, argv, "+chV", long_options, NULL))
           != EOF)
      switch (optchar)
        {
        case '\0':          /* Long option.  */
          break;
        case 'c':
          context = optarg;
          break;
        case 'h':
          do_help = true;
          break;
        case 'V':
          do_version = true;
          break;
        default:
          usage (EXIT_FAILURE);
        }
  }
 --------------------------------------------------------------------

Can you spot what is wrong with this code?

When I invoke the program as "./program -c foo bar", the value of
'optind' is 2, whereas I expected it to be 3 (since I specified that
'--context' takes a required argument and '-c' is the equivalent of
'--context').

Can you spot it now?

The problem is that the properties of an option have to be specified
in *two* places: in the long_options array *and* in the 3rd argument
to getopt_long().

I propose to add to getopt_long() — in Gnulib — code that verifies
the consistency between the two places, when a certain environment
variable (say, GETOPT_DEBUG) is set. And produces output on stderr
such as:
  getopt_long: warning: option '--context' requires an argument but option '-c' 
takes no argument.

Then, at least, a developer could debug the problem by building their
package with
  $ gl_cv_func_getopt_posix=no gl_cv_func_getopt_gnu=no ./configure

Opinions? Objections?

Bruno




Reply via email to