示例#1
0
/**
 *  Print the usage information for a single option.
 *
 * @param opts  the program option descriptor
 * @param od    the option descriptor
 * @param at    names of the option argument types
 */
static void
prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at)
{
    prt_preamble(opts, od, at);

    {
        char z[80];
        char const * atyp;

        /*
         *  Determine the argument type string first on its usage, then,
         *  when the option argument is required, base the type string on the
         *  argument type.
         */
        if (od->fOptState & OPTST_ARG_OPTIONAL) {
            atyp = at->pzOpt;

        } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_NONE:        atyp = at->pzNo;   break;
        case OPARG_TYPE_ENUMERATION: atyp = at->pzKey;  break;
        case OPARG_TYPE_FILE:        atyp = at->pzFile; break;
        case OPARG_TYPE_MEMBERSHIP:  atyp = at->pzKeyL; break;
        case OPARG_TYPE_BOOLEAN:     atyp = at->pzBool; break;
        case OPARG_TYPE_NUMERIC:     atyp = at->pzNum;  break;
        case OPARG_TYPE_HIERARCHY:   atyp = at->pzNest; break;
        case OPARG_TYPE_STRING:      atyp = at->pzStr;  break;
        case OPARG_TYPE_TIME:        atyp = at->pzTime; break;
        default:                     goto bogus_desc;
        }

#ifdef _WIN32
        if (at->pzOptFmt == zGnuOptFmt)
            snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp);
        else if (at->pzOptFmt == zGnuOptFmt + 2)
            snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp);
        else
#endif
        snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name,
                 (od->optMinCt != 0) ? at->pzReq : at->pzOpt);

        fprintf(option_usage_fp, line_fmt_buf, z, od->pzText);

        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
        case OPARG_TYPE_MEMBERSHIP:
            displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
        }
    }

    return;

 bogus_desc:
    fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
    exit(EX_SOFTWARE);
}
示例#2
0
/**
 *  Print the usage information for a single vendor option.
 *
 * @param pOpts     the program option descriptor
 * @param pOD       the option descriptor
 * @param pAT       names of the option argument types
 */
static void
prt_one_vendor(tOptions * pOptions, tOptDesc * pOD,
               arg_types_t * pAT, char const * usefmt)
{
    prt_preamble(pOptions, pOD, pAT);

    {
        char z[ 80 ];
        char const *  pzArgType;

        /*
         *  Determine the argument type string first on its usage, then,
         *  when the option argument is required, base the type string on the
         *  argument type.
         */
        if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
            pzArgType = pAT->pzOpt;

        } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_NONE:        pzArgType = pAT->pzNo;   break;
        case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey;  break;
        case OPARG_TYPE_FILE:        pzArgType = pAT->pzFile; break;
        case OPARG_TYPE_MEMBERSHIP:  pzArgType = pAT->pzKeyL; break;
        case OPARG_TYPE_BOOLEAN:     pzArgType = pAT->pzBool; break;
        case OPARG_TYPE_NUMERIC:     pzArgType = pAT->pzNum;  break;
        case OPARG_TYPE_HIERARCHY:   pzArgType = pAT->pzNest; break;
        case OPARG_TYPE_STRING:      pzArgType = pAT->pzStr;  break;
        case OPARG_TYPE_TIME:        pzArgType = pAT->pzTime; break;
        default:                     goto bogus_desc;
        }

        while (IS_WHITESPACE_CHAR(*pzArgType))  pzArgType++;
        if (*pzArgType == NUL)
            snprintf(z, sizeof(z), "%s", pOD->pz_Name);
        else
            snprintf(z, sizeof(z), "%s=%s", pOD->pz_Name, pzArgType);
        fprintf(option_usage_fp, usefmt, z, pOD->pzText);

        switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
        case OPARG_TYPE_MEMBERSHIP:
            displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum;
        }
    }

    return;

bogus_desc:
    fprintf(stderr, zInvalOptDesc, pOD->pz_Name);
    exit(EX_SOFTWARE);
}
示例#3
0
/**
 *  Print the usage information for a single vendor option.
 *
 * @param[in] opts    the program option descriptor
 * @param[in] od      the option descriptor
 * @param[in] argtp   names of the option argument types
 * @param[in] usefmt  format for primary usage line
 */
static void
prt_one_vendor(tOptions *    opts,  tOptDesc *   od,
               arg_types_t * argtp, char const * usefmt)
{
    prt_preamble(opts, od, argtp);

    {
        char z[ 80 ];
        char const *  pzArgType;

        /*
         *  Determine the argument type string first on its usage, then,
         *  when the option argument is required, base the type string on the
         *  argument type.
         */
        if (od->fOptState & OPTST_ARG_OPTIONAL) {
            pzArgType = argtp->pzOpt;

        } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_NONE:        pzArgType = argtp->pzNo;   break;
        case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey;  break;
        case OPARG_TYPE_FILE:        pzArgType = argtp->pzFile; break;
        case OPARG_TYPE_MEMBERSHIP:  pzArgType = argtp->pzKeyL; break;
        case OPARG_TYPE_BOOLEAN:     pzArgType = argtp->pzBool; break;
        case OPARG_TYPE_NUMERIC:     pzArgType = argtp->pzNum;  break;
        case OPARG_TYPE_HIERARCHY:   pzArgType = argtp->pzNest; break;
        case OPARG_TYPE_STRING:      pzArgType = argtp->pzStr;  break;
        case OPARG_TYPE_TIME:        pzArgType = argtp->pzTime; break;
        default:                     goto bogus_desc;
        }

        pzArgType = SPN_WHITESPACE_CHARS(pzArgType);
        if (*pzArgType == NUL)
            snprintf(z, sizeof(z), "%s", od->pz_Name);
        else
            snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType);
        fprintf(option_usage_fp, usefmt, z, od->pzText);

        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
        case OPARG_TYPE_MEMBERSHIP:
            displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
        }
    }

    return;

 bogus_desc:
    fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
    ao_bug(zbad_arg_type_msg);
}
示例#4
0
文件: restore.c 项目: cernekee/ocserv
/*
 *  optionFixupSavedOpts  Really, it just wipes out option state for
 *  options that are troublesome to copy.  viz., stacked strings and
 *  hierarcicaly valued option args.  We do duplicate string args that
 *  have been marked as allocated though.
 */
static void
fixupSavedOptionArgs(tOptions* pOpts)
{
    tOptions* p   = pOpts->pSavedState;
    tOptDesc* pOD = pOpts->pOptDesc;
    int       ct  = pOpts->optCt;

    /*
     *  Make sure that allocated stuff is only referenced in the
     *  archived copy of the data.
     */
    for (; ct-- > 0; pOD++)  {
        switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_STRING:
            if (pOD->fOptState & OPTST_STACKED) {
                tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
                q->optCookie = NULL;
            }
            if (pOD->fOptState & OPTST_ALLOC_ARG) {
                tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
                AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
            }
            break;

        case OPARG_TYPE_HIERARCHY:
        {
            tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
            q->optCookie = NULL;
        }
        }
    }
}
示例#5
0
static void
emit_action(tOptions * opts, tOptDesc * od)
{
    if (od->pOptProc == optionPrintVersion)
        printf(ECHO_N_EXIT, opts->pzPROGNAME, VER_STR);

    else if (od->pOptProc == optionPagedUsage)
        printf(PAGE_USAGE_TEXT, opts->pzPROGNAME);

    else if (od->pOptProc == optionLoadOpt) {
        printf(LVL3_CMD, NO_LOAD_WARN);
        printf(LVL3_CMD, YES_NEED_OPT_ARG);

    } else if (od->pz_NAME == NULL) {

        if (od->pOptProc == NULL) {
            printf(LVL3_CMD, NO_SAVE_OPTS);
            printf(LVL3_CMD, OK_NEED_OPT_ARG);
        } else
            printf(ECHO_N_EXIT, opts->pzPROGNAME, LONG_USE_STR);

    } else {
        if (od->optMaxCt == 1)
            printf(SGL_ARG_FMT, opts->pzPROGNAME, od->pz_NAME);
        else {
            if ((unsigned)od->optMaxCt < NOLIMIT)
                printf(CHK_MAX_COUNT, opts->pzPROGNAME,
                       od->pz_NAME, od->optMaxCt);

            printf(MULTI_ARG_FMT, opts->pzPROGNAME, od->pz_NAME);
        }

        /*
         *  Fix up the args.
         */
        if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NONE) {
            printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME);
            printf(LVL3_CMD, NO_ARG_NEEDED);

        } else if (od->fOptState & OPTST_ARG_OPTIONAL) {
            printf(SET_MULTI_ARG,  opts->pzPROGNAME, od->pz_NAME);
            printf(LVL3_CMD, OK_NEED_OPT_ARG);

        } else {
            printf(LVL3_CMD, YES_NEED_OPT_ARG);
        }
    }
    fputs(zOptionEndSelect, stdout);
}
示例#6
0
/**
 *  Print program details.
 * @param[in] opts  the program option descriptor
 */
static void
prt_prog_detail(tOptions * opts)
{
    bool need_intro = (opts->papzHomeList == NULL);

    /*
     *  Display all the places we look for config files, if we have
     *  a list of directories to search.
     */
    if (! need_intro)
        prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath);

    /*
     *  Let the user know about environment variable settings
     */
    if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) {
        if (need_intro)
            fputs(zPresetIntro, option_usage_fp);

        fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME);
    }

    /*
     *  IF we found an enumeration,
     *  THEN hunt for it again.  Call the handler proc with a NULL
     *       option struct pointer.  That tells it to display the keywords.
     */
    if (displayEnum) {
        int        ct     = opts->optCt;
        int        optNo  = 0;
        tOptDesc * od     = opts->pOptDesc;

        fputc(NL, option_usage_fp);
        fflush(option_usage_fp);
        do  {
            switch (OPTST_GET_ARGTYPE(od->fOptState)) {
            case OPARG_TYPE_ENUMERATION:
            case OPARG_TYPE_MEMBERSHIP:
                (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
            }
        } while (od++, optNo++, (--ct > 0));
    }

    /*
     *  If there is a detail string, now is the time for that.
     */
    if (opts->pzDetail != NULL)
        fputs(opts->pzDetail, option_usage_fp);
}
示例#7
0
文件: autoopts.c 项目: Distrotech/ntp
/*
 *  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 tSuccess
nextOption(tOptions* pOpts, tOptState* pOptState)
{
    {
        tSuccess res;
        res = findOptDesc(pOpts, pOptState);
        if (! SUCCESSFUL(res))
            return res;
    }

    if (  ((pOptState->flags & OPTST_DEFINED) != 0)
       && ((pOptState->pOD->fOptState & OPTST_NO_COMMAND) != 0)) {
        fprintf(stderr, zNotCmdOpt, pOptState->pOD->pz_Name);
        return FAILURE;
    }

    pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK);

    /*
     *  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.
     */
    {
        enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE;
        tSuccess res;

        if ((pOptState->flags & OPTST_DISABLED) != 0)
            arg_type = ARG_NONE;

        else if (OPTST_GET_ARGTYPE(pOptState->flags) == 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: 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;
        }

        return res;
    }
}
示例#8
0
/*=export_func  optionFindValue
 *
 * what:  find a hierarcicaly valued option instance
 * arg:   + const tOptDesc* + pOptDesc + an option with a nested arg type +
 * arg:   + char const*     + name     + name of value to find +
 * arg:   + char const*     + value    + the matching value    +
 *
 * ret_type:  const tOptionValue*
 * ret_desc:  a compound value structure
 *
 * doc:
 *  This routine will find an entry in a nested value option or configurable.
 *  It will search through the list and return a matching entry.
 *
 * err:
 *  The returned result is NULL and errno is set:
 *  @itemize @bullet
 *  @item
 *  @code{EINVAL} - the @code{pOptValue} does not point to a valid
 *  hierarchical option value.
 *  @item
 *  @code{ENOENT} - no entry matched the given name.
 *  @end itemize
=*/
const tOptionValue*
optionFindValue( const tOptDesc* pOptDesc,
                 char const* pzName, char const* pzVal )
{
    const tOptionValue* pRes = NULL;

    if (  (pOptDesc == NULL)
       || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY))  {
        errno = EINVAL;
    }

    else if (pOptDesc->optCookie == NULL) {
        errno = ENOENT;
    }

    else do {
        tArgList* pAL = pOptDesc->optCookie;
        int    ct   = pAL->useCt;
        void** ppOV = (void**)(pAL->apzArgs);

        if (ct == 0) {
            errno = ENOENT;
            break;
        }

        if (pzName == NULL) {
            pRes = (tOptionValue*)*ppOV;
            break;
        }

        while (--ct >= 0) {
            const tOptionValue* pOV = *(ppOV++);
            const tOptionValue* pRV = optionGetValue( pOV, pzName );

            if (pRV == NULL)
                continue;

            if (pzVal == NULL) {
                pRes = pOV;
                break;
            }
        }
        if (pRes == NULL)
            errno = ENOENT;
    } while (0);

    return pRes;
}
示例#9
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   PROGRAM DETAILS
 */
static void
printProgramDetails( tOptions* pOptions )
{
    ag_bool  initIntro = AG_TRUE;

    /*
     *  Display all the places we look for config files
     */
    printInitList( pOptions->papzHomeList, &initIntro,
                   pOptions->pzRcName, pOptions->pzProgPath );

    /*
     *  Let the user know about environment variable settings
     */
    if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
        if (initIntro)
            fputs( zPresetIntro, option_usage_fp );

        fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME );
    }

    /*
     *  IF we found an enumeration,
     *  THEN hunt for it again.  Call the handler proc with a NULL
     *       option struct pointer.  That tells it to display the keywords.
     */
    if (displayEnum) {
        int        ct     = pOptions->optCt;
        int        optNo  = 0;
        tOptDesc*  pOD    = pOptions->pOptDesc;

        fputc( '\n', option_usage_fp );
        fflush( option_usage_fp );
        do  {
            switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
            case OPARG_TYPE_ENUMERATION:
            case OPARG_TYPE_MEMBERSHIP:
                (*(pOD->pOptProc))( NULL, pOD );
            }
        }  while (pOD++, optNo++, (--ct > 0));
    }

    /*
     *  If there is a detail string, now is the time for that.
     */
    if (pOptions->pzDetail != NULL)
        fputs( pOptions->pzDetail, option_usage_fp );
}
示例#10
0
static void
printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc )
{
    if (pOptDesc->pOptProc == optionPrintVersion)
        printf( zTextExit, pOpts->pzPROGNAME, "VERSION" );

    else if (pOptDesc->pOptProc == optionPagedUsage)
        printf( zPagedUsageExit, pOpts->pzPROGNAME );

    else if (pOptDesc->pOptProc == optionLoadOpt) {
        printf( zCmdFmt, "echo 'Warning:  Cannot load options files' >&2" );
        printf( zCmdFmt, "OPT_ARG_NEEDED=YES" );

    } else if (pOptDesc->pz_NAME == NULL) {

        if (pOptDesc->pOptProc == NULL) {
            printf( zCmdFmt, "echo 'Warning:  Cannot save options files' "
                    ">&2" );
            printf( zCmdFmt, "OPT_ARG_NEEDED=OK" );
        } else
            printf( zTextExit, pOpts->pzPROGNAME, "LONGUSAGE" );

    } else {
        if (pOptDesc->optMaxCt == 1)
            printf( zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
        else {
            if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
                printf( zCountTest, pOpts->pzPROGNAME,
                        pOptDesc->pz_NAME, pOptDesc->optMaxCt );

            printf( zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
        }

        /*
         *  Fix up the args.
         */
        if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
            printf( zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );

        } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
            printf( zMayArg,  pOpts->pzPROGNAME, pOptDesc->pz_NAME );

        } else {
            fputs( zMustArg, stdout );
        }
    }
    fputs( zOptionEndSelect, stdout );
}
示例#11
0
/*=export_func  optionFindValue
 *
 * what:  find a hierarcicaly valued option instance
 * arg:   + const tOptDesc* + odesc + an option with a nested arg type +
 * arg:   + char const*     + name  + name of value to find +
 * arg:   + char const*     + val   + the matching value    +
 *
 * ret_type:  const tOptionValue*
 * ret_desc:  a compound value structure
 *
 * doc:
 *  This routine will find an entry in a nested value option or configurable.
 *  It will search through the list and return a matching entry.
 *
 * err:
 *  The returned result is NULL and errno is set:
 *  @itemize @bullet
 *  @item
 *  @code{EINVAL} - the @code{pOptValue} does not point to a valid
 *  hierarchical option value.
 *  @item
 *  @code{ENOENT} - no entry matched the given name.
 *  @end itemize
=*/
const tOptionValue *
optionFindValue(const tOptDesc * odesc, char const * name, char const * val)
{
    const tOptionValue * res = NULL;

    if (  (odesc == NULL)
       || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY))  {
        errno = EINVAL;
    }

    else if (odesc->optCookie == NULL) {
        errno = ENOENT;
    }

    else do {
        tArgList* argl  = odesc->optCookie;
        int       argct = argl->useCt;
        void **   poptv = (void**)(argl->apzArgs);

        if (argct == 0) {
            errno = ENOENT;
            break;
        }

        if (name == NULL) {
            res = (tOptionValue*)*poptv;
            break;
        }

        while (--argct >= 0) {
            const tOptionValue * ov = *(poptv++);
            const tOptionValue * rv = optionGetValue(ov, name);

            if (rv == NULL)
                continue;

            if (val == NULL) {
                res = ov;
                break;
            }
        }
        if (res == NULL)
            errno = ENOENT;
    } while (false);

    return res;
}
示例#12
0
static void
emit_action(tOptions * pOpts, tOptDesc* pOptDesc)
{
    if (pOptDesc->pOptProc == optionPrintVersion)
        printf(zTextExit, pOpts->pzPROGNAME, VER_STR);

    else if (pOptDesc->pOptProc == optionPagedUsage)
        printf(zPagedUsageExit, pOpts->pzPROGNAME);

    else if (pOptDesc->pOptProc == optionLoadOpt) {
        printf(zCmdFmt, NO_LOAD_WARN);
        printf(zCmdFmt, YES_NEED_OPT_ARG);

    } else if (pOptDesc->pz_NAME == NULL) {

        if (pOptDesc->pOptProc == NULL) {
            printf(zCmdFmt, NO_SAVE_OPTS);
            printf(zCmdFmt, OK_NEED_OPT_ARG);
        } else
            printf(zTextExit, pOpts->pzPROGNAME, LONG_USE_STR);

    } else {
        if (pOptDesc->optMaxCt == 1)
            printf(SGL_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        else {
            if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
                printf(zCountTest, pOpts->pzPROGNAME,
                       pOptDesc->pz_NAME, pOptDesc->optMaxCt);

            printf(MULTI_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        }

        /*
         *  Fix up the args.
         */
        if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
            printf(zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);

        } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
            printf(zMayArg,  pOpts->pzPROGNAME, pOptDesc->pz_NAME);

        } else {
            fputs(zMustArg, stdout);
        }
    }
    fputs(zOptionEndSelect, stdout);
}
示例#13
0
文件: restore.c 项目: cernekee/ocserv
/*=export_func optionFree
 *
 * what:  free allocated option processing memory
 * arg:   tOptions*, pOpts, program options descriptor
 *
 * doc:   AutoOpts sometimes allocates memory and puts pointers to it in the
 *        option state structures.  This routine deallocates all such memory.
 *
 * err:   As long as memory has not been corrupted,
 *        this routine is always successful.
=*/
void
optionFree(tOptions* pOpts)
{
 free_saved_state:
    {
        tOptDesc* p = pOpts->pOptDesc;
        int ct = pOpts->optCt;
        do  {
            if (p->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(p->optArg.argString);
                p->optArg.argString = NULL;
                p->fOptState &= ~OPTST_ALLOC_ARG;
            }

            switch (OPTST_GET_ARGTYPE(p->fOptState)) {
            case OPARG_TYPE_STRING:
#ifdef WITH_LIBREGEX
                if (  (p->fOptState & OPTST_STACKED)
                   && (p->optCookie != NULL)) {
                    p->optArg.argString = ".*";
                    optionUnstackArg(pOpts, p);
                }
#else
                /* leak memory */;
#endif
                break;

            case OPARG_TYPE_HIERARCHY:
                if (p->optCookie != NULL)
                    unload_arg_list(p->optCookie);
                break;
            }

            p->optCookie = NULL;
        } while (p++, --ct > 0);
    }
    if (pOpts->pSavedState != NULL) {
        tOptions * p = (tOptions*)pOpts->pSavedState;
        memcpy(pOpts, p, sizeof(*p));
        memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc));
        AGFREE(pOpts->pSavedState);
        pOpts->pSavedState = NULL;
        goto free_saved_state;
    }
}
示例#14
0
/*
 *  Process a string of short options glued together.  If the last one
 *  does or may take an argument, the do the argument processing and leave.
 */
static tSuccess
checkShortOpts( tOptions* pOpts, char* pzArg, tOptState* pOS,
                char** ppzOpts, int* pOptsIdx )
{
    while (*pzArg != NUL) {
        if (FAILED( shortOptionFind( pOpts, (tAoUC)*pzArg, pOS )))
            return FAILURE;

        /*
         *  See if we can have an arg.
         */
        if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
            pzArg++;

        } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
            /*
             *  Take an argument if it is not attached and it does not
             *  start with a hyphen.
             */
            if (pzArg[1] != NUL)
                return SUCCESS;

            pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
            if (*pzArg != '-')
                ppzOpts[ (*pOptsIdx)++ ] =
                    pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
            return SUCCESS;

        } else {
            /*
             *  IF we need another argument, be sure it is there and
             *  take it.
             */
            if (pzArg[1] == NUL) {
                if (pOpts->curOptIdx >= pOpts->origArgCt)
                    return FAILURE;
                ppzOpts[ (*pOptsIdx)++ ] =
                    pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
            }
            return SUCCESS;
        }
    }
    return SUCCESS;
}
示例#15
0
文件: sort.c 项目: 2asoft/freebsd
/*
 *  Process a string of short options glued together.  If the last one
 *  does or may take an argument, the do the argument processing and leave.
 */
static tSuccess
short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS,
             char ** opt_txt, uint32_t * opt_idx)
{
    while (*arg_txt != NUL) {
        if (FAILED(opt_find_short(opts, (uint8_t)*arg_txt, pOS)))
            return FAILURE;

        /*
         *  See if we can have an arg.
         */
        if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
            arg_txt++;

        } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
            /*
             *  Take an argument if it is not attached and it does not
             *  start with a hyphen.
             */
            if (arg_txt[1] != NUL)
                return SUCCESS;

            arg_txt = opts->origArgVect[ opts->curOptIdx ];
            if (*arg_txt != '-')
                opt_txt[ (*opt_idx)++ ] =
                    opts->origArgVect[ (opts->curOptIdx)++ ];
            return SUCCESS;

        } else {
            /*
             *  IF we need another argument, be sure it is there and
             *  take it.
             */
            if (arg_txt[1] == NUL) {
                if (opts->curOptIdx >= opts->origArgCt)
                    return FAILURE;
                opt_txt[ (*opt_idx)++ ] =
                    opts->origArgVect[ (opts->curOptIdx)++ ];
            }
            return SUCCESS;
        }
    }
    return SUCCESS;
}
示例#16
0
/**
 *  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
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);
}
示例#17
0
/*=export_func  optionFindNextValue
 *
 * what:  find a hierarcicaly valued option instance
 * arg:   + const tOptDesc* + pOptDesc + an option with a nested arg type +
 * arg:   + const tOptionValue* + pPrevVal + the last entry +
 * arg:   + char const*     + name     + name of value to find +
 * arg:   + char const*     + value    + the matching value    +
 *
 * ret_type:  const tOptionValue*
 * ret_desc:  a compound value structure
 *
 * doc:
 *  This routine will find the next entry in a nested value option or
 *  configurable.  It will search through the list and return the next entry
 *  that matches the criteria.
 *
 * err:
 *  The returned result is NULL and errno is set:
 *  @itemize @bullet
 *  @item
 *  @code{EINVAL} - the @code{pOptValue} does not point to a valid
 *  hierarchical option value.
 *  @item
 *  @code{ENOENT} - no entry matched the given name.
 *  @end itemize
=*/
const tOptionValue*
optionFindNextValue( const tOptDesc* pOptDesc, const tOptionValue* pPrevVal,
                 char const* pzName, char const* pzVal )
{
    int foundOldVal = 0;
    tOptionValue* pRes = NULL;

    if (  (pOptDesc == NULL)
       || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY))  {
        errno = EINVAL;
    }

    else if (pOptDesc->optCookie == NULL) {
        errno = ENOENT;
    }

    else do {
        tArgList* pAL = pOptDesc->optCookie;
        int    ct   = pAL->useCt;
        void** ppOV = (void**)pAL->apzArgs;

        if (ct == 0) {
            errno = ENOENT;
            break;
        }

        while (--ct >= 0) {
            tOptionValue* pOV = *(ppOV++);
            if (foundOldVal) {
                pRes = pOV;
                break;
            }
            if (pOV == pPrevVal)
                foundOldVal = 1;
        }
        if (pRes == NULL)
            errno = ENOENT;
    } while (0);

    return pRes;
}
示例#18
0
/*=export_func  optionFindNextValue
 *
 * FIXME: the handling of 'pzName' and 'pzVal' is just wrong.
 *
 * what:  find a hierarcicaly valued option instance
 * arg:   + const tOptDesc* + odesc + an option with a nested arg type +
 * arg:   + const tOptionValue* + pPrevVal + the last entry +
 * arg:   + char const*     + name     + name of value to find +
 * arg:   + char const*     + value    + the matching value    +
 *
 * ret_type:  const tOptionValue*
 * ret_desc:  a compound value structure
 *
 * doc:
 *  This routine will find the next entry in a nested value option or
 *  configurable.  It will search through the list and return the next entry
 *  that matches the criteria.
 *
 * err:
 *  The returned result is NULL and errno is set:
 *  @itemize @bullet
 *  @item
 *  @code{EINVAL} - the @code{pOptValue} does not point to a valid
 *  hierarchical option value.
 *  @item
 *  @code{ENOENT} - no entry matched the given name.
 *  @end itemize
=*/
tOptionValue const *
optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal,
                    char const * pzName, char const * pzVal)
{
    bool old_found = false;
    tOptionValue* res = NULL;

    (void)pzName;
    (void)pzVal;

    if (  (odesc == NULL)
       || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY))  {
        errno = EINVAL;
    }

    else if (odesc->optCookie == NULL) {
        errno = ENOENT;
    }

    else do {
        tArgList* argl = odesc->optCookie;
        int    ct   = argl->useCt;
        void** poptv = (void**)argl->apzArgs;

        while (--ct >= 0) {
            tOptionValue* pOV = *(poptv++);
            if (old_found) {
                res = pOV;
                break;
            }
            if (pOV == pPrevVal)
                old_found = true;
        }
        if (res == NULL)
            errno = ENOENT;
    } while (false);

    return res;
}
示例#19
0
/**
 * Print extended usage.  Usage/help was requested.
 *
 * @param opts  the program option descriptor
 * @param od   the option descriptor
 * @param title the title for the options
 */
static void
prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title)
{
    if (  ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
       && (od->optActualValue == VENDOR_OPTION_VALUE)) {
        prt_vendor_opts(opts, title);
        return;
    }

    /*
     *  IF there are option conflicts or dependencies,
     *  THEN print them here.
     */
    if ((od->pOptMust != NULL) || (od->pOptCant != NULL))
        prt_conflicts(opts, od);

    /*
     *  IF there is a disablement string
     *  THEN print the disablement info
     */
    if (od->pz_DisableName != NULL )
        fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName);

    /*
     *  Check for argument types that have callbacks with magical properties
     */
    switch (OPTST_GET_ARGTYPE(od->fOptState)) {
    case OPARG_TYPE_NUMERIC:
        /*
         *  IF the numeric option has a special callback,
         *  THEN call it, requesting the range or other special info
         */
        if (  (od->pOptProc != NULL)
           && (od->pOptProc != optionNumericVal) ) {
            (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
        }
        break;

    case OPARG_TYPE_FILE:
        (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
        break;
    }

    /*
     *  IF the option defaults to being enabled,
     *  THEN print that out
     */
    if (od->fOptState & OPTST_INITENABLED)
        fputs(zEnab + tab_skip_ct, option_usage_fp);

    /*
     *  IF  the option is in an equivalence class
     *        AND not the designated lead
     *  THEN print equivalence and leave it at that.
     */
    if (  (od->optEquivIndex != NO_EQUIVALENT)
       && (od->optEquivIndex != od->optActualIndex )  )  {
        fprintf(option_usage_fp, zalt_opt + tab_skip_ct,
                 opts->pOptDesc[ od->optEquivIndex ].pz_Name);
        return;
    }

    /*
     *  IF this particular option can NOT be preset
     *    AND some form of presetting IS allowed,
     *    AND it is not an auto-managed option (e.g. --help, et al.)
     *  THEN advise that this option may not be preset.
     */
    if (  ((od->fOptState & OPTST_NO_INIT) != 0)
       && (  (opts->papzHomeList != NULL)
          || (opts->pzPROGNAME != NULL)
          )
       && (od->optIndex < opts->presetOptCt)
       )

        fputs(zNoPreset + tab_skip_ct, option_usage_fp);

    /*
     *  Print the appearance requirements.
     */
    if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP)
        fputs(zMembers + tab_skip_ct, option_usage_fp);

    else switch (od->optMinCt) {
    case 1:
    case 0:
        switch (od->optMaxCt) {
        case 0:       fputs(zPreset + tab_skip_ct, option_usage_fp); break;
        case NOLIMIT: fputs(zNoLim  + tab_skip_ct, option_usage_fp); break;
        case 1:       break;
            /*
             * IF the max is more than one but limited, print "UP TO" message
             */
        default:
            fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break;
        }
        break;

    default:
        /*
         *  More than one is required.  Print the range.
         */
        fprintf(option_usage_fp, zMust + tab_skip_ct,
                od->optMinCt, od->optMaxCt);
    }

    if (  NAMED_OPTS(opts)
       && (opts->specOptIdx.default_opt == od->optIndex))
        fputs(zDefaultOpt + tab_skip_ct, option_usage_fp);
}
示例#20
0
文件: save.c 项目: cernekee/ocserv
/**
 * print one option entry to the save file.
 *
 * @param[in] fp    the file pointer for the save file
 * @param[in] od    the option descriptor to print
 * @param[in] l_arg the last argument for the option
 */
static void
prt_entry(FILE * fp, tOptDesc * od, char const * l_arg)
{
    int space_ct;

    /*
     *  There is an argument.  Pad the name so values line up.
     *  Not disabled *OR* this got equivalenced to another opt,
     *  then use current option name.
     *  Otherwise, there must be a disablement name.
     */
    {
        char const * pz =
            (! DISABLED_OPT(od) || (od->optEquivIndex != NO_EQUIVALENT))
            ? od->pz_Name
            : od->pz_DisableName;
        space_ct = 17 - strlen(pz);
        fputs(pz, fp);
    }

    if (  (l_arg == NULL)
       && (OPTST_GET_ARGTYPE(od->fOptState) != OPARG_TYPE_NUMERIC))
        goto end_entry;

    fputs(" = ", fp);
    while (space_ct-- > 0)  fputc(' ', fp);

    /*
     *  IF the option is numeric only,
     *  THEN the char pointer is really the number
     */
    if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NUMERIC)
        fprintf(fp, "%d", (int)(t_word)l_arg);

    else {
        for (;;) {
            char const * eol = strchr(l_arg, NL);

            /*
             *  IF this is the last line
             *  THEN bail and print it
             */
            if (eol == NULL)
                break;

            /*
             *  Print the continuation and the text from the current line
             */
            (void)fwrite(l_arg, (size_t)(eol - l_arg), (size_t)1, fp);
            l_arg = eol+1; /* advance the Last Arg pointer */
            fputs("\\\n", fp);
        }

        /*
         *  Terminate the entry
         */
        fputs(l_arg, fp);
    }

end_entry:
    fputc(NL, fp);
}
示例#21
0
文件: save.c 项目: cernekee/ocserv
/*=export_func  optionSaveFile
 *
 * what:  saves the option state to a file
 *
 * arg:   tOptions*,   opts,  program options descriptor
 *
 * doc:
 *
 * This routine will save the state of option processing to a file.  The name
 * of that file can be specified with the argument to the @code{--save-opts}
 * option, or by appending the @code{rcfile} attribute to the last
 * @code{homerc} attribute.  If no @code{rcfile} attribute was specified, it
 * will default to @code{.@i{programname}rc}.  If you wish to specify another
 * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro.
 *
 * The recommend usage is as follows:
 * @example
 *    optionProcess(&progOptions, argc, argv);
 *    if (i_want_a_non_standard_place_for_this)
 *        SET_OPT_SAVE_OPTS("myfilename");
 *    optionSaveFile(&progOptions);
 * @end example
 *
 * err:
 *
 * If no @code{homerc} file was specified, this routine will silently return
 * and do nothing.  If the output file cannot be created or updated, a message
 * will be printed to @code{stderr} and the routine will return.
=*/
void
optionSaveFile(tOptions * opts)
{
    tOptDesc *  od;
    int         ct;
    FILE *      fp = open_sv_file(opts);

    if (fp == NULL)
        return;

    /*
     *  FOR each of the defined options, ...
     */
    ct = opts->presetOptCt;
    od = opts->pOptDesc;
    do  {
        tOptDesc * p;

        /*
         *  IF    the option has not been defined
         *     OR it does not take an initialization value
         *     OR it is equivalenced to another option
         *  THEN continue (ignore it)
         *
         *  Equivalenced options get picked up when the equivalenced-to
         *  option is processed.
         */
        if (UNUSED_OPT(od))
            continue;

        if ((od->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0)
            continue;

        if (  (od->optEquivIndex != NO_EQUIVALENT)
           && (od->optEquivIndex != od->optIndex))
            continue;

        /*
         *  The option argument data are found at the equivalenced-to option,
         *  but the actual option argument type comes from the original
         *  option descriptor.  Be careful!
         */
        p = ((od->fOptState & OPTST_EQUIVALENCE) != 0)
            ? (opts->pOptDesc + od->optActualIndex) : od;

        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_NONE:
            prt_no_arg_opt(fp, p, od);
            break;

        case OPARG_TYPE_NUMERIC:
            prt_entry(fp, p, (void*)(p->optArg.argInt));
            break;

        case OPARG_TYPE_STRING:
            prt_str_arg(fp, p);
            break;

        case OPARG_TYPE_ENUMERATION:
            prt_enum_arg(fp, p);
            break;

        case OPARG_TYPE_MEMBERSHIP:
            prt_set_arg(fp, p);
            break;

        case OPARG_TYPE_BOOLEAN:
            prt_entry(fp, p, p->optArg.argBool ? "true" : "false");
            break;

        case OPARG_TYPE_HIERARCHY:
            prt_nested(fp, p);
            break;

        case OPARG_TYPE_FILE:
            prt_file_arg(fp, p, opts);
            break;

        default:
            break; /* cannot handle - skip it */
        }
    } while (od++, (--ct > 0));

    fclose(fp);
}
示例#22
0
static void
emitSetup( tOptions* pOpts )
{
    tOptDesc* pOptDesc = pOpts->pOptDesc;
    int       optionCt = pOpts->presetOptCt;
    char const* pzFmt;
    char const* pzDefault;

    for (;optionCt > 0; pOptDesc++, --optionCt) {
        char zVal[16];

        /*
         *  Options that are either usage documentation or are compiled out
         *  are not to be processed.
         */
        if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
            continue;

        if (pOptDesc->optMaxCt > 1)
             pzFmt = zMultiDef;
        else pzFmt = zSingleDef;

        /*
         *  IF this is an enumeration/bitmask option, then convert the value
         *  to a string before printing the default value.
         */
        switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
            (*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc );
            pzDefault = pOptDesc->optArg.argString;
            break;

        /*
         *  Numeric and membership bit options are just printed as a number.
         */
        case OPARG_TYPE_NUMERIC:
            snprintf( zVal, sizeof( zVal ), "%d",
                      (int)pOptDesc->optArg.argInt );
            pzDefault = zVal;
            break;

        case OPARG_TYPE_MEMBERSHIP:
            snprintf( zVal, sizeof( zVal ), "%lu",
                      (unsigned long)pOptDesc->optArg.argIntptr );
            pzDefault = zVal;
            break;

        case OPARG_TYPE_BOOLEAN:
            pzDefault = (pOptDesc->optArg.argBool) ? "true" : "false";
            break;

        default:
            if (pOptDesc->optArg.argString == NULL) {
                if (pzFmt == zSingleDef)
                    pzFmt = zSingleNoDef;
                pzDefault = NULL;
            }
            else
                pzDefault = pOptDesc->optArg.argString;
        }

        printf( pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault );
    }
}
示例#23
0
/**
 *  Load an option from a block of text.  The text must start with the
 *  configurable/option name and be followed by its associated value.
 *  That value may be processed in any of several ways.  See "tOptionLoadMode"
 *  in autoopts.h.
 *
 * @param[in,out] opts       program options descriptor
 * @param[in,out] opt_state  option processing state
 * @param[in,out] line       source line with long option name in it
 * @param[in]     direction  current processing direction (preset or not)
 * @param[in]     load_mode  option loading mode (OPTION_LOAD_*)
 */
LOCAL void
loadOptionLine(
    tOptions *  opts,
    tOptState * opt_state,
    char *      line,
    tDirection  direction,
    tOptionLoadMode   load_mode )
{
    line = SPN_LOAD_LINE_SKIP_CHARS(line);

    {
        char * arg = assemble_arg_val(line, load_mode);

        if (! SUCCESSFUL(opt_find_long(opts, line, opt_state)))
            return;

        if (opt_state->flags & OPTST_NO_INIT)
            return;

        opt_state->pzOptArg = arg;
    }

    switch (opt_state->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) {
    case 0:
        /*
         *  The selected option has no immediate action.
         *  THEREFORE, if the direction is PRESETTING
         *  THEN we skip this option.
         */
        if (PRESETTING(direction))
            return;
        break;

    case OPTST_IMM:
        if (PRESETTING(direction)) {
            /*
             *  We are in the presetting direction with an option we handle
             *  immediately for enablement, but normally for disablement.
             *  Therefore, skip if disabled.
             */
            if ((opt_state->flags & OPTST_DISABLED) == 0)
                return;
        } else {
            /*
             *  We are in the processing direction with an option we handle
             *  immediately for enablement, but normally for disablement.
             *  Therefore, skip if NOT disabled.
             */
            if ((opt_state->flags & OPTST_DISABLED) != 0)
                return;
        }
        break;

    case OPTST_DISABLE_IMM:
        if (PRESETTING(direction)) {
            /*
             *  We are in the presetting direction with an option we handle
             *  immediately for disablement, but normally for disablement.
             *  Therefore, skip if NOT disabled.
             */
            if ((opt_state->flags & OPTST_DISABLED) != 0)
                return;
        } else {
            /*
             *  We are in the processing direction with an option we handle
             *  immediately for disablement, but normally for disablement.
             *  Therefore, skip if disabled.
             */
            if ((opt_state->flags & OPTST_DISABLED) == 0)
                return;
        }
        break;

    case OPTST_IMM|OPTST_DISABLE_IMM:
        /*
         *  The selected option is always for immediate action.
         *  THEREFORE, if the direction is PROCESSING
         *  THEN we skip this option.
         */
        if (PROCESSING(direction))
            return;
        break;
    }

    /*
     *  Fix up the args.
     */
    if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) {
        if (*opt_state->pzOptArg != NUL)
            return;
        opt_state->pzOptArg = NULL;

    } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) {
        if (*opt_state->pzOptArg == NUL)
             opt_state->pzOptArg = NULL;
        else {
            AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg");
            opt_state->flags |= OPTST_ALLOC_ARG;
        }

    } else {
        if (*opt_state->pzOptArg == NUL)
             opt_state->pzOptArg = zNil;
        else {
            AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg");
            opt_state->flags |= OPTST_ALLOC_ARG;
        }
    }

    {
        tOptionLoadMode sv = option_load_mode;
        option_load_mode = load_mode;
        handle_opt(opts, opt_state);
        option_load_mode = sv;
    }
}
示例#24
0
/*=export_func  optionPutShell
 * what:  write a portable shell script to parse options
 * private:
 * arg:   tOptions *, pOpts, the program options descriptor
 * doc:   This routine will emit portable shell script text for parsing
 *        the options described in the option definitions.
=*/
void
optionPutShell(tOptions * pOpts)
{
    int  optIx = 0;

    printf(zOptCtFmt, pOpts->curOptIdx-1);

    do  {
        tOptDesc * pOD = pOpts->pOptDesc + optIx;

        if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0)
            continue;

        /*
         *  Equivalence classes are hard to deal with.  Where the
         *  option data wind up kind of squishes around.  For the purposes
         *  of emitting shell state, they are not recommended, but we'll
         *  do something.  I guess we'll emit the equivalenced-to option
         *  at the point in time when the base option is found.
         */
        if (pOD->optEquivIndex != NO_EQUIVALENT)
            continue; /* equivalence to a different option */

        /*
         *  Equivalenced to a different option.  Process the current option
         *  as the equivalenced-to option.  Keep the persistent state bits,
         *  but copy over the set-state bits.
         */
        if (pOD->optActualIndex != optIx) {
            tOptDesc * p  = pOpts->pOptDesc + pOD->optActualIndex;
            p->optArg     = pOD->optArg;
            p->fOptState &= OPTST_PERSISTENT_MASK;
            p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
            printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
            pOD = p;
        }

        /*
         *  If the argument type is a set membership bitmask, then we always
         *  emit the thing.  We do this because it will always have some sort
         *  of bitmask value and we need to emit the bit values.
         */
        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
            print_membership(pOpts, pOD);
            continue;
        }

        /*
         *  IF the option was either specified or it wakes up enabled,
         *  then we will emit information.  Otherwise, skip it.
         *  The idea is that if someone defines an option to initialize
         *  enabled, we should tell our shell script that it is enabled.
         */
        if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD))
            continue;

        /*
         *  Handle stacked arguments
         */
        if (  (pOD->fOptState & OPTST_STACKED)
           && (pOD->optCookie != NULL) )  {
            print_stacked_arg(pOpts, pOD);
            continue;
        }

        /*
         *  If the argument has been disabled,
         *  Then set its value to the disablement string
         */
        if ((pOD->fOptState & OPTST_DISABLED) != 0) {
            printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
                   (pOD->pz_DisablePfx != NULL)
                   ? pOD->pz_DisablePfx : "false");
            continue;
        }

        /*
         *  If the argument type is numeric, the last arg pointer
         *  is really the VALUE of the string that was pointed to.
         */
        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
            printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
                   (int)pOD->optArg.argInt);
            continue;
        }

        /*
         *  If the argument type is an enumeration, then it is much
         *  like a text value, except we call the callback function
         *  to emit the value corresponding to the "optArg" number.
         */
        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
            print_enumeration(pOpts, pOD);
            continue;
        }

        /*
         *  If the argument type is numeric, the last arg pointer
         *  is really the VALUE of the string that was pointed to.
         */
        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
            printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
                   (pOD->optArg.argBool == 0) ? "false" : "true");
            continue;
        }

        /*
         *  IF the option has an empty value,
         *  THEN we set the argument to the occurrence count.
         */
        if (  (pOD->optArg.argString == NULL)
           || (pOD->optArg.argString[0] == NUL) ) {

            printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
                   pOD->optOccCt);
            continue;
        }

        /*
         *  This option has a text value
         */
        printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
        print_quot_str(pOD->optArg.argString);
        printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);

    } while (++optIx < pOpts->presetOptCt );

    if (  ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
       && (pOpts->curOptIdx < pOpts->origArgCt))
        print_reordering(pOpts);

    fflush(stdout);
}
示例#25
0
/*
 *  Load an option from a block of text.  The text must start with the
 *  configurable/option name and be followed by its associated value.
 *  That value may be processed in any of several ways.  See "tOptionLoadMode"
 *  in autoopts.h.
 */
LOCAL void
loadOptionLine(
    tOptions*   pOpts,
    tOptState*  pOS,
    char*       pzLine,
    tDirection  direction,
    tOptionLoadMode   load_mode )
{
    while (isspace( (int)*pzLine ))  pzLine++;

    {
        char* pzArg = assembleArgValue( pzLine, load_mode );

        if (! SUCCESSFUL( longOptionFind( pOpts, pzLine, pOS )))
            return;
        if (pOS->flags & OPTST_NO_INIT)
            return;
        pOS->pzOptArg = pzArg;
    }

    switch (pOS->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) {
    case 0:
        /*
         *  The selected option has no immediate action.
         *  THEREFORE, if the direction is PRESETTING
         *  THEN we skip this option.
         */
        if (PRESETTING(direction))
            return;
        break;

    case OPTST_IMM:
        if (PRESETTING(direction)) {
            /*
             *  We are in the presetting direction with an option we handle
             *  immediately for enablement, but normally for disablement.
             *  Therefore, skip if disabled.
             */
            if ((pOS->flags & OPTST_DISABLED) == 0)
                return;
        } else {
            /*
             *  We are in the processing direction with an option we handle
             *  immediately for enablement, but normally for disablement.
             *  Therefore, skip if NOT disabled.
             */
            if ((pOS->flags & OPTST_DISABLED) != 0)
                return;
        }
        break;

    case OPTST_DISABLE_IMM:
        if (PRESETTING(direction)) {
            /*
             *  We are in the presetting direction with an option we handle
             *  immediately for disablement, but normally for disablement.
             *  Therefore, skip if NOT disabled.
             */
            if ((pOS->flags & OPTST_DISABLED) != 0)
                return;
        } else {
            /*
             *  We are in the processing direction with an option we handle
             *  immediately for disablement, but normally for disablement.
             *  Therefore, skip if disabled.
             */
            if ((pOS->flags & OPTST_DISABLED) == 0)
                return;
        }
        break;

    case OPTST_IMM|OPTST_DISABLE_IMM:
        /*
         *  The selected option is always for immediate action.
         *  THEREFORE, if the direction is PROCESSING
         *  THEN we skip this option.
         */
        if (PROCESSING(direction))
            return;
        break;
    }

    /*
     *  Fix up the args.
     */
    if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
        if (*pOS->pzOptArg != NUL)
            return;
        pOS->pzOptArg = NULL;

    } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
        if (*pOS->pzOptArg == NUL)
             pOS->pzOptArg = NULL;
        else {
            AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" );
            pOS->flags |= OPTST_ALLOC_ARG;
        }

    } else {
        if (*pOS->pzOptArg == NUL)
             pOS->pzOptArg = zNil;
        else {
            AGDUPSTR( pOS->pzOptArg, pOS->pzOptArg, "option argument" );
            pOS->flags |= OPTST_ALLOC_ARG;
        }
    }

    {
        tOptionLoadMode sv = option_load_mode;
        option_load_mode = load_mode;
        handleOption( pOpts, pOS );
        option_load_mode = sv;
    }
}
示例#26
0
/*
 *  If the program wants sorted options (separated operands and options),
 *  then this routine will to the trick.
 */
LOCAL void
optionSort( tOptions* pOpts )
{
    char** ppzOpts;
    char** ppzOpds;
    int    optsIdx = 0;
    int    opdsIdx = 0;

    tOptState os = OPTSTATE_INITIALIZER(DEFINED);

    /*
     *  Disable for POSIX conformance, or if there are no operands.
     */
    if (  (getenv( "POSIXLY_CORRECT" ) != NULL)
       || NAMED_OPTS(pOpts))
        return;

    /*
     *  Make sure we can allocate two full-sized arg vectors.
     */
    ppzOpts = malloc( pOpts->origArgCt * sizeof( char* ));
    if (ppzOpts == NULL)
        goto exit_no_mem;

    ppzOpds = malloc( pOpts->origArgCt * sizeof( char* ));
    if (ppzOpds == NULL) {
        free( ppzOpts );
        goto exit_no_mem;
    }

    pOpts->curOptIdx = 1;
    pOpts->pzCurOpt  = NULL;

    /*
     *  Now, process all the options from our current position onward.
     *  (This allows interspersed options and arguments for the few
     *  non-standard programs that require it.)
     */
    for (;;) {
        char* pzArg;
        tSuccess res;

        /*
         *  If we're out of arguments, we're done.  Join the option and
         *  operand lists into the original argument vector.
         */
        if (pOpts->curOptIdx >= pOpts->origArgCt) {
            errno = 0;
            goto joinLists;
        }

        pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
        if (*pzArg != '-') {
            ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
            continue;
        }

        switch (pzArg[1]) {
        case NUL:
            /*
             *  A single hyphen is an operand.
             */
            ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
            continue;

        case '-':
            /*
             *  Two consecutive hypens.  Put them on the options list and then
             *  _always_ force the remainder of the arguments to be operands.
             */
            if (pzArg[2] == NUL) {
                ppzOpts[ optsIdx++ ] =
                    pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
                goto restOperands;
            }
            res = longOptionFind( pOpts, pzArg+2, &os );
            break;

        default:
            /*
             *  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) {
                res = longOptionFind( pOpts, pzArg+1, &os );
            } else {
                res = shortOptionFind( pOpts, (tAoUC)pzArg[1], &os );
            }
            break;
        }
        if (FAILED( res )) {
            errno = EINVAL;
            goto freeTemps;
        }

        /*
         *  We've found an option.  Add the argument to the option list.
         *  Next, we have to see if we need to pull another argument to be
         *  used as the option argument.
         */
        ppzOpts[ optsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];

        if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) {
            /*
             *  No option argument.  If we have a short option here,
             *  then scan for short options until we get to the end
             *  of the argument string.
             */
            if (  (os.optType == TOPT_SHORT)
               && FAILED( checkShortOpts( pOpts, pzArg+2, &os,
                                          ppzOpts, &optsIdx )) )  {
                errno = EINVAL;
                goto freeTemps;
            }

        } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) {
            switch (mayHandleArg( pOpts, pzArg+2, &os, ppzOpts, &optsIdx )) {
            case FAILURE: errno = EIO; goto freeTemps;
            case PROBLEM: errno = 0;   goto joinLists;
            }

        } else {
            switch (mustHandleArg( pOpts, pzArg+2, &os, ppzOpts, &optsIdx )) {
            case PROBLEM:
            case FAILURE: errno = EIO; goto freeTemps;
            }
        }
    } /* for (;;) */

 restOperands:
    while (pOpts->curOptIdx < pOpts->origArgCt)
        ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];

 joinLists:
    if (optsIdx > 0)
        memcpy( pOpts->origArgVect + 1, ppzOpts, optsIdx * sizeof( char* ));
    if (opdsIdx > 0)
        memcpy( pOpts->origArgVect + 1 + optsIdx,
                ppzOpds, opdsIdx * sizeof( char* ));

 freeTemps:
    free( ppzOpts );
    free( ppzOpds );
    return;

 exit_no_mem:
    errno = ENOMEM;
    return;
}
示例#27
0
static void
enum_err(tOptions * pOpts, tOptDesc * pOD,
         char const * const * paz_names, int name_ct)
{
    size_t max_len = 0;
    size_t ttl_len = 0;
    int    ct_down = name_ct;
    int    hidden  = 0;

    /*
     *  A real "pOpts" pointer means someone messed up.  Give a real error.
     */
    if (pOpts > OPTPROC_EMIT_LIMIT)
        fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName,
                pOD->optArg.argString, pOD->pz_Name);

    fprintf(option_usage_fp, zValidKeys, pOD->pz_Name);

    /*
     *  If the first name starts with this funny character, then we have
     *  a first value with an unspellable name.  You cannot specify it.
     *  So, we don't list it either.
     */
    if (**paz_names == 0x7F) {
        paz_names++;
        hidden  = 1;
        ct_down = --name_ct;
    }

    /*
     *  Figure out the maximum length of any name, plus the total length
     *  of all the names.
     */
    {
        char const * const * paz = paz_names;

        do  {
            size_t len = strlen(*(paz++)) + 1;
            if (len > max_len)
                max_len = len;
            ttl_len += len;
        } while (--ct_down > 0);

        ct_down = name_ct;
    }

    /*
     *  IF any one entry is about 1/2 line or longer, print one per line
     */
    if (max_len > 35) {
        do  {
            fprintf(option_usage_fp, ENUM_ERR_LINE, *(paz_names++));
        } while (--ct_down > 0);
    }

    /*
     *  ELSE IF they all fit on one line, then do so.
     */
    else if (ttl_len < 76) {
        fputc(' ', option_usage_fp);
        do  {
            fputc(' ', option_usage_fp);
            fputs(*(paz_names++), option_usage_fp);
        } while (--ct_down > 0);
        fputc(NL, option_usage_fp);
    }

    /*
     *  Otherwise, columnize the output
     */
    else {
        unsigned int ent_no = 0;
        char  zFmt[16];  /* format for all-but-last entries on a line */

        sprintf(zFmt, ENUM_ERR_WIDTH, (int)max_len);
        max_len = 78 / max_len; /* max_len is now max entries on a line */
        fputs(TWO_SPACES_STR, option_usage_fp);

        /*
         *  Loop through all but the last entry
         */
        ct_down = name_ct;
        while (--ct_down > 0) {
            if (++ent_no == max_len) {
                /*
                 *  Last entry on a line.  Start next line, too.
                 */
                fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++));
                ent_no = 0;
            }

            else
                fprintf(option_usage_fp, zFmt, *(paz_names++) );
        }
        fprintf(option_usage_fp, NLSTR_FMT, *paz_names);
    }

    if (pOpts > OPTPROC_EMIT_LIMIT) {
        fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);

        (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
        /* NOTREACHED */
    }

    if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
        fprintf(option_usage_fp, zLowerBits, name_ct);
        fputs(zSetMemberSettings, option_usage_fp);
    } else {
        fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);
    }
}
示例#28
0
static void
emit_setup(tOptions * opts)
{
    tOptDesc *   od     = opts->pOptDesc;
    int          opt_ct = opts->presetOptCt;
    char const * fmt;
    char const * def_val;

    for (;opt_ct > 0; od++, --opt_ct) {
        char int_val_buf[32];

        /*
         *  Options that are either usage documentation or are compiled out
         *  are not to be processed.
         */
        if (SKIP_OPT(od) || (od->pz_NAME == NULL))
            continue;

        if (od->optMaxCt > 1)
             fmt = MULTI_DEF_FMT;
        else fmt = SGL_DEF_FMT;

        /*
         *  IF this is an enumeration/bitmask option, then convert the value
         *  to a string before printing the default value.
         */
        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
            (*(od->pOptProc))(OPTPROC_EMIT_SHELL, od );
            def_val = od->optArg.argString;
            break;

        /*
         *  Numeric and membership bit options are just printed as a number.
         */
        case OPARG_TYPE_NUMERIC:
            snprintf(int_val_buf, sizeof(int_val_buf), "%d",
                     (int)od->optArg.argInt);
            def_val = int_val_buf;
            break;

        case OPARG_TYPE_MEMBERSHIP:
            snprintf(int_val_buf, sizeof(int_val_buf), "%lu",
                     (unsigned long)od->optArg.argIntptr);
            def_val = int_val_buf;
            break;

        case OPARG_TYPE_BOOLEAN:
            def_val = (od->optArg.argBool) ? TRUE_STR : FALSE_STR;
            break;

        default:
            if (od->optArg.argString == NULL) {
                if (fmt == SGL_DEF_FMT)
                    fmt = SGL_NO_DEF_FMT;
                def_val = NULL;
            }
            else
                def_val = od->optArg.argString;
        }

        printf(fmt, opts->pzPROGNAME, od->pz_NAME, def_val);
    }
}
示例#29
0
/*
 *  Print the usage information for a single option.
 */
static void
printOneUsage(
    tOptions*     pOptions,
    tOptDesc*     pOD,
    arg_types_t*  pAT )
{
    /*
     *  Flag prefix: IF no flags at all, then omit it.  If not printable
     *  (not allowed for this option), then blank, else print it.
     *  Follow it with a comma if we are doing GNU usage and long
     *  opts are to be printed too.
     */
    if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
        fputs( pAT->pzSpc, option_usage_fp );
    else if (! isgraph( pOD->optValue)) {
        if (  (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
            fputc( ' ', option_usage_fp );
        fputs( pAT->pzNoF, option_usage_fp );
    } else {
        fprintf( option_usage_fp, "   -%c", pOD->optValue );
        if (  (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
            fputs( ", ", option_usage_fp );
    }

    {
        char  z[ 80 ];
        tCC*  pzArgType;
        /*
         *  Determine the argument type string first on its usage, then,
         *  when the option argument is required, base the type string on the
         *  argument type.
         */
        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) {
            pzArgType = pAT->pzNo;

        } else if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
            pzArgType = pAT->pzOpt;

        } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey;  break;
        case OPARG_TYPE_MEMBERSHIP:  pzArgType = pAT->pzKeyL; break;
        case OPARG_TYPE_BOOLEAN:     pzArgType = pAT->pzBool; break;
        case OPARG_TYPE_NUMERIC:     pzArgType = pAT->pzNum;  break;
        case OPARG_TYPE_HIERARCHY:   pzArgType = pAT->pzNest; break;
        case OPARG_TYPE_STRING:      pzArgType = pAT->pzStr;  break;
        default:                     goto bogus_desc;         break;
        }

        snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
                  (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt );

        fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText );

        switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
        case OPARG_TYPE_ENUMERATION:
        case OPARG_TYPE_MEMBERSHIP:
            displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum;
        }
    }
    return;

 bogus_desc:
    fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
    exit( EX_SOFTWARE );
}
示例#30
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   PER OPTION TYPE USAGE INFORMATION
 */
static void
printExtendedUsage(
    tOptions*     pOptions,
    tOptDesc*     pOD,
    arg_types_t*  pAT )
{
    /*
     *  IF there are option conflicts or dependencies,
     *  THEN print them here.
     */
    if (  (pOD->pOptMust != NULL)
       || (pOD->pOptCant != NULL) ) {

        fputs( zTabHyp, option_usage_fp );

        /*
         *  DEPENDENCIES:
         */
        if (pOD->pOptMust != NULL) {
            const int* pOptNo = pOD->pOptMust;

            fputs( zReqThese, option_usage_fp );
            for (;;) {
                fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
                             *pOptNo ].pz_Name );
                if (*++pOptNo == NO_EQUIVALENT)
                    break;
            }

            if (pOD->pOptCant != NULL)
                fputs( zTabHypAnd, option_usage_fp );
        }

        /*
         *  CONFLICTS:
         */
        if (pOD->pOptCant != NULL) {
            const int* pOptNo = pOD->pOptCant;

            fputs( zProhib, option_usage_fp );
            for (;;) {
                fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
                             *pOptNo ].pz_Name );
                if (*++pOptNo == NO_EQUIVALENT)
                    break;
            }
        }
    }

    /*
     *  IF there is a disablement string
     *  THEN print the disablement info
     */
    if (pOD->pz_DisableName != NULL )
        fprintf( option_usage_fp, zDis, pOD->pz_DisableName );

    /*
     *  IF the numeric option has a special callback,
     *  THEN call it, requesting the range or other special info
     */
    if (  (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC)
       && (pOD->pOptProc != NULL)
       && (pOD->pOptProc != optionNumericVal) ) {
        (*(pOD->pOptProc))( pOptions, NULL );
    }

    /*
     *  IF the option defaults to being enabled,
     *  THEN print that out
     */
    if (pOD->fOptState & OPTST_INITENABLED)
        fputs( zEnab, option_usage_fp );

    /*
     *  IF  the option is in an equivalence class
     *        AND not the designated lead
     *  THEN print equivalence and leave it at that.
     */
    if (  (pOD->optEquivIndex != NO_EQUIVALENT)
       && (pOD->optEquivIndex != pOD->optActualIndex )  )  {
        fprintf( option_usage_fp, zAlt,
                 pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name );
        return;
    }

    /*
     *  IF this particular option can NOT be preset
     *    AND some form of presetting IS allowed,
     *    AND it is not an auto-managed option (e.g. --help, et al.)
     *  THEN advise that this option may not be preset.
     */
    if (  ((pOD->fOptState & OPTST_NO_INIT) != 0)
       && (  (pOptions->papzHomeList != NULL)
          || (pOptions->pzPROGNAME != NULL)
          )
       && (pOD->optIndex < pOptions->presetOptCt)
       )

        fputs( zNoPreset, option_usage_fp );

    /*
     *  Print the appearance requirements.
     */
    if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
        fputs( zMembers, option_usage_fp );

    else switch (pOD->optMinCt) {
    case 1:
    case 0:
        switch (pOD->optMaxCt) {
        case 0:       fputs( zPreset, option_usage_fp ); break;
        case NOLIMIT: fputs( zNoLim, option_usage_fp );  break;
        case 1:       break;
            /*
             * IF the max is more than one but limited, print "UP TO" message
             */
        default:      fprintf( option_usage_fp, zUpTo, pOD->optMaxCt );  break;
        }
        break;

    default:
        /*
         *  More than one is required.  Print the range.
         */
        fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt );
    }

    if (  NAMED_OPTS( pOptions )
       && (pOptions->specOptIdx.default_opt == pOD->optIndex))
        fputs( zDefaultOpt, option_usage_fp );
}