Exemplo n.º 1
0
/*=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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
/**
 * 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;
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
/**
 * 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);
}
Exemplo n.º 6
0
/*=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;
}