Annotation of embedaddon/ntp/sntp/libopts/autoopts.c, revision 1.1

1.1     ! misho       1: 
        !             2: /**
        !             3:  * \file autoopts.c
        !             4:  *
        !             5:  *  Time-stamp:      "2011-03-25 17:55:07 bkorb"
        !             6:  *
        !             7:  *  This file contains all of the routines that must be linked into
        !             8:  *  an executable to use the generated option processing.  The optional
        !             9:  *  routines are in separately compiled modules so that they will not
        !            10:  *  necessarily be linked in.
        !            11:  *
        !            12:  *  This file is part of AutoOpts, a companion to AutoGen.
        !            13:  *  AutoOpts is free software.
        !            14:  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
        !            15:  *
        !            16:  *  AutoOpts is available under any one of two licenses.  The license
        !            17:  *  in use must be one of these two and the choice is under the control
        !            18:  *  of the user of the license.
        !            19:  *
        !            20:  *   The GNU Lesser General Public License, version 3 or later
        !            21:  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
        !            22:  *
        !            23:  *   The Modified Berkeley Software Distribution License
        !            24:  *      See the file "COPYING.mbsd"
        !            25:  *
        !            26:  *  These files have the following md5sums:
        !            27:  *
        !            28:  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
        !            29:  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
        !            30:  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
        !            31:  */
        !            32: 
        !            33: #ifndef PKGDATADIR
        !            34: #  define PKGDATADIR ""
        !            35: #endif
        !            36: 
        !            37: static char const   zNil[] = "";
        !            38: static arg_types_t  argTypes             = { NULL };
        !            39: static char         zOptFmtLine[16]      = { NUL };
        !            40: static ag_bool      displayEnum          = AG_FALSE;
        !            41: static char const   pkgdatadir_default[] = PKGDATADIR;
        !            42: static char const * program_pkgdatadir   = pkgdatadir_default;
        !            43: static tOptionLoadMode option_load_mode  = OPTION_LOAD_UNCOOKED;
        !            44: static tePagerState pagerState           = PAGER_STATE_INITIAL;
        !            45: 
        !            46:        FILE *       option_usage_fp      = NULL;
        !            47: 
        !            48: /* = = = START-STATIC-FORWARD = = = */
        !            49: static tSuccess
        !            50: findOptDesc(tOptions* pOpts, tOptState* pOptState);
        !            51: 
        !            52: static tSuccess
        !            53: next_opt_arg_must(tOptions* pOpts, tOptState* pOptState);
        !            54: 
        !            55: static tSuccess
        !            56: next_opt_arg_may(tOptions* pOpts, tOptState* pOptState);
        !            57: 
        !            58: static tSuccess
        !            59: next_opt_arg_none(tOptions* pOpts, tOptState* pOptState);
        !            60: 
        !            61: static tSuccess
        !            62: nextOption(tOptions* pOpts, tOptState* pOptState);
        !            63: 
        !            64: static tSuccess
        !            65: doPresets(tOptions* pOpts);
        !            66: 
        !            67: static int
        !            68: checkConsistency(tOptions* pOpts);
        !            69: /* = = = END-STATIC-FORWARD = = = */
        !            70: 
        !            71: LOCAL void *
        !            72: ao_malloc(size_t sz)
        !            73: {
        !            74:     void * res = malloc(sz);
        !            75:     if (res == NULL) {
        !            76:         fprintf(stderr, zAO_Alloc, (int)sz);
        !            77:         exit(EXIT_FAILURE);
        !            78:     }
        !            79:     return res;
        !            80: }
        !            81: #undef  malloc
        !            82: #define malloc(_s) ao_malloc(_s)
        !            83: 
        !            84: LOCAL void *
        !            85: ao_realloc(void *p, size_t sz)
        !            86: {
        !            87:     void * res = (p == NULL) ? malloc(sz) : realloc(p, sz);
        !            88:     if (res == NULL) {
        !            89:         fprintf(stderr, zAO_Realloc, (int)sz, p);
        !            90:         exit(EXIT_FAILURE);
        !            91:     }
        !            92:     return res;
        !            93: }
        !            94: #undef  realloc
        !            95: #define realloc(_p,_s) ao_realloc(_p,_s)
        !            96: 
        !            97: LOCAL char *
        !            98: ao_strdup(char const *str)
        !            99: {
        !           100:     char * res = strdup(str);
        !           101:     if (res == NULL) {
        !           102:         fprintf(stderr, zAO_Strdup, (int)strlen(str));
        !           103:         exit(EXIT_FAILURE);
        !           104:     }
        !           105:     return res;
        !           106: }
        !           107: #undef  strdup
        !           108: #define strdup(_p) ao_strdup(_p)
        !           109: 
        !           110: #ifndef HAVE_PATHFIND
        !           111: #  include "compat/pathfind.c"
        !           112: #endif
        !           113: 
        !           114: #ifndef HAVE_SNPRINTF
        !           115: #  include "compat/snprintf.c"
        !           116: #endif
        !           117: 
        !           118: #ifndef HAVE_STRDUP
        !           119: #  include "compat/strdup.c"
        !           120: #endif
        !           121: 
        !           122: #ifndef HAVE_STRCHR
        !           123: #  include "compat/strchr.c"
        !           124: #endif
        !           125: 
        !           126: /*
        !           127:  *  handle_opt
        !           128:  *
        !           129:  *  This routine handles equivalencing, sets the option state flags and
        !           130:  *  invokes the handler procedure, if any.
        !           131:  */
        !           132: LOCAL tSuccess
        !           133: handle_opt(tOptions* pOpts, tOptState* pOptState)
        !           134: {
        !           135:     /*
        !           136:      *  Save a copy of the option procedure pointer.
        !           137:      *  If this is an equivalence class option, we still want this proc.
        !           138:      */
        !           139:     tOptDesc* pOD = pOptState->pOD;
        !           140:     tOptProc* pOP = pOD->pOptProc;
        !           141:     if (pOD->fOptState & OPTST_ALLOC_ARG)
        !           142:         AGFREE(pOD->optArg.argString);
        !           143: 
        !           144:     pOD->optArg.argString = pOptState->pzOptArg;
        !           145: 
        !           146:     /*
        !           147:      *  IF we are presetting options, then we will ignore any un-presettable
        !           148:      *  options.  They are the ones either marked as such.
        !           149:      */
        !           150:     if (  ((pOpts->fOptSet & OPTPROC_PRESETTING) != 0)
        !           151:        && ((pOD->fOptState & OPTST_NO_INIT) != 0)
        !           152:        )
        !           153:         return PROBLEM;
        !           154: 
        !           155:     /*
        !           156:      *  IF this is an equivalence class option,
        !           157:      *  THEN
        !           158:      *      Save the option value that got us to this option
        !           159:      *      entry.  (It may not be pOD->optChar[0], if this is an
        !           160:      *      equivalence entry.)
        !           161:      *      set the pointer to the equivalence class base
        !           162:      */
        !           163:     if (pOD->optEquivIndex != NO_EQUIVALENT) {
        !           164:         tOptDesc* p = pOpts->pOptDesc + pOD->optEquivIndex;
        !           165: 
        !           166:         /*
        !           167:          * IF the current option state has not been defined (set on the
        !           168:          *    command line), THEN we will allow continued resetting of
        !           169:          *    the value.  Once "defined", then it must not change.
        !           170:          */
        !           171:         if ((pOD->fOptState & OPTST_DEFINED) != 0) {
        !           172:             /*
        !           173:              *  The equivalenced-to option has been found on the command
        !           174:              *  line before.  Make sure new occurrences are the same type.
        !           175:              *
        !           176:              *  IF this option has been previously equivalenced and
        !           177:              *     it was not the same equivalenced-to option,
        !           178:              *  THEN we have a usage problem.
        !           179:              */
        !           180:             if (p->optActualIndex != pOD->optIndex) {
        !           181:                 fprintf(stderr, (char*)zMultiEquiv, p->pz_Name, pOD->pz_Name,
        !           182:                         (pOpts->pOptDesc + p->optActualIndex)->pz_Name);
        !           183:                 return FAILURE;
        !           184:             }
        !           185:         } else {
        !           186:             /*
        !           187:              *  Set the equivalenced-to actual option index to no-equivalent
        !           188:              *  so that we set all the entries below.  This option may either
        !           189:              *  never have been selected before, or else it was selected by
        !           190:              *  some sort of "presetting" mechanism.
        !           191:              */
        !           192:             p->optActualIndex = NO_EQUIVALENT;
        !           193:         }
        !           194: 
        !           195:         if (p->optActualIndex != pOD->optIndex) {
        !           196:             /*
        !           197:              *  First time through, copy over the state
        !           198:              *  and add in the equivalence flag
        !           199:              */
        !           200:             p->optActualValue = pOD->optValue;
        !           201:             p->optActualIndex = pOD->optIndex;
        !           202:             pOptState->flags |= OPTST_EQUIVALENCE;
        !           203:         }
        !           204: 
        !           205:         /*
        !           206:          *  Copy the most recent option argument.  set membership state
        !           207:          *  is kept in ``p->optCookie''.  Do not overwrite.
        !           208:          */
        !           209:         p->optArg.argString = pOD->optArg.argString;
        !           210:         pOD = p;
        !           211: 
        !           212:     } else {
        !           213:         pOD->optActualValue = pOD->optValue;
        !           214:         pOD->optActualIndex = pOD->optIndex;
        !           215:     }
        !           216: 
        !           217:     pOD->fOptState &= OPTST_PERSISTENT_MASK;
        !           218:     pOD->fOptState |= (pOptState->flags & ~OPTST_PERSISTENT_MASK);
        !           219: 
        !           220:     /*
        !           221:      *  Keep track of count only for DEFINED (command line) options.
        !           222:      *  IF we have too many, build up an error message and bail.
        !           223:      */
        !           224:     if (  (pOD->fOptState & OPTST_DEFINED)
        !           225:        && (++pOD->optOccCt > pOD->optMaxCt)  )  {
        !           226: 
        !           227:         if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        !           228:             char const * pzEqv =
        !           229:                 (pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;
        !           230: 
        !           231:             fputs(zErrOnly, stderr);
        !           232: 
        !           233:             if (pOD->optMaxCt > 1)
        !           234:                 fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);
        !           235:             else
        !           236:                 fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);
        !           237:         }
        !           238: 
        !           239:         return FAILURE;
        !           240:     }
        !           241: 
        !           242:     /*
        !           243:      *  If provided a procedure to call, call it
        !           244:      */
        !           245:     if (pOP != NULL)
        !           246:         (*pOP)(pOpts, pOD);
        !           247: 
        !           248:     return SUCCESS;
        !           249: }
        !           250: 
        !           251: 
        !           252: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           253:  *
        !           254:  *  HUNT FOR OPTIONS IN THE ARGUMENT LIST
        !           255:  *
        !           256:  *  The next four procedures are "private" to nextOption().
        !           257:  *  nextOption() uses findOptDesc() to find the next descriptor and it, in
        !           258:  *  turn, uses longOptionFind() and shortOptionFind() to actually do the hunt.
        !           259:  *
        !           260:  *  longOptionFind
        !           261:  *
        !           262:  *  Find the long option descriptor for the current option
        !           263:  */
        !           264: LOCAL tSuccess
        !           265: longOptionFind(tOptions* pOpts, char* pzOptName, tOptState* pOptState)
        !           266: {
        !           267:     ag_bool    disable  = AG_FALSE;
        !           268:     char*      pzEq     = strchr(pzOptName, '=');
        !           269:     tOptDesc*  pOD      = pOpts->pOptDesc;
        !           270:     int        idx      = 0;
        !           271:     int        idxLim   = pOpts->optCt;
        !           272:     int        matchCt  = 0;
        !           273:     int        matchIdx = 0;
        !           274:     int        nameLen;
        !           275:     char       opt_name_buf[128];
        !           276: 
        !           277:     /*
        !           278:      *  IF the value is attached to the name,
        !           279:      *  copy it off so we can NUL terminate.
        !           280:      */
        !           281:     if (pzEq != NULL) {
        !           282:         nameLen = (int)(pzEq - pzOptName);
        !           283:         if (nameLen >= sizeof(opt_name_buf))
        !           284:             return FAILURE;
        !           285:         memcpy(opt_name_buf, pzOptName, nameLen);
        !           286:         opt_name_buf[nameLen] = NUL;
        !           287:         pzOptName = opt_name_buf;
        !           288:         pzEq++;
        !           289: 
        !           290:     } else nameLen = strlen(pzOptName);
        !           291: 
        !           292:     do  {
        !           293:         /*
        !           294:          *  If option disabled or a doc option, skip to next
        !           295:          */
        !           296:         if (pOD->pz_Name == NULL)
        !           297:             continue;
        !           298: 
        !           299:         if (  SKIP_OPT(pOD)
        !           300:            && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
        !           301:             continue;
        !           302: 
        !           303:         if (strneqvcmp(pzOptName, pOD->pz_Name, nameLen) == 0) {
        !           304:             /*
        !           305:              *  IF we have a complete match
        !           306:              *  THEN it takes priority over any already located partial
        !           307:              */
        !           308:             if (pOD->pz_Name[ nameLen ] == NUL) {
        !           309:                 matchCt  = 1;
        !           310:                 matchIdx = idx;
        !           311:                 break;
        !           312:             }
        !           313:         }
        !           314: 
        !           315:         /*
        !           316:          *  IF       there is a disable name
        !           317:          *     *AND* no argument value has been supplied
        !           318:          *              (disabled options may have no argument)
        !           319:          *     *AND* the option name matches the disable name
        !           320:          *  THEN ...
        !           321:          */
        !           322:         else if (  (pOD->pz_DisableName != NULL)
        !           323:                 && (strneqvcmp(pzOptName, pOD->pz_DisableName, nameLen) == 0)
        !           324:                 )  {
        !           325:             disable  = AG_TRUE;
        !           326: 
        !           327:             /*
        !           328:              *  IF we have a complete match
        !           329:              *  THEN it takes priority over any already located partial
        !           330:              */
        !           331:             if (pOD->pz_DisableName[ nameLen ] == NUL) {
        !           332:                 matchCt  = 1;
        !           333:                 matchIdx = idx;
        !           334:                 break;
        !           335:             }
        !           336:         }
        !           337: 
        !           338:         else
        !           339:             continue;
        !           340: 
        !           341:         /*
        !           342:          *  We found a partial match, either regular or disabling.
        !           343:          *  Remember the index for later.
        !           344:          */
        !           345:         matchIdx = idx;
        !           346: 
        !           347:         if (++matchCt > 1)
        !           348:             break;
        !           349: 
        !           350:     } while (pOD++, (++idx < idxLim));
        !           351: 
        !           352:     /*
        !           353:      *  Make sure we either found an exact match or found only one partial
        !           354:      */
        !           355:     if (matchCt == 1) {
        !           356:         pOD = pOpts->pOptDesc + matchIdx;
        !           357: 
        !           358:         if (SKIP_OPT(pOD)) {
        !           359:             fprintf(stderr, zDisabledErr, pOpts->pzProgName, pOD->pz_Name);
        !           360:             if (pOD->pzText != NULL)
        !           361:                 fprintf(stderr, " -- %s", pOD->pzText);
        !           362:             fputc('\n', stderr);
        !           363:             (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           364:             /* NOTREACHED */
        !           365:         }
        !           366: 
        !           367:         /*
        !           368:          *  IF we found a disablement name,
        !           369:          *  THEN set the bit in the callers' flag word
        !           370:          */
        !           371:         if (disable)
        !           372:             pOptState->flags |= OPTST_DISABLED;
        !           373: 
        !           374:         pOptState->pOD      = pOD;
        !           375:         pOptState->pzOptArg = pzEq;
        !           376:         pOptState->optType  = TOPT_LONG;
        !           377:         return SUCCESS;
        !           378:     }
        !           379: 
        !           380:     /*
        !           381:      *  IF there is no equal sign
        !           382:      *     *AND* we are using named arguments
        !           383:      *     *AND* there is a default named option,
        !           384:      *  THEN return that option.
        !           385:      */
        !           386:     if (  (pzEq == NULL)
        !           387:        && NAMED_OPTS(pOpts)
        !           388:        && (pOpts->specOptIdx.default_opt != NO_EQUIVALENT)) {
        !           389:         pOptState->pOD = pOpts->pOptDesc + pOpts->specOptIdx.default_opt;
        !           390: 
        !           391:         pOptState->pzOptArg = pzOptName;
        !           392:         pOptState->optType  = TOPT_DEFAULT;
        !           393:         return SUCCESS;
        !           394:     }
        !           395: 
        !           396:     /*
        !           397:      *  IF we are to stop on errors (the default, actually)
        !           398:      *  THEN call the usage procedure.
        !           399:      */
        !           400:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        !           401:         fprintf(stderr, (matchCt == 0) ? zIllOptStr : zAmbigOptStr,
        !           402:                 pOpts->pzProgPath, pzOptName);
        !           403:         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           404:     }
        !           405: 
        !           406:     return FAILURE;
        !           407: }
        !           408: 
        !           409: 
        !           410: /*
        !           411:  *  shortOptionFind
        !           412:  *
        !           413:  *  Find the short option descriptor for the current option
        !           414:  */
        !           415: LOCAL tSuccess
        !           416: shortOptionFind(tOptions* pOpts, uint_t optValue, tOptState* pOptState)
        !           417: {
        !           418:     tOptDesc*  pRes = pOpts->pOptDesc;
        !           419:     int        ct   = pOpts->optCt;
        !           420: 
        !           421:     /*
        !           422:      *  Search the option list
        !           423:      */
        !           424:     do  {
        !           425:         if (optValue != pRes->optValue)
        !           426:             continue;
        !           427: 
        !           428:         if (SKIP_OPT(pRes)) {
        !           429:             if (  (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
        !           430:                && (pRes->pz_Name != NULL)) {
        !           431:                 fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name);
        !           432:                 if (pRes->pzText != NULL)
        !           433:                     fprintf(stderr, " -- %s", pRes->pzText);
        !           434:                 fputc('\n', stderr);
        !           435:                 (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           436:                 /* NOTREACHED */
        !           437:             }
        !           438:             goto short_opt_error;
        !           439:         }
        !           440: 
        !           441:         pOptState->pOD     = pRes;
        !           442:         pOptState->optType = TOPT_SHORT;
        !           443:         return SUCCESS;
        !           444: 
        !           445:     } while (pRes++, --ct > 0);
        !           446: 
        !           447:     /*
        !           448:      *  IF    the character value is a digit
        !           449:      *    AND there is a special number option ("-n")
        !           450:      *  THEN the result is the "option" itself and the
        !           451:      *       option is the specially marked "number" option.
        !           452:      */
        !           453:     if (  IS_DEC_DIGIT_CHAR(optValue)
        !           454:        && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) {
        !           455:         pOptState->pOD = \
        !           456:         pRes           = pOpts->pOptDesc + pOpts->specOptIdx.number_option;
        !           457:         (pOpts->pzCurOpt)--;
        !           458:         pOptState->optType = TOPT_SHORT;
        !           459:         return SUCCESS;
        !           460:     }
        !           461: 
        !           462: short_opt_error:
        !           463: 
        !           464:     /*
        !           465:      *  IF we are to stop on errors (the default, actually)
        !           466:      *  THEN call the usage procedure.
        !           467:      */
        !           468:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        !           469:         fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue);
        !           470:         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           471:     }
        !           472: 
        !           473:     return FAILURE;
        !           474: }
        !           475: 
        !           476: 
        !           477: /*
        !           478:  *  findOptDesc
        !           479:  *
        !           480:  *  Find the option descriptor for the current option
        !           481:  */
        !           482: static tSuccess
        !           483: findOptDesc(tOptions* pOpts, tOptState* pOptState)
        !           484: {
        !           485:     /*
        !           486:      *  IF we are continuing a short option list (e.g. -xyz...)
        !           487:      *  THEN continue a single flag option.
        !           488:      *  OTHERWISE see if there is room to advance and then do so.
        !           489:      */
        !           490:     if ((pOpts->pzCurOpt != NULL) && (*pOpts->pzCurOpt != NUL))
        !           491:         return shortOptionFind(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
        !           492: 
        !           493:     if (pOpts->curOptIdx >= pOpts->origArgCt)
        !           494:         return PROBLEM; /* NORMAL COMPLETION */
        !           495: 
        !           496:     pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ];
        !           497: 
        !           498:     /*
        !           499:      *  IF all arguments must be named options, ...
        !           500:      */
        !           501:     if (NAMED_OPTS(pOpts)) {
        !           502:         char *   pz  = pOpts->pzCurOpt;
        !           503:         int      def;
        !           504:         tSuccess res; 
        !           505:         tAoUS *  def_opt;
        !           506: 
        !           507:         pOpts->curOptIdx++;
        !           508: 
        !           509:         if (*pz != '-')
        !           510:             return longOptionFind(pOpts, pz, pOptState);
        !           511: 
        !           512:         /*
        !           513:          *  The name is prefixed with one or more hyphens.  Strip them off
        !           514:          *  and disable the "default_opt" setting.  Use heavy recasting to
        !           515:          *  strip off the "const" quality of the "default_opt" field.
        !           516:          */
        !           517:         while (*(++pz) == '-')   ;
        !           518:         def_opt = (void *)&(pOpts->specOptIdx.default_opt);
        !           519:         def = *def_opt;
        !           520:         *def_opt = NO_EQUIVALENT;
        !           521:         res = longOptionFind(pOpts, pz, pOptState);
        !           522:         *def_opt = def;
        !           523:         return res;
        !           524:     }
        !           525: 
        !           526:     /*
        !           527:      *  Note the kind of flag/option marker
        !           528:      */
        !           529:     if (*((pOpts->pzCurOpt)++) != '-')
        !           530:         return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
        !           531: 
        !           532:     /*
        !           533:      *  Special hack for a hyphen by itself
        !           534:      */
        !           535:     if (*(pOpts->pzCurOpt) == NUL)
        !           536:         return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
        !           537: 
        !           538:     /*
        !           539:      *  The current argument is to be processed as an option argument
        !           540:      */
        !           541:     pOpts->curOptIdx++;
        !           542: 
        !           543:     /*
        !           544:      *  We have an option marker.
        !           545:      *  Test the next character for long option indication
        !           546:      */
        !           547:     if (pOpts->pzCurOpt[0] == '-') {
        !           548:         if (*++(pOpts->pzCurOpt) == NUL)
        !           549:             /*
        !           550:              *  NORMAL COMPLETION - NOT this arg, but rest are operands
        !           551:              */
        !           552:             return PROBLEM;
        !           553: 
        !           554:         /*
        !           555:          *  We do not allow the hyphen to be used as a flag value.
        !           556:          *  Therefore, if long options are not to be accepted, we punt.
        !           557:          */
        !           558:         if ((pOpts->fOptSet & OPTPROC_LONGOPT) == 0) {
        !           559:             fprintf(stderr, zIllOptStr, pOpts->pzProgPath,
        !           560:                     zIllegal, pOpts->pzCurOpt-2);
        !           561:             return FAILURE;
        !           562:         }
        !           563: 
        !           564:         return longOptionFind(pOpts, pOpts->pzCurOpt, pOptState);
        !           565:     }
        !           566: 
        !           567:     /*
        !           568:      *  If short options are not allowed, then do long
        !           569:      *  option processing.  Otherwise the character must be a
        !           570:      *  short (i.e. single character) option.
        !           571:      */
        !           572:     if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0)
        !           573:         return shortOptionFind(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
        !           574: 
        !           575:     return longOptionFind(pOpts, pOpts->pzCurOpt, pOptState);
        !           576: }
        !           577: 
        !           578: 
        !           579: static tSuccess
        !           580: next_opt_arg_must(tOptions* pOpts, tOptState* pOptState)
        !           581: {
        !           582:     /*
        !           583:      *  An option argument is required.  Long options can either have
        !           584:      *  a separate command line argument, or an argument attached by
        !           585:      *  the '=' character.  Figure out which.
        !           586:      */
        !           587:     switch (pOptState->optType) {
        !           588:     case TOPT_SHORT:
        !           589:         /*
        !           590:          *  See if an arg string follows the flag character
        !           591:          */
        !           592:         if (*++(pOpts->pzCurOpt) == NUL)
        !           593:             pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx++ ];
        !           594:         pOptState->pzOptArg = pOpts->pzCurOpt;
        !           595:         break;
        !           596: 
        !           597:     case TOPT_LONG:
        !           598:         /*
        !           599:          *  See if an arg string has already been assigned (glued on
        !           600:          *  with an `=' character)
        !           601:          */
        !           602:         if (pOptState->pzOptArg == NULL)
        !           603:             pOptState->pzOptArg = pOpts->origArgVect[ pOpts->curOptIdx++ ];
        !           604:         break;
        !           605: 
        !           606:     default:
        !           607: #ifdef DEBUG
        !           608:         fputs("AutoOpts lib error: option type not selected\n", stderr);
        !           609:         exit(EXIT_FAILURE);
        !           610: #endif
        !           611: 
        !           612:     case TOPT_DEFAULT:
        !           613:         /*
        !           614:          *  The option was selected by default.  The current token is
        !           615:          *  the option argument.
        !           616:          */
        !           617:         break;
        !           618:     }
        !           619: 
        !           620:     /*
        !           621:      *  Make sure we did not overflow the argument list.
        !           622:      */
        !           623:     if (pOpts->curOptIdx > pOpts->origArgCt) {
        !           624:         fprintf(stderr, zMisArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
        !           625:         return FAILURE;
        !           626:     }
        !           627: 
        !           628:     pOpts->pzCurOpt = NULL;  /* next time advance to next arg */
        !           629:     return SUCCESS;
        !           630: }
        !           631: 
        !           632: 
        !           633: static tSuccess
        !           634: next_opt_arg_may(tOptions* pOpts, tOptState* pOptState)
        !           635: {
        !           636:     /*
        !           637:      *  An option argument is optional.
        !           638:      */
        !           639:     switch (pOptState->optType) {
        !           640:     case TOPT_SHORT:
        !           641:         if (*++pOpts->pzCurOpt != NUL)
        !           642:             pOptState->pzOptArg = pOpts->pzCurOpt;
        !           643:         else {
        !           644:             char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
        !           645: 
        !           646:             /*
        !           647:              *  BECAUSE it is optional, we must make sure
        !           648:              *  we did not find another flag and that there
        !           649:              *  is such an argument.
        !           650:              */
        !           651:             if ((pzLA == NULL) || (*pzLA == '-'))
        !           652:                 pOptState->pzOptArg = NULL;
        !           653:             else {
        !           654:                 pOpts->curOptIdx++; /* argument found */
        !           655:                 pOptState->pzOptArg = pzLA;
        !           656:             }
        !           657:         }
        !           658:         break;
        !           659: 
        !           660:     case TOPT_LONG:
        !           661:         /*
        !           662:          *  Look for an argument if we don't already have one (glued on
        !           663:          *  with a `=' character) *AND* we are not in named argument mode
        !           664:          */
        !           665:         if (  (pOptState->pzOptArg == NULL)
        !           666:            && (! NAMED_OPTS(pOpts))) {
        !           667:             char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
        !           668: 
        !           669:             /*
        !           670:              *  BECAUSE it is optional, we must make sure
        !           671:              *  we did not find another flag and that there
        !           672:              *  is such an argument.
        !           673:              */
        !           674:             if ((pzLA == NULL) || (*pzLA == '-'))
        !           675:                 pOptState->pzOptArg = NULL;
        !           676:             else {
        !           677:                 pOpts->curOptIdx++; /* argument found */
        !           678:                 pOptState->pzOptArg = pzLA;
        !           679:             }
        !           680:         }
        !           681:         break;
        !           682: 
        !           683:     default:
        !           684:     case TOPT_DEFAULT:
        !           685:         fputs(zAO_Woops, stderr );
        !           686:         exit(EX_SOFTWARE);
        !           687:     }
        !           688: 
        !           689:     /*
        !           690:      *  After an option with an optional argument, we will
        !           691:      *  *always* start with the next option because if there
        !           692:      *  were any characters following the option name/flag,
        !           693:      *  they would be interpreted as the argument.
        !           694:      */
        !           695:     pOpts->pzCurOpt = NULL;
        !           696:     return SUCCESS;
        !           697: }
        !           698: 
        !           699: 
        !           700: static tSuccess
        !           701: next_opt_arg_none(tOptions* pOpts, tOptState* pOptState)
        !           702: {
        !           703:     /*
        !           704:      *  No option argument.  Make sure next time around we find
        !           705:      *  the correct option flag character for short options
        !           706:      */
        !           707:     if (pOptState->optType == TOPT_SHORT)
        !           708:         (pOpts->pzCurOpt)++;
        !           709: 
        !           710:     /*
        !           711:      *  It is a long option.  Make sure there was no ``=xxx'' argument
        !           712:      */
        !           713:     else if (pOptState->pzOptArg != NULL) {
        !           714:         fprintf(stderr, zNoArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
        !           715:         return FAILURE;
        !           716:     }
        !           717: 
        !           718:     /*
        !           719:      *  It is a long option.  Advance to next command line argument.
        !           720:      */
        !           721:     else
        !           722:         pOpts->pzCurOpt = NULL;
        !           723:     return SUCCESS;
        !           724: }
        !           725: 
        !           726: /*
        !           727:  *  nextOption
        !           728:  *
        !           729:  *  Find the option descriptor and option argument (if any) for the
        !           730:  *  next command line argument.  DO NOT modify the descriptor.  Put
        !           731:  *  all the state in the state argument so that the option can be skipped
        !           732:  *  without consequence (side effect).
        !           733:  */
        !           734: static tSuccess
        !           735: nextOption(tOptions* pOpts, tOptState* pOptState)
        !           736: {
        !           737:     {
        !           738:         tSuccess res;
        !           739:         res = findOptDesc(pOpts, pOptState);
        !           740:         if (! SUCCESSFUL(res))
        !           741:             return res;
        !           742:     }
        !           743: 
        !           744:     if (  ((pOptState->flags & OPTST_DEFINED) != 0)
        !           745:        && ((pOptState->pOD->fOptState & OPTST_NO_COMMAND) != 0)) {
        !           746:         fprintf(stderr, zNotCmdOpt, pOptState->pOD->pz_Name);
        !           747:         return FAILURE;
        !           748:     }
        !           749: 
        !           750:     pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK);
        !           751: 
        !           752:     /*
        !           753:      *  Figure out what to do about option arguments.  An argument may be
        !           754:      *  required, not associated with the option, or be optional.  We detect the
        !           755:      *  latter by examining for an option marker on the next possible argument.
        !           756:      *  Disabled mode option selection also disables option arguments.
        !           757:      */
        !           758:     {
        !           759:         enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE;
        !           760:         tSuccess res;
        !           761: 
        !           762:         if ((pOptState->flags & OPTST_DISABLED) != 0)
        !           763:             arg_type = ARG_NONE;
        !           764: 
        !           765:         else if (OPTST_GET_ARGTYPE(pOptState->flags) == OPARG_TYPE_NONE)
        !           766:             arg_type = ARG_NONE;
        !           767: 
        !           768:         else if (pOptState->flags & OPTST_ARG_OPTIONAL)
        !           769:             arg_type = ARG_MAY;
        !           770: 
        !           771:         else
        !           772:             arg_type = ARG_MUST;
        !           773: 
        !           774:         switch (arg_type) {
        !           775:         case ARG_MUST: res = next_opt_arg_must(pOpts, pOptState); break;
        !           776:         case ARG_MAY:  res = next_opt_arg_may( pOpts, pOptState); break;
        !           777:         case ARG_NONE: res = next_opt_arg_none(pOpts, pOptState); break;
        !           778:         }
        !           779: 
        !           780:         return res;
        !           781:     }
        !           782: }
        !           783: 
        !           784: 
        !           785: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           786:  *
        !           787:  *  DO PRESETS
        !           788:  *
        !           789:  *  The next several routines do the immediate action pass on the command
        !           790:  *  line options, then the environment variables, then the config files in
        !           791:  *  reverse order.  Once done with that, the order is reversed and all
        !           792:  *  the config files and environment variables are processed again, this
        !           793:  *  time only processing the non-immediate action options.  doPresets()
        !           794:  *  will then return for optionProcess() to do the final pass on the command
        !           795:  *  line arguments.
        !           796:  */
        !           797: 
        !           798: /**
        !           799:  *  scan the command line for immediate action options.
        !           800:  *  This is only called the first time through.
        !           801:  */
        !           802: LOCAL tSuccess
        !           803: doImmediateOpts(tOptions* pOpts)
        !           804: {
        !           805:     pOpts->curOptIdx = 1;     /* start by skipping program name */
        !           806:     pOpts->pzCurOpt  = NULL;
        !           807: 
        !           808:     /*
        !           809:      *  Examine all the options from the start.  We process any options that
        !           810:      *  are marked for immediate processing.
        !           811:      */
        !           812:     for (;;) {
        !           813:         tOptState optState = OPTSTATE_INITIALIZER(PRESET);
        !           814: 
        !           815:         switch (nextOption(pOpts, &optState)) {
        !           816:         case FAILURE: goto   failed_option;
        !           817:         case PROBLEM: return SUCCESS; /* no more args */
        !           818:         case SUCCESS: break;
        !           819:         }
        !           820: 
        !           821:         /*
        !           822:          *  IF this is an immediate-attribute option, then do it.
        !           823:          */
        !           824:         if (! DO_IMMEDIATELY(optState.flags))
        !           825:             continue;
        !           826: 
        !           827:         if (! SUCCESSFUL(handle_opt(pOpts, &optState)))
        !           828:             break;
        !           829:     } failed_option:;
        !           830: 
        !           831:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
        !           832:         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           833: 
        !           834:     return FAILURE;
        !           835: }
        !           836: 
        !           837: /**
        !           838:  * Process all the options from our current position onward.  (This allows
        !           839:  * interspersed options and arguments for the few non-standard programs that
        !           840:  * require it.)  Thus, do not rewind option indexes because some programs
        !           841:  * choose to re-invoke after a non-option.
        !           842:  */
        !           843: LOCAL tSuccess
        !           844: doRegularOpts(tOptions* pOpts)
        !           845: {
        !           846:     for (;;) {
        !           847:         tOptState optState = OPTSTATE_INITIALIZER(DEFINED);
        !           848: 
        !           849:         switch (nextOption(pOpts, &optState)) {
        !           850:         case FAILURE: goto   failed_option;
        !           851:         case PROBLEM: return SUCCESS; /* no more args */
        !           852:         case SUCCESS: break;
        !           853:         }
        !           854: 
        !           855:         /*
        !           856:          *  IF this is an immediate action option,
        !           857:          *  THEN skip it (unless we are supposed to do it a second time).
        !           858:          */
        !           859:         if (! DO_NORMALLY(optState.flags)) {
        !           860:             if (! DO_SECOND_TIME(optState.flags))
        !           861:                 continue;
        !           862:             optState.pOD->optOccCt--; /* don't count this repetition */
        !           863:         }
        !           864: 
        !           865:         if (! SUCCESSFUL(handle_opt(pOpts, &optState)))
        !           866:             break;
        !           867:     } failed_option:;
        !           868: 
        !           869:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
        !           870:         (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !           871: 
        !           872:     return FAILURE;
        !           873: }
        !           874: 
        !           875: 
        !           876: /**
        !           877:  *  check for preset values from a config files or envrionment variables
        !           878:  */
        !           879: static tSuccess
        !           880: doPresets(tOptions* pOpts)
        !           881: {
        !           882:     tOptDesc * pOD = NULL;
        !           883: 
        !           884:     if (! SUCCESSFUL(doImmediateOpts(pOpts)))
        !           885:         return FAILURE;
        !           886: 
        !           887:     /*
        !           888:      *  IF this option set has a --save-opts option, then it also
        !           889:      *  has a --load-opts option.  See if a command line option has disabled
        !           890:      *  option presetting.
        !           891:      */
        !           892:     if (  (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
        !           893:        && (pOpts->specOptIdx.save_opts != 0)) {
        !           894:         pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
        !           895:         if (DISABLED_OPT(pOD))
        !           896:             return SUCCESS;
        !           897:     }
        !           898: 
        !           899:     /*
        !           900:      *  Until we return from this procedure, disable non-presettable opts
        !           901:      */
        !           902:     pOpts->fOptSet |= OPTPROC_PRESETTING;
        !           903:     /*
        !           904:      *  IF there are no config files,
        !           905:      *  THEN do any environment presets and leave.
        !           906:      */
        !           907:     if (pOpts->papzHomeList == NULL) {
        !           908:         doEnvPresets(pOpts, ENV_ALL);
        !           909:     }
        !           910:     else {
        !           911:         doEnvPresets(pOpts, ENV_IMM);
        !           912: 
        !           913:         /*
        !           914:          *  Check to see if environment variables have disabled presetting.
        !           915:          */
        !           916:         if ((pOD != NULL) && ! DISABLED_OPT(pOD))
        !           917:             internalFileLoad(pOpts);
        !           918: 
        !           919:         /*
        !           920:          *  ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
        !           921:          *  variable options.  Only the loading of .rc files.
        !           922:          */
        !           923:         doEnvPresets(pOpts, ENV_NON_IMM);
        !           924:     }
        !           925:     pOpts->fOptSet &= ~OPTPROC_PRESETTING;
        !           926: 
        !           927:     return SUCCESS;
        !           928: }
        !           929: 
        !           930: 
        !           931: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           932:  *
        !           933:  *  VERIFY OPTION CONSISTENCY
        !           934:  *
        !           935:  *  Make sure that the argument list passes our consistency tests.
        !           936:  */
        !           937: static int
        !           938: checkConsistency(tOptions* pOpts)
        !           939: {
        !           940:     int        errCt = 0;
        !           941:     tOptDesc*  pOD   = pOpts->pOptDesc;
        !           942:     int        oCt   = pOpts->presetOptCt;
        !           943: 
        !           944:     /*
        !           945:      *  FOR each of "oCt" options, ...
        !           946:      */
        !           947:     for (;;) {
        !           948:         const int*  pMust = pOD->pOptMust;
        !           949:         const int*  pCant = pOD->pOptCant;
        !           950: 
        !           951:         /*
        !           952:          *  IF the current option was provided on the command line
        !           953:          *  THEN ensure that any "MUST" requirements are not
        !           954:          *       "DEFAULT" (unspecified) *AND* ensure that any
        !           955:          *       "CANT" options have not been SET or DEFINED.
        !           956:          */
        !           957:         if (SELECTED_OPT(pOD)) {
        !           958:             if (pMust != NULL) for (;;) {
        !           959:                 tOptDesc*  p = pOpts->pOptDesc + *(pMust++);
        !           960:                 if (UNUSED_OPT(p)) {
        !           961:                     const tOptDesc* pN = pOpts->pOptDesc + pMust[-1];
        !           962:                     errCt++;
        !           963:                     fprintf(stderr, zReqFmt, pOD->pz_Name, pN->pz_Name);
        !           964:                 }
        !           965: 
        !           966:                 if (*pMust == NO_EQUIVALENT)
        !           967:                     break;
        !           968:             }
        !           969: 
        !           970:             if (pCant != NULL) for (;;) {
        !           971:                 tOptDesc*  p = pOpts->pOptDesc + *(pCant++);
        !           972:                 if (SELECTED_OPT(p)) {
        !           973:                     const tOptDesc* pN = pOpts->pOptDesc + pCant[-1];
        !           974:                     errCt++;
        !           975:                     fprintf(stderr, zCantFmt, pOD->pz_Name, pN->pz_Name);
        !           976:                 }
        !           977: 
        !           978:                 if (*pCant == NO_EQUIVALENT)
        !           979:                     break;
        !           980:             }
        !           981:         }
        !           982: 
        !           983:         /*
        !           984:          *  IF       this option is not equivalenced to another,
        !           985:          *        OR it is equivalenced to itself (is the equiv. root)
        !           986:          *  THEN we need to make sure it occurs often enough.
        !           987:          */
        !           988:         if (  (pOD->optEquivIndex == NO_EQUIVALENT)
        !           989:            || (pOD->optEquivIndex == pOD->optIndex) )   do {
        !           990:             /*
        !           991:              *  IF the occurrence counts have been satisfied,
        !           992:              *  THEN there is no problem.
        !           993:              */
        !           994:             if (pOD->optOccCt >= pOD->optMinCt)
        !           995:                 break;
        !           996: 
        !           997:             /*
        !           998:              *  IF MUST_SET means SET and PRESET are okay,
        !           999:              *  so min occurrence count doesn't count
        !          1000:              */
        !          1001:             if (  (pOD->fOptState & OPTST_MUST_SET)
        !          1002:                && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) )
        !          1003:                 break;
        !          1004: 
        !          1005:             errCt++;
        !          1006:             if (pOD->optMinCt > 1)
        !          1007:                  fprintf(stderr, zNotEnough, pOD->pz_Name, pOD->optMinCt);
        !          1008:             else fprintf(stderr, zNeedOne, pOD->pz_Name);
        !          1009:         } while (0);
        !          1010: 
        !          1011:         if (--oCt <= 0)
        !          1012:             break;
        !          1013:         pOD++;
        !          1014:     }
        !          1015: 
        !          1016:     /*
        !          1017:      *  IF we are stopping on errors, check to see if any remaining
        !          1018:      *  arguments are required to be there or prohibited from being there.
        !          1019:      */
        !          1020:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        !          1021: 
        !          1022:         /*
        !          1023:          *  Check for prohibition
        !          1024:          */
        !          1025:         if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) {
        !          1026:             if (pOpts->origArgCt > pOpts->curOptIdx) {
        !          1027:                 fprintf(stderr, zNoArgs, pOpts->pzProgName);
        !          1028:                 ++errCt;
        !          1029:             }
        !          1030:         }
        !          1031: 
        !          1032:         /*
        !          1033:          *  ELSE not prohibited, check for being required
        !          1034:          */
        !          1035:         else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) {
        !          1036:             if (pOpts->origArgCt <= pOpts->curOptIdx) {
        !          1037:                 fprintf(stderr, zArgsMust, pOpts->pzProgName);
        !          1038:                 ++errCt;
        !          1039:             }
        !          1040:         }
        !          1041:     }
        !          1042: 
        !          1043:     return errCt;
        !          1044: }
        !          1045: 
        !          1046: 
        !          1047: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !          1048:  *
        !          1049:  *  THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE
        !          1050:  */
        !          1051: /*=--subblock=arg=arg_type,arg_name,arg_desc =*/
        !          1052: /*=*
        !          1053:  * library:  opts
        !          1054:  * header:   your-opts.h
        !          1055:  *
        !          1056:  * lib_description:
        !          1057:  *
        !          1058:  *  These are the routines that libopts users may call directly from their
        !          1059:  *  code.  There are several other routines that can be called by code
        !          1060:  *  generated by the libopts option templates, but they are not to be
        !          1061:  *  called from any other user code.  The @file{options.h} header is
        !          1062:  *  fairly clear about this, too.
        !          1063: =*/
        !          1064: 
        !          1065: /*=export_func optionProcess
        !          1066:  *
        !          1067:  * what: this is the main option processing routine
        !          1068:  *
        !          1069:  * arg:  + tOptions* + pOpts + program options descriptor +
        !          1070:  * arg:  + int       + argc  + program arg count  +
        !          1071:  * arg:  + char**    + argv  + program arg vector +
        !          1072:  *
        !          1073:  * ret_type:  int
        !          1074:  * ret_desc:  the count of the arguments processed
        !          1075:  *
        !          1076:  * doc:
        !          1077:  *
        !          1078:  * This is the main entry point for processing options.  It is intended
        !          1079:  * that this procedure be called once at the beginning of the execution of
        !          1080:  * a program.  Depending on options selected earlier, it is sometimes
        !          1081:  * necessary to stop and restart option processing, or to select completely
        !          1082:  * different sets of options.  This can be done easily, but you generally
        !          1083:  * do not want to do this.
        !          1084:  *
        !          1085:  * The number of arguments processed always includes the program name.
        !          1086:  * If one of the arguments is "--", then it is counted and the processing
        !          1087:  * stops.  If an error was encountered and errors are to be tolerated, then
        !          1088:  * the returned value is the index of the argument causing the error.
        !          1089:  * A hyphen by itself ("-") will also cause processing to stop and will
        !          1090:  * @emph{not} be counted among the processed arguments.  A hyphen by itself
        !          1091:  * is treated as an operand.  Encountering an operand stops option
        !          1092:  * processing.
        !          1093:  *
        !          1094:  * err:  Errors will cause diagnostics to be printed.  @code{exit(3)} may
        !          1095:  *       or may not be called.  It depends upon whether or not the options
        !          1096:  *       were generated with the "allow-errors" attribute, or if the
        !          1097:  *       ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.
        !          1098: =*/
        !          1099: int
        !          1100: optionProcess(tOptions * pOpts, int argCt, char ** argVect)
        !          1101: {
        !          1102:     if (! SUCCESSFUL(validateOptionsStruct(pOpts, argVect[0])))
        !          1103:         exit(EX_SOFTWARE);
        !          1104: 
        !          1105:     /*
        !          1106:      *  Establish the real program name, the program full path,
        !          1107:      *  and do all the presetting the first time thru only.
        !          1108:      */
        !          1109:     if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) {
        !          1110:         pOpts->origArgCt   = argCt;
        !          1111:         pOpts->origArgVect = argVect;
        !          1112:         pOpts->fOptSet    |= OPTPROC_INITDONE;
        !          1113:         if (HAS_pzPkgDataDir(pOpts))
        !          1114:             program_pkgdatadir = pOpts->pzPkgDataDir;
        !          1115: 
        !          1116:         if (! SUCCESSFUL(doPresets(pOpts)))
        !          1117:             return 0;
        !          1118: 
        !          1119:         /*
        !          1120:          *  IF option name conversion was suppressed but it is not suppressed
        !          1121:          *  for the command line, then it's time to translate option names.
        !          1122:          *  Usage text will not get retranslated.
        !          1123:          */
        !          1124:         if (  ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0)
        !          1125:            && (pOpts->pTransProc != NULL)
        !          1126:            && ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK)
        !          1127:               == OPTPROC_NXLAT_OPT_CFG)  )  {
        !          1128: 
        !          1129:             pOpts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
        !          1130:             (*pOpts->pTransProc)();
        !          1131:         }
        !          1132: 
        !          1133:         if ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
        !          1134:             optionSort(pOpts);
        !          1135: 
        !          1136:         pOpts->curOptIdx   = 1;
        !          1137:         pOpts->pzCurOpt    = NULL;
        !          1138:     }
        !          1139: 
        !          1140:     /*
        !          1141:      *  IF we are (re)starting,
        !          1142:      *  THEN reset option location
        !          1143:      */
        !          1144:     else if (pOpts->curOptIdx <= 0) {
        !          1145:         pOpts->curOptIdx = 1;
        !          1146:         pOpts->pzCurOpt  = NULL;
        !          1147:     }
        !          1148: 
        !          1149:     if (! SUCCESSFUL(doRegularOpts(pOpts)))
        !          1150:         return pOpts->origArgCt;
        !          1151: 
        !          1152:     /*
        !          1153:      *  IF    there were no errors
        !          1154:      *    AND we have RC/INI files
        !          1155:      *    AND there is a request to save the files
        !          1156:      *  THEN do that now before testing for conflicts.
        !          1157:      *       (conflicts are ignored in preset options)
        !          1158:      */
        !          1159:     if (  (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
        !          1160:        && (pOpts->specOptIdx.save_opts != 0)) {
        !          1161:         tOptDesc*  pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts;
        !          1162: 
        !          1163:         if (SELECTED_OPT(pOD)) {
        !          1164:             optionSaveFile(pOpts);
        !          1165:             exit(EXIT_SUCCESS);
        !          1166:         }
        !          1167:     }
        !          1168: 
        !          1169:     /*
        !          1170:      *  IF we are checking for errors,
        !          1171:      *  THEN look for too few occurrences of required options
        !          1172:      */
        !          1173:     if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        !          1174:         if (checkConsistency(pOpts) != 0)
        !          1175:             (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
        !          1176:     }
        !          1177: 
        !          1178:     return pOpts->curOptIdx;
        !          1179: }
        !          1180: 
        !          1181: /*
        !          1182:  * Local Variables:
        !          1183:  * mode: C
        !          1184:  * c-file-style: "stroustrup"
        !          1185:  * indent-tabs-mode: nil
        !          1186:  * End:
        !          1187:  * end of autoopts/autoopts.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>