/src/ntp-dev/sntp/libopts/check.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * @file check.c |
3 | | * |
4 | | * @brief option consistency checks. |
5 | | * |
6 | | * @addtogroup autoopts |
7 | | * @{ |
8 | | */ |
9 | | /* |
10 | | * This file is part of AutoOpts, a companion to AutoGen. |
11 | | * AutoOpts is free software. |
12 | | * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved |
13 | | * |
14 | | * AutoOpts is available under any one of two licenses. The license |
15 | | * in use must be one of these two and the choice is under the control |
16 | | * of the user of the license. |
17 | | * |
18 | | * The GNU Lesser General Public License, version 3 or later |
19 | | * See the files "COPYING.lgplv3" and "COPYING.gplv3" |
20 | | * |
21 | | * The Modified Berkeley Software Distribution License |
22 | | * See the file "COPYING.mbsd" |
23 | | * |
24 | | * These files have the following sha256 sums: |
25 | | * |
26 | | * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 |
27 | | * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 |
28 | | * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd |
29 | | */ |
30 | | |
31 | | /** |
32 | | * Check for conflicts based on "must" and "cannot" attributes. |
33 | | */ |
34 | | static bool |
35 | | has_conflict(tOptions * pOpts, tOptDesc * od) |
36 | 0 | { |
37 | 0 | if (od->pOptMust != NULL) { |
38 | 0 | int const * must = od->pOptMust; |
39 | |
|
40 | 0 | while (*must != NO_EQUIVALENT) { |
41 | 0 | tOptDesc * p = pOpts->pOptDesc + *(must++); |
42 | 0 | if (UNUSED_OPT(p)) { |
43 | 0 | const tOptDesc * ood = pOpts->pOptDesc + must[-1]; |
44 | 0 | fprintf(stderr, zneed_fmt, pOpts->pzProgName, |
45 | 0 | od->pz_Name, ood->pz_Name); |
46 | 0 | return true; |
47 | 0 | } |
48 | 0 | } |
49 | 0 | } |
50 | | |
51 | 0 | if (od->pOptCant != NULL) { |
52 | 0 | int const * cant = od->pOptCant; |
53 | |
|
54 | 0 | while (*cant != NO_EQUIVALENT) { |
55 | 0 | tOptDesc * p = pOpts->pOptDesc + *(cant++); |
56 | 0 | if (SELECTED_OPT(p)) { |
57 | 0 | const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; |
58 | 0 | fprintf(stderr, zconflict_fmt, pOpts->pzProgName, |
59 | 0 | od->pz_Name, ood->pz_Name); |
60 | 0 | return true; |
61 | 0 | } |
62 | 0 | } |
63 | 0 | } |
64 | | |
65 | 0 | return false; |
66 | 0 | } |
67 | | |
68 | | /** |
69 | | * Check that the option occurs often enough. Too often is already checked. |
70 | | */ |
71 | | static bool |
72 | | occurs_enough(tOptions * pOpts, tOptDesc * pOD) |
73 | 0 | { |
74 | 0 | (void)pOpts; |
75 | | |
76 | | /* |
77 | | * IF the occurrence counts have been satisfied, |
78 | | * THEN there is no problem. |
79 | | */ |
80 | 0 | if (pOD->optOccCt >= pOD->optMinCt) |
81 | 0 | return true; |
82 | | |
83 | | /* |
84 | | * IF MUST_SET means SET and PRESET are okay, |
85 | | * so min occurrence count doesn't count |
86 | | */ |
87 | 0 | if ( (pOD->fOptState & OPTST_MUST_SET) |
88 | 0 | && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) |
89 | 0 | return true; |
90 | | |
91 | 0 | if (pOD->optMinCt > 1) |
92 | 0 | fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, |
93 | 0 | pOD->optMinCt); |
94 | 0 | else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); |
95 | 0 | return false; |
96 | 0 | } |
97 | | |
98 | | /** |
99 | | * Verify option consistency. |
100 | | * |
101 | | * Make sure that the argument list passes our consistency tests. |
102 | | */ |
103 | | LOCAL bool |
104 | | is_consistent(tOptions * pOpts) |
105 | 0 | { |
106 | 0 | tOptDesc * pOD = pOpts->pOptDesc; |
107 | 0 | int oCt = pOpts->presetOptCt; |
108 | | |
109 | | /* |
110 | | * FOR each of "oCt" options, ... |
111 | | */ |
112 | 0 | for (;;) { |
113 | | /* |
114 | | * IF the current option was provided on the command line |
115 | | * THEN ensure that any "MUST" requirements are not |
116 | | * "DEFAULT" (unspecified) *AND* ensure that any |
117 | | * "CANT" options have not been SET or DEFINED. |
118 | | */ |
119 | 0 | if (SELECTED_OPT(pOD)) { |
120 | 0 | if (has_conflict(pOpts, pOD)) |
121 | 0 | return false; |
122 | 0 | } |
123 | | |
124 | | /* |
125 | | * IF this option is not equivalenced to another, |
126 | | * OR it is equivalenced to itself (is the equiv. root) |
127 | | * THEN we need to make sure it occurs often enough. |
128 | | */ |
129 | 0 | if ( (pOD->optEquivIndex == NO_EQUIVALENT) |
130 | 0 | || (pOD->optEquivIndex == pOD->optIndex) ) |
131 | | |
132 | 0 | if (! occurs_enough(pOpts, pOD)) |
133 | 0 | return false; |
134 | | |
135 | 0 | if (--oCt <= 0) |
136 | 0 | break; |
137 | 0 | pOD++; |
138 | 0 | } |
139 | | |
140 | | /* |
141 | | * IF we are stopping on errors, check to see if any remaining |
142 | | * arguments are required to be there or prohibited from being there. |
143 | | */ |
144 | 0 | if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { |
145 | | |
146 | | /* |
147 | | * Check for prohibition |
148 | | */ |
149 | 0 | if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { |
150 | 0 | if (pOpts->origArgCt > pOpts->curOptIdx) { |
151 | 0 | fprintf(stderr, zNoArgs, pOpts->pzProgName); |
152 | 0 | return false; |
153 | 0 | } |
154 | 0 | } |
155 | | |
156 | | /* |
157 | | * ELSE not prohibited, check for being required |
158 | | */ |
159 | 0 | else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { |
160 | 0 | if (pOpts->origArgCt <= pOpts->curOptIdx) { |
161 | 0 | fprintf(stderr, zargs_must, pOpts->pzProgName); |
162 | 0 | return false; |
163 | 0 | } |
164 | 0 | } |
165 | 0 | } |
166 | | |
167 | 0 | return true; |
168 | 0 | } |
169 | | |
170 | | /** @} |
171 | | * |
172 | | * Local Variables: |
173 | | * mode: C |
174 | | * c-file-style: "stroustrup" |
175 | | * indent-tabs-mode: nil |
176 | | * End: |
177 | | * end of autoopts/check.c */ |