📄 autoopts.c
字号:
* THEN return that option. */ if ( (pzEq == NULL) && NAMED_OPTS(pOpts) && (pOpts->specOptIdx.default_opt != NO_EQUIVALENT)) { pOptState->pOD = pOpts->pOptDesc + pOpts->specOptIdx.default_opt; pOptState->pzOptArg = pzOptName; pOptState->optType = TOPT_DEFAULT; return SUCCESS; } /* * IF we are to stop on errors (the default, actually) * THEN call the usage procedure. */ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { fprintf( stderr, zIllOptStr, pOpts->pzProgPath, (matchCt == 0) ? zIllegal : zAmbiguous, pzOptName ); (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); } return FAILURE;}/* * shortOptionFind * * Find the short option descriptor for the current option */LOCAL tSuccessshortOptionFind( tOptions* pOpts, uint_t optValue, tOptState* pOptState ){ tOptDesc* pRes = pOpts->pOptDesc; int ct = pOpts->optCt; /* * Search the option list */ for (;;) { /* * IF the values match, * THEN we stop here */ if ((! SKIP_OPT(pRes)) && (optValue == pRes->optValue)) { pOptState->pOD = pRes; pOptState->optType = TOPT_SHORT; return SUCCESS; } /* * Advance to next option description */ pRes++; /* * IF we have searched everything, ... */ if (--ct <= 0) break; } /* * IF the character value is a digit * AND there is a special number option ("-n") * THEN the result is the "option" itself and the * option is the specially marked "number" option. */ if ( isdigit( optValue ) && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { pOptState->pOD = \ pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; (pOpts->pzCurOpt)--; pOptState->optType = TOPT_SHORT; return SUCCESS; } /* * IF we are to stop on errors (the default, actually) * THEN call the usage procedure. */ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { fprintf( stderr, zIllOptChr, pOpts->pzProgPath, optValue ); (*pOpts->pUsageProc)( pOpts, EXIT_FAILURE ); } return FAILURE;}/* * findOptDesc * * Find the option descriptor for the current option */static tSuccessfindOptDesc( tOptions* pOpts, tOptState* pOptState ){ /* * IF we are continuing a short option list (e.g. -xyz...) * THEN continue a single flag option. * OTHERWISE see if there is room to advance and then do so. */ if ((pOpts->pzCurOpt != NULL) && (*pOpts->pzCurOpt != NUL)) return shortOptionFind( pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState ); if (pOpts->curOptIdx >= pOpts->origArgCt) return PROBLEM; /* NORMAL COMPLETION */ pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ]; /* * IF all arguments must be named options, ... */ if (NAMED_OPTS(pOpts)) { char* pz = pOpts->pzCurOpt; pOpts->curOptIdx++; /* * Skip over any flag/option markers. * In this mode, they are not required. */ while (*pz == '-') pz++; return longOptionFind( pOpts, pz, pOptState ); } /* * Note the kind of flag/option marker */ if (*((pOpts->pzCurOpt)++) != '-') return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ /* * Special hack for a hyphen by itself */ if (*(pOpts->pzCurOpt) == NUL) return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ /* * The current argument is to be processed as an option argument */ pOpts->curOptIdx++; /* * We have an option marker. * Test the next character for long option indication */ if (pOpts->pzCurOpt[0] == '-') { if (*++(pOpts->pzCurOpt) == NUL) /* * NORMAL COMPLETION - NOT this arg, but rest are operands */ return PROBLEM; /* * We do not allow the hyphen to be used as a flag value. * Therefore, if long options are not to be accepted, we punt. */ if ((pOpts->fOptSet & OPTPROC_LONGOPT) == 0) { fprintf( stderr, zIllOptStr, pOpts->pzProgPath, zIllegal, pOpts->pzCurOpt-2 ); return FAILURE; } return longOptionFind( pOpts, pOpts->pzCurOpt, pOptState ); } /* * If short options are not allowed, then do long * option processing. Otherwise the character must be a * short (i.e. single character) option. */ if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0) return shortOptionFind( pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState ); return longOptionFind( pOpts, pOpts->pzCurOpt, pOptState );}/* * nextOption * * Find the option descriptor and option argument (if any) for the * next command line argument. DO NOT modify the descriptor. Put * all the state in the state argument so that the option can be skipped * without consequence (side effect). */static tSuccessnextOption( tOptions* pOpts, tOptState* pOptState ){ tSuccess res; enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE; teOptArgType at; res = findOptDesc( pOpts, pOptState ); if (! SUCCESSFUL( res )) return res; pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK); at = OPTST_GET_ARGTYPE(pOptState->flags); /* * Figure out what to do about option arguments. An argument may be * required, not associated with the option, or be optional. We detect the * latter by examining for an option marker on the next possible argument. * Disabled mode option selection also disables option arguments. */ if ((pOptState->flags & OPTST_DISABLED) != 0) arg_type = ARG_NONE; else if (at == OPARG_TYPE_NONE) arg_type = ARG_NONE; else if (pOptState->flags & OPTST_ARG_OPTIONAL) arg_type = ARG_MAY; else arg_type = ARG_MUST; switch (arg_type) { case ARG_MUST: /* * An option argument is required. Long options can either have * a separate command line argument, or an argument attached by * the '=' character. Figure out which. */ switch (pOptState->optType) { case TOPT_SHORT: /* * See if an arg string follows the flag character */ if (*++(pOpts->pzCurOpt) == NUL) pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx++ ]; pOptState->pzOptArg = pOpts->pzCurOpt; break; case TOPT_LONG: /* * See if an arg string has already been assigned (glued on * with an `=' character) */ if (pOptState->pzOptArg == NULL) pOptState->pzOptArg = pOpts->origArgVect[ pOpts->curOptIdx++ ]; break; default:#ifdef DEBUG fputs( "AutoOpts lib error: option type not selected\n", stderr ); exit( EXIT_FAILURE );#endif case TOPT_DEFAULT: /* * The option was selected by default. The current token is * the option argument. */ break; } /* * Make sure we did not overflow the argument list. */ if (pOpts->curOptIdx > pOpts->origArgCt) { fprintf( stderr, zMisArg, pOpts->pzProgPath, pOptState->pOD->pz_Name ); return FAILURE; } pOpts->pzCurOpt = NULL; /* next time advance to next arg */ break; case ARG_MAY: /* * An option argument is optional. */ switch (pOptState->optType) { case TOPT_SHORT: if (*++pOpts->pzCurOpt != NUL) pOptState->pzOptArg = pOpts->pzCurOpt; else { char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; /* * BECAUSE it is optional, we must make sure * we did not find another flag and that there * is such an argument. */ if ((pzLA == NULL) || (*pzLA == '-')) pOptState->pzOptArg = NULL; else { pOpts->curOptIdx++; /* argument found */ pOptState->pzOptArg = pzLA; } } break; case TOPT_LONG: /* * Look for an argument if we don't already have one (glued on * with a `=' character) *AND* we are not in named argument mode */ if ( (pOptState->pzOptArg == NULL) && (! NAMED_OPTS(pOpts))) { char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; /* * BECAUSE it is optional, we must make sure * we did not find another flag and that there * is such an argument. */ if ((pzLA == NULL) || (*pzLA == '-')) pOptState->pzOptArg = NULL; else { pOpts->curOptIdx++; /* argument found */ pOptState->pzOptArg = pzLA; } } break; default: case TOPT_DEFAULT: fputs( "AutoOpts lib error: defaulted to option with optional arg\n", stderr ); exit( EX_SOFTWARE ); } /* * After an option with an optional argument, we will * *always* start with the next option because if there * were any characters following the option name/flag, * they would be interpreted as the argument. */ pOpts->pzCurOpt = NULL; break; default: /* CANNOT */ /* * No option argument. Make sure next time around we find * the correct option flag character for short options */ if (pOptState->optType == TOPT_SHORT) (pOpts->pzCurOpt)++; /* * It is a long option. Make sure there was no ``=xxx'' argument */ else if (pOptState->pzOptArg != NULL) { fprintf( stderr, zNoArg, pOpts->pzProgPath, pOptState->pOD->pz_Name ); return FAILURE; } /* * It is a long option. Advance to next command line argument. */ else pOpts->pzCurOpt = NULL; } return SUCCESS;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DO PRESETS * * The next several routines do the immediate action pass on the command * line options, then the environment variables, then the config files in * reverse order. Once done with that, the order is reversed and all * the config files and environment variables are processed again, this * time only processing the non-immediate action options. doPresets() * will then return for optionProcess() to do the final pass on the command * line arguments. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -