# include <config.h>
#endif
#include <stdio.h>
+#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#ifndef ENABLE_NLS
# define ENABLE_NLS 0
#endif
+#ifndef HELP_GETOPT_LONG_ONLY
+# define HELP_GETOPT_LONG_ONLY 0
+#endif
#if ENABLE_NLS
# include <locale.h>
# define mbsnwidth(a, b, c) (assert(0), 0)
#endif
-#define _(s) gettext(s)
+#define STR_L10N_(x)
+#define N_(s) s
/* Returns a single numeric value depending on the type of option:
*
{
int ret = opt->has_arg & 3;
+#if !HELP_GETOPT_LONG_ONLY
if (!opt->flag)
ret |= (opt->val <= CHAR_MAX) << 2;
+#endif
return ret;
}
OPT_LONG_WITHOUT_ARG = 0,
};
+#if HELP_GETOPT_LONG_ONLY
+/* String table generated by gen-strtab.awk from help-glo.str */
+#define STRTAB_INITIALIZER \
+ N_(" -%s [%s]") \
+ "\0" "%*s%.*s\n" \
+ "\0" N_(" -%s %s") \
+ "\0" N_(" -%s") \
+ ""
+enum {
+ fmt_long_optional_arg = 0,
+ fmt_long_mandatory_arg = 19,
+ fmt_long_without_arg = 27,
+ fmt_desc = 10,
+ fmt_nl = 17
+};
+#else
+/* String table generated by gen-strtab.awk from help-std.str */
+#define STRTAB_INITIALIZER \
+ STR_L10N_(N_(" --%s[=%s]")) \
+ STR_L10N_(N_(" --%s=%s")) \
+ STR_L10N_(N_(" --%s")) \
+ N_(" -%c, --%s[=%s]") \
+ "\0" N_(" -%c, --%s=%s") \
+ "\0" N_(" -%c, --%s") \
+ "\0" "%*s%.*s\n" \
+ ""
+enum {
+ fmt_short_optional_arg = 0,
+ fmt_long_optional_arg = 5,
+ fmt_short_mandatory_arg = 16,
+ fmt_long_mandatory_arg = 21,
+ fmt_short_without_arg = 30,
+ fmt_long_without_arg = 35,
+ fmt_desc = 41,
+ fmt_nl = 48
+};
+#endif
+
+static const struct optstr {
+ unsigned char map[HELP_GETOPT_LONG_ONLY ? 3 : 7];
+ char tab[sizeof (STRTAB_INITIALIZER)];
+} optstr = {
+ {
+ offsetof(struct optstr, tab) + fmt_long_without_arg,
+ offsetof(struct optstr, tab) + fmt_long_mandatory_arg,
+ offsetof(struct optstr, tab) + fmt_long_optional_arg,
+#if !HELP_GETOPT_LONG_ONLY
+ 0,
+ offsetof(struct optstr, tab) + fmt_short_without_arg,
+ offsetof(struct optstr, tab) + fmt_short_mandatory_arg,
+ offsetof(struct optstr, tab) + fmt_short_optional_arg,
+#endif
+ },
+ STRTAB_INITIALIZER
+};
+
/*
* When NLS is enabled, we assume snprintf is available. The GNU libintl
* library should provide a suitable fallback if necessary.
}
#endif
+#define has_short_char(type) (!HELP_GETOPT_LONG_ONLY && (type & 4))
+
int help_print_optstring(const struct option *opt, const char *argname, int l)
{
+ int type = option_type(opt);
+ const char *fmt, *nls_arg;
char optstring[256];
int w;
+ fmt = (char *)&optstr + optstr.map[type];
if (!ENABLE_NLS)
goto no_translate;
- switch (option_type(opt)) {
-#if HELP_GETOPT_LONG_ONLY
- case OPT_SHORT_WITH_OPTIONAL_ARG:
- case OPT_LONG_WITH_OPTIONAL_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%s [%s]"), opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_SHORT_WITH_MANDATORY_ARG:
- case OPT_LONG_WITH_MANDATORY_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%s %s"), opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_SHORT_WITHOUT_ARG:
- case OPT_LONG_WITHOUT_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%s"), opt->name);
- break;
-#else
- case OPT_SHORT_WITH_OPTIONAL_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%c, --%s[=%s]"), opt->val, opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_LONG_WITH_OPTIONAL_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" --%s[=%s]"), opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_SHORT_WITH_MANDATORY_ARG:
+ nls_arg = argname ? pgettext_expr(opt->name, argname) : argname;
+ if (has_short_char(type)) {
w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%c, --%s=%s"), opt->val, opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_LONG_WITH_MANDATORY_ARG:
+ gettext(fmt), opt->val, opt->name,
+ nls_arg);
+ } else {
w = help_do_snprintf(optstring, sizeof optstring,
- _(" --%s=%s"), opt->name,
- pgettext_expr(opt->name, argname));
- break;
- case OPT_SHORT_WITHOUT_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" -%c, --%s"), opt->val, opt->name);
- break;
- case OPT_LONG_WITHOUT_ARG:
- w = help_do_snprintf(optstring, sizeof optstring,
- _(" --%s"), opt->name);
- break;
-#endif
- default:
- assert(0);
+ gettext(fmt), opt->name,
+ nls_arg);
}
if (w < 0 || w >= sizeof optstring)
goto out;
no_translate:
- switch (option_type(opt)) {
-#if HELP_GETOPT_LONG_ONLY
- case OPT_SHORT_WITH_OPTIONAL_ARG:
- case OPT_LONG_WITH_OPTIONAL_ARG:
- w = printf(" -%s [%s]", opt->name, argname);
- break;
- case OPT_SHORT_WITH_MANDATORY_ARG:
- case OPT_LONG_WITH_MANDATORY_ARG:
- w = printf(" -%s %s", opt->name, argname);
- break;
- case OPT_SHORT_WITHOUT_ARG:
- case OPT_LONG_WITHOUT_ARG:
- w = printf(" -%s", opt->name);
- break;
-#else
- case OPT_SHORT_WITH_OPTIONAL_ARG:
- w = printf(" -%c, --%s[=%s]", opt->val, opt->name, argname);
- break;
- case OPT_LONG_WITH_OPTIONAL_ARG:
- w = printf(" --%s[=%s]", opt->name, argname);
- break;
- case OPT_SHORT_WITH_MANDATORY_ARG:
- w = printf(" -%c, --%s=%s", opt->val, opt->name, argname);
- break;
- case OPT_LONG_WITH_MANDATORY_ARG:
- w = printf(" --%s=%s", opt->name, argname);
- break;
- case OPT_SHORT_WITHOUT_ARG:
- w = printf(" -%c, --%s", opt->val, opt->name);
- break;
- case OPT_LONG_WITHOUT_ARG:
- w = printf(" --%s", opt->name);
- break;
-#endif
- default:
- assert(0);
+ if (has_short_char(type)) {
+ w = printf(fmt, opt->val, opt->name, argname);
+ } else {
+ w = printf(fmt, opt->name, argname);
}
out:
- if (w < 0 || w > l) {
+ if (w <= 0 || w > l) {
putchar('\n');
return 0;
}
s = pgettext_expr(opt->name, s);
do {
- size_t n = strcspn(s, "\n");
+ size_t n = strcspn(s, &optstr.tab[fmt_nl]);
- printf("%*s%.*s\n", n ? i-w : 0, "", (int)n, s);
+ printf(&optstr.tab[fmt_desc], n ? i-w : 0, "", (int)n, s);
s += n + (s[n] != '\0');
w = 0;
} while (*s);