1290001Sglebius/** 2290001Sglebius * @file check.c 3290001Sglebius * 4290001Sglebius * @brief option consistency checks. 5290001Sglebius * 6290001Sglebius * @addtogroup autoopts 7290001Sglebius * @{ 8290001Sglebius */ 9290001Sglebius/* 10290001Sglebius * This file is part of AutoOpts, a companion to AutoGen. 11290001Sglebius * AutoOpts is free software. 12290001Sglebius * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 13290001Sglebius * 14290001Sglebius * AutoOpts is available under any one of two licenses. The license 15290001Sglebius * in use must be one of these two and the choice is under the control 16290001Sglebius * of the user of the license. 17290001Sglebius * 18290001Sglebius * The GNU Lesser General Public License, version 3 or later 19290001Sglebius * See the files "COPYING.lgplv3" and "COPYING.gplv3" 20290001Sglebius * 21290001Sglebius * The Modified Berkeley Software Distribution License 22290001Sglebius * See the file "COPYING.mbsd" 23290001Sglebius * 24290001Sglebius * These files have the following sha256 sums: 25290001Sglebius * 26290001Sglebius * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 27290001Sglebius * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 28290001Sglebius * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 29290001Sglebius */ 30290001Sglebius 31290001Sglebius/** 32290001Sglebius * Check for conflicts based on "must" and "cannot" attributes. 33290001Sglebius */ 34290001Sglebiusstatic bool 35290001Sglebiushas_conflict(tOptions * pOpts, tOptDesc * od) 36290001Sglebius{ 37290001Sglebius if (od->pOptMust != NULL) { 38290001Sglebius int const * must = od->pOptMust; 39290001Sglebius 40290001Sglebius while (*must != NO_EQUIVALENT) { 41290001Sglebius tOptDesc * p = pOpts->pOptDesc + *(must++); 42290001Sglebius if (UNUSED_OPT(p)) { 43290001Sglebius const tOptDesc * ood = pOpts->pOptDesc + must[-1]; 44290001Sglebius fprintf(stderr, zneed_fmt, pOpts->pzProgName, 45290001Sglebius od->pz_Name, ood->pz_Name); 46290001Sglebius return true; 47290001Sglebius } 48290001Sglebius } 49290001Sglebius } 50290001Sglebius 51290001Sglebius if (od->pOptCant != NULL) { 52290001Sglebius int const * cant = od->pOptCant; 53290001Sglebius 54290001Sglebius while (*cant != NO_EQUIVALENT) { 55290001Sglebius tOptDesc * p = pOpts->pOptDesc + *(cant++); 56290001Sglebius if (SELECTED_OPT(p)) { 57290001Sglebius const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; 58290001Sglebius fprintf(stderr, zconflict_fmt, pOpts->pzProgName, 59290001Sglebius od->pz_Name, ood->pz_Name); 60290001Sglebius return true; 61290001Sglebius } 62290001Sglebius } 63290001Sglebius } 64290001Sglebius 65290001Sglebius return false; 66290001Sglebius} 67290001Sglebius 68290001Sglebius/** 69290001Sglebius * Check that the option occurs often enough. Too often is already checked. 70290001Sglebius */ 71290001Sglebiusstatic bool 72290001Sglebiusoccurs_enough(tOptions * pOpts, tOptDesc * pOD) 73290001Sglebius{ 74290001Sglebius (void)pOpts; 75290001Sglebius 76290001Sglebius /* 77290001Sglebius * IF the occurrence counts have been satisfied, 78290001Sglebius * THEN there is no problem. 79290001Sglebius */ 80290001Sglebius if (pOD->optOccCt >= pOD->optMinCt) 81290001Sglebius return true; 82290001Sglebius 83290001Sglebius /* 84290001Sglebius * IF MUST_SET means SET and PRESET are okay, 85290001Sglebius * so min occurrence count doesn't count 86290001Sglebius */ 87290001Sglebius if ( (pOD->fOptState & OPTST_MUST_SET) 88290001Sglebius && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) 89290001Sglebius return true; 90290001Sglebius 91290001Sglebius if (pOD->optMinCt > 1) 92290001Sglebius fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, 93290001Sglebius pOD->optMinCt); 94290001Sglebius else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); 95290001Sglebius return false; 96290001Sglebius} 97290001Sglebius 98290001Sglebius/** 99290001Sglebius * Verify option consistency. 100290001Sglebius * 101290001Sglebius * Make sure that the argument list passes our consistency tests. 102290001Sglebius */ 103290001SglebiusLOCAL bool 104290001Sglebiusis_consistent(tOptions * pOpts) 105290001Sglebius{ 106290001Sglebius tOptDesc * pOD = pOpts->pOptDesc; 107290001Sglebius int oCt = pOpts->presetOptCt; 108290001Sglebius 109290001Sglebius /* 110290001Sglebius * FOR each of "oCt" options, ... 111290001Sglebius */ 112290001Sglebius for (;;) { 113290001Sglebius /* 114290001Sglebius * IF the current option was provided on the command line 115290001Sglebius * THEN ensure that any "MUST" requirements are not 116290001Sglebius * "DEFAULT" (unspecified) *AND* ensure that any 117290001Sglebius * "CANT" options have not been SET or DEFINED. 118290001Sglebius */ 119290001Sglebius if (SELECTED_OPT(pOD)) { 120290001Sglebius if (has_conflict(pOpts, pOD)) 121290001Sglebius return false; 122290001Sglebius } 123290001Sglebius 124290001Sglebius /* 125290001Sglebius * IF this option is not equivalenced to another, 126290001Sglebius * OR it is equivalenced to itself (is the equiv. root) 127290001Sglebius * THEN we need to make sure it occurs often enough. 128290001Sglebius */ 129290001Sglebius if ( (pOD->optEquivIndex == NO_EQUIVALENT) 130290001Sglebius || (pOD->optEquivIndex == pOD->optIndex) ) 131290001Sglebius 132290001Sglebius if (! occurs_enough(pOpts, pOD)) 133290001Sglebius return false; 134290001Sglebius 135290001Sglebius if (--oCt <= 0) 136290001Sglebius break; 137290001Sglebius pOD++; 138290001Sglebius } 139290001Sglebius 140290001Sglebius /* 141290001Sglebius * IF we are stopping on errors, check to see if any remaining 142290001Sglebius * arguments are required to be there or prohibited from being there. 143290001Sglebius */ 144290001Sglebius if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { 145290001Sglebius 146290001Sglebius /* 147290001Sglebius * Check for prohibition 148290001Sglebius */ 149290001Sglebius if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { 150290001Sglebius if (pOpts->origArgCt > pOpts->curOptIdx) { 151290001Sglebius fprintf(stderr, zNoArgs, pOpts->pzProgName); 152290001Sglebius return false; 153290001Sglebius } 154290001Sglebius } 155290001Sglebius 156290001Sglebius /* 157290001Sglebius * ELSE not prohibited, check for being required 158290001Sglebius */ 159290001Sglebius else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { 160290001Sglebius if (pOpts->origArgCt <= pOpts->curOptIdx) { 161290001Sglebius fprintf(stderr, zargs_must, pOpts->pzProgName); 162290001Sglebius return false; 163290001Sglebius } 164290001Sglebius } 165290001Sglebius } 166290001Sglebius 167290001Sglebius return true; 168290001Sglebius} 169290001Sglebius 170290001Sglebius/** @} 171290001Sglebius * 172290001Sglebius * Local Variables: 173290001Sglebius * mode: C 174290001Sglebius * c-file-style: "stroustrup" 175290001Sglebius * indent-tabs-mode: nil 176290001Sglebius * End: 177290001Sglebius * end of autoopts/check.c */ 178