1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00

update from main archive 970218

1997-02-19 03:28  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/argp-help.c: Add support for user provided filter of help
	messages.
	* argp/argp-parse.c: Likewise.
	* argp/argp.h: Likewise.
	* argp/argp-namefrob.h: Define __argp_input.

	* argp/argp-test.c: Add example for filter.

1997-02-19 02:58  Ulrich Drepper  <drepper@cygnus.com>

	* argp.h: New file.
	* locale/programs/locale.c: Switch to use argp.

	* errno.h: Make it possible to get definition of error_t even
	after having errno.h already.

	* elf/dl-hash.h: New file.  ELF hashing function.  Extracted
	from dl-lookup.c.
	* elf/dl-lookup.c (_dl_elf_hash): Remove definition.

	* elf/dl-load.c: Rename _dl_does_name_match_p to _dl_name_match_p.
	* elf/dl-version.c: Likewise.

	* elf/dl-lookup.c: Implement new versioning lookup scheme.
	* elf/dl-version.c (_dl_check_map_versions): Initialize new field
	in l_versions member.

	* elf/dlvsym.c: Correct call of _dl_lookup_versioned_symbol_skip
	and _dl_lookup_versioned_symbol.

	* elf/link.h: Rename hash_name_pair to struct r_found_version.
	* sysdeps/alpha/dl-machine.h: Likewise.
	* sysdeps/i386/dl-machine.h: Likewise.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/mips/dl-machine.h: Likewise.

	* intl/l10nflist.c: (_nl_make_l10nflist): Fix bug in computation of
	length of abs_filename.

	* locale/Makefile (CPPFLAGS): Define LOCALE_ALIAS_PATH.

	* locale/programs/ld-monetary.c (monetary_add): Allow value 0
	in mon_grouping information.  This means no more grouping.
	* locale/programs/ld-numeric.c (numeric_add): Write value \377
	when seein value 0 in grouping information.
	* locale/programs/linereader.c (lr_close): Don't free fname since
	it might be used in error messages.

	* locale/programs/locale.c: Check whether output of `locale -a'
	really is locale directory.  Also print locale aliases.

	* misc/search.h (__action_fn_t): Parameters VALUE and LEVEL cannot
	be const.

1997-02-19 02:16  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/bsd/sun/sunos4/resourcebits.h: Correct #defin to
	#define.  Reported by Rick Flower <FLOWER@sdvax2.sdd.TRW.COM>.

1997-02-19 01:37  Erik Troan  <ewt@redhat.com>

	* shadow/sgetspent_r.c: Accept empty third, fourth and fifth fields.

1997-02-19 01:02  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/mman/syscalls.list: msync takes 3 arguments.
	Reported by Andreas Jaeger <aj@arthur.pfalz.de>.

	* sysdeps/stub/msync.c (msync): Add missing third parameter.

1997-02-19 00:29  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/bsd/sigsuspend.c: Call __sigpause with needed
	additional argument.

1997-02-18 22:13  Ulrich Drepper  <drepper@cygnus.com>

	* inet/net/ethernet.h: New file.
	* sysdeps/unix/sysv/linux/netinet/if_ether.c: Add BSD compatibility.
	* sysdeps/unix/sysv/linux/net/if_slip.h: New file.
	Contributed by a sun <asun@zoology.washington.edu>.

	* sysdeps/unix/sysv/linux/net/if_arp.h: Include <sys/socket.h>.
	* sunrpc/rpc/rpc_msg.h: Include <rpc/clnt.h>.
	Reported by a sun <asun@zoology.washington.edu>.

1997-02-16 14:25  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makerules ((common-objpfx)distinfo-$(subdir)): Depend on sysdep
	makefiles which may change the distinfo variables.

1997-02-16 14:03  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers)
	[$(subdir)=misc]: Add sys/quota.h.
	(sysdep_headers) [$(subdir)=inet]: Add netinet/udp.h.

1997-02-17 13:12  aleph1@dfw.net

	* sunrpc/clnt_simp.c (callrpc): Prevent buffer overflow by using
	strncpy.

1997-02-18 03:28  Ulrich Drepper  <drepper@cygnus.com>

	* stdio-common/bug10.c (main): Correct parameter.

1997-02-17 02:51  Ulrich Drepper  <drepper@cygnus.com>

	* malloc/obstack.h: Add `extern "C"' protection.
	* posix/regex.h: Likewise.
	* io/ftw.h: Likewise.
	* misc/libgen.h: Likewise.
	* login/utmp.h: Likewise.
	* sysdeps/unix/sysv/linux/sys/reboot.h: Likewise.
	* sysdeps/unix/sysv/linux/netinet/in.h: Likewise.
	* sunrpc/rpc/pmap_rmt.h: Likewise.
	* sunrpc/rpc/auth_des.h: Likewise.
	* elf/link.h: Likewise.
	Reported by HJ Lu.

1997-02-17 01:45  a sun  <asun@zoology.washington.edu>

	Linux specific network headers.
	* sysdeps/unix/sysv/linux/netinet/if_fddi.h: New file.
	* sysdeps/unix/sysv/linux/netinet/if_tr.h: New file.
	* sysdeps/unix/sysv/linux/netinet/ip_icmp.h: New file.
	* sysdeps/unix/sysv/linux/netinet/ip_fw.h: New file.
	* sysdeps/unix/sysv/linux/netinet/igmp.h: New file.
	* sysdeps/unix/sysv/linux/netinet/icmp.h: New file.
	* sysdeps/unix/sysv/linux/netinet/ip.h: New file.
	* sysdeps/unix/sysv/linux/netinet/tcp.h: New file.
	* sysdeps/unix/sysv/linux/netipx/ipx.h: New file.
	* sysdeps/unix/sysv/linux/netatalk/atalk.h: New file.
	* sysdeps/unix/sysv/linux/Dist: Add new network headers.
	* sysdeps/unix/sysv/linux/Makefile [$(subdir)=misc] (sysdep_headers):
	Add sys/quota.h.
	[$(subdir)=inet] (sysdep_headers): Add new network header.

	* sysdeps/unix/sysv/linux/netinet/udp.h: Add Linux specific changes.

	* inet/netinet/ip.h: Move to sysdeps/generic.
	* inet/netinet/tcp.h: Likewise.
	* sysdeps/generic/netinet/ip.h: Moved to here from inet/netinet.
	* sysdeps/generic/netinet/tcp.h: Likewise.

1997-02-17 01:18  Ulrich Drepper  <drepper@cygnus.com>

	* misc/sys/syslog.h (prioritynames): Correct definition to use
	braces where necessary.
	(facilitynames): Likewise.
	Patch by Ronald F. Guilmette <rfg@monkeys.com>.
	Comment and beautify declarations.

1997-02-16 19:54 1997  Philip Blundell  <Philip.Blundell@pobox.com>

	* inet/Makefile (routines): Add in6_addr, getnameinfo.
	* inet/getnameinfo.c: New file.  Implementation of getnameinfo()
	by Craig Metz.
	* inet/in6_addr.c: New file.  IPv6 addressing constants.
	* posix/Makefile (routines): Add gai_strerror.
	* resolv/netdb.h: Add more constants for IPv6 basic API.
	* sysdeps/posix/gai_strerror.c: New file.
	* sysdeps/stub/gai_strerror.c New file.
	* sysdeps/unix/sysv/linux/netinet/in.h: Add definitions for IPv6
	basic API.

	* sysdeps/posix/getaddrinfo.c: Update from latest version by
	Craig Metz and use reentrant getXXbyYY functions.

1997-02-15 14:32 Andreas Jaeger  <aj@arthur.pfalz.de>

	* argp/argp.h: Declare argp_program_version as const char.
	* argp/argp-test.c: Likewise

	* stdlib/testrand.c (main): Declare main prototype.
	* stdlib/testdiv.c (main): Likewise.
	* string/testcopy.c (main): Likewise.
	* string/test-ffs.c (main): Likewise.
	* time/test_time.c (main): Likewise.

	* locale/duplocale.c (__duplocale): Return result.

1997-02-16 03:54  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/netinet/in.h: Declare bindresvport.
	Reported by fabsoft@fabserver1.zarm.uni-bremen.de.

	* nss/nss.h: Remove declaration of __nss_shlib_revision.
	* nss/nsswitch.c: Don't use NSS_SHLIB_VERSION macro.

1997-02-16 03:48  Thorsten Kukuk  <kukuk@weber.uni-paderborn.de>

	* nis/nss_nis/nis-ethers.c (_nss_nis_getethernam_r): Rename to
	_nss_nis_gethostton_r.
	(_nss_nis_getetherbyaddr_r): Rename to _nss_nis_getntohost_r.

1997-02-15 22:37  Andy Berkheimer  <andy@tho.org>

	* resolv/gethnamaddr.c (gethostbyname2): Test for ':' in name before
	trying to resolv name as numeric IPv6 address.
	* nss/digits_dots.c: Likewise.

Sat Feb 15 04:51:08 1997  Ulrich Drepper  <drepper@cygnus.com>

	* locale/setlocale.c (setlocale): Don't try to be clever about
	unused locales.  When the existence of the locale files isn't
	tested the result of setlocale might be different.

1997-02-15 03:34  Ulrich Drepper  <drepper@cygnus.com>

	* locale/setlocale.c (setlocale): Don't increment usage_count of
	new locale if it already has the value MAX_USAGE_COUNT (it might
	be the C locale data which is read-only).
This commit is contained in:
Ulrich Drepper
1997-02-19 04:43:53 +00:00
parent c84142e8fe
commit 1fb05e3db1
84 changed files with 3256 additions and 597 deletions

View File

@ -169,6 +169,9 @@ struct hol_entry
/* The cluster of options this entry belongs to, or 0 if none. */
struct hol_cluster *cluster;
/* The argp from which this option came. */
const struct argp *argp;
};
/* A cluster of entries to reflect the argp tree structure. */
@ -190,6 +193,9 @@ struct hol_cluster
level. */
struct hol_cluster *parent;
/* The argp from which this cluster is (eventually) derived. */
const struct argp *argp;
/* The distance this cluster is from the root. */
int depth;
@ -215,13 +221,14 @@ struct hol
struct hol_cluster *clusters;
};
/* Create a struct hol from an array of struct argp_option. CLUSTER is the
/* Create a struct hol from the options in ARGP. CLUSTER is the
hol_cluster in which these entries occur, or 0, if at the root. */
static struct hol *
make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
make_hol (const struct argp *argp, struct hol_cluster *cluster)
{
char *so;
const struct argp_option *o;
const struct argp_option *opts = argp->options;
struct hol_entry *entry;
unsigned num_short_options = 0;
struct hol *hol = malloc (sizeof (struct hol));
@ -231,15 +238,15 @@ make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
hol->num_entries = 0;
hol->clusters = 0;
if (opt)
if (opts)
{
int cur_group = 0;
/* The first option must not be an alias. */
assert (! oalias (opt));
assert (! oalias (opts));
/* Calculate the space needed. */
for (o = opt; ! oend (o); o++)
for (o = opts; ! oend (o); o++)
{
if (! oalias (o))
hol->num_entries++;
@ -254,7 +261,7 @@ make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
/* Fill in the entries. */
so = hol->short_options;
for (o = opt, entry = hol->entries; ! oend (o); entry++)
for (o = opts, entry = hol->entries; ! oend (o); entry++)
{
entry->opt = o;
entry->num = 0;
@ -266,6 +273,7 @@ make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
? cur_group + 1
: cur_group);
entry->cluster = cluster;
entry->argp = argp;
do
{
@ -285,10 +293,10 @@ make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
associated argp child list entry), INDEX, and PARENT, and return a pointer
to it. */
to it. ARGP is the argp that this cluster results from. */
static struct hol_cluster *
hol_add_cluster (struct hol *hol, int group, const char *header, int index,
struct hol_cluster *parent)
struct hol_cluster *parent, const struct argp *argp)
{
struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
if (cl)
@ -298,6 +306,7 @@ hol_add_cluster (struct hol *hol, int group, const char *header, int index,
cl->index = index;
cl->parent = parent;
cl->argp = argp;
cl->next = hol->clusters;
hol->clusters = cl;
@ -657,8 +666,8 @@ hol_append (struct hol *hol, struct hol *more)
if (oshort (opt) && ch == opt->key)
/* The next short option in MORE_SO, CH, is from OPT. */
{
if (! find_char (ch,
short_options, short_options + hol_so_len))
if (! find_char (ch, short_options,
short_options + hol_so_len))
/* The short option CH isn't shadowed by HOL's options,
so add it to the sum. */
*so++ = ch;
@ -689,6 +698,18 @@ indent_to (argp_fmtstream_t stream, unsigned col)
__argp_fmtstream_putc (stream, ' ');
}
/* Output to STREAM either a space, or a newline if there isn't room for at
least ENSURE characters before the right margin. */
static void
space (argp_fmtstream_t stream, size_t ensure)
{
if (__argp_fmtstream_point (stream) + ensure
>= __argp_fmtstream_rmargin (stream))
__argp_fmtstream_putc (stream, '\n');
else
__argp_fmtstream_putc (stream, ' ');
}
/* If the option REAL has an argument, we print it in using the printf
format REQ_FMT or OPT_FMT depending on whether it's a required or
optional argument. */
@ -715,44 +736,79 @@ struct pentry_state
struct hol_entry **prev_entry;
int *sep_groups;
int first; /* True if nothing's been printed so far. */
/* True if nothing's been printed so far. */
int first;
/* If non-zero, the state that was used to print this help. */
const struct argp_state *state;
};
/* If a user doc filter should be applied to DOC, do so. */
static const char *
filter_doc (const char *doc, int key, const struct argp *argp,
struct pentry_state *pest)
{
if (argp->help_filter)
/* We must apply a user filter to this output. */
{
void *input = __argp_input (argp, pest->state);
return (*argp->help_filter) (key, doc, input);
}
else
/* No filter. */
return (char *)doc;
}
/* Prints STR as a header line, with the margin lines set appropiately, and
notes the fact that groups should be separated with a blank line. Note
notes the fact that groups should be separated with a blank line. ARGP is
the argp that should dictate any user doc filtering to take place. Note
that the previous wrap margin isn't restored, but the left margin is reset
to 0. */
static void
print_header (const char *str, struct pentry_state *st)
print_header (const char *str, const struct argp *argp,
struct pentry_state *pest)
{
if (*str)
const char *tstr = gettext (str);
const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest);
if (fstr)
{
if (st->prev_entry && *st->prev_entry)
__argp_fmtstream_putc (st->stream, '\n'); /* Precede with a blank line. */
indent_to (st->stream, HEADER_COL);
__argp_fmtstream_set_lmargin (st->stream, HEADER_COL);
__argp_fmtstream_set_wmargin (st->stream, HEADER_COL);
__argp_fmtstream_puts (st->stream, str);
__argp_fmtstream_set_lmargin (st->stream, 0);
if (*fstr)
{
if (pest->prev_entry && *pest->prev_entry)
/* Precede with a blank line. */
__argp_fmtstream_putc (pest->stream, '\n');
indent_to (pest->stream, HEADER_COL);
__argp_fmtstream_set_lmargin (pest->stream, HEADER_COL);
__argp_fmtstream_set_wmargin (pest->stream, HEADER_COL);
__argp_fmtstream_puts (pest->stream, fstr);
__argp_fmtstream_set_lmargin (pest->stream, 0);
__argp_fmtstream_putc (pest->stream, '\n');
}
if (pest->sep_groups)
*pest->sep_groups = 1; /* Separate subsequent groups. */
}
if (st->sep_groups)
*st->sep_groups = 1; /* Separate subsequent groups. */
if (fstr != tstr)
free ((char *) fstr);
}
/* Inserts a comma if this isn't the first item on the line, and then makes
sure we're at least to column COL. Also clears FIRST. */
sure we're at least to column COL. If this *is* the first item on a line,
prints any pending whitespace/headers that should precede this line. Also
clears FIRST. */
static void
comma (unsigned col, struct pentry_state *st)
comma (unsigned col, struct pentry_state *pest)
{
if (st->first)
if (pest->first)
{
const struct hol_entry *pe = st->prev_entry ? *st->prev_entry : 0;
const struct hol_cluster *cl = st->entry->cluster;
const struct hol_entry *pe = pest->prev_entry ? *pest->prev_entry : 0;
const struct hol_cluster *cl = pest->entry->cluster;
if (st->sep_groups && *st->sep_groups
&& pe && st->entry->group != pe->group)
__argp_fmtstream_putc (st->stream, '\n');
if (pest->sep_groups && *pest->sep_groups
&& pe && pest->entry->group != pe->group)
__argp_fmtstream_putc (pest->stream, '\n');
if (pe && cl && pe->cluster != cl && cl->header && *cl->header
&& !hol_cluster_is_child (pe->cluster, cl))
@ -761,18 +817,17 @@ comma (unsigned col, struct pentry_state *st)
(in which case we had just popped into a sub-cluster for a bit).
If so, then print the cluster's header line. */
{
int old_wm = __argp_fmtstream_wmargin (st->stream);
print_header (cl->header, st);
__argp_fmtstream_putc (st->stream, '\n');
__argp_fmtstream_set_wmargin (st->stream, old_wm);
int old_wm = __argp_fmtstream_wmargin (pest->stream);
print_header (cl->header, cl->argp, pest);
__argp_fmtstream_set_wmargin (pest->stream, old_wm);
}
st->first = 0;
pest->first = 0;
}
else
__argp_fmtstream_puts (st->stream, ", ");
__argp_fmtstream_puts (pest->stream, ", ");
indent_to (st->stream, col);
indent_to (pest->stream, col);
}
/* Print help for ENTRY to STREAM. *PREV_ENTRY should contain the last entry
@ -781,15 +836,19 @@ comma (unsigned col, struct pentry_state *st)
printed before any output. *SEP_GROUPS is also set to true if a
user-specified group header is printed. */
static void
hol_entry_help (struct hol_entry *entry, argp_fmtstream_t stream,
hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
argp_fmtstream_t stream,
struct hol_entry **prev_entry, int *sep_groups)
{
unsigned num;
const struct argp_option *real = entry->opt, *opt;
char *so = entry->short_options;
/* Saved margins. */
int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
int old_wm = __argp_fmtstream_wmargin (stream);
struct pentry_state pest = { entry, stream, prev_entry, sep_groups, 1 };
/* PEST is a state block holding some of our variables that we'd like to
share with helper functions. */
struct pentry_state pest = { entry, stream, prev_entry, sep_groups, 1, state };
/* First emit short options. */
__argp_fmtstream_set_wmargin (stream, SHORT_OPT_COL); /* For truly bizarre cases. */
@ -809,7 +868,7 @@ hol_entry_help (struct hol_entry *entry, argp_fmtstream_t stream,
/* Now, long options. */
if (odoc (real))
/* Really a `documentation' option. */
/* A `documentation' option. */
{
__argp_fmtstream_set_wmargin (stream, DOC_OPT_COL);
for (opt = real, num = entry->num; num > 0; opt++, num--)
@ -823,7 +882,7 @@ hol_entry_help (struct hol_entry *entry, argp_fmtstream_t stream,
}
}
else
/* A realy long option. */
/* A real long option. */
{
__argp_fmtstream_set_wmargin (stream, LONG_OPT_COL);
for (opt = real, num = entry->num; num > 0; opt++, num--)
@ -835,39 +894,45 @@ hol_entry_help (struct hol_entry *entry, argp_fmtstream_t stream,
}
}
/* Next, documentation strings. */
__argp_fmtstream_set_lmargin (stream, 0);
if (pest.first)
/* Didn't print any switches, what's up? */
if (!oshort (real) && !real->name && real->doc)
if (!oshort (real) && !real->name)
/* This is a group header, print it nicely. */
print_header (real->doc, &pest);
print_header (real->doc, entry->argp, &pest);
else
/* Just a totally shadowed option or null header; print nothing. */
goto cleanup; /* Just return, after cleaning up. */
else if (real->doc)
/* Now the option documentation. */
else
{
unsigned col = __argp_fmtstream_point (stream);
const char *doc = real->doc;
const char *tstr = real->doc ? gettext (real->doc) : 0;
const char *fstr = filter_doc (tstr, real->key, entry->argp, &pest);
if (fstr && *fstr)
{
unsigned col = __argp_fmtstream_point (stream);
__argp_fmtstream_set_lmargin (stream, OPT_DOC_COL);
__argp_fmtstream_set_wmargin (stream, OPT_DOC_COL);
__argp_fmtstream_set_lmargin (stream, OPT_DOC_COL);
__argp_fmtstream_set_wmargin (stream, OPT_DOC_COL);
if (col > OPT_DOC_COL + 3)
__argp_fmtstream_putc (stream, '\n');
else if (col >= OPT_DOC_COL)
__argp_fmtstream_puts (stream, " ");
else
indent_to (stream, OPT_DOC_COL);
if (col > OPT_DOC_COL + 3)
__argp_fmtstream_putc (stream, '\n');
else if (col >= OPT_DOC_COL)
__argp_fmtstream_puts (stream, " ");
else
indent_to (stream, OPT_DOC_COL);
__argp_fmtstream_puts (stream, doc);
__argp_fmtstream_puts (stream, fstr);
}
if (fstr && fstr != tstr)
free ((char *) fstr);
/* Reset the left margin. */
__argp_fmtstream_set_lmargin (stream, 0);
__argp_fmtstream_putc (stream, '\n');
}
__argp_fmtstream_putc (stream, '\n');
if (prev_entry)
*prev_entry = entry;
@ -878,7 +943,8 @@ cleanup:
/* Output a long help message about the options in HOL to STREAM. */
static void
hol_help (struct hol *hol, argp_fmtstream_t stream)
hol_help (struct hol *hol, const struct argp_state *state,
argp_fmtstream_t stream)
{
unsigned num;
struct hol_entry *entry;
@ -886,7 +952,7 @@ hol_help (struct hol *hol, argp_fmtstream_t stream)
int sep_groups = 0; /* True if we should separate different
sections with blank lines. */
for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
hol_entry_help (entry, stream, &last_entry, &sep_groups);
hol_entry_help (entry, state, stream, &last_entry, &sep_groups);
}
/* Helper functions for hol_usage. */
@ -927,11 +993,7 @@ usage_argful_short_opt (const struct argp_option *opt,
{
/* Manually do line wrapping so that it (probably) won't
get wrapped at the embedded space. */
if (__argp_fmtstream_point (stream) + 6 + strlen (arg)
>= __argp_fmtstream_rmargin (stream))
__argp_fmtstream_putc (stream, '\n');
else
__argp_fmtstream_putc (stream, ' ');
space (stream, 6 + strlen (arg));
__argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
}
}
@ -1008,7 +1070,7 @@ static struct hol *
argp_hol (const struct argp *argp, struct hol_cluster *cluster)
{
const struct argp_child *child = argp->children;
struct hol *hol = make_hol (argp->options, cluster);
struct hol *hol = make_hol (argp, cluster);
if (child)
while (child->argp)
{
@ -1016,7 +1078,7 @@ argp_hol (const struct argp *argp, struct hol_cluster *cluster)
((child->group || child->header)
/* Put CHILD->argp within its own cluster. */
? hol_add_cluster (hol, child->group, child->header,
child - argp->children, cluster)
child - argp->children, cluster, argp)
/* Just merge it into the parent's cluster. */
: cluster);
hol_append (hol, argp_hol (child->argp, child_cluster)) ;
@ -1075,11 +1137,7 @@ argp_args_usage (const struct argp *argp, char **levels, int advance,
/* Manually do line wrapping so that it (probably) won't get wrapped at
any embedded spaces. */
if (__argp_fmtstream_point (stream) + 1 + nl - doc
>= __argp_fmtstream_rmargin (stream))
__argp_fmtstream_putc (stream, '\n');
else
__argp_fmtstream_putc (stream, ' ');
space (stream, 1 + nl - doc);
__argp_fmtstream_write (stream, doc, nl - doc);
}
@ -1111,46 +1169,98 @@ argp_args_usage (const struct argp *argp, char **levels, int advance,
then the first is as well. If FIRST_ONLY is true, only the first
occurance is output. Returns true if anything was output. */
static int
argp_doc (const struct argp *argp, int post, int pre_blank, int first_only,
argp_doc (const struct argp *argp, const struct argp_state *state,
int post, int pre_blank, int first_only,
argp_fmtstream_t stream)
{
const struct argp_child *child = argp->children;
const char *doc = argp->doc;
const char *text;
const char *inp_text;
void *input = 0;
int anything = 0;
size_t inp_text_limit = 0;
const char *doc = gettext (argp->doc);
const struct argp_child *child = argp->children;
if (doc)
{
char *vt = strchr (doc, '\v');
inp_text = post ? (vt ? vt + 1 : 0) : doc;
inp_text_limit = (!post && vt) ? (vt - doc) : 0;
}
else
inp_text = 0;
if (pre_blank && (vt || !post))
if (argp->help_filter)
/* We have to filter the doc strings. */
{
if (inp_text_limit)
/* Copy INP_TEXT so that it's nul-terminated. */
inp_text = strndup (inp_text, inp_text_limit);
input = __argp_input (argp, state);
text =
(*argp->help_filter) (post
? ARGP_KEY_HELP_POST_DOC
: ARGP_KEY_HELP_PRE_DOC,
inp_text, input);
}
else
text = (const char *) inp_text;
if (text)
{
if (pre_blank)
__argp_fmtstream_putc (stream, '\n');
if (vt)
if (post)
__argp_fmtstream_puts (stream, vt + 1);
else
__argp_fmtstream_write (stream, doc, vt - doc);
if (text == inp_text && inp_text_limit)
__argp_fmtstream_write (stream, inp_text, inp_text_limit);
else
if (! post)
__argp_fmtstream_puts (stream, doc);
__argp_fmtstream_puts (stream, text);
if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
__argp_fmtstream_putc (stream, '\n');
anything = 1;
}
if (text && text != inp_text)
free ((char *) text); /* Free TEXT returned from the help filter. */
if (inp_text && inp_text_limit && argp->help_filter)
free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
if (post && argp->help_filter)
/* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
{
text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
if (text)
{
if (anything || pre_blank)
__argp_fmtstream_putc (stream, '\n');
__argp_fmtstream_puts (stream, text);
free ((char *) text);
if (__argp_fmtstream_point (stream)
> __argp_fmtstream_lmargin (stream))
__argp_fmtstream_putc (stream, '\n');
anything = 1;
}
}
if (child)
while (child->argp && !(first_only && anything))
anything |=
argp_doc ((child++)->argp, post, anything || pre_blank, first_only,
argp_doc ((child++)->argp, state,
post, anything || pre_blank, first_only,
stream);
return anything;
}
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
void __argp_help (const struct argp *argp, FILE *stream,
unsigned flags, char *name)
/* Output a usage message for ARGP to STREAM. If called from
argp_state_help, STATE is the relevent parsing state. FLAGS are from the
set ARGP_HELP_*. NAME is what to use wherever a `program name' is
needed. */
static void
_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
unsigned flags, char *name)
{
int anything = 0; /* Whether we've output anything. */
struct hol *hol = 0;
@ -1190,7 +1300,8 @@ void __argp_help (const struct argp *argp, FILE *stream,
char *levels = pattern_levels;
__argp_fmtstream_printf (fs, "%s %s",
first_pattern ? "Usage:" : " or: ", name);
_(first_pattern ? "Usage:" : " or: "),
name);
/* We set the lmargin as well as the wmargin, because hol_usage
manually wraps options with newline to avoid annoying breaks. */
@ -1200,7 +1311,7 @@ void __argp_help (const struct argp *argp, FILE *stream,
/* Just show where the options go. */
{
if (hol->num_entries > 0)
__argp_fmtstream_puts (fs, " [OPTION...]");
__argp_fmtstream_puts (fs, _(" [OPTION...]"));
}
else
/* Actually print the options. */
@ -1223,13 +1334,13 @@ void __argp_help (const struct argp *argp, FILE *stream,
}
if (flags & ARGP_HELP_PRE_DOC)
anything |= argp_doc (argp, 0, 0, 1, fs);
anything |= argp_doc (argp, state, 0, 0, 1, fs);
if (flags & ARGP_HELP_SEE)
{
__argp_fmtstream_printf (fs,
"Try `%s --help' or `%s --usage' for more information.\n",
name, name);
__argp_fmtstream_printf (fs, _("\
Try `%s --help' or `%s --usage' for more information.\n"),
name, name);
anything = 1;
}
@ -1241,20 +1352,21 @@ void __argp_help (const struct argp *argp, FILE *stream,
{
if (anything)
__argp_fmtstream_putc (fs, '\n');
hol_help (hol, fs);
hol_help (hol, state, fs);
anything = 1;
}
}
if (flags & ARGP_HELP_POST_DOC)
/* Print any documentation strings at the end. */
anything |= argp_doc (argp, 1, anything, 0, fs);
anything |= argp_doc (argp, state, 1, anything, 0, fs);
if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
{
if (anything)
__argp_fmtstream_putc (fs, '\n');
__argp_fmtstream_printf (fs, "Report bugs to %s.\n", argp_program_bug_address);
__argp_fmtstream_printf (fs, _("Report bugs to %s.\n"),
argp_program_bug_address);
anything = 1;
}
@ -1263,6 +1375,14 @@ void __argp_help (const struct argp *argp, FILE *stream,
__argp_fmtstream_free (fs);
}
/* Output a usage message for ARGP to STREAM. FLAGS are from the set
ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
void __argp_help (const struct argp *argp, FILE *stream,
unsigned flags, char *name)
{
_help (argp, 0, stream, flags, name);
}
#ifdef weak_alias
weak_alias (__argp_help, argp_help)
#endif
@ -1277,8 +1397,8 @@ __argp_state_help (struct argp_state *state, FILE *stream, unsigned flags)
if (state && (state->flags & ARGP_LONG_ONLY))
flags |= ARGP_HELP_LONG_ONLY;
__argp_help (state ? state->argp : 0, stream, flags,
state ? state->name : program_invocation_name);
_help (state ? state->argp : 0, state, stream, flags,
state ? state->name : program_invocation_short_name);
if (!state || ! (state->flags & ARGP_NO_EXIT))
{
@ -1307,7 +1427,7 @@ __argp_error (struct argp_state *state, const char *fmt, ...)
{
va_list ap;
fputs (state ? state->name : program_invocation_name, stream);
fputs (state ? state->name : program_invocation_short_name, stream);
putc (':', stream);
putc (' ', stream);
@ -1343,7 +1463,7 @@ __argp_failure (struct argp_state *state, int status, int errnum,
if (stream)
{
fputs (state ? state->name : program_invocation_name, stream);
fputs (state ? state->name : program_invocation_short_name, stream);
if (fmt)
{