Permalink
Browse files

Add a new field to dropt_option to store additional callback data

Add a new field to dropt_option to store additional callback data.
This can be used to allow option handlers to store predefined values
to option variables (i.e., to offer functionality equivalent to
store_const from Python's argparse module).

Unfortunately, this warranted renaming the existing handler_data
member, so this might require adjusting any existing code that
initialized dropt_option members by name.  Since I'm already breaking
API compatibility for 2.0, I might as well do this now.

Since C does not guarantee that integers may be converted to pointers
and back, for maximum flexibility, the new member should be a
uintptr_t instead of a void*.  However, for compatibility with C89,
we can't use uintptr_t directly and must fall back to size_t.  Alas.
  • Loading branch information...
jamesderlin committed Jan 24, 2018
1 parent acc4aad commit 7c1c82754a857120ee0744682644eee455fd20e0
Showing with 182 additions and 68 deletions.
  1. +9 −3 README.md
  2. +2 −2 dropt_example.c
  3. +6 −6 droptxx_example.cpp
  4. +19 −7 include/dropt.h
  5. +4 −3 src/dropt.c
  6. +85 −25 src/dropt_handlers.c
  7. +15 −15 src/droptxx.cpp
  8. +42 −7 src/test_dropt.c
@@ -105,9 +105,15 @@ Download

Version History
---------------
* 2.0.0 (2018-01-21)
* 2.0.0 (2018-01-24)
* Modified the signature for option handlers to accept a pointer to the
matched `dropt_option` entry.
matched `dropt_option` entry. Custom option handlers will need to be
adjusted.
* Added a new field to `dropt_option` to store additional callback data.
This warranted renaming the existing `handler_data` member. Code that
initialized `dropt_option` members by name will need to be adjusted.
* Added a new `dropt_handle_const` handler that uses the new callback data
to store predefined values.
* Reformatted code and comments.
* 1.1.1 (2013-03-17)
* Fixed a build issue with gcc with optimizations enabled.
@@ -132,7 +138,7 @@ Version History
* Made some other minor style adjustments.
* 1.0.4 (2010-09-12)
* The `DROPT_HANDLER_DECL` macro has been replaced with a
`dropt_option_handler_decl` function `typedef`. I apologize for breaking
`dropt_option_handler_decl` `typedef`. I apologize for breaking
compatibility in a minor version update, but in this case the breakage
should be minor, and it should be trivial to fix sites that used the old
macro:
@@ -139,10 +139,10 @@ static dropt_error
handle_face(dropt_context* context,
const dropt_option* option,
const char* optionArgument,
void* handlerData)
void* dest)
{
dropt_error err = dropt_error_none;
face_type* face = handlerData;
face_type* face = dest;
assert(face != NULL);

/* Option handlers should handle `optionArgument` being `NULL` (if the
@@ -54,7 +54,7 @@ main(int argc, char** argv)
opt.short_name = 'h';
opt.long_name = "help";
opt.handler = dropt::handle_bool;
opt.handler_data = &showHelp;
opt.dest = &showHelp;
opt.attr = dropt_attr_halt;
options.push_back(opt);

@@ -67,7 +67,7 @@ main(int argc, char** argv)
opt.long_name = "version";
opt.description = "Shows version information.";
opt.handler = dropt::handle_bool;
opt.handler_data = &showVersion;
opt.dest = &showVersion;
opt.attr = dropt_attr_halt;
options.push_back(opt);

@@ -77,7 +77,7 @@ main(int argc, char** argv)
opt.description = "Sample integer option.";
opt.arg_description = "value";
opt.handler = dropt::handle_int;
opt.handler_data = &i;
opt.dest = &i;
options.push_back(opt);

opt = emptyOpt;
@@ -86,7 +86,7 @@ main(int argc, char** argv)
opt.description = "Sample custom option.";
opt.arg_description = "{heads, tails}";
opt.handler = handle_face;
opt.handler_data = &face;
opt.dest = &face;
options.push_back(opt);

// Required sentinel value.
@@ -158,10 +158,10 @@ static dropt_error
handle_face(dropt_context* context,
const dropt_option* option,
const char* optionArgument,
void* handlerData)
void* dest)
{
dropt_error err = dropt_error_none;
face_type* face = static_cast<face_type*>(handlerData);
face_type* face = static_cast<face_type*>(dest);
assert(face != NULL);

/* Option handlers should handle `optionArgument` being null (if the
@@ -34,6 +34,14 @@
#include <stdio.h>
#include <wchar.h>

#if __STDC_VERSION__ >= 199901L
#include <stdint.h>
typedef uintptr_t dropt_uintptr;
#else
typedef size_t dropt_uintptr;
#endif


#ifdef __cplusplus
extern "C" {
#endif
@@ -109,13 +117,13 @@ typedef struct dropt_option dropt_option;
* handler, again with no argument. Handlers should be aware of this if they
* have side-effects.
*
* `handlerData` is the client-specified value specified in the `dropt_option`
* table.
* `dest` is the client-specified pointer to a variable for the handler to
* modify.
*/
typedef dropt_error dropt_option_handler_decl(dropt_context* context,
const dropt_option* option,
const dropt_char* optionArgument,
void* handlerData);
void* dest);
typedef dropt_option_handler_decl* dropt_option_handler_func;

/** `dropt_error_handler_func` callbacks are responsible for generating error
@@ -157,12 +165,14 @@ typedef int (*dropt_strncmp_func)(const dropt_char* s, const dropt_char* t,
* The handler callback and data invoked in response to encountering the
* option.
*
* handler_data:
* Callback data for the handler. For typical handlers, this is usually
* the address of a variable for the handler to modify.
* dest:
* The address of a variable for the handler to modify, if necessary.
*
* attr:
* Miscellaneous attributes. See below.
*
* extra_data:
* Additional callback data for the handler.
*/
struct dropt_option
{
@@ -171,8 +181,9 @@ struct dropt_option
const dropt_char* description;
const dropt_char* arg_description;
dropt_option_handler_func handler;
void* handler_data;
void* dest;
unsigned int attr;
dropt_uintptr extra_data;
};


@@ -249,6 +260,7 @@ dropt_option_handler_decl dropt_handle_int;
dropt_option_handler_decl dropt_handle_uint;
dropt_option_handler_decl dropt_handle_double;
dropt_option_handler_decl dropt_handle_string;
dropt_option_handler_decl dropt_handle_const;

#define DROPT_MISUSE(message) dropt_misuse(message, __FILE__, __LINE__)
void dropt_misuse(const char* message, const char* filename, int line);
@@ -417,8 +417,9 @@ is_valid_option(const dropt_option* option)
&& option->description == NULL
&& option->arg_description == NULL
&& option->handler == NULL
&& option->handler_data == NULL
&& option->attr == 0);
&& option->dest == NULL
&& option->attr == 0
&& option->extra_data == 0);
}


@@ -984,7 +985,7 @@ set_option_value(dropt_context* context,
}

return option->handler(context, option, optionArgument,
option->handler_data);
option->dest);
}


Oops, something went wrong.

0 comments on commit 7c1c827

Please sign in to comment.