Пример #1
0
/*=export_func  optionAlias
 * private:
 *
 * what:  relay an option to its alias
 * arg:   + tOptions *   + opts   + program options descriptor  +
 * arg:   + tOptDesc *   + old_od + the descriptor for this arg +
 * arg:   + unsigned int + alias  + the aliased-to option index +
 * ret-type: int
 *
 * doc:
 *  Handle one option as if it had been specified as another.  Exactly.
 *  Returns "-1" if the aliased-to option has appeared too many times.
=*/
int
optionAlias(tOptions * opts, tOptDesc * old_od, unsigned int alias)
{
    tOptDesc * new_od;

    if (opts <= OPTPROC_EMIT_LIMIT)
        return 0;

    new_od = opts->pOptDesc + alias;
    if ((unsigned)opts->optCt <= alias) {
        fputs(zbad_alias_id, stderr);
        option_exits(EXIT_FAILURE);
    }

    /*
     *  Copy over the option instance flags
     */
    new_od->fOptState &= OPTST_PERSISTENT_MASK;
    new_od->fOptState |= (old_od->fOptState & ~OPTST_PERSISTENT_MASK);
    new_od->optArg.argString = old_od->optArg.argString;

    /*
     *  Keep track of count only for DEFINED (command line) options.
     *  IF we have too many, build up an error message and bail.
     */
    if (  (new_od->fOptState & OPTST_DEFINED)
       && (++new_od->optOccCt > new_od->optMaxCt)  )
        return too_many_occurrences(opts, new_od);

    /*
     *  Clear the state bits and counters
     */
    old_od->fOptState &= OPTST_PERSISTENT_MASK;
    old_od->optOccCt   = 0;

    /*
     *  If there is a procedure to call, call it
     */
    if (new_od->pOptProc != NULL)
        (*new_od->pOptProc)(opts, new_od);
    return 0;
}
Пример #2
0
/**
 *  handle an option.
 *
 *  This routine handles equivalencing, sets the option state flags and
 *  invokes the handler procedure, if any.
 */
LOCAL tSuccess
handle_opt(tOptions * opts, tOptState * o_st)
{
    /*
     *  Save a copy of the option procedure pointer.
     *  If this is an equivalence class option, we still want this proc.
     */
    tOptDesc *  od = o_st->pOD;
    tOptProc *  opt_proc = od->pOptProc;
    if (od->fOptState & OPTST_ALLOC_ARG)
        AGFREE(od->optArg.argString);

    od->optArg.argString = o_st->pzOptArg;

    /*
     *  IF we are presetting options, then we will ignore any un-presettable
     *  options.  They are the ones either marked as such.
     */
    if (  ((opts->fOptSet & OPTPROC_PRESETTING) != 0)
            && ((od->fOptState & OPTST_NO_INIT) != 0)
       )
        return PROBLEM;

    /*
     *  IF this is an equivalence class option,
     *  THEN
     *      Save the option value that got us to this option
     *      entry.  (It may not be od->optChar[0], if this is an
     *      equivalence entry.)
     *      set the pointer to the equivalence class base
     */
    if (od->optEquivIndex != NO_EQUIVALENT) {
        tOptDesc * eqv_od = opts->pOptDesc + od->optEquivIndex;

        /*
         * IF the current option state has not been defined (set on the
         *    command line), THEN we will allow continued resetting of
         *    the value.  Once "defined", then it must not change.
         */
        if ((od->fOptState & OPTST_DEFINED) != 0) {
            /*
             *  The equivalenced-to option has been found on the command
             *  line before.  Make sure new occurrences are the same type.
             *
             *  IF this option has been previously equivalenced and
             *     it was not the same equivalenced-to option,
             *  THEN we have a usage problem.
             */
            if (eqv_od->optActualIndex != od->optIndex) {
                fprintf(stderr, zmultiway_bug, eqv_od->pz_Name, od->pz_Name,
                        (opts->pOptDesc + eqv_od->optActualIndex)->pz_Name);
                return FAILURE;
            }
        } else {
            /*
             *  Set the equivalenced-to actual option index to no-equivalent
             *  so that we set all the entries below.  This option may either
             *  never have been selected before, or else it was selected by
             *  some sort of "presetting" mechanism.
             */
            eqv_od->optActualIndex = NO_EQUIVALENT;
        }

        if (eqv_od->optActualIndex != od->optIndex) {
            /*
             *  First time through, copy over the state
             *  and add in the equivalence flag
             */
            eqv_od->optActualValue = od->optValue;
            eqv_od->optActualIndex = od->optIndex;
            o_st->flags |= OPTST_EQUIVALENCE;
        }

        /*
         *  Copy the most recent option argument.  set membership state
         *  is kept in 'eqv_od->optCookie'.  Do not overwrite.
         */
        eqv_od->optArg.argString = od->optArg.argString;
        od = eqv_od;

    } else {
        od->optActualValue = od->optValue;
        od->optActualIndex = od->optIndex;
    }

    od->fOptState &= OPTST_PERSISTENT_MASK;
    od->fOptState |= (o_st->flags & ~OPTST_PERSISTENT_MASK);

    /*
     *  Keep track of count only for DEFINED (command line) options.
     *  IF we have too many, build up an error message and bail.
     */
    if (  (od->fOptState & OPTST_DEFINED)
            && (++od->optOccCt > od->optMaxCt)  )
        return too_many_occurrences(opts, od);
    /*
     *  If provided a procedure to call, call it
     */
    if (opt_proc != NULL)
        (*opt_proc)(opts, od);

    return SUCCESS;
}