1#include "test-tool.h"
2#include "git-compat-util.h"
3#include "gettext.h"
4
5struct reg_flag {
6 const char *name;
7 int flag;
8};
9
10static struct reg_flag reg_flags[] = {
11 { "EXTENDED", REG_EXTENDED },
12 { "NEWLINE", REG_NEWLINE },
13 { "ICASE", REG_ICASE },
14 { "NOTBOL", REG_NOTBOL },
15#ifdef REG_STARTEND
16 { "STARTEND", REG_STARTEND },
17#endif
18 { NULL, 0 }
19};
20
21static 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 /* http://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 return 0;
38}
39
40int cmd__regex(int argc, const char **argv)
41{
42 const char *pat;
43 const char *str;
44 int flags = 0;
45 regex_t r;
46 regmatch_t m[1];
47
48 if (argc == 2 && !strcmp(argv[1], "--bug"))
49 return test_regex_bug();
50 else if (argc < 3)
51 usage("test-tool regex --bug\n"
52 "test-tool regex <pattern> <string> [<options>]");
53
54 argv++;
55 pat = *argv++;
56 str = *argv++;
57 while (*argv) {
58 struct reg_flag *rf;
59 for (rf = reg_flags; rf->name; rf++)
60 if (!strcmp(*argv, rf->name)) {
61 flags |= rf->flag;
62 break;
63 }
64 if (!rf->name)
65 die("do not recognize %s", *argv);
66 argv++;
67 }
68 git_setup_gettext();
69
70 if (regcomp(&r, pat, flags))
71 die("failed regcomp() for pattern '%s'", pat);
72 if (regexec(&r, str, 1, m, 0))
73 return 1;
74
75 return 0;
76}