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