aboutsummaryrefslogtreecommitdiff
path: root/sntp/libopts/usage.c
diff options
context:
space:
mode:
Diffstat (limited to 'sntp/libopts/usage.c')
-rw-r--r--sntp/libopts/usage.c643
1 files changed, 400 insertions, 243 deletions
diff --git a/sntp/libopts/usage.c b/sntp/libopts/usage.c
index 960339b63cbc..4d106675c304 100644
--- a/sntp/libopts/usage.c
+++ b/sntp/libopts/usage.c
@@ -1,7 +1,8 @@
/*
- * usage.c $Id: usage.c,v 4.15 2007/04/28 22:19:23 bkorb Exp $
- * Time-stamp: "2007-04-15 11:02:46 bkorb"
+ * \file usage.c
+ *
+ * Time-stamp: "2011-02-01 14:42:37 bkorb"
*
* This module implements the default usage procedure for
* Automated Options. It may be overridden, of course.
@@ -13,117 +14,183 @@
*/
/*
- * Automated Options copyright 1992-2007 Bruce Korb
- *
- * Automated Options is free software.
- * You may redistribute it and/or modify it under the terms of the
- * GNU General Public License, as published by the Free Software
- * Foundation; either version 2, or (at your option) any later version.
- *
- * Automated Options is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
*
- * You should have received a copy of the GNU General Public License
- * along with Automated Options. See the file "COPYING". If not,
- * write to: The Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * AutoOpts is available under any one of two licenses. The license
+ * in use must be one of these two and the choice is under the control
+ * of the user of the license.
*
- * As a special exception, Bruce Korb gives permission for additional
- * uses of the text contained in his release of AutoOpts.
+ * The GNU Lesser General Public License, version 3 or later
+ * See the files "COPYING.lgplv3" and "COPYING.gplv3"
*
- * The exception is that, if you link the AutoOpts library with other
- * files to produce an executable, this does not by itself cause the
- * resulting executable to be covered by the GNU General Public License.
- * Your use of that executable is in no way restricted on account of
- * linking the AutoOpts library code into it.
+ * The Modified Berkeley Software Distribution License
+ * See the file "COPYING.mbsd"
*
- * This exception does not however invalidate any other reasons why
- * the executable file might be covered by the GNU General Public License.
+ * These files have the following md5sums:
*
- * This exception applies only to the code released by Bruce Korb under
- * the name AutoOpts. If you copy code from other sources under the
- * General Public License into a copy of AutoOpts, as the General Public
- * License permits, the exception does not apply to the code that you add
- * in this way. To avoid misleading anyone as to the status of such
- * modified files, you must delete this exception notice from them.
- *
- * If you write modifications of your own for AutoOpts, it is your choice
- * whether to permit this exception to apply to your modifications.
- * If you do not wish that, delete this exception notice.
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
*/
#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
-static arg_types_t argTypes;
+/* = = = START-STATIC-FORWARD = = = */
+static void
+set_usage_flags(tOptions * opts, char const * flg_txt);
+
+static inline ag_bool
+do_gnu_usage(tOptions * pOpts);
-FILE* option_usage_fp = NULL;
-static char zOptFmtLine[ 16 ];
-static ag_bool displayEnum;
+static inline ag_bool
+skip_misuse_usage(tOptions * pOpts);
-/* = = = START-STATIC-FORWARD = = = */
-/* static forward declarations maintained by :mkfwd */
-static ag_bool
-checkGNUUsage( tOptions* pOpts );
+static void
+print_usage_details(tOptions * opts, int exit_code);
+
+static void
+prt_extd_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT);
static void
-printExtendedUsage(
- tOptions* pOptions,
- tOptDesc* pOD,
- arg_types_t* pAT );
+prt_ini_list(char const * const * papz, ag_bool * pInitIntro,
+ char const * pzRc, char const * pzPN);
static void
-printInitList(
- tCC* const* papz,
- ag_bool* pInitIntro,
- tCC* pzRc,
- tCC* pzPN );
+prt_preamble(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT);
static void
-printOneUsage(
- tOptions* pOptions,
- tOptDesc* pOD,
- arg_types_t* pAT );
+prt_one_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT);
static void
-printOptionUsage(
- tOptions* pOpts,
- int ex_code,
- tCC* pOptTitle );
+prt_opt_usage(tOptions * pOpts, int ex_code, char const * pOptTitle);
static void
-printProgramDetails( tOptions* pOptions );
+prt_prog_detail(tOptions* pOptions);
static int
-setGnuOptFmts( tOptions* pOpts, tCC** ppT );
+setGnuOptFmts(tOptions* pOpts, tCC** ppT);
static int
-setStdOptFmts( tOptions* pOpts, tCC** ppT );
+setStdOptFmts(tOptions* pOpts, tCC** ppT);
/* = = = END-STATIC-FORWARD = = = */
-
/*
- * Figure out if we should try to format usage text sort-of like
- * the way many GNU programs do.
+ * NB: no entry may be a prefix of another entry
*/
-static ag_bool
-checkGNUUsage( tOptions* pOpts )
+#define AOFLAG_TABLE \
+ _aof_(gnu, OPTPROC_GNUUSAGE ) \
+ _aof_(autoopts, ~OPTPROC_GNUUSAGE) \
+ _aof_(no_misuse_usage, OPTPROC_MISUSE ) \
+ _aof_(misuse_usage, ~OPTPROC_MISUSE )
+
+static void
+set_usage_flags(tOptions * opts, char const * flg_txt)
{
- char* pz = getenv( "AUTOOPTS_USAGE" );
- if (pz == NULL)
- ;
+ typedef struct {
+ size_t fnm_len;
+ uint32_t fnm_mask;
+ char const * fnm_name;
+ } ao_flag_names_t;
+
+# define _aof_(_n, _f) AOUF_ ## _n ## _ID,
+ typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t;
+# undef _aof_
+
+# define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID),
+ typedef enum { AOFLAG_TABLE } ao_flags_t;
+# undef _aof_
+
+# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n },
+ static ao_flag_names_t const fn_table[AOUF_COUNT] = {
+ AOFLAG_TABLE
+ };
+# undef _aof_
+
+ ao_flags_t flg = 0;
+
+ if (flg_txt == NULL) {
+ flg_txt = getenv("AUTOOPTS_USAGE");
+ if (flg_txt == NULL)
+ return;
+ }
- else if (streqvcmp( pz, "gnu" ) == 0)
- pOpts->fOptSet |= OPTPROC_GNUUSAGE;
+ while (IS_WHITESPACE_CHAR(*flg_txt)) flg_txt++;
+ if (*flg_txt == NUL)
+ return;
- else if (streqvcmp( pz, "autoopts" ) == 0)
- pOpts->fOptSet &= ~OPTPROC_GNUUSAGE;
+ for (;;) {
+ int ix = 0;
+ ao_flag_names_t const * fnt = fn_table;
+
+ for (;;) {
+ if (strneqvcmp(flg_txt, fnt->fnm_name, fnt->fnm_len) == 0)
+ break;
+ if (++ix >= AOUF_COUNT)
+ return;
+ fnt++;
+ }
+ /*
+ * Make sure we have a full match. Look for whitespace,
+ * a comma, or a NUL byte.
+ */
+ if (! IS_END_LIST_ENTRY_CHAR(flg_txt[fnt->fnm_len]))
+ return;
+
+ flg |= 1 << ix;
+ flg_txt += fnt->fnm_len;
+ while (IS_WHITESPACE_CHAR(*flg_txt)) flg_txt++;
+
+ if (*flg_txt == NUL)
+ break;
+
+ if (*flg_txt == ',') {
+ /*
+ * skip the comma and following white space
+ */
+ while (IS_WHITESPACE_CHAR(*++flg_txt)) ;
+ if (*flg_txt == NUL)
+ break;
+ }
+ }
+
+ {
+ ao_flag_names_t const * fnm = fn_table;
+
+ while (flg != 0) {
+ if ((flg & 1) != 0) {
+ if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
+ opts->fOptSet &= fnm->fnm_mask;
+ else opts->fOptSet |= fnm->fnm_mask;
+ }
+ flg >>= 1;
+ fnm++;
+ }
+ }
+}
+
+/*
+ * Figure out if we should try to format usage text sort-of like
+ * the way many GNU programs do.
+ */
+static inline ag_bool
+do_gnu_usage(tOptions * pOpts)
+{
return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? AG_TRUE : AG_FALSE;
}
+/*
+ * Figure out if we should try to format usage text sort-of like
+ * the way many GNU programs do.
+ */
+static inline ag_bool
+skip_misuse_usage(tOptions * pOpts)
+{
+ return (pOpts->fOptSet & OPTPROC_MISUSE) ? AG_TRUE : AG_FALSE;
+}
+
/*=export_func optionOnlyUsage
*
@@ -137,23 +204,107 @@ checkGNUUsage( tOptions* pOpts )
* information not available to AutoOpts.
=*/
void
-optionOnlyUsage(
- tOptions* pOpts,
- int ex_code )
+optionOnlyUsage(tOptions * pOpts, int ex_code)
{
- tCC* pOptTitle = NULL;
+ char const * pOptTitle = NULL;
+
+ set_usage_flags(pOpts, NULL);
+ if ((ex_code != EXIT_SUCCESS) &&
+ skip_misuse_usage(pOpts))
+ return;
/*
* Determine which header and which option formatting strings to use
*/
- if (checkGNUUsage(pOpts)) {
- (void)setGnuOptFmts( pOpts, &pOptTitle );
+ if (do_gnu_usage(pOpts)) {
+ (void)setGnuOptFmts(pOpts, &pOptTitle);
}
else {
- (void)setStdOptFmts( pOpts, &pOptTitle );
+ (void)setStdOptFmts(pOpts, &pOptTitle);
+ }
+
+ prt_opt_usage(pOpts, ex_code, pOptTitle);
+
+ fflush(option_usage_fp);
+ if (ferror(option_usage_fp) != 0) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void
+print_usage_details(tOptions * opts, int exit_code)
+{
+ {
+ char const * pOptTitle = NULL;
+
+ /*
+ * Determine which header and which option formatting strings to use
+ */
+ if (do_gnu_usage(opts)) {
+ int flen = setGnuOptFmts(opts, &pOptTitle);
+ sprintf(zOptFmtLine, zFmtFmt, flen);
+ fputc('\n', option_usage_fp);
+ }
+ else {
+ int flen = setStdOptFmts(opts, &pOptTitle);
+ sprintf(zOptFmtLine, 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);
+ }
+
+ 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;
}
- printOptionUsage( pOpts, ex_code, pOptTitle );
+ 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) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
}
@@ -174,11 +325,9 @@ optionOnlyUsage(
* and the actual exit code will be "EXIT_SUCCESS".
=*/
void
-optionUsage(
- tOptions* pOptions,
- int usage_exit_code )
+optionUsage(tOptions * pOptions, int usage_exit_code)
{
- int actual_exit_code =
+ int exit_code =
(usage_exit_code == EX_USAGE) ? EXIT_SUCCESS : usage_exit_code;
displayEnum = AG_FALSE;
@@ -187,74 +336,42 @@ optionUsage(
* Paged usage will preset option_usage_fp to an output file.
* If it hasn't already been set, then set it to standard output
* on successful exit (help was requested), otherwise error out.
+ *
+ * Test the version before obtaining pzFullUsage or pzShortUsage.
+ * These fields do not exist before revision 30.
*/
- if (option_usage_fp == NULL)
- option_usage_fp = (actual_exit_code != EXIT_SUCCESS) ? stderr : stdout;
-
- fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName );
-
{
- tCC* pOptTitle = NULL;
+ char const * pz;
- /*
- * Determine which header and which option formatting strings to use
- */
- if (checkGNUUsage(pOptions)) {
- int flen = setGnuOptFmts( pOptions, &pOptTitle );
- sprintf( zOptFmtLine, zFmtFmt, flen );
- fputc( '\n', option_usage_fp );
- }
- else {
- int flen = setStdOptFmts( pOptions, &pOptTitle );
- sprintf( zOptFmtLine, zFmtFmt, flen );
+ if (exit_code == EXIT_SUCCESS) {
+ pz = (pOptions->structVersion >= 30 * 4096)
+ ? pOptions->pzFullUsage : NULL;
- /*
- * 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 ( (usage_exit_code != EXIT_SUCCESS)
- || ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
+ if (option_usage_fp == NULL)
+ option_usage_fp = stdout;
+ } else {
+ pz = (pOptions->structVersion >= 30 * 4096)
+ ? pOptions->pzShortUsage : NULL;
- fputs( pOptTitle, option_usage_fp );
+ if (option_usage_fp == NULL)
+ option_usage_fp = stderr;
}
- printOptionUsage( pOptions, usage_exit_code, pOptTitle );
- }
-
- /*
- * Describe the mechanics of denoting the options
- */
- switch (pOptions->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 ((pOptions->fOptSet & OPTPROC_NUM_OPT) != 0) {
- fputs( zNumberOpt, option_usage_fp );
- }
-
- if ((pOptions->fOptSet & OPTPROC_REORDER) != 0) {
- fputs( zReorder, option_usage_fp );
+ if (pz != NULL) {
+ fputs(pz, option_usage_fp);
+ exit(exit_code);
+ }
}
- if (pOptions->pzExplain != NULL)
- fputs( pOptions->pzExplain, option_usage_fp );
+ fprintf(option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName);
+ set_usage_flags(pOptions, NULL);
- /*
- * IF the user is asking for help (thus exiting with SUCCESS),
- * THEN see what additional information we can provide.
- */
- if (usage_exit_code == EXIT_SUCCESS)
- printProgramDetails( pOptions );
+ if ((exit_code == EXIT_SUCCESS) ||
+ (! skip_misuse_usage(pOptions)))
- if (pOptions->pzBugAddr != NULL)
- fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr );
- fflush( option_usage_fp );
+ print_usage_details(pOptions, usage_exit_code);
- exit( actual_exit_code );
+ exit(exit_code);
}
@@ -263,10 +380,7 @@ optionUsage(
* PER OPTION TYPE USAGE INFORMATION
*/
static void
-printExtendedUsage(
- tOptions* pOptions,
- tOptDesc* pOD,
- arg_types_t* pAT )
+prt_extd_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT)
{
/*
* IF there are option conflicts or dependencies,
@@ -275,7 +389,7 @@ printExtendedUsage(
if ( (pOD->pOptMust != NULL)
|| (pOD->pOptCant != NULL) ) {
- fputs( zTabHyp, option_usage_fp );
+ fputs(zTabHyp, option_usage_fp);
/*
* DEPENDENCIES:
@@ -283,16 +397,16 @@ printExtendedUsage(
if (pOD->pOptMust != NULL) {
const int* pOptNo = pOD->pOptMust;
- fputs( zReqThese, option_usage_fp );
+ fputs(zReqThese, option_usage_fp);
for (;;) {
- fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
- *pOptNo ].pz_Name );
+ fprintf(option_usage_fp, zTabout,
+ pOptions->pOptDesc[*pOptNo].pz_Name);
if (*++pOptNo == NO_EQUIVALENT)
break;
}
if (pOD->pOptCant != NULL)
- fputs( zTabHypAnd, option_usage_fp );
+ fputs(zTabHypAnd, option_usage_fp);
}
/*
@@ -301,10 +415,10 @@ printExtendedUsage(
if (pOD->pOptCant != NULL) {
const int* pOptNo = pOD->pOptCant;
- fputs( zProhib, option_usage_fp );
+ fputs(zProhib, option_usage_fp);
for (;;) {
- fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
- *pOptNo ].pz_Name );
+ fprintf(option_usage_fp, zTabout,
+ pOptions->pOptDesc[*pOptNo].pz_Name);
if (*++pOptNo == NO_EQUIVALENT)
break;
}
@@ -316,16 +430,26 @@ printExtendedUsage(
* THEN print the disablement info
*/
if (pOD->pz_DisableName != NULL )
- fprintf( option_usage_fp, zDis, pOD->pz_DisableName );
+ fprintf(option_usage_fp, zDis, pOD->pz_DisableName);
/*
- * IF the numeric option has a special callback,
- * THEN call it, requesting the range or other special info
+ * Check for argument types that have callbacks with magical properties
*/
- if ( (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC)
- && (pOD->pOptProc != NULL)
- && (pOD->pOptProc != optionNumericVal) ) {
- (*(pOD->pOptProc))( pOptions, NULL );
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NUMERIC:
+ /*
+ * IF the numeric option has a special callback,
+ * THEN call it, requesting the range or other special info
+ */
+ if ( (pOD->pOptProc != NULL)
+ && (pOD->pOptProc != optionNumericVal) ) {
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
+ }
+ break;
+
+ case OPARG_TYPE_FILE:
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
+ break;
}
/*
@@ -333,7 +457,7 @@ printExtendedUsage(
* THEN print that out
*/
if (pOD->fOptState & OPTST_INITENABLED)
- fputs( zEnab, option_usage_fp );
+ fputs(zEnab, option_usage_fp);
/*
* IF the option is in an equivalence class
@@ -342,8 +466,8 @@ printExtendedUsage(
*/
if ( (pOD->optEquivIndex != NO_EQUIVALENT)
&& (pOD->optEquivIndex != pOD->optActualIndex ) ) {
- fprintf( option_usage_fp, zAlt,
- pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name );
+ fprintf(option_usage_fp, zAlt,
+ pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name);
return;
}
@@ -360,25 +484,25 @@ printExtendedUsage(
&& (pOD->optIndex < pOptions->presetOptCt)
)
- fputs( zNoPreset, option_usage_fp );
+ fputs(zNoPreset, option_usage_fp);
/*
* Print the appearance requirements.
*/
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
- fputs( zMembers, option_usage_fp );
+ fputs(zMembers, option_usage_fp);
else switch (pOD->optMinCt) {
case 1:
case 0:
switch (pOD->optMaxCt) {
- case 0: fputs( zPreset, option_usage_fp ); break;
- case NOLIMIT: fputs( zNoLim, option_usage_fp ); break;
+ case 0: fputs(zPreset, option_usage_fp); break;
+ case NOLIMIT: fputs(zNoLim, option_usage_fp); break;
case 1: break;
/*
* IF the max is more than one but limited, print "UP TO" message
*/
- default: fprintf( option_usage_fp, zUpTo, pOD->optMaxCt ); break;
+ default: fprintf(option_usage_fp, zUpTo, pOD->optMaxCt); break;
}
break;
@@ -386,12 +510,12 @@ printExtendedUsage(
/*
* More than one is required. Print the range.
*/
- fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt );
+ fprintf(option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt);
}
- if ( NAMED_OPTS( pOptions )
+ if ( NAMED_OPTS(pOptions)
&& (pOptions->specOptIdx.default_opt == pOD->optIndex))
- fputs( zDefaultOpt, option_usage_fp );
+ fputs(zDefaultOpt, option_usage_fp);
}
@@ -403,34 +527,43 @@ printExtendedUsage(
* squishy, but important to tell users how to find these files.
*/
static void
-printInitList(
- tCC* const* papz,
- ag_bool* pInitIntro,
- tCC* pzRc,
- tCC* pzPN )
+prt_ini_list(char const * const * papz, ag_bool * pInitIntro,
+ char const * pzRc, char const * pzPN)
{
- char zPath[ AG_PATH_MAX+1 ];
+ char zPath[AG_PATH_MAX+1];
if (papz == NULL)
return;
- fputs( zPresetIntro, option_usage_fp );
+ fputs(zPresetIntro, option_usage_fp);
*pInitIntro = AG_FALSE;
for (;;) {
- char const* pzPath = *(papz++);
+ char const * pzPath = *(papz++);
+ char const * pzReal = zPath;
if (pzPath == NULL)
break;
- if (optionMakePath(zPath, (int)sizeof( zPath ), pzPath, pzPN))
- pzPath = zPath;
+ /*
+ * Ignore any invalid paths
+ */
+ if (! optionMakePath(zPath, (int)sizeof(zPath), pzPath, pzPN))
+ pzReal = pzPath;
+
+ /*
+ * Expand paths that are relative to the executable or installation
+ * directories. Leave alone paths that use environment variables.
+ */
+ else if ((*pzPath == '$')
+ && ((pzPath[1] == '$') || (pzPath[1] == '@')))
+ pzPath = pzReal;
/*
* Print the name of the "homerc" file. If the "rcfile" name is
* not empty, we may or may not print that, too...
*/
- fprintf( option_usage_fp, zPathFmt, pzPath );
+ fprintf(option_usage_fp, zPathFmt, pzPath);
if (*pzRc != NUL) {
struct stat sb;
@@ -438,26 +571,19 @@ printInitList(
* IF the "homerc" file is a directory,
* then append the "rcfile" name.
*/
- if ( (stat( pzPath, &sb ) == 0)
- && S_ISDIR( sb.st_mode ) ) {
- fputc( DIRCH, option_usage_fp );
- fputs( pzRc, option_usage_fp );
+ if ((stat(pzReal, &sb) == 0) && S_ISDIR(sb.st_mode)) {
+ fputc(DIRCH, option_usage_fp);
+ fputs(pzRc, option_usage_fp);
}
}
- fputc( '\n', option_usage_fp );
+ fputc('\n', option_usage_fp);
}
}
-/*
- * Print the usage information for a single option.
- */
static void
-printOneUsage(
- tOptions* pOptions,
- tOptDesc* pOD,
- arg_types_t* pAT )
+prt_preamble(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT)
{
/*
* Flag prefix: IF no flags at all, then omit it. If not printable
@@ -466,47 +592,59 @@ printOneUsage(
* opts are to be printed too.
*/
if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
- fputs( pAT->pzSpc, option_usage_fp );
- else if (! isgraph( pOD->optValue)) {
+ fputs(pAT->pzSpc, option_usage_fp);
+
+ else if (! IS_GRAPHIC_CHAR(pOD->optValue)) {
if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
== (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
- fputc( ' ', option_usage_fp );
- fputs( pAT->pzNoF, option_usage_fp );
+ fputc(' ', option_usage_fp);
+ fputs(pAT->pzNoF, option_usage_fp);
+
} else {
- fprintf( option_usage_fp, " -%c", pOD->optValue );
+ fprintf(option_usage_fp, " -%c", pOD->optValue);
if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
== (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
- fputs( ", ", option_usage_fp );
+ fputs(", ", option_usage_fp);
}
+}
+
+/*
+ * Print the usage information for a single option.
+ */
+static void
+prt_one_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT)
+{
+ prt_preamble(pOptions, pOD, pAT);
{
- char z[ 80 ];
- tCC* pzArgType;
+ char z[ 80 ];
+ char const * pzArgType;
+
/*
* Determine the argument type string first on its usage, then,
* when the option argument is required, base the type string on the
* argument type.
*/
- if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) {
- pzArgType = pAT->pzNo;
-
- } else if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
pzArgType = pAT->pzOpt;
} else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NONE: pzArgType = pAT->pzNo; break;
case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break;
+ case OPARG_TYPE_FILE: pzArgType = pAT->pzFile; break;
case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break;
case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break;
case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break;
case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break;
case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break;
- default: goto bogus_desc; break;
+ case OPARG_TYPE_TIME: pzArgType = pAT->pzTime; break;
+ default: goto bogus_desc;
}
- snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
- (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt );
+ snprintf(z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
+ (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt);
- fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText );
+ fprintf(option_usage_fp, zOptFmtLine, z, pOD->pzText);
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_ENUMERATION:
@@ -517,8 +655,8 @@ printOneUsage(
return;
bogus_desc:
- fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
- exit( EX_SOFTWARE );
+ fprintf(stderr, zInvalOptDesc, pOD->pz_Name);
+ exit(EX_SOFTWARE);
}
@@ -526,19 +664,34 @@ printOneUsage(
* Print out the usage information for just the options.
*/
static void
-printOptionUsage(
- tOptions* pOpts,
- int ex_code,
- tCC* pOptTitle )
+prt_opt_usage(tOptions * pOpts, int ex_code, char const * pOptTitle)
{
- int ct = pOpts->optCt;
- int optNo = 0;
- tOptDesc* pOD = pOpts->pOptDesc;
- int docCt = 0;
+ int ct = pOpts->optCt;
+ int optNo = 0;
+ tOptDesc * pOD = pOpts->pOptDesc;
+ int docCt = 0;
do {
- if ((pOD->fOptState & OPTST_OMITTED) != 0)
+ if ((pOD->fOptState & OPTST_NO_USAGE_MASK) != 0) {
+
+ /*
+ * IF this is a compiled-out option
+ * *AND* usage was requested with "omitted-usage"
+ * *AND* this is NOT abbreviated usage
+ * THEN display this option.
+ */
+ if ( (pOD->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
+ && (pOD->pz_Name != NULL)
+ && (ex_code == EXIT_SUCCESS)) {
+
+ char const * why_pz =
+ (pOD->pzText == NULL) ? zDisabledWhy : pOD->pzText;
+ prt_preamble(pOpts, pOD, &argTypes);
+ fprintf(option_usage_fp, zDisabledOpt, pOD->pz_Name, why_pz);
+ }
+
continue;
+ }
if ((pOD->fOptState & OPTST_DOCUMENT) != 0) {
if (ex_code == EXIT_SUCCESS) {
@@ -558,23 +711,23 @@ printOptionUsage(
* THEN document that the remaining options are not user opts
*/
if ( (pOpts->presetOptCt == optNo)
- && (ex_code == EXIT_SUCCESS)
- && (docCt > 0)
- && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) )
- fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle );
+ && (ex_code == EXIT_SUCCESS)
+ && (docCt > 0)
+ && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) )
+ fprintf(option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle);
- printOneUsage( pOpts, pOD, &argTypes );
+ prt_one_usage(pOpts, pOD, &argTypes);
/*
* IF we were invoked because of the --help option,
* THEN print all the extra info
*/
if (ex_code == EXIT_SUCCESS)
- printExtendedUsage( pOpts, pOD, &argTypes );
+ prt_extd_usage(pOpts, pOD, &argTypes);
} while (pOD++, optNo++, (--ct > 0));
- fputc( '\n', option_usage_fp );
+ fputc('\n', option_usage_fp);
}
@@ -583,24 +736,24 @@ printOptionUsage(
* PROGRAM DETAILS
*/
static void
-printProgramDetails( tOptions* pOptions )
+prt_prog_detail(tOptions* pOptions)
{
ag_bool initIntro = AG_TRUE;
/*
* Display all the places we look for config files
*/
- printInitList( pOptions->papzHomeList, &initIntro,
- pOptions->pzRcName, pOptions->pzProgPath );
+ prt_ini_list(pOptions->papzHomeList, &initIntro,
+ pOptions->pzRcName, pOptions->pzProgPath);
/*
* Let the user know about environment variable settings
*/
if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
if (initIntro)
- fputs( zPresetIntro, option_usage_fp );
+ fputs(zPresetIntro, option_usage_fp);
- fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME );
+ fprintf(option_usage_fp, zExamineFmt, pOptions->pzPROGNAME);
}
/*
@@ -613,13 +766,13 @@ printProgramDetails( tOptions* pOptions )
int optNo = 0;
tOptDesc* pOD = pOptions->pOptDesc;
- fputc( '\n', option_usage_fp );
- fflush( option_usage_fp );
+ fputc('\n', option_usage_fp);
+ fflush(option_usage_fp);
do {
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_ENUMERATION:
case OPARG_TYPE_MEMBERSHIP:
- (*(pOD->pOptProc))( NULL, pOD );
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
}
} while (pOD++, optNo++, (--ct > 0));
}
@@ -628,7 +781,7 @@ printProgramDetails( tOptions* pOptions )
* If there is a detail string, now is the time for that.
*/
if (pOptions->pzDetail != NULL)
- fputs( pOptions->pzDetail, option_usage_fp );
+ fputs(pOptions->pzDetail, option_usage_fp);
}
@@ -647,7 +800,7 @@ printProgramDetails( tOptions* pOptions )
* Set up the formatting for GNU-style output
*/
static int
-setGnuOptFmts( tOptions* pOpts, tCC** ppT )
+setGnuOptFmts(tOptions* pOpts, tCC** ppT)
{
int flen = 22;
*ppT = zNoRq_ShrtTtl;
@@ -657,6 +810,8 @@ setGnuOptFmts( tOptions* pOpts, tCC** ppT )
argTypes.pzNum = zGnuNumArg;
argTypes.pzKey = zGnuKeyArg;
argTypes.pzKeyL = zGnuKeyLArg;
+ argTypes.pzTime = zGnuTimeArg;
+ argTypes.pzFile = zGnuFileArg;
argTypes.pzBool = zGnuBoolArg;
argTypes.pzNest = zGnuNestArg;
argTypes.pzOpt = zGnuOptArg;
@@ -685,7 +840,7 @@ setGnuOptFmts( tOptions* pOpts, tCC** ppT )
* Standard (AutoOpts normal) option line formatting
*/
static int
-setStdOptFmts( tOptions* pOpts, tCC** ppT )
+setStdOptFmts(tOptions* pOpts, tCC** ppT)
{
int flen = 0;
@@ -694,6 +849,8 @@ setStdOptFmts( tOptions* pOpts, tCC** ppT )
argTypes.pzNum = zStdNumArg;
argTypes.pzKey = zStdKeyArg;
argTypes.pzKeyL = zStdKeyLArg;
+ argTypes.pzTime = zStdTimeArg;
+ argTypes.pzFile = zStdFileArg;
argTypes.pzBool = zStdBoolArg;
argTypes.pzNest = zStdNestArg;
argTypes.pzOpt = zStdOptArg;