/*=export_func optionProcess * * what: this is the main option processing routine * * arg: + tOptions* + opts + program options descriptor + * arg: + int + a_ct + program arg count + * arg: + char** + a_v + program arg vector + * * ret_type: int * ret_desc: the count of the arguments processed * * doc: * * This is the main entry point for processing options. It is intended * that this procedure be called once at the beginning of the execution of * a program. Depending on options selected earlier, it is sometimes * necessary to stop and restart option processing, or to select completely * different sets of options. This can be done easily, but you generally * do not want to do this. * * The number of arguments processed always includes the program name. * If one of the arguments is "--", then it is counted and the processing * stops. If an error was encountered and errors are to be tolerated, then * the returned value is the index of the argument causing the error. * A hyphen by itself ("-") will also cause processing to stop and will * @emph{not} be counted among the processed arguments. A hyphen by itself * is treated as an operand. Encountering an operand stops option * processing. * * err: Errors will cause diagnostics to be printed. @code{exit(3)} may * or may not be called. It depends upon whether or not the options * were generated with the "allow-errors" attribute, or if the * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. =*/ int optionProcess(tOptions * opts, int a_ct, char ** a_v) { if (! SUCCESSFUL(validate_struct(opts, a_v[0]))) ao_bug(zbad_data_msg); /* * Establish the real program name, the program full path, * and do all the presetting the first time thru only. */ if (! ao_initialize(opts, a_ct, a_v)) return 0; /* * IF we are (re)starting, * THEN reset option location */ if (opts->curOptIdx <= 0) { opts->curOptIdx = 1; opts->pzCurOpt = NULL; } if (! SUCCESSFUL(regular_opts(opts))) return (int)opts->origArgCt; /* * IF there were no errors * AND we have RC/INI files * AND there is a request to save the files * THEN do that now before testing for conflicts. * (conflicts are ignored in preset options) */ switch (opts->specOptIdx.save_opts) { case 0: case NO_EQUIVALENT: break; default: { tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts; if (SELECTED_OPT(od)) { optionSaveFile(opts); option_exits(EXIT_SUCCESS); } } } /* * IF we are checking for errors, * THEN look for too few occurrences of required options */ if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0) && (! is_consistent(opts))) (*opts->pUsageProc)(opts, EXIT_FAILURE); return (int)opts->curOptIdx; }
/* * doPrognameEnv - check for preset values from the ${PROGNAME} * environment variable. This is accomplished by parsing the text into * tokens, temporarily replacing the arg vector and calling * immediate_opts and/or regular_opts. */ LOCAL void doPrognameEnv(tOptions * pOpts, teEnvPresetType type) { char const* pczOptStr = getenv(pOpts->pzPROGNAME); token_list_t* pTL; int sv_argc; tAoUI sv_flag; char** sv_argv; /* * No such beast? Then bail now. */ if (pczOptStr == NULL) return; /* * Tokenize the string. If there's nothing of interest, we'll bail * here immediately. */ pTL = ao_string_tokenize(pczOptStr); if (pTL == NULL) return; /* * Substitute our $PROGNAME argument list for the real one */ sv_argc = pOpts->origArgCt; sv_argv = pOpts->origArgVect; sv_flag = pOpts->fOptSet; /* * We add a bogus pointer to the start of the list. The program name * has already been pulled from "argv", so it won't get dereferenced. * The option scanning code will skip the "program name" at the start * of this list of tokens, so we accommodate this way .... */ pOpts->origArgVect = (char**)(pTL->tkn_list - 1); pOpts->origArgCt = pTL->tkn_ct + 1; pOpts->fOptSet &= ~OPTPROC_ERRSTOP; pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; switch (type) { case ENV_IMM: (void)immediate_opts(pOpts); break; case ENV_ALL: (void)immediate_opts(pOpts); pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; /* FALLTHROUGH */ case ENV_NON_IMM: (void)regular_opts(pOpts); } /* * Free up the temporary arg vector and restore the original program args. */ free(pTL); pOpts->origArgVect = sv_argv; pOpts->origArgCt = sv_argc; pOpts->fOptSet = sv_flag; }
/*=export_func optionProcess * * what: this is the main option processing routine * * arg: + tOptions* + pOpts + program options descriptor + * arg: + int + argc + program arg count + * arg: + char** + argv + program arg vector + * * ret_type: int * ret_desc: the count of the arguments processed * * doc: * * This is the main entry point for processing options. It is intended * that this procedure be called once at the beginning of the execution of * a program. Depending on options selected earlier, it is sometimes * necessary to stop and restart option processing, or to select completely * different sets of options. This can be done easily, but you generally * do not want to do this. * * The number of arguments processed always includes the program name. * If one of the arguments is "--", then it is counted and the processing * stops. If an error was encountered and errors are to be tolerated, then * the returned value is the index of the argument causing the error. * A hyphen by itself ("-") will also cause processing to stop and will * @emph{not} be counted among the processed arguments. A hyphen by itself * is treated as an operand. Encountering an operand stops option * processing. * * err: Errors will cause diagnostics to be printed. @code{exit(3)} may * or may not be called. It depends upon whether or not the options * were generated with the "allow-errors" attribute, or if the * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. =*/ int optionProcess(tOptions * pOpts, int argCt, char ** argVect) { if (! SUCCESSFUL(validate_struct(pOpts, argVect[0]))) exit(EX_SOFTWARE); /* * Establish the real program name, the program full path, * and do all the presetting the first time thru only. */ if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) { pOpts->origArgCt = (unsigned int)argCt; pOpts->origArgVect = argVect; pOpts->fOptSet |= OPTPROC_INITDONE; if (HAS_pzPkgDataDir(pOpts)) program_pkgdatadir = pOpts->pzPkgDataDir; if (! SUCCESSFUL(doPresets(pOpts))) return 0; /* * IF option name conversion was suppressed but it is not suppressed * for the command line, then it's time to translate option names. * Usage text will not get retranslated. */ if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0) && (pOpts->pTransProc != NULL) && ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) ) { pOpts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; (*pOpts->pTransProc)(); } if ((pOpts->fOptSet & OPTPROC_REORDER) != 0) optionSort(pOpts); pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; } /* * IF we are (re)starting, * THEN reset option location */ else if (pOpts->curOptIdx <= 0) { pOpts->curOptIdx = 1; pOpts->pzCurOpt = NULL; } if (! SUCCESSFUL(regular_opts(pOpts))) return pOpts->origArgCt; /* * IF there were no errors * AND we have RC/INI files * AND there is a request to save the files * THEN do that now before testing for conflicts. * (conflicts are ignored in preset options) */ if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) && (pOpts->specOptIdx.save_opts != 0)) { tOptDesc* pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts; if (SELECTED_OPT(pOD)) { optionSaveFile(pOpts); exit(EXIT_SUCCESS); } } /* * IF we are checking for errors, * THEN look for too few occurrences of required options */ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { if (! is_consistent(pOpts)) (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); } return pOpts->curOptIdx; }