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. */
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#include <alloca.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <getopt_int.h>
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.
- When compiling libc, the _ macro is predefined. */
-# if defined HAVE_LIBINTL_H || defined _LIBC
-# include <libintl.h>
-# ifdef _LIBC
-# undef dgettext
-# define dgettext(domain, msgid) \
- INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
-# endif
-# else
-# define dgettext(domain, msgid) (msgid)
-# define gettext(msgid) (msgid)
-# endif
-#endif
-#ifndef N_
-# define N_(msgid) (msgid)
+#ifdef _LIBC
+# include <libintl.h>
+# undef dgettext
+# define dgettext(domain, msgid) \
+ INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
+#else
+# include "gettext.h"
#endif
+#define N_(msgid) msgid
#include "argp.h"
#include "argp-namefrob.h"
+#define alignof(type) offsetof (struct { char c; type x; }, x)
+#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d))
+
/* Getopt return values. */
#define KEY_END (-1) /* The end of the options. */
#define KEY_ARG 1 /* A non-option argument. */
static const struct argp_option argp_default_options[] =
{
- {"help", '?', 0, 0, N_("Give this help list"), -1},
- {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")},
- {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name")},
- {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
- N_("Hang for SECS seconds (default 3600)")},
- {0, 0}
+ {"help", '?', 0, 0, N_("give this help list"), -1},
+ {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0},
+ {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0},
+ {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
+ N_("hang for SECS seconds (default 3600)"), 0},
+ {NULL, 0, 0, 0, NULL, 0}
};
static error_t
break;
case OPT_USAGE:
__argp_state_help (state, state->out_stream,
- ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
+ ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
break;
case OPT_PROGNAME: /* Set the program name. */
to be that, so we have to be a bit careful here.] */
/* Update what we use for messages. */
- state->name = strrchr (arg, '/');
- if (state->name)
- state->name++;
- else
- state->name = arg;
+ state->name = __argp_base_name (arg);
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
program_invocation_short_name = state->name;
\f
static const struct argp_option argp_version_options[] =
{
- {"version", 'V', 0, 0, N_("Print program version"), -1},
- {0, 0}
+ {"version", 'V', 0, 0, N_("print program version"), -1},
+ {NULL, 0, 0, 0, NULL, 0}
};
static error_t
struct group *group;
struct parser_sizes szs;
struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
+ char *storage;
+ size_t glen, gsum;
+ size_t clen, csum;
+ size_t llen, lsum;
+ size_t slen, ssum;
szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
szs.long_len = 0;
calc_sizes (argp, &szs);
/* Lengths of the various bits of storage used by PARSER. */
-#define GLEN (szs.num_groups + 1) * sizeof (struct group)
-#define CLEN (szs.num_child_inputs * sizeof (void *))
-#define LLEN ((szs.long_len + 1) * sizeof (struct option))
-#define SLEN (szs.short_len + 1)
-
- parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
+ glen = (szs.num_groups + 1) * sizeof (struct group);
+ clen = szs.num_child_inputs * sizeof (void *);
+ llen = (szs.long_len + 1) * sizeof (struct option);
+ slen = szs.short_len + 1;
+
+ /* Sums of previous lengths, properly aligned. There's no need to
+ align gsum, since struct group is aligned at least as strictly as
+ void * (since it contains a void * member). And there's no need
+ to align lsum, since struct option is aligned at least as
+ strictly as char. */
+ gsum = glen;
+ csum = alignto (gsum + clen, alignof (struct option));
+ lsum = csum + llen;
+ ssum = lsum + slen;
+
+ parser->storage = malloc (ssum);
if (! parser->storage)
return ENOMEM;
+ storage = parser->storage;
parser->groups = parser->storage;
- parser->child_inputs = parser->storage + GLEN;
- parser->long_opts = parser->storage + GLEN + CLEN;
- parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
+ parser->child_inputs = (void **) (storage + gsum);
+ parser->long_opts = (struct option *) (storage + csum);
+ parser->short_opts = storage + lsum;
parser->opt_data = opt_data;
- memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
+ memset (parser->child_inputs, 0, clen);
parser_convert (parser, argp, flags);
memset (&parser->state, 0, sizeof (struct argp_state));
if (parser->state.argv == argv && argv[0])
/* There's an argv[0]; use it for messages. */
- {
- char *short_name = strrchr (argv[0], '/');
- parser->state.name = short_name ? short_name + 1 : argv[0];
- }
+ parser->state.name = __argp_base_name (argv[0]);
else
parser->state.name = __argp_short_program_name ();
to be parsed (which in some cases isn't actually an error). */
int arg_ebadkey = 0;
+#ifndef _LIBC
+ if (!(flags & ARGP_PARSE_ARGV0))
+ {
+#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME
+ if (!program_invocation_name)
+ program_invocation_name = argv[0];
+#endif
+#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
+ if (!program_invocation_short_name)
+ program_invocation_short_name = __argp_base_name (argv[0]);
+#endif
+ }
+#endif
+
if (! (flags & ARGP_NO_HELP))
/* Add our own options. */
{