[OPT_CL_HELP] = 0
};
-struct opt_context {
- struct opt_precomputed * opts;
- struct opt_precomputed ** shortopt;
- struct opt_item ** hooks;
- int opt_count;
- int hook_count;
- int positional_max;
- int positional_count;
- bool stop_parsing;
-};
-
void opt_failure(const char * mesg, ...) {
va_list args;
va_start(args, mesg);
{
for (int i = 0; i < oc->hook_count; i++) {
struct opt_item *hook = oc->hooks[i];
- if (hook->flags & event)
- hook->u.hook(item, event, value, hook->ptr);
+ if (hook->flags & event) {
+ void *data = (hook->flags & OPT_HOOK_INTERNAL) ? oc : hook->ptr;
+ hook->u.hook(item, event, value, data);
+ }
}
}
(*((int *)item->ptr))++;
break;
case OPT_CL_CALL:
- item->u.call(item, value, item->ptr);
- break;
+ {
+ void *data = (opt->flags & OPT_INTERNAL) ? oc : item->ptr;
+ item->u.call(item, value, data);
+ break;
+ }
case OPT_CL_USER:
{
char * e = NULL;
int opt_parse(const struct opt_section * options, char ** argv) {
struct opt_context * oc = alloca(sizeof(*oc));
memset(oc, 0, sizeof (*oc));
+ oc->options = options;
opt_count_items(oc, options);
oc->opts = alloca(sizeof(*oc->opts) * oc->opt_count);
*
***/
-#define OPT_HELP_OPTION(help) OPT_CALL(0, "help", opt_handle_help, &help, OPT_BEFORE_CONFIG | OPT_NO_VALUE, "\tShow this help")
+#define OPT_HELP_OPTION OPT_CALL(0, "help", opt_handle_help, NULL, OPT_BEFORE_CONFIG | OPT_INTERNAL | OPT_NO_VALUE, "\tShow this help")
#define OPT_HELP(line) { .help = line, .cls = OPT_CL_HELP }
#define OPT_BOOL(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = &target, .help = desc, .flags = fl, .cls = OPT_CL_BOOL, .type = CT_INT }
#define OPT_STRING(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = &target, .help = desc, .flags = fl, .cls = OPT_CL_STATIC, .type = CT_STRING }
#define OPT_CONF_OPTIONS OPT_CONF_CONFIG, OPT_CONF_SET, OPT_CONF_HOOK
#endif
-#define OPT_CONF_CONFIG OPT_CALL('C', "config", opt_handle_config, NULL, OPT_BEFORE_CONFIG | OPT_REQUIRED_VALUE, "<file>\tOverride the default configuration file")
-#define OPT_CONF_SET OPT_CALL('S', "set", opt_handle_set, NULL, OPT_BEFORE_CONFIG | OPT_REQUIRED_VALUE, "<item>\tManual setting of a configuration item")
-#define OPT_CONF_DUMPCONFIG OPT_CALL(0, "dumpconfig", opt_handle_dumpconfig, NULL, OPT_NO_VALUE, "\tDump program configuration")
-#define OPT_CONF_HOOK OPT_HOOK(opt_conf_hook_internal, NULL, OPT_HOOK_BEFORE_VALUE | OPT_HOOK_FINAL)
+#define OPT_CONF_CONFIG OPT_CALL('C', "config", opt_handle_config, NULL, OPT_BEFORE_CONFIG | OPT_INTERNAL | OPT_REQUIRED_VALUE, "<file>\tOverride the default configuration file")
+#define OPT_CONF_SET OPT_CALL('S', "set", opt_handle_set, NULL, OPT_BEFORE_CONFIG | OPT_INTERNAL | OPT_REQUIRED_VALUE, "<item>\tManual setting of a configuration item")
+#define OPT_CONF_DUMPCONFIG OPT_CALL(0, "dumpconfig", opt_handle_dumpconfig, NULL, OPT_INTERNAL | OPT_NO_VALUE, "\tDump program configuration")
+#define OPT_CONF_HOOK OPT_HOOK(opt_conf_hook_internal, NULL, OPT_HOOK_BEFORE_VALUE | OPT_HOOK_FINAL | OPT_HOOK_INTERNAL)
void opt_handle_config(struct opt_item * opt, const char * value, void * data);
void opt_handle_set(struct opt_item * opt, const char * value, void * data);
#define OPT_LAST_ARG 0x40 /** Stop processing argv after this line **/
#define OPT_SINGLE 0x100 /** Argument must appear at most once **/
#define OPT_MULTIPLE 0x200 /** Argument may appear any time; will save all the values into a simple list **/
-#define OPT_SEEN_AS_LONG 0x400 // Used internally
+#define OPT_SEEN_AS_LONG 0x400 // Used internally to signal that we currently process the long form of the option
#define OPT_BEFORE_CONFIG 0x800 /** Argument may appear before config file is loaded **/
+#define OPT_INTERNAL 0x4000 // Used internally to ask for passing of struct opt_context to OPT_CALL
// For hooks, the flags contain a combination of events.
#define OPT_HOOK_BEFORE_ARG 0x1 /** Call before option parsing **/
#define OPT_HOOK_BEFORE_VALUE 0x2 /** Call before value parsing **/
#define OPT_HOOK_AFTER_VALUE 0x4 /** Call after value parsing **/
#define OPT_HOOK_FINAL 0x8 /** Call just before opt_parse() returns **/
+#define OPT_HOOK_INTERNAL 0x4000 // Used internally to ask for passing of struct opt_context
void opt_failure(const char * mesg, ...) FORMAT_CHECK(printf,1,2) NONRET;
void opt_help(const struct opt_section * sec);