From: Pavel Charvat Date: Tue, 14 Jan 2014 21:15:21 +0000 (+0100) Subject: Opt: Merged fixes from Gigamail. X-Git-Tag: v5.99~25^2~29 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=b1f7cfb12a103c904184af46008f1b147498c174;p=libucw.git Opt: Merged fixes from Gigamail. --- diff --git a/ucw/opt-test.c b/ucw/opt-test.c index 7de4767c..0d5337df 100644 --- a/ucw/opt-test.c +++ b/ucw/opt-test.c @@ -123,7 +123,7 @@ static struct opt_section help = { OPT_HELP("At least one kind of tea must be specified."), OPT_HELP(""), OPT_HELP("Options:"), - OPT_HELP_OPTION, + OPT_HELP_OPTION(help), OPT_CALL('V', "version", show_version, NULL, OPT_NO_VALUE, "\tShow the version"), OPT_HELP(""), OPT_BOOL('e', "english-style", english, 0, "\tEnglish style (with milk)"), diff --git a/ucw/opt.c b/ucw/opt.c index 0c420194..39b5b69a 100644 --- a/ucw/opt.c +++ b/ucw/opt.c @@ -18,9 +18,25 @@ #include #include -// FIXME: Do we need these? -int opt_parsed_count = 0; -int opt_conf_parsed_count = 0; +/*** + * Value flags defaults + * ~~~~~~~~~~~~~~~~~~~~ + * + * OPT_NO_VALUE for OPT_BOOL, OPT_SWITCH and OPT_INC + * OPT_MAYBE_VALUE for OPT_STRING, OPT_UNS, OPT_INT + * Some of the value flags (OPT_NO_VALUE, OPT_MAYBE_VALUE, OPT_REQUIRED_VALUE) + * must be specified for OPT_CALL and OPT_USER. + ***/ +static uns opt_default_value_flags[] = { + [OPT_CL_BOOL] = OPT_NO_VALUE, + [OPT_CL_STATIC] = OPT_MAYBE_VALUE, + [OPT_CL_SWITCH] = OPT_NO_VALUE, + [OPT_CL_INC] = OPT_NO_VALUE, + [OPT_CL_CALL] = 0, + [OPT_CL_USER] = 0, + [OPT_CL_SECTION] = 0, + [OPT_CL_HELP] = 0 +}; struct opt_precomputed { struct opt_item * item; @@ -70,11 +86,10 @@ static void opt_failure(const char * mesg, ...) { else if (!(flags & OPT_VALUE_FLAGS)) /* FIXME: Streamline the conditions */ \ flags |= opt_default_value_flags[item->cls]; \ } while (0) + // FIXME: Is this still useful? Isn't it better to use OPT_ADD_DEFAULT_ITEM_FLAGS during init? #define OPT_ITEM_FLAGS(item) ((item->flags & OPT_VALUE_FLAGS) ? item->flags : item->flags | opt_default_value_flags[item->cls]) -const struct opt_section * opt_section_root; - #define FOREACHLINE(text) for (const char * begin = (text), * end = (text); (*end) && (end = strchrnul(begin, '\n')); begin = end+1) static inline uns uns_min(uns x, uns y) @@ -82,7 +97,7 @@ static inline uns uns_min(uns x, uns y) return MIN(x, y); } -void opt_help_internal(const struct opt_section * help) { +void opt_help(const struct opt_section * help) { int sections_cnt = 0; int lines_cnt = 0; @@ -179,7 +194,7 @@ void opt_help_internal(const struct opt_section * help) { #define LASTFIELD(k) uns_min(strchrnul(lines[i][k], '\t') - lines[i][k], strchrnul(lines[i][k], '\n') - lines[i][k]), lines[i][k] for (int i=0;ihooks_after_value_count;i++) oc->hooks_after_value[i]->u.call(item, value, oc->hooks_after_value[i]->ptr); @@ -547,7 +561,10 @@ void opt_parse(const struct opt_section * options, char ** argv) { continue; if (!oc->shortopt[i]->count && (oc->shortopt[i]->flags & OPT_REQUIRED)) if (i < 256) - opt_failure("Required option -%c not found.", oc->shortopt[i]->item->letter); + if (oc->shortopt[i]->item->name) + opt_failure("Required option -%c/--%s not found.", oc->shortopt[i]->item->letter, oc->shortopt[i]->item->name); + else + opt_failure("Required option -%c not found.", oc->shortopt[i]->item->letter); else opt_failure("Required positional argument #%d not found.", (i > 256) ? oc->shortopt[i]->item->letter-256 : oc->positional_max+1); } @@ -588,8 +605,6 @@ void opt_conf_internal(struct opt_item * opt, const char * value, void * data UN break; #endif } - - opt_conf_parsed_count++; } void opt_conf_hook_internal(struct opt_item * opt, const char * value UNUSED, void * data UNUSED) { diff --git a/ucw/opt.h b/ucw/opt.h index 54bcde42..9328caea 100644 --- a/ucw/opt.h +++ b/ucw/opt.h @@ -19,10 +19,8 @@ #ifdef CONFIG_UCW_CLEAN_ABI #define opt_conf_hook_internal ucw_opt_conf_hook_internal #define opt_conf_internal ucw_opt_conf_internal -#define opt_conf_parsed_count ucw_opt_conf_parsed_count #define opt_help_internal ucw_opt_help_internal #define opt_parse ucw_opt_parse -#define opt_parsed_count ucw_opt_parsed_count #define opt_section_root ucw_opt_section_root #endif @@ -91,7 +89,7 @@ struct opt_section { * ***/ -#define OPT_HELP_OPTION OPT_CALL(0, "help", opt_show_help_internal, NULL, OPT_NO_VALUE, "Show this help") +#define OPT_HELP_OPTION(help) OPT_CALL(0, "help", opt_show_help_internal, &help, OPT_NO_VALUE, "Show 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 } @@ -133,9 +131,6 @@ struct opt_section { void opt_conf_internal(struct opt_item * opt, const char * value, void * data); void opt_conf_hook_internal(struct opt_item * opt, const char * value, void * data); -extern int opt_parsed_count; /** How many opts have been already parsed. **/ -extern int opt_conf_parsed_count; - /*** * Predefined shortopt arguments * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -174,41 +169,15 @@ extern int opt_conf_parsed_count; #define OPT_HOOK_BEFORE_VALUE 0x2000 /** Call before value parsing **/ #define OPT_HOOK_AFTER_VALUE 0x4000 /** Call after value parsing **/ - -/*** - * Value flags defaults - * ~~~~~~~~~~~~~~~~~~~~ - * - * OPT_NO_VALUE for OPT_BOOL, OPT_SWITCH and OPT_INC - * OPT_MAYBE_VALUE for OPT_STRING, OPT_UNS, OPT_INT - * Some of the value flags (OPT_NO_VALUE, OPT_MAYBE_VALUE, OPT_REQUIRED_VALUE) - * must be specified for OPT_CALL and OPT_USER. - ***/ - -static uns opt_default_value_flags[] = { - [OPT_CL_BOOL] = OPT_NO_VALUE, - [OPT_CL_STATIC] = OPT_MAYBE_VALUE, - [OPT_CL_SWITCH] = OPT_NO_VALUE, - [OPT_CL_INC] = OPT_NO_VALUE, - [OPT_CL_CALL] = 0, - [OPT_CL_USER] = 0, - [OPT_CL_SECTION] = 0, - [OPT_CL_HELP] = 0 -}; - extern const struct opt_section * opt_section_root; -void opt_help_internal(const struct opt_section * help); - -static void opt_help(void) { - opt_help_internal(opt_section_root); -} +void opt_help(const struct opt_section * help); -static void opt_usage(void) { +static inline void opt_usage(void) { fprintf(stderr, "Run with argument --help for more information.\n"); } -static void opt_show_help_internal(struct opt_item * opt UNUSED, const char * value UNUSED, void * data UNUSED) { - opt_help(); +static inline void opt_show_help_internal(struct opt_item * opt UNUSED, const char * value UNUSED, void * data) { + opt_help(data); exit(0); }