-# Copyright © 2015 Nick Bowler
+# Copyright © 2015, 2019, 2021-2023 Nick Bowler
#
# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
# This is free software: you are free to do what the fuck you want to.
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -I$(top_srcdir)/src
+AM_CPPFLAGS = -I$(top_srcdir)/src
check_LIBRARIES = t/libdummy.a t/libempty.a
if HAVE_STRUCT_OPTION
check_PROGRAMS += t/helpdesc t/helpopt t/helpopt2
+
+if HAVE_WCWIDTH
+check_PROGRAMS += t/helpopt3
+endif
endif
EXTRA_LIBRARIES = libglohelp.a
libglohelp_a_SOURCES = src/help.c
-libglohelp_a_CFLAGS = -DHELP_GETOPT_LONG_ONLY
+libglohelp_a_CPPFLAGS = -DHELP_GETOPT_LONG_ONLY
libglohelp_a_SHORTNAME = glo
+EXTRA_LIBRARIES += libnlshelp.a
+libnlshelp_a_SOURCES = src/help.c t/nls/mbswidth.c
+libnlshelp_a_CPPFLAGS = -DENABLE_NLS -I$(top_srcdir)/t/nls
+libnlshelp_a_SHORTNAME = nls
+
t_helpdesc_SOURCES = t/helpdesc.c src/help.c src/tap.c
t_helpopt_SOURCES = t/helpopt.c src/help.c src/tap.c
+
t_helpopt2_SOURCES = t/helpopt.c src/tap.c
t_helpopt2_LDADD = $(libglohelp_a_OBJECTS)
EXTRA_t_helpopt2_DEPENDENCIES = $(t_helpopt2_LDADD)
+t_helpopt3_SOURCES = t/helpopt.c src/tap.c
+t_helpopt3_LDADD = $(libnlshelp_a_OBJECTS)
+EXTRA_t_helpopt3_DEPENDENCIES = $(t_helpopt3_LDADD)
+
check_PROGRAMS += t/copysym
t_copysym_SOURCES = t/copysym.c src/tap.c
t_copysym_LDADD = $(libnlscopysym_a_OBJECTS)
EXTRA_LIBRARIES += libnlscopysym.a
libnlscopysym_a_SOURCES = src/copysym.c
-libnlscopysym_a_CFLAGS = -DENABLE_NLS
+libnlscopysym_a_CPPFLAGS = -DENABLE_NLS
libnlscopysym_a_SHORTNAME = nls
DISTCLEANFILES =
-dnl Copyright © 2015, 2019-2022 Nick Bowler
+dnl Copyright © 2015, 2019-2023 Nick Bowler
dnl
dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
dnl This is free software: you are free to do what the fuck you want to.
DX_INIT([.])
+AC_USE_SYSTEM_EXTENSIONS
+AC_CHECK_FUNCS_ONCE([wcwidth])
+AM_CONDITIONAL([HAVE_WCWIDTH], [test x"$ac_cv_func_wcwidth" = x"yes"])
+
AC_CONFIG_TESTDIR([.])
DX_PROG_AUTOTEST
AM_CONDITIONAL([HAVE_AUTOTEST], [test x"$dx_cv_autotest_works" = x"yes"])
--- /dev/null
+# Copyright © 2023 Nick Bowler
+#
+# Helper macros for finding a locale using a specific character set.
+#
+# License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+# This is free software: you are free to do what the fuck you want to.
+# There is NO WARRANTY, to the extent permitted by law.
+
+# TEST_UTF8_LOCALE([variable], [action-if-found], [action-if-not-found])
+#
+# Try to find a supported UTF-8 locale. If any is found, the given shell
+# variable is set to the name of one such locale, and action-if-found is
+# expanded.
+#
+# If no suitable locale is found, then variable is set to the empty string
+# and action-if-not-found is expanded. If no action is specified, the
+# default action in this scenario is to skip the current test group.
+#
+# Since m4sh overrides LC_ALL, it is recommended to use the locale by
+# setting LC_ALL to the detected value when running a program.
+m4_defun([TEST_UTF8_LOCALE],
+[AS_VAR_SET([$1], [`_TEST_UTF8_LOCALE`])
+AS_VAR_IF([$1], [""], [m4_default([$3], [AT_SKIP_IF([:])])], [$2])])
+
+m4_defun([_TEST_UTF8_LOCALE], [m4_require([_TEST_NLS_SETUP])dnl
+test_find_locale_charmap '[[Uu][Tt][Ff]-*8]'])
+
+# Output shell function definitions to implement locale detection.
+#
+# - test_check_locale_charmap name regex
+#
+# Returns success if setting LC_ALL to the given locale name results in a
+# charmap string that matches the given regex (as interpreted by 'grep').
+#
+# - test_find_locale_charmap regex
+#
+# Try to find any locale for which test_check_locale_charmap is successful
+# with the given regex. If a matching locale is found, it is printed to
+# standard output.
+#
+# By default, the user's own LC_CTYPE is preferred. Otherwise, the first
+# match in the output of "locale -a" is chosen.
+
+m4_defun_once([_TEST_NLS_SETUP], [m4_divert_push([HEADER-COPYRIGHT])
+# save user locale setting before m4sh clobbers it
+_orig_LC_ALL=$LC_ALL
+
+m4_divert([PREPARE_TESTS])
+test_check_locale_charmap () {
+ LC_ALL=$[1] locale -ck charmap 2>&AS_MESSAGE_LOG_FD | grep "$[2]" >/dev/null 2>&1
+}
+
+test_find_locale_charmap () {
+ save_LC_ALL=$LC_ALL
+ LC_ALL=$_orig_LC_ALL
+ re=$[1]
+
+ init_ctype=`locale 2>&AS_MESSAGE_LOG_FD | $AWK -F= '$[1] == "LC_CTYPE" {
+ $[1] = ""; sub(/^ "/, ""); sub(/"$/, ""); print
+ }'`
+
+ LC_ALL=$save_LC_ALL
+ if test_check_locale_charmap "$init_ctype" "$re"; then
+ AS_ECHO(["$init_ctype"])
+ return;
+ fi
+
+ set x `locale -a | grep "$re"`; shift
+ for arg; do
+ if test_check_locale_charmap "$arg" "$re"; then
+ AS_ECHO(["$arg"])
+ return;
+ fi
+ done
+}
+m4_divert_pop([PREPARE_TESTS])
+])
/helpdesc
/helpopt
/helpopt2
+/helpopt3
/packtest[su]
/packtest[su]64
--- /dev/null
+/*
+ * Copyright © 2023 Nick Bowler
+ *
+ * Stub gettext macros for test purposes.
+ *
+ * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+ * This is free software: you are free to do what the fuck you want to.
+ * There is NO WARRANTY, to the extent permitted by law.
+ */
+
+#ifndef TEST_NLS_GETTEXT_H_
+#define TEST_NLS_GETTEXT_H_
+
+#define gettext(s) (s)
+#define pgettext_expr(a, s) (s)
+
+#endif
--- /dev/null
+/*
+ * Copyright © 2023 Nick Bowler
+ *
+ * Simplified mbsnwidth for test purposes.
+ *
+ * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+ * This is free software: you are free to do what the fuck you want to.
+ * There is NO WARRANTY, to the extent permitted by law.
+ */
+
+#include <string.h>
+#include <locale.h>
+#include <wchar.h>
+
+#include "mbswidth.h"
+
+int mbsnwidth(const char *buf, size_t buflen, int flags)
+{
+ static int initialized;
+ mbstate_t ps;
+ int ret = 0;
+
+ if (!initialized) {
+ setlocale(LC_CTYPE, "");
+ initialized = 1;
+ }
+
+ memset(&ps, 0, sizeof ps);
+ while (buflen > 0) {
+ wchar_t wc;
+ size_t l;
+ int w;
+
+ l = mbrtowc(&wc, buf, buflen, &ps);
+ if (l == (size_t)-1 || l == (size_t)-2)
+ return -1;
+ else if (l == 0)
+ break;
+
+ buflen -= l;
+ buf += l;
+
+ w = wcwidth(wc);
+ if (w < 0)
+ return -1;
+ ret += w;
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright © 2023 Nick Bowler
+ *
+ * Simplified mbsnwidth for test purposes.
+ *
+ * License WTFPL2: Do What The Fuck You Want To Public License, version 2.
+ * This is free software: you are free to do what the fuck you want to.
+ * There is NO WARRANTY, to the extent permitted by law.
+ */
+
+#ifndef TEST_NLS_MBSWIDTH_H_
+#define TEST_NLS_MBSWIDTH_H_
+
+#include <stddef.h>
+
+int mbsnwidth(const char *buf, size_t n, int flags);
+
+#endif
AT_CLEANUP
+AT_SETUP([help_print_optstring (NLS fullwidth/halfwidth)])
+AT_KEYWORDS([help nls])
+
+AT_SKIP_IF([test ! -x "$builddir/t/helpopt3"])
+TEST_UTF8_LOCALE([locale_utf8])
+
+AT_CHECK([m4_join([ ],
+ [LC_ALL=$locale_utf8 "$builddir/t/helpopt3"],
+ [--全角],
+ [--ハンカク],
+ )], [0],
+[[ --全角 8
+ --ハンカク 8
+]])
+
+AT_CLEANUP
+
AT_BANNER([Miscellaneous functions])
TEST_TAP_SIMPLE([copyright_symbol], [copysym], [], [])
AT_COPYRIGHT([dnl
-Copyright © 2015,2019-2023 Nick Bowler
+Copyright © 2015, 2019-2023 Nick Bowler
License WTFPL2: Do What The Fuck You Want To Public License, version 2.
This is free software: you are free to do what the fuck you want to.
There is NO WARRANTY, to the extent permitted by law.])
AT_COLOR_TESTS
m4_include([snippet/test-tap.at])
+m4_include([snippet/test-nls.at])
m4_divert_push([PREPARE_TESTS])dnl
# Reduce influence from the toplevel "make" invocation on test cases.