Bug in getopt_long/getopt_long_only?

From: Generic Usenet Account (usenet_at_sta.samsung.com)
Date: 05/06/04


Date: 6 May 2004 11:51:14 -0700

I suspect that the getopt_long() function has a bug, and here's why.

On a Linux 2.4.7-10 system, I am invoking
getopt_long/getopt_long_only. I am defining a "long" option with
optional parameters (i.e. "has_arg" field in the option struct is set
to 2). However, when I am pasing a parameter with this argument,
getopt_long is returning an error message. In fact, "has_arg" value
of 2 is being treated exactly as "has_arg" value of 0 (i.e. no
argument). The source code follows.

Thanks,
Bhta

/*************************************************************************/

#define GTOPT_NOARG 0
#define GTOPT_YESARG 1
#define GTOPT_OPTARG 2

#define GT_OPTRETVAL 0

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

/******************************************************************/
/* Return value of -1 indicates failure */
/******************************************************************/
int
parseCmdLineParms(int argc, char **argv)
{
  int ch = GT_OPTRETVAL;
  int ambiguity = 0;

  for(;;)
  {
    int option_index = 0;
    static struct option long_options[] =
                      {
                        {"noarg", GTOPT_NOARG, 0, GT_OPTRETVAL},
                        {"yesarg", GTOPT_YESARG, 0, GT_OPTRETVAL},
                        /*{"ypparg", GTOPT_YESARG, 0, GT_OPTRETVAL},
/* Just to test for ambiguity */
                        {"optionalarg", GTOPT_OPTARG, 0,
GT_OPTRETVAL},
                        {0, 0, 0, 0}
                      };

    ch = getopt_long_only (argc, argv, "",
                        long_options, &option_index);

    if (ch)
    {
      /*
        A non-zero value was returned.
        If -1 was returned, there was an error
        Else, ambiguity was detected
      */
      if(ch != -1)
      {
        ambiguity = 1;
        ch = -1;
        /* Set to failure, since this is what we are
           returning from this function */
      }
      break;
    }

    printf ("option %s", long_options[option_index].name);
    if (optarg)
      printf (" with arg %s\n", optarg);
  }

  if(!ambiguity)
  {
    if (optind < argc)
    {
      printf (" non-option ARGV-elements: ");
    
      while (optind < argc)
        printf ("%s ", argv[optind++]);
      printf ("\n");
    }
    else
      ch = GT_OPTRETVAL;
  }

  return ch;
}

/******************************************************************/
/* */
/******************************************************************/
int
main (int argc, char **argv)
{
  int retVal = parseCmdLineParms(argc, argv);

  if(retVal == -1)
    printf("\nFAILURE\n");
  else
    printf("\nSUCCESS\n");

  exit (0);
}