Skip to content

Commit 7c1c827

Browse files
committed
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.
1 parent acc4aad commit 7c1c827

8 files changed

+182
-68
lines changed

README.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,15 @@ Download
105105

106106
Version History
107107
---------------
108-
* 2.0.0 (2018-01-21)
108+
* 2.0.0 (2018-01-24)
109109
* Modified the signature for option handlers to accept a pointer to the
110-
matched `dropt_option` entry.
110+
matched `dropt_option` entry. Custom option handlers will need to be
111+
adjusted.
112+
* Added a new field to `dropt_option` to store additional callback data.
113+
This warranted renaming the existing `handler_data` member. Code that
114+
initialized `dropt_option` members by name will need to be adjusted.
115+
* Added a new `dropt_handle_const` handler that uses the new callback data
116+
to store predefined values.
111117
* Reformatted code and comments.
112118
* 1.1.1 (2013-03-17)
113119
* Fixed a build issue with gcc with optimizations enabled.
@@ -132,7 +138,7 @@ Version History
132138
* Made some other minor style adjustments.
133139
* 1.0.4 (2010-09-12)
134140
* The `DROPT_HANDLER_DECL` macro has been replaced with a
135-
`dropt_option_handler_decl` function `typedef`. I apologize for breaking
141+
`dropt_option_handler_decl` `typedef`. I apologize for breaking
136142
compatibility in a minor version update, but in this case the breakage
137143
should be minor, and it should be trivial to fix sites that used the old
138144
macro:

dropt_example.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,10 @@ static dropt_error
139139
handle_face(dropt_context* context,
140140
const dropt_option* option,
141141
const char* optionArgument,
142-
void* handlerData)
142+
void* dest)
143143
{
144144
dropt_error err = dropt_error_none;
145-
face_type* face = handlerData;
145+
face_type* face = dest;
146146
assert(face != NULL);
147147

148148
/* Option handlers should handle `optionArgument` being `NULL` (if the

droptxx_example.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ main(int argc, char** argv)
5454
opt.short_name = 'h';
5555
opt.long_name = "help";
5656
opt.handler = dropt::handle_bool;
57-
opt.handler_data = &showHelp;
57+
opt.dest = &showHelp;
5858
opt.attr = dropt_attr_halt;
5959
options.push_back(opt);
6060

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

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

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

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

167167
/* Option handlers should handle `optionArgument` being null (if the

include/dropt.h

+19-7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434
#include <stdio.h>
3535
#include <wchar.h>
3636

37+
#if __STDC_VERSION__ >= 199901L
38+
#include <stdint.h>
39+
typedef uintptr_t dropt_uintptr;
40+
#else
41+
typedef size_t dropt_uintptr;
42+
#endif
43+
44+
3745
#ifdef __cplusplus
3846
extern "C" {
3947
#endif
@@ -109,13 +117,13 @@ typedef struct dropt_option dropt_option;
109117
* handler, again with no argument. Handlers should be aware of this if they
110118
* have side-effects.
111119
*
112-
* `handlerData` is the client-specified value specified in the `dropt_option`
113-
* table.
120+
* `dest` is the client-specified pointer to a variable for the handler to
121+
* modify.
114122
*/
115123
typedef dropt_error dropt_option_handler_decl(dropt_context* context,
116124
const dropt_option* option,
117125
const dropt_char* optionArgument,
118-
void* handlerData);
126+
void* dest);
119127
typedef dropt_option_handler_decl* dropt_option_handler_func;
120128

121129
/** `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,
157165
* The handler callback and data invoked in response to encountering the
158166
* option.
159167
*
160-
* handler_data:
161-
* Callback data for the handler. For typical handlers, this is usually
162-
* the address of a variable for the handler to modify.
168+
* dest:
169+
* The address of a variable for the handler to modify, if necessary.
163170
*
164171
* attr:
165172
* Miscellaneous attributes. See below.
173+
*
174+
* extra_data:
175+
* Additional callback data for the handler.
166176
*/
167177
struct dropt_option
168178
{
@@ -171,8 +181,9 @@ struct dropt_option
171181
const dropt_char* description;
172182
const dropt_char* arg_description;
173183
dropt_option_handler_func handler;
174-
void* handler_data;
184+
void* dest;
175185
unsigned int attr;
186+
dropt_uintptr extra_data;
176187
};
177188

178189

@@ -249,6 +260,7 @@ dropt_option_handler_decl dropt_handle_int;
249260
dropt_option_handler_decl dropt_handle_uint;
250261
dropt_option_handler_decl dropt_handle_double;
251262
dropt_option_handler_decl dropt_handle_string;
263+
dropt_option_handler_decl dropt_handle_const;
252264

253265
#define DROPT_MISUSE(message) dropt_misuse(message, __FILE__, __LINE__)
254266
void dropt_misuse(const char* message, const char* filename, int line);

src/dropt.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,9 @@ is_valid_option(const dropt_option* option)
417417
&& option->description == NULL
418418
&& option->arg_description == NULL
419419
&& option->handler == NULL
420-
&& option->handler_data == NULL
421-
&& option->attr == 0);
420+
&& option->dest == NULL
421+
&& option->attr == 0
422+
&& option->extra_data == 0);
422423
}
423424

424425

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

986987
return option->handler(context, option, optionArgument,
987-
option->handler_data);
988+
option->dest);
988989
}
989990

990991

0 commit comments

Comments
 (0)