Gengetopt 2.21 enhancement suggestions

"J. David Bryan" <[email protected]>
Newsgroups gmane.comp.gnu.gengetopt.general
Organization Palomar Corporation
Message-ID <[email protected]>
Greetings,

I have been using gengetopt for a few months and have used it to generate 
option processors for about ten programs.  From my use, I have three 
suggestions for a future version:

 1. Allow the automatic addition of the help and version options if the
    user respecifies the short options (but not the long options).

    Currently, if either the long or short option is respecified, the
    built-in usage is suppressed.  For example, if the user specifies
    his own "-h" ("--height") option, the built-in help option is lost,
    and the user must provide it manually.  However, often we still want
    to use "--help" for the help option and "--version" for the version
    option (just without short options).  It would be nicer if gengetopt
    provided these automatically.  Of course, if the user specified a
    "--help" or "--version" (long) option explicitly, then gengetopt
    should not provide its own.

    The attached "gengetopt-2.21-enh-1.diff" suggests an implementation.


 2. Provide a way to suppress the error message from "getopt_long" for an
    invalid option.

    The "--no-handle-error" option to gengetopt causes the parser to
    return an error value to the calling program.  The manual says that
    this is so "the program can print a help message."  However,
    "getopt_long" always prints an error message before returning the
    error indication.  This is because "opterr = 1" is set within the
    parser and cannot be changed by the user.

    It would be nice if the value (0 or 1) could be specified by the
    user, so that the user program can handle the error completely if
    desired.  Either "opterr" could be set automatically to 0 if the
    "--no-handle-error" option to gengetopt was used, or "opterr" could
    be set from a new cmdline_parser_params" item that the user would
    set explicitly (with default to 1) and then pass to
    "cmdline_parser_ext".

    This is useful in cases where options are used that either do not
    match C identifier syntax (e.g., "-?") or are unknown until run time
    (e.g., "-<n>", where the values for <n> are determined by the
    contents of a file specified on the command line).  The generated
    parser can still be used to handle the help and version options (and
    perhaps more), while the caller can handle the "unparseable" options
    without spurious error messages appearing.

    The attached "gengetopt-2.21-enh-2.diff" suggests an implementation.


 3. Allow an option with a "values=" restriction to return a specified
    argtype.

    When "values=" is specified, the manual says that "The type is
    considered string and must not be specified."  However, the option
    value often is not a string and must be converted for use.  For
    example, a "--rotate" option might limit values to 0, 90, 180, or
    270 degrees.  The rotation value is an integer, but it will be
    returned as a string, and the caller must do string comparisons or a
    string-to-int conversion.

    What would be more flexible would be to allow "argtype" to be
    specified in addition to "values=".  So if we had:

      option "rotate" r "Rotate clockwise" int values="0","90","180","270"

    ...then the return value would be one of the four integers converted
    from a string.  Specifying "string" as the "argtype" would return a
    string value (as gengetopt does now).  Specifying "enum" would
    generate an enumeration type (example: "enum rotate_type { rotate_0,
    rotate_90, ... };") and return one of the enumeration values.  Note
    that if the argtype defaulted to "string," the new behavior would be
    backward-compatible.

    This issue was previously discussed in:

    http://lists.gnu.org/archive/html/help-gengetopt/2006-04/msg00007.html

    ...in the context of returning enumeration values (only).

                                      -- Dave

_______________________________________________
Help-gengetopt mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gengetopt
gengetopt-2.21-enh-1.diff (application/octet-stream, 1.5 KB)
diff -u -r -N original/src/gengetopt.cc patched/src/gengetopt.cc
--- original/src/gengetopt.cc	2007-07-28 09:45:33.000000000 -0400
+++ patched/src/gengetopt.cc	2007-10-04 17:22:24.000000000 -0400
@@ -107,7 +107,7 @@
   char *header_ext  ; /* extenstion of header file */
   string output_dir; /* output directory (default empty -> current dir)*/
 
-  int i;
+  int i, has_help, has_version;
   FILE *input_file ;
 
   if (cmdline_parser (argc, argv, &args_info) != 0) {
@@ -179,8 +179,10 @@
     free(current_section);
   current_section = 0;
 
-  if (gengetopt_has_option (VERSION_LONG_OPT, VERSION_SHORT_OPT) == 0) {
-    gengetopt_create_option (opt, VERSION_LONG_OPT, VERSION_SHORT_OPT,
+  has_version = gengetopt_has_option (VERSION_LONG_OPT, VERSION_SHORT_OPT);
+
+  if (has_version != REQ_LONG_OPTION) {
+    gengetopt_create_option (opt, VERSION_LONG_OPT, has_version ? '-' : VERSION_SHORT_OPT,
                                  VERSION_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0);
     gengetopt_options.push_front(opt);
   }
@@ -191,8 +193,10 @@
       gengetopt_options.push_front(opt);
   }
 
-  if (gengetopt_has_option(HELP_LONG_OPT, HELP_SHORT_OPT) == 0) {
-    gengetopt_create_option (opt, HELP_LONG_OPT, HELP_SHORT_OPT,
+  has_help = gengetopt_has_option(HELP_LONG_OPT, HELP_SHORT_OPT);
+  
+  if (has_help != REQ_LONG_OPTION) {
+    gengetopt_create_option (opt, HELP_LONG_OPT, has_help ? '-' : HELP_SHORT_OPT,
                                  HELP_OPT_DESCR, ARG_NO, 0, 0, 0, 0, 0, 0);
     gengetopt_options.push_front(opt);
   }
gengetopt-2.21-enh-2.diff (application/octet-stream, 4.1 KB)
diff -u -r -N original/src/skels/c_source.cc patched/src/skels/c_source.cc
--- original/src/skels/c_source.cc	2007-07-28 06:29:25.000000000 -0400
+++ patched/src/skels/c_source.cc	2007-10-08 15:15:29.000000000 -0400
@@ -617,6 +617,9 @@
   stream << "      params->check_ambiguity = 0;";
   stream << "\n";
   stream << indent_str;
+  stream << "      params->print_errors = 0;";
+  stream << "\n";
+  stream << indent_str;
   stream << "    }";
   stream << "\n";
   stream << indent_str;
@@ -1401,6 +1404,9 @@
   stream << "  params.check_ambiguity = 0;";
   stream << "\n";
   stream << indent_str;
+  stream << "  params.print_errors = 1;";
+  stream << "\n";
+  stream << indent_str;
   stream << "\n";
   stream << indent_str;
   stream << "  result = ";
@@ -1635,7 +1641,7 @@
   stream << "  optind = 0;";
   stream << "\n";
   stream << indent_str;
-  stream << "  opterr = 1;";
+  stream << "  opterr = params->print_errors;";
   stream << "\n";
   stream << indent_str;
   stream << "  optopt = '?';";
@@ -2451,6 +2457,9 @@
       stream << "  params.check_ambiguity = 0;";
       stream << "\n";
       stream << indent_str;
+      stream << "  params.print_errors = 1;";
+      stream << "\n";
+      stream << indent_str;
       indent = 2;
       stream << "  ";
       indent = 0;
@@ -2837,6 +2846,9 @@
       stream << "  params.check_ambiguity = 0;";
       stream << "\n";
       stream << indent_str;
+      stream << "  params.print_errors = 1;";
+      stream << "\n";
+      stream << indent_str;
       stream << "\n";
       stream << indent_str;
       stream << "  return ";
diff -u -r -N original/src/skels/c_source.h_skel patched/src/skels/c_source.h_skel
--- original/src/skels/c_source.h_skel	2007-07-28 06:29:19.000000000 -0400
+++ patched/src/skels/c_source.h_skel	2007-10-08 15:15:06.000000000 -0400
@@ -172,6 +172,7 @@
       params->initialize = 0;
       params->check_required = 0;
       params->check_ambiguity = 0;
+      params->print_errors = 0;
     }
     
   return params;
@@ -432,6 +433,7 @@
   params.initialize = initialize;
   params.check_required = check_required;
   params.check_ambiguity = 0;
+  params.print_errors = 1;
 
   result = @parser_name@_internal (argc, argv, args_info, &params, NULL);
 
@@ -500,7 +502,7 @@
 
   optarg = 0;
   optind = 0;
-  opterr = 1;
+  opterr = params->print_errors;
   optopt = '?';
 
   while (1)
@@ -766,6 +768,7 @@
   params.initialize = initialize;
   params.check_required = check_required;
   params.check_ambiguity = 0;
+  params.print_errors = 1;
   
   return @parser_name@_config_file (filename, args_info, &params);
 }
@@ -893,6 +896,7 @@
   params.initialize = initialize;
   params.check_required = check_required;
   params.check_ambiguity = 0;
+  params.print_errors = 1;
 
   return @parser_name@_string_ext(cmdline, args_info, prog_name, &params);
 }
diff -u -r -N original/src/skels/header.cc patched/src/skels/header.cc
--- original/src/skels/header.cc	2007-07-28 05:32:39.000000000 -0400
+++ patched/src/skels/header.cc	2007-10-08 15:15:14.000000000 -0400
@@ -198,6 +198,11 @@
   stream << " (default 0) */";
   stream << "\n";
   stream << indent_str;
+  stream << "  int print_errors; /**< ";
+  stream << "@";
+  stream << "brief whether getopt_long should print an error message for a bad option (default 0) */";
+  stream << "\n";
+  stream << indent_str;
   stream << "} ;";
   stream << "\n";
   stream << indent_str;
diff -u -r -N original/src/skels/header.h_skel patched/src/skels/header.h_skel
--- original/src/skels/header.h_skel	2007-07-28 05:32:37.000000000 -0400
+++ patched/src/skels/header.h_skel	2007-10-08 15:14:44.000000000 -0400
@@ -42,6 +42,7 @@
   int initialize; /**< @@brief whether to initialize the option structure @args_info@ (default 0) */
   int check_required; /**< @@brief whether to check that all required options were provided (default 0) */
   int check_ambiguity; /**< @@brief whether to check for options already specified in the option structure @args_info@ (default 0) */
+  int print_errors; /**< @@brief whether getopt_long should print an error message for a bad option (default 0) */
 } ;
 
 /** @@brief the purpose string of the program */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.