Typo fixes.
[gnupg.git] / common / argparse.c
index 6a90920..0a36a9e 100644 (file)
@@ -1,6 +1,6 @@
 /* [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) 1998-2001, 2006-2008, 2012  Free Software Foundation, Inc.
+ * Copyright (C) 1997-2001, 2006-2008, 2013 Werner Koch
  *
  * This file is part of JNLIB, which is a subsystem of GnuPG.
  *
@@ -38,6 +38,8 @@
 #include <ctype.h>
 #include <string.h>
 #include <stdarg.h>
+#include <limits.h>
+#include <errno.h>
 
 #include "libjnlib-config.h"
 #include "mischelp.h"
  *              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 }
@@ -259,6 +263,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
             s = _("keyword too long");
           else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
             s = _("missing argument");
+          else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
+            s = _("invalid argument");
           else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
             s = _("invalid command");
           else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
@@ -275,6 +281,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
 
           if ( arg->r_opt == ARGPARSE_MISSING_ARG )
             jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s);
+          else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
+            jnlib_log_error (_("invalid argument for option \"%.50s\"\n"), s);
           else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
             jnlib_log_error (_("option \"%.50s\" does not expect an "
                                "argument\n"), s );
@@ -482,7 +490,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"))
                     {
@@ -500,9 +513,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;
@@ -514,9 +527,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;
@@ -552,7 +565,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
                 {
@@ -580,7 +593,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
                             p[strlen(p)-1] = 0;
                         }
                       if (!set_opt_arg (arg, opts[idx].flags, p))
-                       jnlib_free(buffer);
+                        jnlib_free(buffer);
                     }
                 }
               break;
@@ -614,7 +627,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"))
                 {
@@ -849,7 +866,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",
@@ -868,7 +885,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 )
             {
@@ -952,7 +969,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 )
               {
@@ -1020,23 +1037,54 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
 }
 
 
-
+/* Returns: -1 on error, 0 for an integer type and 1 for a non integer
+   type argument.  */
 static int
-set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s)
+set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s)
 {
-  int base = (flags & 16)? 0 : 10;
+  int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10;
+  long l;
 
-  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);
-      return 0;
     case ARGPARSE_TYPE_LONG:
-      arg->r.ret_long= strtol(s,NULL,base);
+    case ARGPARSE_TYPE_INT:
+      errno = 0;
+      l = strtol (s, NULL, base);
+      if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE)
+        {
+          arg->r_opt = ARGPARSE_INVALID_ARG;
+          return -1;
+        }
+      if (arg->r_type == ARGPARSE_TYPE_LONG)
+        arg->r.ret_long = l;
+      else if ( (l < 0 && l < INT_MIN) || l > INT_MAX )
+        {
+          arg->r_opt = ARGPARSE_INVALID_ARG;
+          return -1;
+        }
+      else
+        arg->r.ret_int = (int)l;
       return 0;
+
     case ARGPARSE_TYPE_ULONG:
-      arg->r.ret_ulong= strtoul(s,NULL,base);
+      while (isascii (*s) && isspace(*s))
+        s++;
+      if (*s == '-')
+        {
+          arg->r.ret_ulong = 0;
+          arg->r_opt = ARGPARSE_INVALID_ARG;
+          return -1;
+        }
+      errno = 0;
+      arg->r.ret_ulong = strtoul (s, NULL, base);
+      if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE)
+        {
+          arg->r_opt = ARGPARSE_INVALID_ARG;
+          return -1;
+        }
       return 0;
+
     case ARGPARSE_TYPE_STRING:
     default:
       arg->r.ret_str = s;
@@ -1114,7 +1162,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.  */
@@ -1222,35 +1270,8 @@ show_help (ARGPARSE_OPTS *opts, unsigned int flags)
     }
   if ( (s=strusage(19)) )
     {
-      /* bug reports to ... */
-      char *s2;
-
       writestrings (0, "\n", NULL);
-      s2 = strstr (s, "@EMAIL@");
-      if (s2)
-        {
-          if (s2-s)
-            {
-              const char *s3;
-
-              for (s3=s; s3 < s2; s3++)
-                {
-                  tmp[0] = *s3;
-                  tmp[1] = 0;
-                  writestrings (0, tmp, NULL);
-                }
-            }
-#ifdef PACKAGE_BUGREPORT
-          writestrings (0, PACKAGE_BUGREPORT, NULL);
-#else
-          writestrings (0, "bug@example.org", NULL);
-#endif
-          s2 += 7;
-          if (*s2)
-            writestrings (0, s2, NULL);
-        }
-      else
-        writestrings (0, s, NULL);
+      writestrings (0, s, NULL);
     }
   flushstrings (0);
   exit(0);
@@ -1342,7 +1363,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 )
     {
@@ -1351,7 +1372,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";