[git] GPG-ERROR - branch, master, updated. gpgrt-1.28-29-g253ca17

by Werner Koch cvs at cvs.gnupg.org
Wed Apr 11 09:47:37 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Error codes used by GnuPG et al.".

The branch, master has been updated
       via  253ca177055e23617b14e0934b09ef50253f29eb (commit)
       via  c3825327da826e434ada9abde34e6bbd7ef61737 (commit)
       via  f4c4592a15f9ec997c82c3d3d25656e0c2982d97 (commit)
       via  e901c9fb04f5a96ba2bd49225b396ce7857a3782 (commit)
      from  99e976be723ebbf7fe5c73671dd916bd4a067727 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 253ca177055e23617b14e0934b09ef50253f29eb
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Apr 11 09:40:17 2018 +0200

    Post release updates
    
    --

diff --git a/NEWS b/NEWS
index 7b024f7..9c1459f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Noteworthy changes in version 1.30 (unreleased) [C24/A24/R_]
+-----------------------------------------------
+
+
 Noteworthy changes in version 1.29 (2018-04-11) [C24/A24/R0]
 -----------------------------------------------
 
diff --git a/configure.ac b/configure.ac
index 5328af4..e1f8858 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,7 +29,7 @@ min_automake_version="1.14"
 # See below for the LT versions.
 m4_define([mym4_package],[libgpg-error])
 m4_define([mym4_major], [1])
-m4_define([mym4_minor], [29])
+m4_define([mym4_minor], [30])
 
 # Below is m4 magic to extract and compute the revision number, the
 # decimalized short revision number, a beta version string, and a flag

commit c3825327da826e434ada9abde34e6bbd7ef61737
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Apr 11 09:24:03 2018 +0200

    Release 1.29
    
    * configure.ac: Bump LT version to C24/A24/R0.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index 44da9ee..7b024f7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Noteworthy changes in version 1.29 (unreleased) [C23/A23/R_]
+Noteworthy changes in version 1.29 (2018-04-11) [C24/A24/R0]
 -----------------------------------------------
 
  * The yat2m tool is during cross-compile now also installed on the
diff --git a/README b/README
index 9cc5de0..bab9c95 100644
--- a/README
+++ b/README
@@ -22,6 +22,10 @@ components are
 
  - Log functions
 
+ - Option parser
+
+ - BAse-64 encoder and decoder.
+
 More components will be added over time.  Most functions are prefixed
 with "gpgrt" (GnuPG Run Time) instead of "gpg_err" to indicate the
 long term plan to rename this library to gpgrt.
@@ -106,13 +110,8 @@ To build for Windows you you may use the convenience command:
 
    ./autogen.sh --build-w32
 
-which runs configure with suitable options.  For WindowsCE the command
-is:
-
-   ./autogen.sh --build-w32ce
-
-There is also _experimental_ support for building a 64 bit Windows
-version:
+which runs configure with suitable options.  There is also basic
+support for building a 64 bit Windows version:
 
    ./autogen.sh --build-w64
 
diff --git a/configure.ac b/configure.ac
index 0214fb6..5328af4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,8 +49,8 @@ AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org])
 #   (Interfaces added:			AGE++)
 #   (Interfaces removed:		AGE=0)
 # Note that added error codes don't constitute an interface change.
-LIBGPG_ERROR_LT_CURRENT=23
-LIBGPG_ERROR_LT_AGE=23
+LIBGPG_ERROR_LT_CURRENT=24
+LIBGPG_ERROR_LT_AGE=24
 LIBGPG_ERROR_LT_REVISION=0
 ################################################
 

commit f4c4592a15f9ec997c82c3d3d25656e0c2982d97
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Apr 11 09:12:39 2018 +0200

    doc: Beautify comments in gpg-error.h.
    
    --
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index f585808..ce7d278 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -1,7 +1,7 @@
-/* gpg-error.h or gpgrt.h - Public interface to libgpg-error.   -*- c -*-
+/* gpg-error.h or gpgrt.h - Common code for GnuPG and others.    -*- c -*-
  * Copyright (C) 2001-2018 g10 Code GmbH
  *
- * This file is part of libgpg-error.
+ * This file is part of libgpg-error (aka libgpgrt).
  *
  * libgpg-error is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -20,6 +20,41 @@
  * @configure_input@
  */
 
+/* The GnuPG project consists of many components.  Error codes are
+ * exchanged between all components.  The common error codes and their
+ * user-presentable descriptions are kept into a shared library to
+ * allow adding new error codes and components without recompiling any
+ * of the other components.  In addition to error codes this library
+ * also features several other groups of functions which are common to
+ * all GnuPG components.  They may be used by independet project as
+ * well.  The interfaces will not change in a backward incompatible way.
+ *
+ * An error code together with an error source build up an error
+ * value.  As the error value is been passed from one component to
+ * another, it preserves the information about the source and nature
+ * of the error.
+ *
+ * A component of the GnuPG project can define the following macros to
+ * tune the behaviour of the library:
+ *
+ * GPG_ERR_SOURCE_DEFAULT: Define to an error source of type
+ * gpg_err_source_t to make that source the default for gpg_error().
+ * Otherwise GPG_ERR_SOURCE_UNKNOWN is used as default.
+ *
+ * GPG_ERR_ENABLE_GETTEXT_MACROS: Define to provide macros to map the
+ * internal gettext API to standard names.  This has only an effect on
+ * Windows platforms.
+ *
+ * GPGRT_ENABLE_ES_MACROS: Define to provide "es_" macros for the
+ * estream functions.
+ *
+ * GPGRT_ENABLE_LOG_MACROS: Define to provide short versions of the
+ * log functions.
+ *
+ * GPGRT_ENABLE_ARGPARSE_MACROS: Needs to be defined to provide the
+ * mandatory macros of the argparse interface.
+ */
+
 #ifndef GPG_ERROR_H
 #define GPG_ERROR_H 1
 #ifndef GPGRT_H
@@ -57,50 +92,17 @@ extern "C" {
 #endif
 #endif /* __cplusplus */
 
-/* The GnuPG project consists of many components.  Error codes are
-   exchanged between all components.  The common error codes and their
-   user-presentable descriptions are kept into a shared library to
-   allow adding new error codes and components without recompiling any
-   of the other components.  The interface will not change in a
-   backward incompatible way.
-
-   An error code together with an error source build up an error
-   value.  As the error value is been passed from one component to
-   another, it preserver the information about the source and nature
-   of the error.
-
-   A component of the GnuPG project can define the following macros to
-   tune the behaviour of the library:
-
-   GPG_ERR_SOURCE_DEFAULT: Define to an error source of type
-   gpg_err_source_t to make that source the default for gpg_error().
-   Otherwise GPG_ERR_SOURCE_UNKNOWN is used as default.
-
-   GPG_ERR_ENABLE_GETTEXT_MACROS: Define to provide macros to map the
-   internal gettext API to standard names.  This has only an effect on
-   Windows platforms.
-
-   GPGRT_ENABLE_ES_MACROS: Define to provide "es_" macros for the
-   estream functions.
-
-   GPGRT_ENABLE_LOG_MACROS: Define to provide short versions of the
-   log functions.
-
-   GPGRT_ENABLE_ARGPARSE_MACROS: Needs to be defined to provide the
-   mandatory macros of the argparse interface.
-
-   In addition to the error codes, Libgpg-error also provides a set of
-   functions used by most GnuPG components.  */
 
 

 /* The error source type gpg_err_source_t.
-
-   Where as the Poo out of a welle small
-   Taketh his firste springing and his sours.
-					--Chaucer.  */
+ *
+ * Where as the Poo out of a welle small
+ * Taketh his firste springing and his sours.
+ *					--Chaucer.
+ */
 
 /* Only use free slots, never change or reorder the existing
-   entries.  */
+ * entries.  */
 typedef enum
   {
 @include:err-sources@
@@ -112,7 +114,7 @@ typedef enum
 /* The error code type gpg_err_code_t.  */
 
 /* Only use free slots, never change or reorder the existing
-   entries.  */
+ * entries.  */
 typedef enum
   {
 @include:err-codes@
@@ -127,13 +129,13 @@ typedef enum
 /* The error value type gpg_error_t.  */
 
 /* We would really like to use bit-fields in a struct, but using
-   structs as return values can cause binary compatibility issues, in
-   particular if you want to do it efficiently (also see
-   -freg-struct-return option to GCC).  */
+ * structs as return values can cause binary compatibility issues, in
+ * particular if you want to do it efficiently (also see
+ * -freg-struct-return option to GCC).  */
 typedef unsigned int gpg_error_t;
 
 /* We use the lowest 16 bits of gpg_error_t for error codes.  The 16th
-   bit indicates system errors.  */
+ * bit indicates system errors.  */
 #define GPG_ERR_CODE_MASK	(GPG_ERR_CODE_DIM - 1)
 
 /* Bits 17 to 24 are reserved.  */
@@ -143,11 +145,13 @@ typedef unsigned int gpg_error_t;
 #define GPG_ERR_SOURCE_SHIFT	24
 
 /* The highest bit is reserved.  It shouldn't be used to prevent
-   potential negative numbers when transmitting error values as
-   text.  */
+ * potential negative numbers when transmitting error values as
+ * text.  */
 
 

-/* GCC feature test.  */
+/*
+ * GCC feature test.
+ */
 #if __GNUC__
 # define _GPG_ERR_GCC_VERSION (__GNUC__ * 10000 \
                                + __GNUC_MINOR__ * 100 \
@@ -208,9 +212,9 @@ typedef unsigned int gpg_error_t;
 #endif
 
 /* The used and unused attributes.
-   I am not sure since when the unused attribute is really supported.
-   In any case it it only needed for gcc versions which print a
-   warning.  Thus let us require gcc >= 3.5.  */
+ * I am not sure since when the unused attribute is really supported.
+ * In any case it it only needed for gcc versions which print a
+ * warning.  Thus let us require gcc >= 3.5.  */
 #if _GPG_ERR_GCC_VERSION >= 40000
 # define GPGRT_ATTR_USED  __attribute__ ((used))
 #else
@@ -290,7 +294,9 @@ gpgrt_annotate_leaked_object (const void *p)
 }
 
 

-/* Initialization function.  */
+/*
+ * Initialization function.
+ */
 
 /* Initialize the library.  This function should be run early.  */
 gpg_error_t gpg_err_init (void) _GPG_ERR_CONSTRUCTOR;
@@ -320,10 +326,12 @@ void gpgrt_set_alloc_func  (void *(*f)(void *a, size_t n));
 
 
 

-/* Constructor and accessor functions.  */
+/*
+ * Constructor and accessor functions.
+ */
 
 /* Construct an error value from an error code and source.  Within a
-   subsystem, use gpg_error.  */
+ * subsystem, use gpg_error.  */
 static GPG_ERR_INLINE gpg_error_t
 gpg_err_make (gpg_err_source_t source, gpg_err_code_t code)
 {
@@ -334,7 +342,7 @@ gpg_err_make (gpg_err_source_t source, gpg_err_code_t code)
 
 
 /* The user should define GPG_ERR_SOURCE_DEFAULT before including this
-   file to specify a default source for gpg_error.  */
+ * file to specify a default source for gpg_error.  */
 #ifndef GPG_ERR_SOURCE_DEFAULT
 #define GPG_ERR_SOURCE_DEFAULT	GPG_ERR_SOURCE_UNKNOWN
 #endif
@@ -366,44 +374,44 @@ gpg_err_source (gpg_error_t err)
 /* String functions.  */
 
 /* Return a pointer to a string containing a description of the error
-   code in the error value ERR.  This function is not thread-safe.  */
+ * code in the error value ERR.  This function is not thread-safe.  */
 const char *gpg_strerror (gpg_error_t err);
 
 /* Return the error string for ERR in the user-supplied buffer BUF of
-   size BUFLEN.  This function is, in contrast to gpg_strerror,
-   thread-safe if a thread-safe strerror_r() function is provided by
-   the system.  If the function succeeds, 0 is returned and BUF
-   contains the string describing the error.  If the buffer was not
-   large enough, ERANGE is returned and BUF contains as much of the
-   beginning of the error string as fits into the buffer.  */
+ * size BUFLEN.  This function is, in contrast to gpg_strerror,
+ * thread-safe if a thread-safe strerror_r() function is provided by
+ * the system.  If the function succeeds, 0 is returned and BUF
+ * contains the string describing the error.  If the buffer was not
+ * large enough, ERANGE is returned and BUF contains as much of the
+ * beginning of the error string as fits into the buffer.  */
 int gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);
 
 /* Return a pointer to a string containing a description of the error
-   source in the error value ERR.  */
+ * source in the error value ERR.  */
 const char *gpg_strsource (gpg_error_t err);
 
 

-/* Mapping of system errors (errno).  */
+/*
+ * Mapping of system errors (errno).
+ */
 
 /* Retrieve the error code for the system error ERR.  This returns
-   GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
-   this). */
+ * GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ * this). */
 gpg_err_code_t gpg_err_code_from_errno (int err);
 
-
 /* Retrieve the system error for the error code CODE.  This returns 0
-   if CODE is not a system error code.  */
+ * if CODE is not a system error code.  */
 int gpg_err_code_to_errno (gpg_err_code_t code);
 
-
 /* Retrieve the error code directly from the ERRNO variable.  This
-   returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped
-   (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */
+ * returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped
+ * (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */
 gpg_err_code_t gpg_err_code_from_syserror (void);
 
 
 /* Set the ERRNO variable.  This function is the preferred way to set
-   ERRNO due to peculiarities on WindowsCE.  */
+ * ERRNO due to peculiarities on WindowsCE.  */
 void gpg_err_set_errno (int err);
 
 /* Return or check the version.  Both functions are identical.  */
@@ -1252,7 +1260,9 @@ typedef struct
 
 #endif /* GPGRT_ENABLE_ARGPARSE_MACROS */
 
-
+/* Take care: gpgrt_argparse keeps state in ARG and requires that
+ * either ARGPARSE_FLAG_RESET is used after OPTS has been changed or
+ * gpgrt_argparse (NULL, ARG, NULL) is called first.  */
 int gpgrt_argparse (gpgrt_stream_t fp,
                     gpgrt_argparse_t *arg, gpgrt_opt_t *opts);
 void gpgrt_usage (int level);

commit e901c9fb04f5a96ba2bd49225b396ce7857a3782
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Apr 11 09:10:14 2018 +0200

    core: Finalize the API for argparse.
    
    * src/gpg-error.h.in (ARGPARSE_end): Simplify.
    * src/argparse.c (_gpgrt_argparse_internal_s): Add field opts.
    (deinitialize): Release new field.
    (initialize): Add arg opts and create a copy of the option list.  Add
    the internal options.
    (_gpgrt_argparse): Rename arg opts to opts_orig and set new local var
    opts.  Adjust all references to opts.
    (find_long_option): Adjust for chnaged type of OPTS.  Re-indent.
    (arg_parse): Remove internal option assignment.  Rename arg opts to
    opts_orig and set new local var opts.  Adjust all references to opts.
    (show_help): Adjust all references to opts.
    --
    
    The old ARGPARSE_end maro was a bit cumbersome and does not allow to
    chnage the number of internal options.  Thus this somewhat larger
    chnage to keep the internal options out of the API.
    
    Note that with this change the internal options now also work in a
    option file and not just on the command line; that does not make much
    sense but is probably less surprising.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/argparse.c b/src/argparse.c
index 00ba68c..2dab2ca 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -55,6 +55,7 @@ struct _gpgrt_argparse_internal_s
   void *aliases;
   const void *cur_alias;
   void *iio_list;
+  gpgrt_opt_t **opts;  /* Malloced array of pointer to user provided opts.  */
 };
 
 
@@ -83,9 +84,9 @@ static int (*custom_outfnc) (int, const char *);
 /* Optional handler to map strings.  See _gpgrt_set_fixed_string_mapper.  */
 static const char *(*fixed_string_mapper)(const char*);
 
-static int  set_opt_arg(gpgrt_argparse_t *arg, unsigned flags, char *s);
-static void show_help(gpgrt_opt_t *opts, unsigned flags);
-static void show_version(void);
+static int  set_opt_arg (gpgrt_argparse_t *arg, unsigned int flags, char *s);
+static void show_help (gpgrt_opt_t **opts, unsigned int flags);
+static void show_version (void);
 static int writestrings (int is_error, const char *string,
                          ...) GPGRT_ATTR_SENTINEL(0);
 static int arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts);
@@ -186,8 +187,12 @@ flushstrings (int is_error)
 static void
 deinitialize (gpgrt_argparse_t *arg)
 {
-  xfree (arg->internal);
-  arg->internal = NULL;
+  if (arg->internal)
+    {
+      xfree (arg->internal->opts);
+      xfree (arg->internal);
+      arg->internal = NULL;
+    }
 
   arg->lineno = 0;
   arg->err = 0;
@@ -203,7 +208,7 @@ my_exit (gpgrt_argparse_t *arg, int code)
 
 
 static gpg_err_code_t
-initialize (gpgrt_argparse_t *arg, estream_t fp)
+initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
 {
   if (!arg->internal || (arg->flags & ARGPARSE_FLAG_RESET))
     {
@@ -214,6 +219,9 @@ initialize (gpgrt_argparse_t *arg, estream_t fp)
           if (!arg->internal)
             return _gpg_err_code_from_syserror ();
         }
+      else if (arg->internal->opts)
+        xfree (arg->internal->opts);
+      arg->internal->opts = NULL;
 
       /* Initialize this instance. */
       arg->internal->idx = 0;
@@ -224,6 +232,7 @@ initialize (gpgrt_argparse_t *arg, estream_t fp)
       arg->internal->cur_alias = NULL;
       arg->internal->iio_list = NULL;
 
+      /* Clear the copy of the option list.  */
       /* Clear the error indicator.  */
       arg->err = 0;
 
@@ -243,6 +252,60 @@ initialize (gpgrt_argparse_t *arg, estream_t fp)
 
     }
 
+  /* Create an array with pointers to the provided list of options.
+   * Keeping a copy is useful to sort that array and thus do a binary
+   * search and to allow for extra space at the end to insert the
+   * hidden options.  An ARGPARSE_FLAG_RESET can be used to reinit
+   * this array.  */
+  if (!arg->internal->opts)
+    {
+      static gpgrt_opt_t help_opt
+        = ARGPARSE_s_n (ARGPARSE_SHORTOPT_HELP, "help", "@");
+      static gpgrt_opt_t version_opt
+        = ARGPARSE_s_n (ARGPARSE_SHORTOPT_VERSION, "version", "@");
+      static gpgrt_opt_t warranty_opt
+        = ARGPARSE_s_n (ARGPARSE_SHORTOPT_WARRANTY, "warranty", "@");
+      static gpgrt_opt_t dump_options_opt
+        = ARGPARSE_s_n(ARGPARSE_SHORTOPT_DUMP_OPTIONS, "dump-options", "@");
+      static gpgrt_opt_t end_marker
+        = ARGPARSE_end ();
+      int seen_help = 0;
+      int seen_version = 0;
+      int seen_warranty = 0;
+      int seen_dump_options = 0;
+      int i;
+
+      for (i=0; opts[i].short_opt; i++)
+        {
+          if (opts[i].long_opt)
+            {
+              if (!strcmp(opts[i].long_opt, help_opt.long_opt))
+                seen_help = 1;
+              else if (!strcmp(opts[i].long_opt, version_opt.long_opt))
+                seen_version = 1;
+              else if (!strcmp(opts[i].long_opt, warranty_opt.long_opt))
+                seen_warranty = 1;
+              else if (!strcmp(opts[i].long_opt, dump_options_opt.long_opt))
+                seen_dump_options = 1;
+            }
+        }
+      i += 4; /* The number of the above internal options.  */
+      i++;    /* End of list marker.  */
+      arg->internal->opts = xtrycalloc (i, sizeof *arg->internal->opts);
+      if (!arg->internal->opts)
+        return _gpg_err_code_from_syserror ();
+      for(i=0; opts[i].short_opt; i++)
+        arg->internal->opts[i] = opts + i;
+      if (!seen_help)
+        arg->internal->opts[i++] = &help_opt;
+      if (!seen_version)
+        arg->internal->opts[i++] = &version_opt;
+      if (!seen_warranty)
+        arg->internal->opts[i++] = &warranty_opt;
+      if (!seen_dump_options)
+        arg->internal->opts[i++] = &dump_options_opt;
+      arg->internal->opts[i] = &end_marker;
+    }
 
   if (arg->err)
     {
@@ -453,10 +516,11 @@ ignore_invalid_option_clear (gpgrt_argparse_t *arg)
  * Note: Abbreviation of options is here not allowed.
  */
 int
-_gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
+_gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
 {
+  gpgrt_opt_t **opts;
   int state, i, c;
-  int idx=0;
+  int idx = 0;
   char keyword[100];
   char *buffer = NULL;
   size_t buflen = 0;
@@ -464,18 +528,19 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
   int unread_buf[3];  /* We use an int so that we can store EOF.  */
   int unread_buf_count = 0;
 
-  if (arg && !opts)
+  if (arg && !opts_orig)
     {
       deinitialize (arg);
       return 0;
     }
 
   if (!fp) /* Divert to arg_parse() in this case.  */
-    return arg_parse (arg, opts);
+    return arg_parse (arg, opts_orig);
 
-  if (initialize (arg, fp))
+  if (initialize (arg, opts_orig, fp))
     return (arg->r_opt = ARGPARSE_OUT_OF_CORE);
 
+  opts = arg->internal->opts;
 
   /* If the LINENO is zero we assume that we are at the start of a
    * file and we skip over a possible Byte Order Mark.  */
@@ -507,19 +572,19 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
           else if (state == 2)
             {
               keyword[i] = 0;
-              for (i=0; opts[i].short_opt; i++ )
+              for (i=0; opts[i]->short_opt; i++ )
                 {
-                  if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
+                  if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword))
                     break;
                 }
               idx = i;
-              arg->r_opt = opts[idx].short_opt;
-              if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
+              arg->r_opt = opts[idx]->short_opt;
+              if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE))
                 {
                   state = i = 0;
                   continue;
                 }
-              else if (!opts[idx].short_opt )
+              else if (!opts[idx]->short_opt )
                 {
                   if (!strcmp (keyword, "ignore-invalid-option"))
                     {
@@ -533,13 +598,13 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
                       state = i = 0;
                       continue;
                     }
-                  arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
+                  arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND)
                                 ? ARGPARSE_INVALID_COMMAND
                                 : ARGPARSE_INVALID_OPTION);
                 }
-              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
+              else if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK))
                 arg->r_type = 0; /* Does not take an arg. */
-              else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) )
+              else if ((opts[idx]->flags & ARGPARSE_OPT_OPTIONAL) )
                 arg->r_type = 0; /* Arg is optional.  */
               else
                 arg->r_opt = ARGPARSE_MISSING_ARG;
@@ -551,9 +616,9 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
               /* No argument found.  */
               if (in_alias)
                 arg->r_opt = ARGPARSE_MISSING_ARG;
-              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
+              else if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK))
                 arg->r_type = 0; /* Does not take an arg. */
-              else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL))
+              else if ((opts[idx]->flags & ARGPARSE_OPT_OPTIONAL))
                 arg->r_type = 0; /* No optional argument. */
               else
                 arg->r_opt = ARGPARSE_MISSING_ARG;
@@ -589,7 +654,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
                         }
 		    }
 		}
-              else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
+              else if (!(opts[idx]->flags & ARGPARSE_TYPE_MASK))
                 arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
               else
                 {
@@ -616,7 +681,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
                           if (*p && p[strlen(p)-1] == '\"' )
                             p[strlen(p)-1] = 0;
                         }
-                      if (!set_opt_arg (arg, opts[idx].flags, p))
+                      if (!set_opt_arg (arg, opts[idx]->flags, p))
                         xfree (buffer);
                       else
                         gpgrt_annotate_leaked_object (buffer);
@@ -648,16 +713,16 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
         {
           /* Check keyword.  */
           keyword[i] = 0;
-          for (i=0; opts[i].short_opt; i++ )
-            if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
+          for (i=0; opts[i]->short_opt; i++ )
+            if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword))
               break;
           idx = i;
-          arg->r_opt = opts[idx].short_opt;
-          if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
+          arg->r_opt = opts[idx]->short_opt;
+          if ((opts[idx]->flags & ARGPARSE_OPT_IGNORE))
             {
               state = 1; /* Process like a comment.  */
             }
-          else if (!opts[idx].short_opt)
+          else if (!opts[idx]->short_opt)
             {
               if (!strcmp (keyword, "alias"))
                 {
@@ -678,7 +743,7 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
                 state = 1; /* Process like a comment.  */
               else
                 {
-                  arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
+                  arg->r_opt = ((opts[idx]->flags & ARGPARSE_OPT_COMMAND)
                                 ? ARGPARSE_INVALID_COMMAND
                                 : ARGPARSE_INVALID_OPTION);
                   state = -1; /* Skip rest of line and leave.  */
@@ -759,109 +824,80 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 }
 
 
-
+/* Given the list of options OPTS and a keyword, return the index of
+ * the long option macthing KEYWORD.  On error -1 is retruned for not
+ * found or -2 for ambigious keyword.  */
 static int
-find_long_option (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, const char *keyword)
+find_long_option (gpgrt_argparse_t *arg, gpgrt_opt_t **opts,
+                  const char *keyword)
 {
-    int i;
-    size_t n;
-
-    (void)arg;
-
-    /* Would be better if we can do a binary search, but it is not
-       possible to reorder our option table because we would mess
-       up our help strings - What we can do is: Build a nice option
-       lookup table when this function is first invoked */
-    if( !*keyword )
-	return -1;
-    for(i=0; opts[i].short_opt; i++ )
-	if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
-	    return i;
+  int i;
+  size_t n;
+
+  (void)arg;  /* Not yet required.  */
+
+  /* Would be better if we can do a binary search, but it is not
+   * possible to reorder our option table because we would mess up our
+   * help strings.  What we can do is: Build an option lookup table
+   * when this function is first invoked.  */
+  if (!*keyword)
+    return -1;
+  for (i=0; opts[i]->short_opt; i++ )
+    if (opts[i]->long_opt && !strcmp (opts[i]->long_opt, keyword))
+      return i;
 #if 0
-    {
-	ALIAS_DEF a;
-	/* see whether it is an alias */
-	for( a = args->internal->aliases; a; a = a->next ) {
-	    if( !strcmp( a->name, keyword) ) {
-		/* todo: must parse the alias here */
-		args->internal->cur_alias = a;
-		return -3; /* alias available */
-	    }
-	}
-    }
+  {
+    ALIAS_DEF a;
+    /* see whether it is an alias */
+    for (a = args->internal->aliases; a; a = a->next)
+      {
+        if (!strcmp( a->name, keyword))
+          {
+            /* todo: must parse the alias here */
+            args->internal->cur_alias = a;
+            return -3; /* alias available */
+          }
+      }
+  }
 #endif
-    /* not found, see whether it is an abbreviation */
-    /* aliases may not be abbreviated */
-    n = strlen( keyword );
-    for(i=0; opts[i].short_opt; i++ ) {
-	if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) {
-	    int j;
-	    for(j=i+1; opts[j].short_opt; j++ ) {
-		if( opts[j].long_opt
-		    && !strncmp( opts[j].long_opt, keyword, n )
-                    && !(opts[j].short_opt == opts[i].short_opt
-                         && opts[j].flags == opts[i].flags ) )
-		    return -2;	/* abbreviation is ambiguous */
+  /* Not found.  See whether it is an abbreviation.  Aliases may not
+   * be abbreviated, though. */
+  n = strlen (keyword);
+  for (i=0; opts[i]->short_opt; i++)
+    {
+      if (opts[i]->long_opt && !strncmp (opts[i]->long_opt, keyword, n))
+        {
+          int j;
+          for (j=i+1; opts[j]->short_opt; j++)
+            {
+              if (opts[j]->long_opt
+                  && !strncmp (opts[j]->long_opt, keyword, n)
+                  && !(opts[j]->short_opt == opts[i]->short_opt
+                       && opts[j]->flags == opts[i]->flags ) )
+                return -2;  /* Abbreviation is ambiguous.  */
 	    }
-	    return i;
+          return i;
 	}
     }
-    return -1;  /* Not found.  */
+  return -1;  /* Not found.  */
 }
 
 
+/* The option parser for command line options.  */
 static int
-arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
+arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
 {
   int idx;
+  gpgrt_opt_t **opts;
   int argc;
   char **argv;
   char *s, *s2;
   int i;
 
-  /* Fill in missing standard options: help, version, warranty and
-   * dump-options.  */
-  gpgrt_opt_t help_opt
-    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_HELP, "help", "@");
-  gpgrt_opt_t version_opt
-    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_VERSION, "version", "@");
-  gpgrt_opt_t warranty_opt
-    = ARGPARSE_s_n (ARGPARSE_SHORTOPT_WARRANTY, "warranty", "@");
-  gpgrt_opt_t dump_options_opt
-    = ARGPARSE_s_n(ARGPARSE_SHORTOPT_DUMP_OPTIONS, "dump-options", "@");
-  int seen_help = 0;
-  int seen_version = 0;
-  int seen_warranty = 0;
-  int seen_dump_options = 0;
-
-  i = 0;
-  while (opts[i].short_opt)
-    {
-      if (opts[i].long_opt)
-	{
-	  if (!strcmp(opts[i].long_opt, help_opt.long_opt))
-	    seen_help = 1;
-	  else if (!strcmp(opts[i].long_opt, version_opt.long_opt))
-	    seen_version = 1;
-	  else if (!strcmp(opts[i].long_opt, warranty_opt.long_opt))
-	    seen_warranty = 1;
-	  else if (!strcmp(opts[i].long_opt, dump_options_opt.long_opt))
-	    seen_dump_options = 1;
-	}
-      i++;
-    }
-  if (! seen_help)
-    opts[i++] = help_opt;
-  if (! seen_version)
-    opts[i++] = version_opt;
-  if (! seen_warranty)
-    opts[i++] = warranty_opt;
-  if (! seen_dump_options)
-    opts[i++] = dump_options_opt;
-
-  if (initialize( arg, NULL))
+  if (initialize (arg, opts_orig, NULL))
     return (arg->r_opt = ARGPARSE_OUT_OF_CORE);
 
+  opts = arg->internal->opts;
   argc = *arg->argc;
   argv = *arg->argv;
   idx = arg->internal->idx;
@@ -917,9 +953,9 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
       if ( argpos )
         *argpos = '=';
 
-      if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_HELP)
+      if (i > 0 && opts[i]->short_opt == ARGPARSE_SHORTOPT_HELP)
         show_help (opts, arg->flags);
-      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_VERSION)
+      else if (i > 0 && opts[i]->short_opt == ARGPARSE_SHORTOPT_VERSION)
         {
           if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
             {
@@ -927,17 +963,17 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
               my_exit (arg, 0);
             }
 	}
-      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_WARRANTY)
+      else if (i > 0 && opts[i]->short_opt == ARGPARSE_SHORTOPT_WARRANTY)
         {
           writestrings (0, _gpgrt_strusage (16), "\n", NULL);
           my_exit (arg, 0);
 	}
-      else if (i > 0 && opts[i].short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
+      else if (i > 0 && opts[i]->short_opt == ARGPARSE_SHORTOPT_DUMP_OPTIONS)
         {
-          for (i=0; opts[i].short_opt; i++ )
+          for (i=0; opts[i]->short_opt; i++ )
             {
-              if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
-                writestrings (0, "--", opts[i].long_opt, "\n", NULL);
+              if (opts[i]->long_opt && !(opts[i]->flags & ARGPARSE_OPT_IGNORE))
+                writestrings (0, "--", opts[i]->long_opt, "\n", NULL);
 	    }
           my_exit (arg, 0);
 	}
@@ -950,10 +986,10 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
           arg->r.ret_str = s+2;
 	}
       else
-        arg->r_opt = opts[i].short_opt;
+        arg->r_opt = opts[i]->short_opt;
       if ( i < 0 )
         ;
-      else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
+      else if ( (opts[i]->flags & ARGPARSE_TYPE_MASK) )
         {
           if ( argpos )
             {
@@ -963,7 +999,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 	    }
           else
             s2 = argv[1];
-          if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
+          if ( !s2 && (opts[i]->flags & ARGPARSE_OPT_OPTIONAL) )
             {
               arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional.  */
 	    }
@@ -972,7 +1008,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
               arg->r_opt = ARGPARSE_MISSING_ARG;
 	    }
           else if ( !argpos && *s2 == '-'
-                    && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
+                    && (opts[i]->flags & ARGPARSE_OPT_OPTIONAL) )
             {
               /* The argument is optional and the next seems to be an
                  option.  We do not check this possible option but
@@ -981,7 +1017,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 	    }
           else
             {
-              set_opt_arg (arg, opts[i].flags, s2);
+              set_opt_arg (arg, opts[i]->flags, s2);
               if ( !argpos )
                 {
                   argc--; argv++; idx++; /* Skip one.  */
@@ -1009,8 +1045,8 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 	    arg->internal->inarg++;
 	    if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) )
               {
-                for (i=0; opts[i].short_opt; i++ )
-                  if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1))
+                for (i=0; opts[i]->short_opt; i++ )
+                  if ( opts[i]->long_opt && !strcmp (opts[i]->long_opt, s+1))
                     {
                       dash_kludge = 1;
                       break;
@@ -1021,33 +1057,33 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 
 	if (!dash_kludge )
           {
-	    for (i=0; opts[i].short_opt; i++ )
-              if ( opts[i].short_opt == *s )
+	    for (i=0; opts[i]->short_opt; i++ )
+              if ( opts[i]->short_opt == *s )
                 break;
           }
 
-	if ( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) )
+	if ( !opts[i]->short_opt && ( *s == 'h' || *s == '?' ) )
           show_help (opts, arg->flags);
 
-	arg->r_opt = opts[i].short_opt;
-	if (!opts[i].short_opt )
+	arg->r_opt = opts[i]->short_opt;
+	if (!opts[i]->short_opt )
           {
-	    arg->r_opt = (opts[i].flags & ARGPARSE_OPT_COMMAND)?
+	    arg->r_opt = (opts[i]->flags & ARGPARSE_OPT_COMMAND)?
               ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION;
 	    arg->internal->inarg++; /* Point to the next arg.  */
 	    arg->r.ret_str = s;
           }
-	else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
+	else if ( (opts[i]->flags & ARGPARSE_TYPE_MASK) )
           {
 	    if ( s[1] && !dash_kludge )
               {
 		s2 = s+1;
-		set_opt_arg (arg, opts[i].flags, s2);
+		set_opt_arg (arg, opts[i]->flags, s2);
               }
 	    else
               {
 		s2 = argv[1];
-		if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
+		if ( !s2 && (opts[i]->flags & ARGPARSE_OPT_OPTIONAL) )
                   {
 		    arg->r_type = ARGPARSE_TYPE_NONE;
                   }
@@ -1056,7 +1092,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
 		    arg->r_opt = ARGPARSE_MISSING_ARG;
                   }
 		else if ( *s2 == '-' && s2[1]
-                          && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
+                          && (opts[i]->flags & ARGPARSE_OPT_OPTIONAL) )
                   {
 		    /* The argument is optional and the next seems to
 	               be an option.  We do not check this possible
@@ -1065,7 +1101,7 @@ arg_parse (gpgrt_argparse_t *arg, gpgrt_opt_t *opts)
                   }
 		else
                   {
-		    set_opt_arg (arg, opts[i].flags, s2);
+		    set_opt_arg (arg, opts[i]->flags, s2);
 		    argc--; argv++; idx++; /* Skip one.  */
                   }
               }
@@ -1161,8 +1197,10 @@ set_opt_arg (gpgrt_argparse_t *arg, unsigned flags, char *s)
 }
 
 
+/* Return the length of the option O.  This needs to consider the
+ * description as weel as the option name.  */
 static size_t
-long_opt_strlen( gpgrt_opt_t *o )
+long_opt_strlen (gpgrt_opt_t *o)
 {
   size_t n = strlen (o->long_opt);
 
@@ -1175,8 +1213,8 @@ long_opt_strlen( gpgrt_opt_t *o )
       if ( *s != '=' )
         n++;
       /* For a (mostly) correct length calculation we exclude
-         continuation bytes (10xxxxxx) if we are on a native utf8
-         terminal. */
+       * continuation bytes (10xxxxxx) if we are on a native utf8
+       * terminal. */
       for (; *s && *s != '|'; s++ )
         if ( is_utf8 && (*s&0xc0) != 0x80 )
           n++;
@@ -1197,7 +1235,7 @@ long_opt_strlen( gpgrt_opt_t *o )
  *    bar and the next one as arguments of the long option.
  */
 static void
-show_help (gpgrt_opt_t *opts, unsigned int flags)
+show_help (gpgrt_opt_t **opts, unsigned int flags)
 {
   const char *s;
   char tmp[2];
@@ -1214,27 +1252,27 @@ show_help (gpgrt_opt_t *opts, unsigned int flags)
     }
   s = _gpgrt_strusage(41);
   writestrings (0, s, "\n", NULL);
-  if ( opts[0].description )
+  if ( opts[0]->description )
     {
       /* Auto format the option description.  */
       int i,j, indent;
 
       /* Get max. length of long options.  */
-      for (i=indent=0; opts[i].short_opt; i++ )
+      for (i=indent=0; opts[i]->short_opt; i++ )
         {
-          if ( opts[i].long_opt )
-            if ( !opts[i].description || *opts[i].description != '@' )
-              if ( (j=long_opt_strlen(opts+i)) > indent && j < 35 )
+          if ( opts[i]->long_opt )
+            if ( !opts[i]->description || *opts[i]->description != '@' )
+              if ( (j=long_opt_strlen(opts[i])) > indent && j < 35 )
                 indent = j;
 	}
 
       /* Example: " -v, --verbose   Viele Sachen ausgeben" */
       indent += 10;
-      if ( *opts[0].description != '@' )
+      if ( *opts[0]->description != '@' )
         writestrings (0, "Options:", "\n", NULL);
-      for (i=0; opts[i].short_opt; i++ )
+      for (i=0; opts[i]->short_opt; i++ )
         {
-          s = map_fixed_string (_( opts[i].description ));
+          s = map_fixed_string (_( opts[i]->description ));
           if ( s && *s== '@' && !s[1] ) /* Hide this line.  */
             continue;
           if ( s && *s == '@' )  /* Unindented comment only line.  */
@@ -1258,12 +1296,12 @@ show_help (gpgrt_opt_t *opts, unsigned int flags)
 	    }
 
           j = 3;
-          if ( opts[i].short_opt < 256 )
+          if ( opts[i]->short_opt < 256 )
             {
-              tmp[0] = opts[i].short_opt;
+              tmp[0] = opts[i]->short_opt;
               tmp[1] = 0;
               writestrings (0, " -", tmp, NULL );
-              if ( !opts[i].long_opt )
+              if ( !opts[i]->long_opt )
                 {
                   if (s && *s == '|' )
                     {
@@ -1281,11 +1319,11 @@ show_help (gpgrt_opt_t *opts, unsigned int flags)
 	    }
           else
             writestrings (0, "   ", NULL);
-          if ( opts[i].long_opt )
+          if ( opts[i]->long_opt )
             {
-              tmp[0] = opts[i].short_opt < 256?',':' ';
+              tmp[0] = opts[i]->short_opt < 256?',':' ';
               tmp[1] = 0;
-              j += writestrings (0, tmp, " --", opts[i].long_opt, NULL);
+              j += writestrings (0, tmp, " --", opts[i]->long_opt, NULL);
               if (s && *s == '|' )
                 {
                   if ( *++s != '=' )
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index a36e8b1..f585808 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -1246,14 +1246,10 @@ typedef struct
 #define ARGPARSE_group(s,d) \
      { (s), NULL, 0, (d) }
 
-/* Placeholder options for help, version, warranty and dump-options.
- * See arg_parse().   FIXME: We need to hide this from the API.  */
+/* Mark the end of the list (mandatory).  */
 #define ARGPARSE_end() \
-     { 0, NULL, 0, NULL }, \
-     { 0, NULL, 0, NULL }, \
-     { 0, NULL, 0, NULL }, \
-     { 0, NULL, 0, NULL }, \
      { 0, NULL, 0, NULL }
+
 #endif /* GPGRT_ENABLE_ARGPARSE_MACROS */
 
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS               |   6 +-
 README             |  13 +-
 configure.ac       |   6 +-
 src/argparse.c     | 348 +++++++++++++++++++++++++++++------------------------
 src/gpg-error.h.in | 166 +++++++++++++------------
 5 files changed, 293 insertions(+), 246 deletions(-)


hooks/post-receive
-- 
Error codes used by GnuPG et al.
http://git.gnupg.org




More information about the Gnupg-commits mailing list