/*=export_func optionTimeDate * private: * * what: process an option with a time and date. * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * Decipher a time and date value. =*/ void optionTimeDate(tOptions * pOpts, tOptDesc * pOD) { #if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV) if ((! HAS_pzPkgDataDir(pOpts)) || (pOpts->pzPkgDataDir == NULL)) goto default_action; /* * Export the DATEMSK environment variable. getdate_r() uses it to * find the file with the strptime formats. If we cannot find the file * we need ($PKGDATADIR/datemsk), then fall back to just a time duration. */ { static char * envptr = NULL; if (envptr == NULL) { static char const fmt[] = "DATEMSK=%s/datemsk"; envptr = AGALOC(sizeof(fmt) + strlen(pOpts->pzPkgDataDir), fmt); sprintf(envptr, fmt, pOpts->pzPkgDataDir); putenv(envptr); } if (access(envptr+8, R_OK) != 0) goto default_action; } /* * Convert the date to a time since the epoch and stash it in a long int. */ { struct tm stm; time_t tm; if (getdate_r(pOD->optArg.argString, &stm) != 0) { fprintf(stderr, zNotDate, pOpts->pzProgName, pOD->optArg.argString); if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); return; } tm = mktime(&stm); if (pOD->fOptState & OPTST_ALLOC_ARG) { AGFREE(pOD->optArg.argString); pOD->fOptState &= ~OPTST_ALLOC_ARG; } pOD->optArg.argInt = tm; } return; default_action: #endif optionTimeVal(pOpts, pOD); if (pOD->optArg.argInt != BAD_TIME) pOD->optArg.argInt += (unsigned long)time(NULL); }
static void emit_copy_note(tOptions * pOpts, FILE * fp) { if (pOpts->pzCopyright != NULL) { fputs(pOpts->pzCopyright, fp); fputc('\n', fp); } if (pOpts->pzCopyNotice != NULL) { fputs(pOpts->pzCopyNotice, fp); fputc('\n', fp); } fprintf(fp, zAO_Ver, optionVersion()); if (HAS_pzPkgDataDir(pOpts) && (pOpts->pzPackager != NULL)) fputs(pOpts->pzPackager, fp); else if (pOpts->pzBugAddr != NULL) fprintf(fp, zPlsSendBugs, pOpts->pzBugAddr); }
/** * AutoOpts initialization * * @param[in,out] opts the structure to initialize * @param[in] a_ct program argument count * @param[in] a_v program argument vector */ LOCAL bool ao_initialize(tOptions * opts, int a_ct, char ** a_v) { if ((opts->fOptSet & OPTPROC_INITDONE) != 0) return true; opts->origArgCt = (unsigned int)a_ct; opts->origArgVect = a_v; opts->fOptSet |= OPTPROC_INITDONE; if (HAS_pzPkgDataDir(opts)) program_pkgdatadir = opts->pzPkgDataDir; if (! SUCCESSFUL(do_presets(opts))) return false; /* * 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 ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) && (opts->pTransProc != NULL) && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) ) { opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; (*opts->pTransProc)(); } if ((opts->fOptSet & OPTPROC_REORDER) != 0) optionSort(opts); opts->curOptIdx = 1; opts->pzCurOpt = NULL; return true; }
static void emit_copy_ver(tOptions * pOpts, FILE * fp) { if (pOpts->pzCopyright != NULL) fputs(pOpts->pzCopyright, fp); else if (pOpts->pzFullVersion != NULL) fputs(pOpts->pzFullVersion, fp); else { char const * pe = strchr(pOpts->pzUsageTitle, '\n'); if (pe == NULL) pe = pOpts->pzUsageTitle + strlen(pOpts->pzUsageTitle); fwrite(pOpts->pzUsageTitle, 1, pe - pOpts->pzCopyright, fp); } fputc('\n', fp); if (HAS_pzPkgDataDir(pOpts) && (pOpts->pzPackager != NULL)) fputs(pOpts->pzPackager, fp); else if (pOpts->pzBugAddr != NULL) fprintf(fp, zPlsSendBugs, pOpts->pzBugAddr); }
/** * Print information about each option. * * @param[in] opts the program options * @param[in] exit_code whether or not there was a usage error reported. * used to select full usage versus abbreviated. */ static void print_usage_details(tOptions * opts, int exit_code) { { char const * pOptTitle = NULL; int flen; /* * Determine which header and which option formatting strings to use */ if (do_gnu_usage(opts)) { flen = setGnuOptFmts(opts, &pOptTitle); sprintf(line_fmt_buf, zFmtFmt, flen); fputc(NL, option_usage_fp); } else { flen = setStdOptFmts(opts, &pOptTitle); sprintf(line_fmt_buf, zFmtFmt, flen); /* * When we exit with EXIT_SUCCESS and the first option is a doc * option, we do *NOT* want to emit the column headers. * Otherwise, we do. */ if ( (exit_code != EXIT_SUCCESS) || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) ) fputs(pOptTitle, option_usage_fp); } flen = 4 - ((flen + 15) / 8); if (flen > 0) tab_skip_ct = flen; prt_opt_usage(opts, exit_code, pOptTitle); } /* * Describe the mechanics of denoting the options */ switch (opts->fOptSet & OPTPROC_L_N_S) { case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break; case OPTPROC_SHORTOPT: break; case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break; case 0: fputs(zOptsOnly, option_usage_fp); break; } if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0) fputs(zNumberOpt, option_usage_fp); if ((opts->fOptSet & OPTPROC_REORDER) != 0) fputs(zReorder, option_usage_fp); if (opts->pzExplain != NULL) fputs(opts->pzExplain, option_usage_fp); /* * IF the user is asking for help (thus exiting with SUCCESS), * THEN see what additional information we can provide. */ if (exit_code == EXIT_SUCCESS) prt_prog_detail(opts); /* * Give bug notification preference to the packager information */ if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) fputs(opts->pzPackager, option_usage_fp); else if (opts->pzBugAddr != NULL) fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr); fflush(option_usage_fp); if (ferror(option_usage_fp) != 0) fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr) ? zstderr_name : zstdout_name); }
/*=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(validateOptionsStruct(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 = 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(doRegularOpts(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 (checkConsistency(pOpts) != 0) (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); } return pOpts->curOptIdx; }