/* Hierarchial argument parsing help output
- Copyright (C) 1995-2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This program is free software; you can 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.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program 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
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#include <config.h>
#endif
-#ifndef alloca
-# ifdef __GNUC__
-# define alloca __builtin_alloca
-# define HAVE_ALLOCA 1
+/* AIX requires this to be the first thing in the file. */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H || defined _LIBC
+# include <alloca.h>
# else
-# if defined HAVE_ALLOCA_H || defined _LIBC
-# include <alloca.h>
+# ifdef _AIX
+#pragma alloca
# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca
+# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
-# endif
# endif
# endif
# endif
#include <string.h>
#include <assert.h>
#include <stdarg.h>
-#include <malloc.h>
#include <ctype.h>
+#include <limits.h>
#ifdef USE_IN_LIBIO
# include <wchar.h>
#endif
# endif
#endif
+#ifndef _LIBC
+# if HAVE_STRERROR_R
+# if !HAVE_DECL_STRERROR_R
+char *strerror_r (int errnum, char *buf, size_t buflen);
+# endif
+# else
+# if !HAVE_DECL_STRERROR
+char *strerror (int errnum);
+# endif
+# endif
+#endif
+
#include "argp.h"
#include "argp-fmtstream.h"
#include "argp-namefrob.h"
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
\f
/* User-selectable (using an environment variable) formatting parameters.
hol->short_options = malloc (num_short_options + 1);
assert (hol->entries && hol->short_options);
+#if SIZE_MAX <= UINT_MAX
+ assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
+#endif
/* Fill in the entries. */
so = hol->short_options;
free (hol);
}
\f
-static inline int
+static int
hol_entry_short_iterate (const struct hol_entry *entry,
int (*func)(const struct argp_option *opt,
const struct argp_option *real,
}
static inline int
+__attribute__ ((always_inline))
hol_entry_long_iterate (const struct hol_entry *entry,
int (*func)(const struct argp_option *opt,
const struct argp_option *real,
char *short_options =
malloc (hol_so_len + strlen (more->short_options) + 1);
+ assert (entries && short_options);
+#if SIZE_MAX <= UINT_MAX
+ assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
+#endif
+
__mempcpy (__mempcpy (entries, hol->entries,
hol->num_entries * sizeof (struct hol_entry)),
more->entries,
if (! stream)
return;
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__flockfile (stream);
+#endif
if (! uparams.valid)
fill_in_uparams (state);
fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
if (! fs)
{
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__funlockfile (stream);
+#endif
return;
}
anything = 1;
}
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__funlockfile (stream);
+#endif
if (hol)
hol_free (hol);
weak_alias (__argp_help, argp_help)
#endif
+#ifndef _LIBC
+char *__argp_basename (char *name)
+{
+ char *short_name = strrchr (name, '/');
+ return short_name ? short_name + 1 : name;
+}
+
+char *
+__argp_short_program_name (void)
+{
+# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+ return program_invocation_short_name;
+# elif HAVE_DECL_PROGRAM_INVOCATION_NAME
+ return __argp_basename (program_invocation_name);
+# else
+ /* FIXME: What now? Miles suggests that it is better to use NULL,
+ but currently the value is passed on directly to fputs_unlocked,
+ so that requires more changes. */
+# if __GNUC__
+# warning No reasonable value to return
+# endif /* __GNUC__ */
+ return "";
+# endif
+}
+#endif
+
/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
from the set ARGP_HELP_*. */
void
flags |= ARGP_HELP_LONG_ONLY;
_help (state ? state->root_argp : 0, state, stream, flags,
- state ? state->name : program_invocation_short_name);
+ state ? state->name : __argp_short_program_name ());
if (!state || ! (state->flags & ARGP_NO_EXIT))
{
{
va_list ap;
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__flockfile (stream);
+#endif
va_start (ap, fmt);
__asprintf (&buf, fmt, ap);
__fwprintf (stream, L"%s: %s\n",
- state ? state->name : program_invocation_short_name,
+ state ? state->name : __argp_short_program_name (),
buf);
free (buf);
#endif
{
fputs_unlocked (state
- ? state->name : program_invocation_short_name,
+ ? state->name : __argp_short_program_name (),
stream);
putc_unlocked (':', stream);
putc_unlocked (' ', stream);
va_end (ap);
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__funlockfile (stream);
+#endif
}
}
}
if (stream)
{
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__flockfile (stream);
+#endif
#ifdef USE_IN_LIBIO
if (_IO_fwide (stream, 0) > 0)
__fwprintf (stream, L"%s",
- state ? state->name : program_invocation_short_name);
+ state ? state->name : __argp_short_program_name ());
else
#endif
fputs_unlocked (state
- ? state->name : program_invocation_short_name,
+ ? state->name : __argp_short_program_name (),
stream);
if (fmt)
{
putc_unlocked (':', stream);
putc_unlocked (' ', stream);
+#if defined _LIBC || defined HAVE_STRERROR_R
fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
+#else
+ fputs (strerror (errnum), stream);
+#endif
}
}
#endif
putc_unlocked ('\n', stream);
+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
__funlockfile (stream);
+#endif
if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
exit (status);