]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/opt.h
Extended types: Cleaned up unit name parsing
[libucw.git] / ucw / opt.h
index 5eae050eb68938f624a484fdec60ad7b7e6bb1f4..20df7fd7b340d5277c4e34ed175d2b39988c8b36 100644 (file)
--- a/ucw/opt.h
+++ b/ucw/opt.h
@@ -63,6 +63,8 @@
  *   contents of another list of options.
  * - `OPT_CL_HELP`: no option, just print a help text.
  * - `OPT_CL_HOOK`: no option, but a definition of a <<hooks,hook>>.
+ * - `OPT_CL_BREAK`: when a given option occurs, stop parsing and keep
+ *   the option in the argument list.
  ***/
 
 enum opt_class {
@@ -76,6 +78,7 @@ enum opt_class {
   OPT_CL_SECTION,
   OPT_CL_HELP,
   OPT_CL_HOOK,
+  OPT_CL_BREAK,
 };
 
 /***
@@ -92,7 +95,7 @@ enum opt_class {
 
 /** A section of option list. **/
 struct opt_section {
-  struct opt_item * opt;
+  const struct opt_item * opt;
 };
 
 /** A definition of a single option item. **/
@@ -100,12 +103,12 @@ struct opt_item {
   const char * name;                   // long name (NULL if none)
   int letter;                          // short name (0 if none)
   void * ptr;                          // variable to store the value to
-  const char * help;                   // description in --help
+  const char * help;                   // description in --help (NULL to omit the option from the help)
   union opt_union {
-    struct opt_section * section;      // subsection for OPT_CL_SECTION
+    const struct opt_section * section;        // subsection for OPT_CL_SECTION
     int value;                         // value for OPT_CL_SWITCH
-    void (* call)(struct opt_item * opt, const char * value, void * data);             // function to call for OPT_CL_CALL
-    void (* hook)(struct opt_item * opt, uns event, const char * value, void * data);  // function to call for OPT_CL_HOOK
+    void (* call)(const struct opt_item * opt, const char * value, void * data);               // function to call for OPT_CL_CALL
+    void (* hook)(const struct opt_item * opt, uint event, const char * value, void * data);   // function to call for OPT_CL_HOOK
     struct cf_user_type * utype;       // specification of the user-defined type for CT_USER
   } u;
   u16 flags;                           // as defined below (for hooks, event mask is stored instead)
@@ -126,12 +129,12 @@ struct opt_item {
 #define OPT_NO_VALUE       0x4         /** The option must have no value. **/
 #define OPT_MAYBE_VALUE            0x8         /** The option may have a value. **/
 #define OPT_NEGATIVE       0x10        /** Reversing the effect of OPT_INC or saving @false into OPT_BOOL. **/
-#define OPT_NO_HELP        0x20        /** Exclude this option from the help. **/
 #define OPT_LAST_ARG       0x40        /** Stop processing arguments after this line. **/
 #define OPT_SINGLE         0x100       /** The option must appear at most once. **/
 #define OPT_MULTIPLE       0x200       /** The option may appear multiple times; will save all the values into a simple list. **/
 #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      /** The option may appear before a config file is loaded. **/
+#define OPT_HELP_COL        0x1000     /** Used for OPT_CL_HELP to signal that tabs switch columns. **/
 #define OPT_INTERNAL        0x4000     // Used internally to ask for passing of struct opt_context to OPT_CALL
 
 /**
@@ -159,6 +162,9 @@ struct opt_item {
 /** No option, just a piece of help text. **/
 #define OPT_HELP(line) { .help = line, .cls = OPT_CL_HELP }
 
+/** Like OPT_HELP, but the help text uses tab characters to switch columns like help text for ordinary options does. **/
+#define OPT_HELP_COLUMNS(line) { .help = line, .flags = OPT_HELP_COL, .cls = OPT_CL_HELP }
+
 /** Standard `--help` option. **/
 #define OPT_HELP_OPTION OPT_CALL(0, "help", opt_handle_help, NULL, OPT_BEFORE_CONFIG | OPT_INTERNAL | OPT_NO_VALUE, "\tShow this help")
 
@@ -183,8 +189,8 @@ struct opt_item {
 /** IP address option, currently IPv4 only. @target should be a variable of type `u32`. **/
 #define OPT_IP(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = CHECK_PTR_TYPE(&target, u32 *), .help = desc, .flags = fl, .cls = OPT_CL_STATIC, .type = CT_IP }
 
-/** Multi-valued string option. @target should be a growing array of `int`s. **/
-#define OPT_BOOL_MULTIPLE(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = CHECK_PTR_TYPE(&target, char ***), .help = desc, .flags = fl, .cls = OPT_CL_MULTIPLE, .type = CT_STRING }
+/** Multi-valued string option. @target should be a growing array of `char *`s. **/
+#define OPT_STRING_MULTIPLE(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = CHECK_PTR_TYPE(&target, char ***), .help = desc, .flags = fl, .cls = OPT_CL_MULTIPLE, .type = CT_STRING }
 
 /** Multi-valued integer option. @target should be a growing array of `int`s. **/
 #define OPT_INT_MULTIPLE(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = CHECK_PTR_TYPE(&target, int **), .help = desc, .flags = fl, .cls = OPT_CL_MULTIPLE, .type = CT_INT }
@@ -207,6 +213,14 @@ struct opt_item {
 /** Incrementing option. @target should be a variable of type `int`. **/
 #define OPT_INC(shortopt, longopt, target, fl, desc) { .letter = shortopt, .name = longopt, .ptr = CHECK_PTR_TYPE(&target, int *), .flags = fl, .help = desc, .cls = OPT_CL_INC, .type = CT_INT }
 
+/** Breakpoint option. When this option occurs, parsing is terminated and the option is kept in the argument array. **/
+#define OPT_BREAK(shortopt, longopt, fl) { .letter = shortopt, .name = longopt, .flags = fl, .cls = OPT_CL_BREAK }
+
+/* FIXME: Backwards compatibility only, should not be used anymore. */
+#define OPT_UNS OPT_UINT
+#define OPT_UNS_MULTIPLE OPT_UINT_MULTIPLE
+
+
 /**
  * When this option appears, call the function @fn with parameters @item, @value, @data,
  * where @item points to the <<struct_opt_item,`struct opt_item`>> of this option,
@@ -294,7 +308,7 @@ int opt_parse(const struct opt_section * options, char ** argv);
 void opt_failure(const char * mesg, ...) FORMAT_CHECK(printf,1,2) NONRET;
 
 void opt_help(const struct opt_section * sec);
-void opt_handle_help(struct opt_item * opt, const char * value, void * data);
+void opt_handle_help(const struct opt_item * opt, const char * value, void * data);
 
 /***
  * [[conf]]
@@ -343,10 +357,10 @@ void opt_handle_help(struct opt_item * opt, const char * value, void * data);
 #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);
-void opt_handle_dumpconfig(struct opt_item * opt, const char * value, void * data);
-void opt_conf_hook_internal(struct opt_item * opt, uns event, const char * value, void * data);
+void opt_handle_config(const struct opt_item * opt, const char * value, void * data);
+void opt_handle_set(const struct opt_item * opt, const char * value, void * data);
+void opt_handle_dumpconfig(const struct opt_item * opt, const char * value, void * data);
+void opt_conf_hook_internal(const struct opt_item * opt, uint event, const char * value, void * data);
 
 // XXX: This is duplicated with <ucw/getopt.h>, but that one will hopefully go away one day.
 /**