diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c index 10284cc56f..d6f28ca8d1 100644 --- a/t/helper/test-regex.c +++ b/t/helper/test-regex.c @@ -1,5 +1,4 @@ #include "test-tool.h" -#include "git-compat-util.h" #include "gettext.h" struct reg_flag { @@ -8,12 +7,13 @@ struct reg_flag { }; static struct reg_flag reg_flags[] = { - { "EXTENDED", REG_EXTENDED }, - { "NEWLINE", REG_NEWLINE }, - { "ICASE", REG_ICASE }, - { "NOTBOL", REG_NOTBOL }, + { "EXTENDED", REG_EXTENDED }, + { "NEWLINE", REG_NEWLINE }, + { "ICASE", REG_ICASE }, + { "NOTBOL", REG_NOTBOL }, + { "NOTEOL", REG_NOTEOL }, #ifdef REG_STARTEND - { "STARTEND", REG_STARTEND }, + { "STARTEND", REG_STARTEND }, #endif { NULL, 0 } }; @@ -41,36 +41,74 @@ int cmd__regex(int argc, const char **argv) { const char *pat; const char *str; - int flags = 0; + int ret, silent = 0, flags = 0; regex_t r; regmatch_t m[1]; - - if (argc == 2 && !strcmp(argv[1], "--bug")) - return test_regex_bug(); - else if (argc < 3) - usage("test-tool regex --bug\n" - "test-tool regex []"); + char errbuf[64]; argv++; - pat = *argv++; - str = *argv++; - while (*argv) { - struct reg_flag *rf; - for (rf = reg_flags; rf->name; rf++) - if (!strcmp(*argv, rf->name)) { - flags |= rf->flag; - break; - } - if (!rf->name) - die("do not recognize %s", *argv); + argc--; + + if (!argc) + goto usage; + + if (!strcmp(*argv, "--bug")) { + if (argc == 1) + return test_regex_bug(); + else + goto usage; + } + if (!strcmp(*argv, "--silent")) { + silent = 1; argv++; + argc--; + } + if (!argc) + goto usage; + + pat = *argv++; + if (argc == 1) + str = NULL; + else { + str = *argv++; + while (*argv) { + struct reg_flag *rf; + for (rf = reg_flags; rf->name; rf++) + if (!strcmp(*argv, rf->name)) { + flags |= rf->flag; + break; + } + if (!rf->name) + die("do not recognize flag %s", *argv); + argv++; + } } git_setup_gettext(); - if (regcomp(&r, pat, flags)) - die("failed regcomp() for pattern '%s'", pat); - if (regexec(&r, str, 1, m, 0)) - return 1; + ret = regcomp(&r, pat, flags); + if (ret) { + if (silent) + return ret; + + regerror(ret, &r, errbuf, sizeof(errbuf)); + die("failed regcomp() for pattern '%s' (%s)", pat, errbuf); + } + if (!str) + return 0; + + ret = regexec(&r, str, 1, m, 0); + if (ret) { + if (silent || ret == REG_NOMATCH) + return ret; + + regerror(ret, &r, errbuf, sizeof(errbuf)); + die("failed regexec() for subject '%s' (%s)", str, errbuf); + } return 0; +usage: + usage("\ttest-tool regex --bug\n" + "\ttest-tool regex [--silent] \n" + "\ttest-tool regex [--silent] []"); + return -1; } diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index c3792081e6..d2dfcf164e 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -10,6 +10,13 @@ latin1_e=$(printf '\351') # invalid UTF-8 invalid_e=$(printf '\303\50)') # ")" at end to close opening "(" +have_reg_illseq= +if test_have_prereq GETTEXT_LOCALE && + ! LC_ALL=$is_IS_locale test-tool regex --silent $latin1_e +then + have_reg_illseq=1 +fi + test_expect_success 'create commits in different encodings' ' test_tick && cat >msg <<-EOF && @@ -51,43 +58,77 @@ test_expect_success !MINGW 'log --grep does not find non-reencoded values (utf8) test_must_be_empty actual ' -test_expect_success !MINGW 'log --grep does not find non-reencoded values (latin1)' ' +test_expect_success 'log --grep does not find non-reencoded values (latin1)' ' git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual && test_must_be_empty actual ' +triggers_undefined_behaviour () { + local engine=$1 + + case $engine in + fixed) + if test -n "$have_reg_illseq" && + ! test_have_prereq LIBPCRE2 + then + return 0 + fi + ;; + basic|extended) + if test -n "$have_reg_illseq" + then + return 0 + fi + ;; + esac + return 1 +} + +mismatched_git_log () { + local pattern=$1 + + LC_ALL=$is_IS_locale git log --encoding=ISO-8859-1 --format=%s \ + --grep=$pattern +} + for engine in fixed basic extended perl do prereq= if test $engine = "perl" then - prereq="PCRE" - else - prereq="" + prereq=PCRE fi force_regex= if test $engine != "fixed" then - force_regex=.* + force_regex='.*' fi - test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " - cat >expect <<-\EOF && - latin1 - utf8 - EOF - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$latin1_e\" >actual && - test_cmp expect actual + + test_expect_success $prereq "config grep.patternType=$engine" " + git config grep.patternType $engine " - test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$utf8_e\" >actual && + test_expect_success GETTEXT_LOCALE,$prereq "log --grep does not find non-reencoded values (latin1 + locale)" " + mismatched_git_log '$force_regex$utf8_e' >actual && test_must_be_empty actual " - test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual && - test_must_be_empty actual - " + if ! triggers_undefined_behaviour $engine + then + test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "log --grep searches in log output encoding (latin1 + locale)" " + cat >expect <<-\EOF && + latin1 + utf8 + EOF + mismatched_git_log '$force_regex$latin1_e' >actual && + test_cmp expect actual + " + + test_expect_success GETTEXT_LOCALE,$prereq "log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " + mismatched_git_log '$force_regex$invalid_e' >actual && + test_must_be_empty actual + " + fi done test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index 88bb797141..dbc027ff26 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1489,12 +1489,6 @@ case $uname_s in test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR ;; -FreeBSD) - test_set_prereq REGEX_ILLSEQ - test_set_prereq POSIXPERM - test_set_prereq BSLASHPSPEC - test_set_prereq EXECKEEPSPID - ;; *) test_set_prereq POSIXPERM test_set_prereq BSLASHPSPEC