The current code calls snprintf unconditionally, even if NLS is disabled
(although the function is not called, the code is still compiled), so it
won't build in environments which lack this function.
For the NLS-enabled case we can rely on the GNU libintl fallback being
available as required.
Otherwise we can just provide a stub to ensure the dead code compiles,
and for the NLS test programs hack in sprintf as a replacement which
should work just fine.
OPT_LONG_WITHOUT_ARG = 0,
};
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)
{
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:
#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:
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:
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:
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:
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:
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:
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:
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:
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);
}
break;
#endif
default:
assert(0);
}
+ if (w < 0 || w >= sizeof optstring)
goto no_translate;
w = mbsnwidth(optstring, w, 0);
goto no_translate;
w = mbsnwidth(optstring, w, 0);
#ifndef TEST_NLS_GETTEXT_H_
#define TEST_NLS_GETTEXT_H_
#ifndef TEST_NLS_GETTEXT_H_
#define TEST_NLS_GETTEXT_H_
+#include <stdio.h>
+#include <stdarg.h>
+
#define gettext(s) (s)
#define pgettext_expr(a, s) (s)
#define gettext(s) (s)
#define pgettext_expr(a, s) (s)
+/*
+ * We don't need a real snprintf for testing help functionality; substitute
+ * using vsprintf to ease testing on C89 implementations.
+ */
+#define help_do_snprintf help_do_snprintf
+static inline int help_do_snprintf(char *buf, size_t n, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vsprintf(buf, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+