X-Git-Url: http://git.draconx.ca/gitweb/dxcommon.git/blobdiff_plain/6532aaac91a7efd99eb74726679c4000459e7bb3..9cacb902a5d6f6c4271ee3066e2efe13663f145a:/src/help.c diff --git a/src/help.c b/src/help.c index ea817e8..4b77b2c 100644 --- a/src/help.c +++ b/src/help.c @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Nick Bowler + * Copyright © 2021-2023 Nick Bowler * * Helper functions for formatting --help program output. * @@ -51,7 +51,12 @@ */ static int option_type(const struct option *opt) { - return ((opt->val <= CHAR_MAX) << 2) | (opt->has_arg & 3); + int ret = opt->has_arg & 3; + + if (!opt->flag) + ret |= (opt->val <= CHAR_MAX) << 2; + + return ret; } enum { @@ -63,9 +68,23 @@ enum { OPT_LONG_WITHOUT_ARG = 0, }; +/* + * When NLS is enabled, we assume snprintf is available. The GNU libintl + * library should provide a suitable fallback if necessary. + */ +#if ENABLE_NLS && !defined(help_do_snprintf) +#define help_do_snprintf snprintf +#elif !ENABLE_NLS +#define help_do_snprintf fake_snprintf +static inline int fake_snprintf(char *buf, size_t n, const char *fmt, ...) +{ + return -1; +} +#endif + int help_print_optstring(const struct option *opt, const char *argname, int l) { - char optstring[100]; + char optstring[256]; int w; if (!ENABLE_NLS) @@ -75,56 +94,56 @@ int help_print_optstring(const struct option *opt, const char *argname, int l) #if HELP_GETOPT_LONG_ONLY case OPT_SHORT_WITH_OPTIONAL_ARG: case OPT_LONG_WITH_OPTIONAL_ARG: - w = snprintf(optstring, sizeof optstring, - _(" -%s [%s]"), opt->name, - pgettext_expr(opt->name, argname)); + 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 = snprintf(optstring, sizeof optstring, - _(" -%s %s"), opt->name, - pgettext_expr(opt->name, argname)); + 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 = snprintf(optstring, sizeof optstring, - _(" -%s"), opt->name); + w = help_do_snprintf(optstring, sizeof optstring, + _(" -%s"), opt->name); break; #else case OPT_SHORT_WITH_OPTIONAL_ARG: - w = snprintf(optstring, sizeof optstring, - _(" -%c, --%s[=%s]"), opt->val, opt->name, - pgettext_expr(opt->name, argname)); + 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 = snprintf(optstring, sizeof optstring, - _(" --%s[=%s]"), opt->name, - pgettext_expr(opt->name, argname)); + w = help_do_snprintf(optstring, sizeof optstring, + _(" --%s[=%s]"), opt->name, + pgettext_expr(opt->name, argname)); break; case OPT_SHORT_WITH_MANDATORY_ARG: - w = snprintf(optstring, sizeof optstring, - _(" -%c, --%s=%s"), opt->val, opt->name, - pgettext_expr(opt->name, argname)); + 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: - w = snprintf(optstring, sizeof optstring, - _(" --%s=%s"), opt->name, - pgettext_expr(opt->name, argname)); + w = help_do_snprintf(optstring, sizeof optstring, + _(" --%s=%s"), opt->name, + pgettext_expr(opt->name, argname)); break; case OPT_SHORT_WITHOUT_ARG: - w = snprintf(optstring, sizeof optstring, - _(" -%c, --%s"), opt->val, opt->name); + w = help_do_snprintf(optstring, sizeof optstring, + _(" -%c, --%s"), opt->val, opt->name); break; case OPT_LONG_WITHOUT_ARG: - w = snprintf(optstring, sizeof optstring, - _(" --%s"), opt->name); + w = help_do_snprintf(optstring, sizeof optstring, + _(" --%s"), opt->name); break; #endif default: assert(0); } - if (w < 0) + if (w < 0 || w >= sizeof optstring) goto no_translate; w = mbsnwidth(optstring, w, 0); @@ -183,6 +202,9 @@ void help_print_desc(const struct option *opt, const char *s, int i, int w) if (opt) s = pgettext_expr(opt->name, s); + if (i && s[0] == '\0') + putchar('\n'); + for (; *s; w = 0) { const char *nl = strchr(s, '\n'); int n = (nl ? nl-s : -1);