]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
include/optutils: add err_exclusive_options()
authorKarel Zak <kzak@redhat.com>
Thu, 26 Jul 2012 07:04:55 +0000 (09:04 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 26 Jul 2012 07:22:35 +0000 (09:22 +0200)
This is improved implementation of exclusive_option(). The new
implementation:

  - uses regular struct option to compose error messages
  - relationships between options are described in one const static array
  - the current status is stored in one int array

Signed-off-by: Karel Zak <kzak@redhat.com>
include/optutils.h

index fae28fd0d12ea01017777a3fab006d753374bf6a..7819ab360d8a6461eee8bd28502dbf10caf9f7d4 100644 (file)
@@ -17,6 +17,8 @@ static inline const char *option_to_longopt(int c, const struct option *opts)
 #ifndef OPTUTILS_EXIT_CODE
 # define OPTUTILS_EXIT_CODE EXIT_FAILURE
 #endif
+
+/* deprecated */
 static inline void exclusive_option(int *what, const int how,
                                    const char *errmesg)
 {
@@ -30,5 +32,78 @@ static inline void exclusive_option(int *what, const int how,
             _("options %s are mutually exclusive"), errmesg);
 }
 
+/*
+ * Check collisions between options.
+ *
+ * The conflicts between options are described in ul_excl_t array. The
+ * array contains groups of mutually exclusive options. For example
+ *
+ *     static const ul_excl_t excl[] = {
+ *             { 'Z','b','c' },                // first group
+ *             { 'b','x' },                    // second group
+ *             { 0 }
+ *     };
+ *
+ *     int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
+ *
+ *     while ((c = getopt_long(argc, argv, "Zbcx", longopts, NULL)) != -1) {
+ *
+ *             err_exclusive_options(c, longopts, excl, excl_st);
+ *
+ *             switch (c) {
+ *             case 'Z':
+ *                ....
+ *             }
+ *     }
+ *
+ * The array excl[] defines two groups of the mutually exclusive options. The
+ * option '-b' is in the both groups.
+ *
+ * Note that the options in the group have to be in ASCII order (ABC..abc..) and
+ * groups have to be also in ASCII order.
+ *
+ * The current status of options is stored in excl_st array. The size of the array
+ * must be the same as number of the groups in the ul_excl_t array.
+ *
+ * If you're unsure then see sys-utils/mount.c or misc-utils/findmnt.c.
+ */
+#define UL_EXCL_STATUS_INIT    { 0 }
+typedef int ul_excl_t[16];
+
+static inline void err_exclusive_options(
+                       int c,
+                       const struct option *opts,
+                       const ul_excl_t *excl,
+                       int *status)
+{
+       int e;
+
+       for (e = 0; excl[e][0] && excl[e][0] <= c; e++) {
+               const int *op = excl[e];
+
+               for (; *op && *op <= c; op++) {
+                       if (*op != c)
+                               continue;
+                       if (status[e] == 0)
+                               status[e] = c;
+                       else if (status[e] != c) {
+                               fprintf(stderr, _("%s: options "),
+                                               program_invocation_short_name);
+                               for (op = excl[e]; *op; op++) {
+                                       if (opts)
+                                               fprintf(stderr, "--%s ",
+                                                       option_to_longopt(*op, opts));
+                                       else
+                                               fprintf(stderr, "-%c ", *op);
+                               }
+                               fprintf(stderr, _("are mutually exclusive."));
+                               fputc('\n', stderr);
+                               exit(OPTUTILS_EXIT_CODE);
+                       }
+                       break;
+               }
+       }
+}
+
 #endif