Register DCO for Stefan Tomanek.
[gnupg.git] / common / argparse.c
index c9930ea..c713bf6 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, which is a subsystem of GnuPG.
  *
  *              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 }
@@ -185,19 +188,6 @@ argparse_register_outfnc (int (*fnc)(int, const char *))
 }
 
 
-static void
-writechar (int is_error, int c)
-{
-  char tmp[2];
-
-  tmp[0] = c;
-  tmp[1] = 0;
-  if (custom_outfnc)
-    custom_outfnc (is_error? 2:1, tmp);
-  else
-    fputs (tmp, is_error? stderr : stdout);
-}
-
 /* Write STRING and all following const char * arguments either to
    stdout or, if IS_ERROR is set, to stderr.  The list of strings must
    be terminated by a NULL.  */
@@ -214,64 +204,11 @@ writestrings (int is_error, const char *string, ...)
       va_start (arg_ptr, string);
       do
         {
-          const char *s2, *s3;
-
-          /* Check whether to substitute a macro. */
-          if (s && (s2 = strchr (s, '@')) && s2[1] >= 'A' && s2[1] <= 'Z'
-              && (s3 = (strchr (s2+1, '@'))))
-            {
-              /* Might be.  */
-              static struct {
-                const char *name;
-                const char *value;
-              } macros[] = {
-#             ifdef PACKAGE_BUGREPORT
-                { "EMAIL", PACKAGE_BUGREPORT },
-#             else
-                { "EMAIL", "bug@example.org" },
-#             endif
-                { "GNUPG",     GNUPG_NAME },
-                { "GPG",       GPG_NAME },
-                { "GPGSM",     GPGSM_NAME },
-                { "GPG_AGENT", GPG_AGENT_NAME },
-                { "SCDAEMON",  SCDAEMON_NAME },
-                { "DIRMNGR",   DIRMNGR_NAME },
-                { "G13",       G13_NAME },
-                { "GPGCONF",   GPGCONF_NAME },
-                { "GPGTAR",    GPGTAR_NAME }
-              };
-              int idx;
-
-              s2++;
-              for (idx=0; idx < DIM (macros); idx++)
-                if (strlen (macros[idx].name) == (s3 - s2)
-                    && !memcmp (macros[idx].name, s2, (s3 - s2)))
-                  break;
-              s2--;
-              if (idx < DIM (macros)) /* Found.  Print and substitute.  */
-                {
-                  for (; s < s2; s++, count++)
-                    writechar (is_error, *s);
-                  count += writestrings (is_error, macros[idx].value, NULL);
-                  s3++;
-                }
-              else /* Not found.  Print macro as is. */
-                {
-                  for (; s < s3; s++, count++)
-                    writechar (is_error, *s);
-                }
-              /* Now recurse so that remaining macros are also
-                 substituted. */
-              count += writestrings (is_error, s3, NULL);
-            }
+          if (custom_outfnc)
+            custom_outfnc (is_error? 2:1, s);
           else
-            {
-              if (custom_outfnc)
-                custom_outfnc (is_error? 2:1, s);
-              else
-                fputs (s, is_error? stderr : stdout);
-              count += strlen (s);
-            }
+            fputs (s, is_error? stderr : stdout);
+          count += strlen (s);
         }
       while ((s = va_arg (arg_ptr, const char *)));
       va_end (arg_ptr);
@@ -548,7 +485,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"))
                     {
@@ -566,9 +508,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;
@@ -580,9 +522,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;
@@ -618,7 +560,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
                 {
@@ -680,7 +622,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"))
                 {
@@ -915,7 +861,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))
                 writestrings (0, "--", opts[i].long_opt, "\n", NULL);
            }
           writestrings (0, "--dump-options\n--help\n--version\n--warranty\n",
@@ -934,7 +880,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 )
             {
@@ -1018,7 +964,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 )
               {
@@ -1090,9 +1036,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);
@@ -1180,7 +1126,7 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
         writestrings (0, "Options:", "\n", NULL);
       for (i=0; opts[i].short_opt; i++ )
         {
-          s = _( opts[i].description );
+          s = map_static_macro_string (_( opts[i].description ));
           if ( s && *s== '@' && !s[1] ) /* Hide this line.  */
             continue;
           if ( s && *s == '@' )  /* Unindented comment only line.  */
@@ -1381,7 +1327,7 @@ strusage( int level )
   const char *p = strusage_handler? strusage_handler(level) : NULL;
 
   if ( p )
-    return p;
+    return map_static_macro_string (p);
 
   switch ( level )
     {
@@ -1390,7 +1336,7 @@ strusage( int level )
       break;
     case 11: p = "foo"; break;
     case 13: p = "0.0"; break;
-    case 14: p = "Copyright (C) 2012 Free Software Foundation, Inc."; break;
+    case 14: p = "Copyright (C) 2014 Free Software Foundation, Inc."; break;
     case 15: p =
 "This is free software: you are free to change and redistribute it.\n"
 "There is NO WARRANTY, to the extent permitted by law.\n";