diff --git a/Makefile b/Makefile index 91786ad4b3..7f74610ea7 100644 --- a/Makefile +++ b/Makefile @@ -662,6 +662,7 @@ TEST_PROGRAMS_NEED_X += test-example-decorate TEST_PROGRAMS_NEED_X += test-fake-ssh TEST_PROGRAMS_NEED_X += test-genrandom TEST_PROGRAMS_NEED_X += test-hashmap +TEST_PROGRAMS_NEED_X += test-helper TEST_PROGRAMS_NEED_X += test-index-version TEST_PROGRAMS_NEED_X += test-lazy-init-name-hash TEST_PROGRAMS_NEED_X += test-line-buffer diff --git a/t/helper/test-helper.c b/t/helper/test-helper.c new file mode 100644 index 0000000000..1eaf8df925 --- /dev/null +++ b/t/helper/test-helper.c @@ -0,0 +1,69 @@ +#include "git-compat-util.h" +#include "strbuf.h" +#include "gettext.h" +#include "parse-options.h" + +static const char * const test_helper_usage[] = { + N_("test-helper []"), + NULL +}; + +static int cmp(int argc, const char **argv) +{ + FILE *f0, *f1; + struct strbuf b0 = STRBUF_INIT, b1 = STRBUF_INIT; + + if (argc != 3) + die("Require exactly 2 arguments, got %d", argc); + + if (!(f0 = !strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"))) + return error_errno("could not open '%s'", argv[1]); + if (!(f1 = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"))) { + fclose(f0); + return error_errno("could not open '%s'", argv[2]); + } + + for (;;) { + int r0 = strbuf_getline(&b0, f0); + int r1 = strbuf_getline(&b1, f1); + + if (r0 == EOF) { + fclose(f0); + fclose(f1); + strbuf_release(&b0); + strbuf_release(&b1); + if (r1 == EOF) + return 0; + return 1; + } + if (r1 == EOF || strbuf_cmp(&b0, &b1)) { + fclose(f0); + fclose(f1); + strbuf_release(&b0); + strbuf_release(&b1); + return 1; + } + } +} + +int cmd_main(int argc, const char **argv) +{ + enum mode { + CMP = 1 + } command = 0; + struct option options[] = { + OPT_CMDMODE(0, "cmp", &command, + N_("compare files (ignoring LF vs CR/LF)"), CMP), + OPT_END() + }; + + argc = parse_options(argc, argv, NULL, options, + test_helper_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); + + if (command == CMP) + return !!cmp(argc, argv); + + die("unhandled mode"); +} + diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index ea9a68bbd1..61cfe9b2ae 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -696,7 +696,7 @@ test_expect_code () { # - not all diff versions understand "-u" test_cmp() { - $GIT_TEST_CMP "$@" + GIT_ALLOC_LIMIT=0 $GIT_TEST_CMP "$@" } # test_cmp_bin - helper to compare binary files @@ -889,72 +889,6 @@ test_skip_or_die () { esac } -# The following mingw_* functions obey POSIX shell syntax, but are actually -# bash scripts, and are meant to be used only with bash on Windows. - -# A test_cmp function that treats LF and CRLF equal and avoids to fork -# diff when possible. -mingw_test_cmp () { - # Read text into shell variables and compare them. If the results - # are different, use regular diff to report the difference. - local test_cmp_a= test_cmp_b= - - # When text came from stdin (one argument is '-') we must feed it - # to diff. - local stdin_for_diff= - - # Since it is difficult to detect the difference between an - # empty input file and a failure to read the files, we go straight - # to diff if one of the inputs is empty. - if test -s "$1" && test -s "$2" - then - # regular case: both files non-empty - mingw_read_file_strip_cr_ test_cmp_a <"$1" - mingw_read_file_strip_cr_ test_cmp_b <"$2" - elif test -s "$1" && test "$2" = - - then - # read 2nd file from stdin - mingw_read_file_strip_cr_ test_cmp_a <"$1" - mingw_read_file_strip_cr_ test_cmp_b - stdin_for_diff='<<<"$test_cmp_b"' - elif test "$1" = - && test -s "$2" - then - # read 1st file from stdin - mingw_read_file_strip_cr_ test_cmp_a - mingw_read_file_strip_cr_ test_cmp_b <"$2" - stdin_for_diff='<<<"$test_cmp_a"' - fi - test -n "$test_cmp_a" && - test -n "$test_cmp_b" && - test "$test_cmp_a" = "$test_cmp_b" || - eval "diff -u \"\$@\" $stdin_for_diff" -} - -# $1 is the name of the shell variable to fill in -mingw_read_file_strip_cr_ () { - # Read line-wise using LF as the line separator - # and use IFS to strip CR. - local line - while : - do - if IFS=$'\r' read -r -d $'\n' line - then - # good - line=$line$'\n' - else - # we get here at EOF, but also if the last line - # was not terminated by LF; in the latter case, - # some text was read - if test -z "$line" - then - # EOF, really - break - fi - fi - eval "$1=\$$1\$line" - done -} - # Like "env FOO=BAR some-program", but run inside a subshell, which means # it also works for shell functions (though those functions cannot impact # the environment outside of the test_env invocation). diff --git a/t/test-lib.sh b/t/test-lib.sh index e55ba1d3d0..746ba7bcee 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1035,7 +1035,7 @@ case $uname_s in test_set_prereq NATIVE_CRLF test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR - GIT_TEST_CMP=mingw_test_cmp + GIT_TEST_CMP="test-helper --cmp" ;; *CYGWIN*) test_set_prereq POSIXPERM