summaryrefslogtreecommitdiffstats
path: root/t/helper/test-regex.c
diff options
context:
space:
mode:
Diffstat (limited to 't/helper/test-regex.c')
-rw-r--r--t/helper/test-regex.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c
new file mode 100644
index 0000000..bd871a7
--- /dev/null
+++ b/t/helper/test-regex.c
@@ -0,0 +1,117 @@
+#include "test-tool.h"
+#include "gettext.h"
+
+struct reg_flag {
+ const char *name;
+ int flag;
+};
+
+static struct reg_flag reg_flags[] = {
+ { "EXTENDED", REG_EXTENDED },
+ { "NEWLINE", REG_NEWLINE },
+ { "ICASE", REG_ICASE },
+ { "NOTBOL", REG_NOTBOL },
+ { "NOTEOL", REG_NOTEOL },
+#ifdef REG_STARTEND
+ { "STARTEND", REG_STARTEND },
+#endif
+ { NULL, 0 }
+};
+
+static int test_regex_bug(void)
+{
+ char *pat = "[^={} \t]+";
+ char *str = "={}\nfred";
+ regex_t r;
+ regmatch_t m[1];
+
+ if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
+ die("failed regcomp() for pattern '%s'", pat);
+ if (regexec(&r, str, 1, m, 0))
+ die("no match of pattern '%s' to string '%s'", pat, str);
+
+ /* http://sourceware.org/bugzilla/show_bug.cgi?id=3957 */
+ if (m[0].rm_so == 3) /* matches '\n' when it should not */
+ die("regex bug confirmed: re-build git with NO_REGEX=1");
+
+ regfree(&r);
+ return 0;
+}
+
+int cmd__regex(int argc, const char **argv)
+{
+ const char *pat;
+ const char *str;
+ int ret, silent = 0, flags = 0;
+ regex_t r;
+ regmatch_t m[1];
+ char errbuf[64];
+
+ 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();
+
+ 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)
+ goto cleanup;
+
+ ret = regexec(&r, str, 1, m, 0);
+ if (ret) {
+ if (silent || ret == REG_NOMATCH)
+ goto cleanup;
+
+ regerror(ret, &r, errbuf, sizeof(errbuf));
+ die("failed regexec() for subject '%s' (%s)", str, errbuf);
+ }
+
+cleanup:
+ regfree(&r);
+ return ret;
+usage:
+ usage("\ttest-tool regex --bug\n"
+ "\ttest-tool regex [--silent] <pattern>\n"
+ "\ttest-tool regex [--silent] <pattern> <string> [<options>]");
+ return -1;
+}