]> mj.ucw.cz Git - libucw.git/commitdiff
Opt: Merged fixes from Gigamail.
authorPavel Charvat <pchar@ucw.cz>
Tue, 14 Jan 2014 21:15:21 +0000 (22:15 +0100)
committerPavel Charvat <pchar@ucw.cz>
Tue, 14 Jan 2014 21:15:21 +0000 (22:15 +0100)
ucw/opt-test.c
ucw/opt.c
ucw/opt.h

index 7de4767c9594a08df3eaaa9919d006d4074d91cc..0d5337df173f283aa438dab76d848131092db590 100644 (file)
@@ -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)"),
index 0c420194ba24297105fcb6c0aeecabadef180eb8..39b5b69a71cd09a503c3968a74a02988cfe257cb 100644 (file)
--- a/ucw/opt.c
+++ b/ucw/opt.c
 #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;
@@ -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;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)
@@ -192,7 +207,7 @@ void opt_help_internal(const struct opt_section * help) {
       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++;
   }
 }
@@ -346,7 +361,6 @@ static void opt_parse_value(struct opt_context * oc, struct opt_precomputed * op
     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);
@@ -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) {
index 54bcde42e1738bddb6852ec0199cc9f84ad12057..9328caeaccde081fd669349bb1f9c7201ac15742 100644 (file)
--- a/ucw/opt.h
+++ b/ucw/opt.h
 #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);
 }