check.c revision 285612
175631Salfred/** 275631Salfred * @file check.c 375631Salfred * 475631Salfred * @brief option consistency checks. 575631Salfred * 675631Salfred * @addtogroup autoopts 775631Salfred * @{ 875631Salfred */ 975631Salfred/* 1075631Salfred * This file is part of AutoOpts, a companion to AutoGen. 1175631Salfred * AutoOpts is free software. 1275631Salfred * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 1375631Salfred * 1475631Salfred * AutoOpts is available under any one of two licenses. The license 1575631Salfred * in use must be one of these two and the choice is under the control 1675631Salfred * of the user of the license. 1775631Salfred * 1875631Salfred * The GNU Lesser General Public License, version 3 or later 1975631Salfred * See the files "COPYING.lgplv3" and "COPYING.gplv3" 2075631Salfred * 2175631Salfred * The Modified Berkeley Software Distribution License 2275631Salfred * See the file "COPYING.mbsd" 2375631Salfred * 2475631Salfred * These files have the following sha256 sums: 2575631Salfred * 2675631Salfred * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 2775631Salfred * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 2875631Salfred * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 2975631Salfred */ 3075631Salfred 3175631Salfred/** 3275631Salfred * Check for conflicts based on "must" and "cannot" attributes. 3375631Salfred */ 3483651Speterstatic bool 3575631Salfredhas_conflict(tOptions * pOpts, tOptDesc * od) 3675631Salfred{ 3775631Salfred if (od->pOptMust != NULL) { 3875631Salfred int const * must = od->pOptMust; 3975631Salfred 4083651Speter while (*must != NO_EQUIVALENT) { 4175631Salfred tOptDesc * p = pOpts->pOptDesc + *(must++); 4275631Salfred if (UNUSED_OPT(p)) { 4375631Salfred const tOptDesc * ood = pOpts->pOptDesc + must[-1]; 4475631Salfred fprintf(stderr, zneed_fmt, pOpts->pzProgName, 45138430Sphk od->pz_Name, ood->pz_Name); 4675631Salfred return true; 4775631Salfred } 4875631Salfred } 4975631Salfred } 5075631Salfred 5175631Salfred if (od->pOptCant != NULL) { 5275631Salfred int const * cant = od->pOptCant; 5375631Salfred 5475631Salfred while (*cant != NO_EQUIVALENT) { 5575631Salfred tOptDesc * p = pOpts->pOptDesc + *(cant++); 5675631Salfred if (SELECTED_OPT(p)) { 5775631Salfred const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; 5875631Salfred fprintf(stderr, zconflict_fmt, pOpts->pzProgName, 59138430Sphk od->pz_Name, ood->pz_Name); 6075631Salfred return true; 6175631Salfred } 6275631Salfred } 6375631Salfred } 6475631Salfred 65138430Sphk return false; 6675631Salfred} 6775631Salfred 6875631Salfred/** 6975631Salfred * Check that the option occurs often enough. Too often is already checked. 7075631Salfred */ 71100134Salfredstatic bool 7275631Salfredoccurs_enough(tOptions * pOpts, tOptDesc * pOD) 7375631Salfred{ 74101947Salfred (void)pOpts; 75210455Srmacklem 7675631Salfred /* 7775631Salfred * IF the occurrence counts have been satisfied, 7875631Salfred * THEN there is no problem. 7975631Salfred */ 8075631Salfred if (pOD->optOccCt >= pOD->optMinCt) 8175631Salfred return true; 8275631Salfred 8375631Salfred /* 8475631Salfred * IF MUST_SET means SET and PRESET are okay, 8575631Salfred * so min occurrence count doesn't count 8675631Salfred */ 8775631Salfred if ( (pOD->fOptState & OPTST_MUST_SET) 8875631Salfred && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) 8975631Salfred return true; 90214048Srmacklem 91214048Srmacklem if (pOD->optMinCt > 1) 9275631Salfred fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, 93 pOD->optMinCt); 94 else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); 95 return false; 96} 97 98/** 99 * Verify option consistency. 100 * 101 * Make sure that the argument list passes our consistency tests. 102 */ 103LOCAL bool 104is_consistent(tOptions * pOpts) 105{ 106 tOptDesc * pOD = pOpts->pOptDesc; 107 int oCt = pOpts->presetOptCt; 108 109 /* 110 * FOR each of "oCt" options, ... 111 */ 112 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 if (SELECTED_OPT(pOD)) { 120 if (has_conflict(pOpts, pOD)) 121 return false; 122 } 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 if ( (pOD->optEquivIndex == NO_EQUIVALENT) 130 || (pOD->optEquivIndex == pOD->optIndex) ) 131 132 if (! occurs_enough(pOpts, pOD)) 133 return false; 134 135 if (--oCt <= 0) 136 break; 137 pOD++; 138 } 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 if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { 145 146 /* 147 * Check for prohibition 148 */ 149 if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { 150 if (pOpts->origArgCt > pOpts->curOptIdx) { 151 fprintf(stderr, zNoArgs, pOpts->pzProgName); 152 return false; 153 } 154 } 155 156 /* 157 * ELSE not prohibited, check for being required 158 */ 159 else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { 160 if (pOpts->origArgCt <= pOpts->curOptIdx) { 161 fprintf(stderr, zargs_must, pOpts->pzProgName); 162 return false; 163 } 164 } 165 } 166 167 return true; 168} 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 */ 178