#include <alloca.h>
#include <math.h>
-// 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;
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)
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;
#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;i<line;i++) {
while (s < sections_cnt && sections[s].pos == i) {
- opt_help_internal(sections[s].sect);
+ opt_help(sections[s].sect);
s++;
}
if (lines[i][0] == NULL)
printf("%-*.*s %-*.*s %.*s\n", FIELD(0), FIELD(1), LASTFIELD(2));
}
while (s < sections_cnt && sections[s].pos == line) {
- opt_help_internal(sections[s].sect);
+ opt_help(sections[s].sect);
s++;
}
}
default:
ASSERT(0);
}
- opt_parsed_count++;
for (int i=0;i<oc->hooks_after_value_count;i++)
oc->hooks_after_value[i]->u.call(item, value, oc->hooks_after_value[i]->ptr);
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);
}
break;
#endif
}
-
- opt_conf_parsed_count++;
}
void opt_conf_hook_internal(struct opt_item * opt, const char * value UNUSED, void * data UNUSED) {
#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
*
***/
-#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 }
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
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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);
}