]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/optutils.h
setterm: disallow "default" for --ulcolor/--hbcolor
[thirdparty/util-linux.git] / include / optutils.h
1 #ifndef UTIL_LINUX_OPTUTILS_H
2 #define UTIL_LINUX_OPTUTILS_H
3
4 #include <assert.h>
5
6 #include "c.h"
7 #include "nls.h"
8 #include "cctype.h"
9
10 static inline const char *option_to_longopt(int c, const struct option *opts)
11 {
12 const struct option *o;
13
14 assert(!(opts == NULL));
15 for (o = opts; o->name; o++)
16 if (o->val == c)
17 return o->name;
18 return NULL;
19 }
20
21 #ifndef OPTUTILS_EXIT_CODE
22 # define OPTUTILS_EXIT_CODE EXIT_FAILURE
23 #endif
24
25 /*
26 * Check collisions between options.
27 *
28 * The conflicts between options are described in ul_excl_t array. The
29 * array contains groups of mutually exclusive options. For example
30 *
31 * static const ul_excl_t excl[] = {
32 * { 'Z','b','c' }, // first group
33 * { 'b','x' }, // second group
34 * { 0 }
35 * };
36 *
37 * int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
38 *
39 * while ((c = getopt_long(argc, argv, "Zbcx", longopts, NULL)) != -1) {
40 *
41 * err_exclusive_options(c, longopts, excl, excl_st);
42 *
43 * switch (c) {
44 * case 'Z':
45 * ....
46 * }
47 * }
48 *
49 * The array excl[] defines two groups of the mutually exclusive options. The
50 * option '-b' is in the both groups.
51 *
52 * Note that the options in the group have to be in ASCII order (ABC..abc..) and
53 * groups have to be also in ASCII order.
54 *
55 * The maximal number of the options in the group is 15 (size of the array is
56 * 16, last is zero).
57 *
58 * The current status of options is stored in excl_st array. The size of the array
59 * must be the same as number of the groups in the ul_excl_t array.
60 *
61 * If you're unsure then see sys-utils/mount.c or misc-utils/findmnt.c.
62 */
63 #define UL_EXCL_STATUS_INIT { 0 }
64 typedef int ul_excl_t[16];
65
66 static inline void err_exclusive_options(
67 int c,
68 const struct option *opts,
69 const ul_excl_t *excl,
70 int *status)
71 {
72 int e;
73
74 for (e = 0; excl[e][0] && excl[e][0] <= c; e++) {
75 const int *op = excl[e];
76
77 for (; *op && *op <= c; op++) {
78 if (*op != c)
79 continue;
80 if (status[e] == 0)
81 status[e] = c;
82 else if (status[e] != c) {
83 size_t ct = 0;
84
85 fprintf(stderr, _("%s: mutually exclusive "
86 "arguments:"),
87 program_invocation_short_name);
88
89 for (op = excl[e];
90 ct + 1 < ARRAY_SIZE(excl[0]) && *op;
91 op++, ct++) {
92 const char *n = option_to_longopt(*op, opts);
93 if (n)
94 fprintf(stderr, " --%s", n);
95 else if (c_isgraph(*op))
96 fprintf(stderr, " -%c", *op);
97 }
98 fputc('\n', stderr);
99 exit(OPTUTILS_EXIT_CODE);
100 }
101 break;
102 }
103 }
104 }
105
106 #endif
107