]> git.ipfire.org Git - thirdparty/git.git/blob - t/helper/test-regex.c
The fifth batch
[thirdparty/git.git] / t / helper / test-regex.c
1 #include "test-tool.h"
2 #include "gettext.h"
3
4 struct reg_flag {
5 const char *name;
6 int flag;
7 };
8
9 static struct reg_flag reg_flags[] = {
10 { "EXTENDED", REG_EXTENDED },
11 { "NEWLINE", REG_NEWLINE },
12 { "ICASE", REG_ICASE },
13 { "NOTBOL", REG_NOTBOL },
14 { "NOTEOL", REG_NOTEOL },
15 #ifdef REG_STARTEND
16 { "STARTEND", REG_STARTEND },
17 #endif
18 { NULL, 0 }
19 };
20
21 static int test_regex_bug(void)
22 {
23 char *pat = "[^={} \t]+";
24 char *str = "={}\nfred";
25 regex_t r;
26 regmatch_t m[1];
27
28 if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
29 die("failed regcomp() for pattern '%s'", pat);
30 if (regexec(&r, str, 1, m, 0))
31 die("no match of pattern '%s' to string '%s'", pat, str);
32
33 /* https://sourceware.org/bugzilla/show_bug.cgi?id=3957 */
34 if (m[0].rm_so == 3) /* matches '\n' when it should not */
35 die("regex bug confirmed: re-build git with NO_REGEX=1");
36
37 regfree(&r);
38 return 0;
39 }
40
41 int cmd__regex(int argc, const char **argv)
42 {
43 const char *pat;
44 const char *str;
45 int ret, silent = 0, flags = 0;
46 regex_t r;
47 regmatch_t m[1];
48 char errbuf[64];
49
50 argv++;
51 argc--;
52
53 if (!argc)
54 goto usage;
55
56 if (!strcmp(*argv, "--bug")) {
57 if (argc == 1)
58 return test_regex_bug();
59 else
60 goto usage;
61 }
62 if (!strcmp(*argv, "--silent")) {
63 silent = 1;
64 argv++;
65 argc--;
66 }
67 if (!argc)
68 goto usage;
69
70 pat = *argv++;
71 if (argc == 1)
72 str = NULL;
73 else {
74 str = *argv++;
75 while (*argv) {
76 struct reg_flag *rf;
77 for (rf = reg_flags; rf->name; rf++)
78 if (!strcmp(*argv, rf->name)) {
79 flags |= rf->flag;
80 break;
81 }
82 if (!rf->name)
83 die("do not recognize flag %s", *argv);
84 argv++;
85 }
86 }
87 git_setup_gettext();
88
89 ret = regcomp(&r, pat, flags);
90 if (ret) {
91 if (silent)
92 return ret;
93
94 regerror(ret, &r, errbuf, sizeof(errbuf));
95 die("failed regcomp() for pattern '%s' (%s)", pat, errbuf);
96 }
97 if (!str)
98 goto cleanup;
99
100 ret = regexec(&r, str, 1, m, 0);
101 if (ret) {
102 if (silent || ret == REG_NOMATCH)
103 goto cleanup;
104
105 regerror(ret, &r, errbuf, sizeof(errbuf));
106 die("failed regexec() for subject '%s' (%s)", str, errbuf);
107 }
108
109 cleanup:
110 regfree(&r);
111 return ret;
112 usage:
113 usage("\ttest-tool regex --bug\n"
114 "\ttest-tool regex [--silent] <pattern>\n"
115 "\ttest-tool regex [--silent] <pattern> <string> [<options>]");
116 return -1;
117 }