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