Coverage Report

Created: 2025-07-11 06:18

/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