blob: 28a54b2ab6b58eb0f07af3c0d5f3afa031bb0ac6 [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 *
51 * The current status of options is stored in excl_st array. The size of the array
52 * must be the same as number of the groups in the ul_excl_t array.
53 *
54 * If you're unsure then see sys-utils/mount.c or misc-utils/findmnt.c.
55 */
56#define UL_EXCL_STATUS_INIT { 0 }
57typedef int ul_excl_t[16];
58
59static inline void err_exclusive_options(
60 int c,
61 const struct option *opts,
62 const ul_excl_t *excl,
63 int *status)
64{
65 int e;
66
67 for (e = 0; excl[e][0] && excl[e][0] <= c; e++) {
68 const int *op = excl[e];
69
70 for (; *op && *op <= c; op++) {
71 if (*op != c)
72 continue;
73 if (status[e] == 0)
74 status[e] = c;
75 else if (status[e] != c) {
76 fprintf(stderr, _("%s: options "),
77 program_invocation_short_name);
78 for (op = excl[e]; *op; op++) {
79 if (opts)
80 fprintf(stderr, "--%s ",
81 option_to_longopt(*op, opts));
82 else
83 fprintf(stderr, "-%c ", *op);
84 }
85 fprintf(stderr, _("are mutually exclusive."));
86 fputc('\n', stderr);
87 exit(OPTUTILS_EXIT_CODE);
88 }
89 break;
90 }
91 }
92}
93
94#endif
95