Allow marking options as ignored.
authorWerner Koch <wk@gnupg.org>
Thu, 18 Apr 2013 12:40:43 +0000 (14:40 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 22 Apr 2013 13:03:34 +0000 (15:03 +0200)
* jnlib/argparse.h (ARGPARSE_OPT_IGNORE): New.
(ARGPARSE_TYPE_MASK): New, for internal use.
(ARGPARSE_ignore): New.
* jnlib/argparse.c (optfile_parse, arg_parse): Replace remaining
constants by macros.
(optfile_parse): Implement ARGPARSE_OPT_IGNORE.
(arg_parse): Exclide ignore options from --dump-options.
--

In addition to the ignore-invalid-option (commit 8ea49cf5) it is often
useful to mark options in a configuration which as NOP.  For example
options which have no more function at all but can be expected to be
found in existing conf files.  Such an option (or command) may now be
given as

  ARGPARSE_ignore (300, "obsolete-option")

The 300 is merely used as a non-valid single option name much like
group names or the 500+n values used for long options.

Signed-off-by: Werner Koch <wk@gnupg.org>
jnlib/argparse.c
jnlib/argparse.h

index dab4bba..ea624e8 100644 (file)
@@ -1,6 +1,7 @@
 /* [argparse.c wk 17.06.97] Argument Parser for option handling
  * Copyright (C) 1998, 1999, 2000, 2001, 2006
  *               2007, 2008, 2012  Free Software Foundation, Inc.
+ * Copyright (C) 1997, 2013 Werner Koch
  *
  * This file is part of JNLIB.
  *
@@ -92,7 +93,8 @@
  *              4 = takes ulong argument
  *     Bit 3 : argument is optional (r_type will the be set to 0)
  *     Bit 4 : allow 0x etc. prefixed values.
- *     Bit 7 : this is a command and not an option
+ *     Bit 6 : Ignore this option
+ *     Bit 7 : This is a command and not an option
  *  You stop the option processing by setting opts to NULL, the function will
  *  then return 0.
  * @Return Value
  *     { 'o', "output",    2 },
  *     { 'c', "cross-ref", 2|8 },
  *     { 'm', "my-option", 1|8 },
+ *     { 300, "ignored-long-option, ARGPARSE_OP_IGNORE},
  *     { 500, "have-no-short-option-for-this-long-option", 0 },
  *     {0} };
  *     ARGPARSE_ARGS pargs = { &argc, &argv, 0 }
@@ -418,7 +421,12 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
                 }
               idx = i;
               arg->r_opt = opts[idx].short_opt;
-              if (!opts[idx].short_opt )
+              if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
+                {
+                  state = i = 0;
+                  continue;
+                }
+              else if (!opts[idx].short_opt )
                 {
                   if (!strcmp (keyword, "ignore-invalid-option"))
                     {
@@ -436,9 +444,9 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
                                 ? ARGPARSE_INVALID_COMMAND
                                 : ARGPARSE_INVALID_OPTION);
                 }
-              else if (!(opts[idx].flags & 7))
+              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
                 arg->r_type = 0; /* Does not take an arg. */
-              else if ((opts[idx].flags & 8) )
+              else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) )
                 arg->r_type = 0; /* Arg is optional.  */
               else
                 arg->r_opt = ARGPARSE_MISSING_ARG;
@@ -450,9 +458,9 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
               /* No argument found.  */
               if (in_alias)
                 arg->r_opt = ARGPARSE_MISSING_ARG;
-              else if (!(opts[idx].flags & 7))
+              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
                 arg->r_type = 0; /* Does not take an arg. */
-              else if ((opts[idx].flags & 8))
+              else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL))
                 arg->r_type = 0; /* No optional argument. */
               else
                 arg->r_opt = ARGPARSE_MISSING_ARG;
@@ -488,7 +496,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
                         }
                    }
                }
-              else if (!(opts[idx].flags & 7))
+              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
                 arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
               else
                 {
@@ -550,7 +558,11 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
               break;
           idx = i;
           arg->r_opt = opts[idx].short_opt;
-          if (!opts[idx].short_opt)
+          if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
+            {
+              state = 1; /* Process like a comment.  */
+            }
+          else if (!opts[idx].short_opt)
             {
               if (!strcmp (keyword, "alias"))
                 {
@@ -784,7 +796,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
         {
           for (i=0; opts[i].short_opt; i++ )
             {
-              if ( opts[i].long_opt )
+              if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
                 printf ("--%s\n", opts[i].long_opt);
            }
           fputs ("--dump-options\n--help\n--version\n--warranty\n", stdout);
@@ -802,7 +814,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
         arg->r_opt = opts[i].short_opt;
       if ( i < 0 )
         ;
-      else if ( (opts[i].flags & 0x07) )
+      else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
         {
           if ( argpos )
             {
@@ -886,7 +898,7 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
            arg->internal.inarg++; /* Point to the next arg.  */
            arg->r.ret_str = s;
           }
-       else if ( (opts[i].flags & 7) )
+       else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
           {
            if ( s[1] && !dash_kludge )
               {
@@ -958,9 +970,9 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
 static int
 set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s)
 {
-  int base = (flags & 16)? 0 : 10;
+  int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10;
 
-  switch ( (arg->r_type = (flags & 7)) )
+  switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) )
     {
     case ARGPARSE_TYPE_INT:
       arg->r.ret_int = (int)strtol(s,NULL,base);
index a4203b5..dd9b30b 100644 (file)
 #include "types.h"
 
 typedef struct
-{                  
+{
   int  *argc;        /* Pointer to ARGC (value subject to change). */
   char ***argv;              /* Pointer to ARGV (value subject to change). */
   unsigned int flags; /* Global flags.  May be set prior to calling the
                          parser.  The parser may change the value.  */
-  int err;            /* Print error description for last option. 
+  int err;            /* Print error description for last option.
                          Either 0,  ARGPARSE_PRINT_WARNING or
                          ARGPARSE_PRINT_ERROR.  */
 
@@ -79,9 +79,12 @@ typedef struct
 #define ARGPARSE_TYPE_STRING      2  /* Takes a string argument.          */
 #define ARGPARSE_TYPE_LONG        3  /* Takes a long argument.            */
 #define ARGPARSE_TYPE_ULONG       4  /* Takes an unsigned long argument.  */
-#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional.             */ 
+#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional.             */
 #define ARGPARSE_OPT_PREFIX   (1<<4) /* Allow 0x etc. prefixed values.    */
-#define ARGPARSE_OPT_COMMAND  (1<<8) /* The argument is a command.        */
+#define ARGPARSE_OPT_IGNORE   (1<<6) /* Ignore command or option.         */
+#define ARGPARSE_OPT_COMMAND  (1<<7) /* The argument is a command.        */
+
+#define ARGPARSE_TYPE_MASK  7  /* Mask for the type values (internal).  */
 
 /* A set of macros to make option definitions easier to read.  */
 #define ARGPARSE_x(s,l,t,f,d) \
@@ -148,9 +151,11 @@ typedef struct
 #define ARGPARSE_c(s,l,d) \
      { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) }
 
+#define ARGPARSE_ignore(s,l) \
+     { (s), (l), (ARGPARSE_OPT_IGNORE), "@" }
 
 #define ARGPARSE_group(s,d) \
-     { (s), NULL, 0, (d) } 
+     { (s), NULL, 0, (d) }
 
 #define ARGPARSE_end()  { 0, NULL, 0, NULL }