]> git.ipfire.org Git - thirdparty/util-linux.git/blame - include/optutils.h
login: reduce file-descriptors cleanup overhead
[thirdparty/util-linux.git] / include / optutils.h
CommitLineData
732a6311
KZ
1#ifndef UTIL_LINUX_OPTUTILS_H
2#define UTIL_LINUX_OPTUTILS_H
3
fdf8e1f5
SK
4#include <assert.h>
5
8f77d454
SK
6#include "c.h"
7#include "nls.h"
9bf13750 8#include "cctype.h"
8f77d454 9
732a6311
KZ
10static inline const char *option_to_longopt(int c, const struct option *opts)
11{
12 const struct option *o;
13
fdf8e1f5 14 assert(!(opts == NULL));
732a6311
KZ
15 for (o = opts; o->name; o++)
16 if (o->val == c)
17 return o->name;
18 return NULL;
19}
20
8f77d454
SK
21#ifndef OPTUTILS_EXIT_CODE
22# define OPTUTILS_EXIT_CODE EXIT_FAILURE
23#endif
217d20a7 24
217d20a7
KZ
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 *
2c7bcdf8
KZ
55 * The maximal number of the options in the group is 15 (size of the array is
56 * 16, last is zero).
57 *
217d20a7
KZ
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 }
64typedef int ul_excl_t[16];
65
66static 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) {
2c7bcdf8
KZ
83 size_t ct = 0;
84
9bf13750
WP
85 fprintf(stderr, _("%s: mutually exclusive "
86 "arguments:"),
217d20a7 87 program_invocation_short_name);
2c7bcdf8
KZ
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)
1d231190 94 fprintf(stderr, " --%s", n);
9bf13750 95 else if (c_isgraph(*op))
1d231190 96 fprintf(stderr, " -%c", *op);
217d20a7 97 }
217d20a7
KZ
98 fputc('\n', stderr);
99 exit(OPTUTILS_EXIT_CODE);
100 }
101 break;
102 }
103 }
104}
105
732a6311
KZ
106#endif
107