--- /dev/null
+dnl Copyright © 2022 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.
+dnl There is NO WARRANTY, to the extent permitted by law.
+
+dnl DX_PROG_JOIN
+dnl
+dnl Search PATH for standard POSIX "join" utility. If found, the JOIN
+dnl variable (which is substituted by AC_SUBST) is set to the result and
+dnl the cache variable dx_cv_join_works is set to "yes". Otherwise,
+dnl dx_cv_join_works is set to "no" and JOIN is set to an incomplete
+dnl awk-based implementation which supports no options.
+
+AC_DEFUN([DX_PROG_JOIN], [AC_PREREQ([2.62])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_CACHE_CHECK([for join], [ac_cv_path_JOIN],
+[dx_cv_join_found=:
+AC_PATH_PROGS_FEATURE_CHECK([JOIN], [join],
+[_DX_JOIN_DO_TEST([$ac_path_JOIN],
+[DX_BASENAME([join_relcmd], ["$ac_path_JOIN"])
+join_bypath=`{ command -v "$join_relcmd"; } 2>/dev/null` #''
+ac_cv_path_JOIN=$ac_path_JOIN
+test x"$join_bypath" = x"$ac_path_JOIN" && ac_cv_path_JOIN=$join_relcmd
+ac_path_JOIN_found=:
+dx_cv_join_works=yes])], [ac_cv_path_JOIN=no dx_cv_join_found=false])])
+AS_IF([$dx_cv_join_found],
+[JOIN=$ac_cv_path_JOIN
+AC_SUBST([JOIN])dnl
+AC_CACHE_CHECK([whether $JOIN works], [dx_cv_join_works],
+[_DX_JOIN_DO_TEST([$JOIN], [dx_cv_join_works=yes], [dx_cv_join_works=no])])])
+rm -f conftest.a conftest.b conftest.c
+AS_IF([test x"$dx_cv_join_works" != x"yes"],
+[JOIN="$AWK -f m4_do(
+ [m4_pushdef([m4_include], [$][1])],
+ [m4_include(DX_BASEDIR[/scripts/join.awk])],
+ [m4_popdef([m4_include])])"])])
+
+AC_DEFUN([_DX_JOIN_DO_TEST],
+[AS_IF([test ! -f conftest.b],
+[cat >conftest.a <<'EOF'
+1 a
+3 a1 x
+3 a2 x
+5 a
+7 a
+9 a1 x
+9 a2 x
+EOF
+cat >conftest.b <<'EOF'
+2 b
+2 b
+3 b y
+4 b
+6 b
+7 b1 y
+7 b2 y
+8 b
+9 b1 y
+9 b2 y
+EOF])
+AS_IF([$1 conftest.a conftest.b >conftest.c 2>&AS_MESSAGE_LOG_FD],
+[if diff - conftest.c >/dev/null 2>&1 <<'EOF'
+3 a1 x b y
+3 a2 x b y
+7 a b1 y
+7 a b2 y
+9 a1 x b1 y
+9 a1 x b2 y
+9 a2 x b1 y
+9 a2 x b2 y
+EOF
+then :
+$2
+else :
+$3
+fi], [$3])])
-dnl Copyright © 2011, 2021 Nick Bowler
+dnl Copyright © 2011, 2021-2022 Nick Bowler
dnl
dnl Computes the set of .po and .mo files based on the LINGUAS environment
dnl variable. The variable POFILES is set to the complete list of .po files,
AC_DEFUN([DX_LINGUAS],
[AC_REQUIRE([AM_GNU_GETTEXT])dnl
+AC_REQUIRE([DX_PROG_JOIN])dnl
POFILES=
MOFILES=
for (i = 1; i <= NF; i++) {
print $(i)
}
- }' "$srcdir/po/LINGUAS" | sort -u >conftest.all
+ }' "$srcdir/po/LINGUAS" | LC_ALL=C sort -u >conftest.all
: "${LINGUAS=all}"
if test x"$LINGUAS" = x"all"; then
;;
esac
done
- } | sort -u >conftest.ena
+ } | LC_ALL=C sort -u >conftest.ena
fi
exec 3<conftest.all
done
if test x"$USE_NLS" = x"yes"; then
- join conftest.ena conftest.all >conftest.out
+ LC_ALL=C $JOIN conftest.ena conftest.all >conftest.out
exec 3<conftest.out
while read x <&3; do
AS_VAR_APPEND([MOFILES], ["${MOFILES:+ }po/$x.mo"])
--- /dev/null
+#!/bin/awk -f
+#
+# Copyright © 2022 Nick Bowler
+#
+# Partial implementation of POSIX "join" command. No options are supported.
+#
+# 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.
+
+BEGIN {
+ if (ARGC != 3) {
+ exit 1;
+ }
+
+ file2 = ARGV[2];
+ delete ARGV[2];
+
+ advance_rhs();
+}
+
+$1 == lhs_prev {
+ # Rewind RHS as we have duplicate keys in LHS.
+ close(file2);
+ advance_rhs();
+}
+
+$1 < rhs[1] { next }
+{
+ while ($1 > rhs[1]) {
+ if (advance_rhs() == 0)
+ exit(0);
+ }
+}
+
+$1 == rhs[1] {
+ lhs_prev = $1 = $1;
+ do {
+ print_match();
+ advance_rhs();
+ } while ($1 == rhs[1]);
+}
+
+function advance_rhs(raw, rc)
+{
+ rc = getline raw < file2;
+ if (rc < 0)
+ exit(1);
+
+ split(raw, rhs);
+ return rc;
+}
+
+function print_match(i)
+{
+ printf "%s", $0
+ for (i = 2; i in rhs; i++) {
+ printf " %s", rhs[i];
+ }
+ print ""
+}
-dnl Copyright © 2014-2015, 2018-2019, 2021 Nick Bowler
+dnl Copyright © 2014-2015, 2018-2019, 2021-2022 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.
AT_CLEANUP
+AT_SETUP([DX_LINGUAS with broken "join" utility])
+AT_KEYWORDS([DX_LINGUAS macro])
+
+echo : >config.rpath
+chmod +x config.rpath
+
+mkdir bin
+cat >bin/join <<EOF
+#!/bin/sh
+:
+EOF
+chmod +x bin/join
+
+mkdir po
+AT_DATA([po/LINGUAS], [[en ja # a comment ko
+zh en_US
+]])
+
+AT_DATA([test.in], [[POFILES = @POFILES@
+MOFILES = @MOFILES@
+]])
+
+TEST_CONFIGURE_AC(
+[[m4@&t@_traceoff([AM_GNU_GETTEXT])
+AM_GNU_GETTEXT([external])
+DX_LINGUAS
+AC_CONFIG_FILES([test])
+]])
+TEST_AUTORECONF
+
+save_PATH=$PATH
+PATH=`pwd`/bin${PATH:+":$PATH"}
+LINGUAS='en_US'; export LINGUAS; TEST_CONFIGURE
+
+AT_CHECK([cat test], [0],
+[[POFILES = po/en.po po/en_US.po po/ja.po po/zh.po
+MOFILES = po/en.mo po/en_US.mo
+]])
+
+LINGUAS='en_US'; export LINGUAS; TEST_CONFIGURE([JOIN=false])
+
+AT_CHECK([cat test], [0],
+[[POFILES = po/en.po po/en_US.po po/ja.po po/zh.po
+MOFILES = po/en.mo po/en_US.mo
+]])
+
+PATH=$save_PATH
+
+AT_CLEANUP
+
AT_SETUP([DX_BASENAME])
AT_KEYWORDS([DX_BASENAME macro])
])
AT_CLEANUP
+
+AT_SETUP([DX_PROG_JOIN distribution])
+AT_KEYWORDS([DX_PROG_JOIN macro])
+
+TEST_CONFIGURE_AC([[AM_INIT_AUTOMAKE([foreign])
+DX_PROG_JOIN
+AC_CONFIG_FILES([Makefile])
+]])
+
+AT_DATA([Makefile.am],
+[[foo: ; printf '%s\n' $(DX_BASEDIR) $(DISTFILES)
+]])
+TEST_AUTORECONF
+
+TEST_CONFIGURE
+AT_CHECK([make -s foo], [0], [stdout])
+AT_CHECK([exec 3<stdout
+read basedir <&3; while read f <&3; do
+ test x"$f" = x"$basedir/scripts/join.awk" && exit
+done
+exit 1])
+
+AT_CLEANUP
-dnl Copyright © 2020-2021 Nick Bowler
+dnl Copyright © 2020-2022 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.
])
AT_CLEANUP
+
+AT_SETUP([join probes])
+
+AT_DATA([test.in],
+[[JOIN=@JOIN@
+dx_cv_join_works=@dx_cv_join_works@
+]])
+
+TEST_CONFIGURE_AC([[DX_PROG_JOIN
+AC_SUBST([dx_cv_join_works])
+
+set x conftest*; shift
+if test -f $[]1; then
+ AC_MSG_ERROR([$[]1 left behind by [D@@&t@&t@X_PROG_JOIN]])
+fi
+
+AC_CONFIG_FILES([test])
+]])
+TEST_AUTORECONF
+
+TEST_CONFIGURE([JOIN=true AWK="$AWK"])
+AT_CHECK_UNQUOTED([$AWK '{ print $1 }' test], [0],
+[JOIN=$AWK
+dx_cv_join_works=no
+])
+
+save_IFS=$IFS
+IFS='='; read x JOIN <test
+IFS=$save_IFS
+
+AT_DATA([a],
+[[a
+b
+c
+d
+]])
+
+AT_DATA([b],
+[[b
+d
+d
+]])
+
+AT_CHECK([$JOIN a b], [0], [[b
+d
+d
+]])
+
+TEST_CONFIGURE([JOIN="$JOIN"])
+AT_CHECK_UNQUOTED([cat test], [0],
+[JOIN=$JOIN
+dx_cv_join_works=yes
+])
+
+AT_CLEANUP