diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-05-05 12:27:49 +0300 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-05-05 12:51:42 +0300 |
commit | c3c3c9b844f7fd4c9fcd19ba19b306d88b75e65a (patch) | |
tree | d9c26136a5b92b368806a3848ff2898d1b43ac25 /src/libopts/find.c | |
parent | b3bab6daacff9126b194ca78485fdc7073d05a42 (diff) | |
download | gnutls-c3c3c9b844f7fd4c9fcd19ba19b306d88b75e65a.tar.gz |
updated libopts to autogen 5.17.3
Diffstat (limited to 'src/libopts/find.c')
-rw-r--r-- | src/libopts/find.c | 373 |
1 files changed, 289 insertions, 84 deletions
diff --git a/src/libopts/find.c b/src/libopts/find.c index f6510ee745..e3534291d1 100644 --- a/src/libopts/find.c +++ b/src/libopts/find.c @@ -3,14 +3,16 @@ * * @brief Hunt for options in the option descriptor list * - * Time-stamp: "2012-01-29 19:07:30 bkorb" - * * This file contains the routines that deal with processing quoted strings * into an internal format. * + * @addtogroup autoopts + * @{ + */ +/* * This file is part of AutoOpts, a companion to AutoGen. * AutoOpts is free software. - * AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved + * AutoOpts is Copyright (C) 1992-2013 by Bruce Korb - all rights reserved * * AutoOpts is available under any one of two licenses. The license * in use must be one of these two and the choice is under the control @@ -22,13 +24,43 @@ * The Modified Berkeley Software Distribution License * See the file "COPYING.mbsd" * - * These files have the following md5sums: + * These files have the following sha256 sums: * - * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 - * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 - * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd */ +/* = = = START-STATIC-FORWARD = = = */ +static int +parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz); + +static void +opt_ambiguities(tOptions * opts, char const * name, int nm_len); + +static int +opt_match_ct(tOptions * opts, char const * name, int nm_len, + int * ixp, bool * disable); + +static tSuccess +opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st); + +static tSuccess +opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st); + +static tSuccess +opt_ambiguous(tOptions * opts, char const * name, int match_ct); + +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st); + +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st); + +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState* o_st); +/* = = = END-STATIC-FORWARD = = = */ + /** * find the name and name length we are looking for */ @@ -44,10 +76,7 @@ parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) case NUL: return res; case '=': - if (res >= (int)bufsz) - return -1; - - memcpy(buf, *nm_pp, res); + memcpy(buf, *nm_pp, (size_t)res); buf[res] = NUL; *nm_pp = buf; @@ -55,7 +84,8 @@ parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) return res; default: - res++; + if (++res >= (int)bufsz) + return -1; } } } @@ -75,15 +105,15 @@ opt_ambiguities(tOptions * opts, char const * name, int nm_len) tOptDesc * pOD = opts->pOptDesc; int idx = 0; - fputs(zAmbigList, stderr); + fputs(zambig_list_msg, stderr); do { if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) - fprintf(stderr, zAmbiguous, hyph, pOD->pz_Name); + fprintf(stderr, zambig_file, hyph, pOD->pz_Name); else if ( (pOD->pz_DisableName != NULL) && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) ) - fprintf(stderr, zAmbiguous, hyph, pOD->pz_DisableName); + fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName); } while (pOD++, (++idx < opts->optCt)); } @@ -257,9 +287,9 @@ static tSuccess opt_ambiguous(tOptions * opts, char const * name, int match_ct) { if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { - fprintf(stderr, zAmbigOptStr, opts->pzProgPath, name, match_ct); + fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct); if (match_ct <= 4) - opt_ambiguities(opts, name, strlen(name)); + opt_ambiguities(opts, name, (int)strlen(name)); (*opts->pUsageProc)(opts, EXIT_FAILURE); /* NOTREACHED */ _exit(EXIT_FAILURE); /* to be certain */ @@ -286,6 +316,12 @@ optionVendorOption(tOptions * pOpts, tOptDesc * pOD) tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); char const * vopt_str = pOD->optArg.argString; + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + + if ((pOD->fOptState & OPTST_RESET) != 0) + return; + if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) opt_st.flags = OPTST_DEFINED; @@ -293,9 +329,10 @@ optionVendorOption(tOptions * pOpts, tOptDesc * pOD) || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) { - fprintf(stderr, zIllVendOptStr, vopt_str); + fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ } /* @@ -321,31 +358,39 @@ optionVendorOption(tOptions * pOpts, tOptDesc * pOD) /** * Find the option descriptor by full name. * - * @param pOpts option data - * @param opt_name name of option to look for - * @param pOptState state about current option + * @param opts option data + * @param opt_name name of option to look for + * @param state state about current option * * @return success status */ LOCAL tSuccess -opt_find_long(tOptions * pOpts, char const * opt_name, tOptState * pOptState) +opt_find_long(tOptions * opts, char const * opt_name, tOptState * state) { char name_buf[128]; char * opt_arg; int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf)); - int matchIdx = 0; - bool disable = false; - int match_ct = - opt_match_ct(pOpts, opt_name, nm_len, &matchIdx, &disable); + int idx = 0; + bool disable = false; + int ct; + + if (nm_len <= 0) { + fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable); /* * See if we found one match, no matches or multiple matches. */ - switch (match_ct) { - case 1: return opt_set(pOpts, opt_arg, matchIdx, disable, pOptState); - case 0: return opt_unknown(pOpts, opt_name, opt_arg, pOptState); - default: return opt_ambiguous(pOpts, opt_name, match_ct); + switch (ct) { + case 1: return opt_set(opts, opt_arg, idx, disable, state); + case 0: return opt_unknown(opts, opt_name, opt_arg, state); + default: return opt_ambiguous(opts, opt_name, ct); } } @@ -405,7 +450,7 @@ opt_find_short(tOptions* pOpts, uint_t optValue, tOptState* pOptState) return SUCCESS; } -short_opt_error: + short_opt_error: /* * IF we are to stop on errors (the default, actually) @@ -421,75 +466,235 @@ short_opt_error: return FAILURE; } -LOCAL tSuccess -get_opt_arg(tOptions * pOpts, tOptState * pOptState) +/** + * Process option with a required argument. Long options can either have a + * separate command line argument, or an argument attached by the '=' + * character. Figure out which. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st) { - pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK); + switch (o_st->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character + */ + if (*++(opts->pzCurOpt) == NUL) + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ]; + o_st->pzOptArg = opts->pzCurOpt; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character) + */ + if (o_st->pzOptArg == NULL) + o_st->pzOptArg = opts->origArgVect[ opts->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; + } /* - * 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. + * Make sure we did not overflow the argument list. */ - { - enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE; - tSuccess res; + if (opts->curOptIdx > opts->origArgCt) { + fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; + } - if ((pOptState->flags & OPTST_DISABLED) != 0) - arg_type = ARG_NONE; + opts->pzCurOpt = NULL; /* next time advance to next arg */ + return SUCCESS; +} - else if (OPTST_GET_ARGTYPE(pOptState->flags) == OPARG_TYPE_NONE) - arg_type = ARG_NONE; +/** + * Process an option with an optional argument. For short options, it looks + * at the character after the option character, or it consumes the next full + * argument. For long options, it looks for an '=' character attachment to + * the long option name before deciding to take the next command line + * argument. + * + * @param pOpts the option descriptor + * @param o_st a structure for managing the current processing state + * @returns SUCCESS or does not return + */ +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st) +{ + /* + * An option argument is optional. + */ + switch (o_st->optType) { + case TOPT_SHORT: + if (*++pOpts->pzCurOpt != NUL) + o_st->pzOptArg = pOpts->pzCurOpt; + else { + char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; - else if (pOptState->flags & OPTST_ARG_OPTIONAL) - arg_type = ARG_MAY; + /* + * 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 == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } + } + break; - else - arg_type = ARG_MUST; + 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 ( (o_st->pzOptArg == NULL) + && (! NAMED_OPTS(pOpts))) { + char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; - switch (arg_type) { - case ARG_MUST: res = next_opt_arg_must(pOpts, pOptState); break; - case ARG_MAY: res = next_opt_arg_may( pOpts, pOptState); break; - case ARG_NONE: res = next_opt_arg_none(pOpts, pOptState); break; + /* + * 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 == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } } + break; - return res; + default: + case TOPT_DEFAULT: + ao_bug(zbad_default_msg); + } + + /* + * 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; + return SUCCESS; +} + +/** + * Process option that does not have an argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState* o_st) +{ + /* + * No option argument. Make sure next time around we find + * the correct option flag character for short options + */ + if (o_st->optType == TOPT_SHORT) + (pOpts->pzCurOpt)++; + + /* + * It is a long option. Make sure there was no ``=xxx'' argument + */ + else if (o_st->pzOptArg != NULL) { + fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; } + + /* + * It is a long option. Advance to next command line argument. + */ + else + pOpts->pzCurOpt = NULL; + return SUCCESS; } /** - * Find the option descriptor for the current option + * Process option. Figure out whether or not to look for an option argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE */ LOCAL tSuccess -find_opt(tOptions * pOpts, tOptState * pOptState) +get_opt_arg(tOptions * opts, tOptState * o_st) +{ + o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK); + + /* + * Disabled options and options specified to not have arguments + * are handled with the "none" procedure. Otherwise, check the + * optional flag and call either the "may" or "must" function. + */ + if ( ((o_st->flags & OPTST_DISABLED) != 0) + || (OPTST_GET_ARGTYPE(o_st->flags) == OPARG_TYPE_NONE)) + return get_opt_arg_none(opts, o_st); + + if (o_st->flags & OPTST_ARG_OPTIONAL) + return get_opt_arg_may( opts, o_st); + + return get_opt_arg_must(opts, o_st); +} + +/** + * Find the option descriptor for the current option. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +LOCAL tSuccess +find_opt(tOptions * opts, tOptState * o_st) { /* * 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 opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState); + if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL)) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); - if (pOpts->curOptIdx >= pOpts->origArgCt) + if (opts->curOptIdx >= opts->origArgCt) return PROBLEM; /* NORMAL COMPLETION */ - pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ]; + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ]; /* * IF all arguments must be named options, ... */ - if (NAMED_OPTS(pOpts)) { - char * pz = pOpts->pzCurOpt; - int def; - tSuccess res; - tAoUS * def_opt; + if (NAMED_OPTS(opts)) { + char * pz = opts->pzCurOpt; + int def; + tSuccess res; + uint16_t * def_opt; - pOpts->curOptIdx++; + opts->curOptIdx++; if (*pz != '-') - return opt_find_long(pOpts, pz, pOptState); + return opt_find_long(opts, pz, o_st); /* * The name is prefixed with one or more hyphens. Strip them off @@ -497,37 +702,37 @@ find_opt(tOptions * pOpts, tOptState * pOptState) * strip off the "const" quality of the "default_opt" field. */ while (*(++pz) == '-') ; - def_opt = (void *)&(pOpts->specOptIdx.default_opt); - def = *def_opt; + def_opt = (void *)&(opts->specOptIdx.default_opt); + def = *def_opt; *def_opt = NO_EQUIVALENT; - res = opt_find_long(pOpts, pz, pOptState); - *def_opt = def; + res = opt_find_long(opts, pz, o_st); + *def_opt = (uint16_t)def; return res; } /* * Note the kind of flag/option marker */ - if (*((pOpts->pzCurOpt)++) != '-') + if (*((opts->pzCurOpt)++) != '-') return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ /* * Special hack for a hyphen by itself */ - if (*(pOpts->pzCurOpt) == NUL) + if (*(opts->pzCurOpt) == NUL) return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ /* * The current argument is to be processed as an option argument */ - pOpts->curOptIdx++; + opts->curOptIdx++; /* * We have an option marker. * Test the next character for long option indication */ - if (pOpts->pzCurOpt[0] == '-') { - if (*++(pOpts->pzCurOpt) == NUL) + if (opts->pzCurOpt[0] == '-') { + if (*++(opts->pzCurOpt) == NUL) /* * NORMAL COMPLETION - NOT this arg, but rest are operands */ @@ -537,13 +742,12 @@ find_opt(tOptions * pOpts, tOptState * pOptState) * 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, - pOpts->pzCurOpt-2); + if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) { + fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2); return FAILURE; } - return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState); + return opt_find_long(opts, opts->pzCurOpt, o_st); } /* @@ -551,13 +755,14 @@ find_opt(tOptions * pOpts, tOptState * pOptState) * option processing. Otherwise the character must be a * short (i.e. single character) option. */ - if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0) - return opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState); + if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); - return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState); + return opt_find_long(opts, opts->pzCurOpt, o_st); } -/* +/** @} + * * Local Variables: * mode: C * c-file-style: "stroustrup" |