Jim Meyering [EMAIL PROTECTED] wrote:
You can make any argp-using program infloop simply by running it
with --help and with something like ARGP_HELP_FMT=rmargin=a in the
environment. Or use a valid (but small) width: ARGP_HELP_FMT=rmargin=2
Fixed in gnulib repository. The following patch is applied (it also
fixes a coredump one would get in some cases, e.g. when running
ARGP_HELP_FMT=rmargin=39 tar --help).
Regards,
Sergey
2005-12-10 Sergey Poznyakoff [EMAIL PROTECTED]
* lib/argp-fmtstream.c (__argp_fmtstream_update): Fix coredump
* lib/argp-help.c (fill_in_uparams): Check if the constructed
struct uparams is valid. Fall back to the default values if it is
not.
* m4/argp.m4: Define HAVE_DECL_PROGRAM_INVOCATION_NAME and
HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
Index: lib/argp-fmtstream.c
===
RCS file: /cvsroot/gnulib/gnulib/lib/argp-fmtstream.c,v
retrieving revision 1.6
diff -p -u -r1.6 argp-fmtstream.c
--- lib/argp-fmtstream.c29 Sep 2005 12:24:42 - 1.6
+++ lib/argp-fmtstream.c10 Dec 2005 21:30:53 -
@@ -246,9 +246,10 @@ __argp_fmtstream_update (argp_fmtstream_
Oh well. Put it on an overlong line by itself. */
p = buf + (r + 1 - fs-point_col);
/* Find the end of the long word. */
- do
- ++p;
- while (p nl !isblank (*p));
+ if (p nl)
+ do
+ ++p;
+ while (p nl !isblank (*p));
if (p == nl)
{
/* It already ends a line. No fussing required. */
Index: lib/argp-help.c
===
RCS file: /cvsroot/gnulib/gnulib/lib/argp-help.c,v
retrieving revision 1.19
diff -p -u -r1.19 argp-help.c
--- lib/argp-help.c 9 Dec 2005 12:28:58 - 1.19
+++ lib/argp-help.c 10 Dec 2005 21:30:57 -
@@ -90,15 +90,15 @@ struct uparams
int dup_args_note;
/* Various output columns. */
- int short_opt_col;
- int long_opt_col;
- int doc_opt_col;
- int opt_doc_col;
- int header_col;
- int usage_indent;
- int rmargin;
+ int short_opt_col; /* column in which short options start */
+ int long_opt_col; /* column in which long options start */
+ int doc_opt_col;/* column in which doc options start */
+ int opt_doc_col;/* column in which option text starts */
+ int header_col; /* column in which group headers are printed */
+ int usage_indent; /* indentation of wrapped usage lines */
+ int rmargin;/* right margin used for wrapping */
- int valid; /* True when the values in here are valid. */
+ int valid; /* True when the values in here are valid. */
};
/* This is a global variable, as user options are only ever read once. */
@@ -132,91 +132,126 @@ static const struct uparam_name uparam_n
{ 0 }
};
-/* Read user options from the environment, and fill in UPARAMS appropiately.
*/
+static void
+validate_uparams (const struct argp_state *state, struct uparams *upptr)
+{
+ const struct uparam_name *up;
+
+ for (up = uparam_names; up-name; up++)
+{
+ if (up-is_bool
+ || up-uparams_offs == offsetof (struct uparams, rmargin))
+ continue;
+ if (*(int *)((char *)upptr + up-uparams_offs) = upptr-rmargin)
+ {
+ __argp_failure (state, 0, 0,
+ dgettext (state-root_argp-argp_domain,
+ \
+ARGP_HELP_FMT: %s value is less then or equal to %s),
+ rmargin, up-name);
+ return;
+ }
+}
+ uparams = *upptr;
+ uparams.valid = 1;
+}
+
+/* Read user options from the environment, and fill in UPARAMS appropiately. */
static void
fill_in_uparams (const struct argp_state *state)
{
const char *var = getenv (ARGP_HELP_FMT);
-
+ struct uparams new_params = uparams;
+
#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
if (var)
-/* Parse var. */
-while (*var)
- {
- SKIPWS (var);
-
- if (isalpha (*var))
- {
- size_t var_len;
- const struct uparam_name *un;
- int unspec = 0, val = 0;
- const char *arg = var;
-
- while (isalnum (*arg) || *arg == '-' || *arg == '_')
- arg++;
- var_len = arg - var;
-
- SKIPWS (arg);
-
- if (*arg == '\0' || *arg == ',')
- unspec = 1;
- else if (*arg == '=')
- {
- arg++;
- SKIPWS (arg);
- }
+{
+ /* Parse var. */
+ while (*var)
+ {
+ SKIPWS (var);
+
+ if (isalpha (*var))
+ {
+ size_t var_len;
+ const struct uparam_name *un;
+ int unspec = 0, val = 0;
+