/*=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; }
/** * 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; }