1#include "git-compat-util.h"
2#include "gettext.h"
3
4struct reg_flag {
5 const char *name;
6 int flag;
7};
8
9static struct reg_flag reg_flags[] = {
10 { "EXTENDED", REG_EXTENDED },
11 { "NEWLINE", REG_NEWLINE },
12 { "ICASE", REG_ICASE },
13 { "NOTBOL", REG_NOTBOL },
14#ifdef REG_STARTEND
15 { "STARTEND", REG_STARTEND },
16#endif
17 { NULL, 0 }
18};
19
20static int test_regex_bug(void)
21{
22 char *pat = "[^={} \t]+";
23 char *str = "={}\nfred";
24 regex_t r;
25 regmatch_t m[1];
26
27 if (regcomp(&r, pat, REG_EXTENDED | REG_NEWLINE))
28 die("failed regcomp() for pattern '%s'", pat);
29 if (regexec(&r, str, 1, m, 0))
30 die("no match of pattern '%s' to string '%s'", pat, str);
31
32 /* http://sourceware.org/bugzilla/show_bug.cgi?id=3957 */
33 if (m[0].rm_so == 3) /* matches '\n' when it should not */
34 die("regex bug confirmed: re-build git with NO_REGEX=1");
35
36 return 0;
37}
38
39int cmd_main(int argc, const char **argv)
40{
41 const char *pat;
42 const char *str;
43 int flags = 0;
44 regex_t r;
45 regmatch_t m[1];
46
47 if (argc == 2 && !strcmp(argv[1], "--bug"))
48 return test_regex_bug();
49 else if (argc < 3)
50 usage("test-regex --bug\n"
51 "test-regex <pattern> <string> [<options>]");
52
53 argv++;
54 pat = *argv++;
55 str = *argv++;
56 while (*argv) {
57 struct reg_flag *rf;
58 for (rf = reg_flags; rf->name; rf++)
59 if (!strcmp(*argv, rf->name)) {
60 flags |= rf->flag;
61 break;
62 }
63 if (!rf->name)
64 die("do not recognize %s", *argv);
65 argv++;
66 }
67 git_setup_gettext();
68
69 if (regcomp(&r, pat, flags))
70 die("failed regcomp() for pattern '%s'", pat);
71 if (regexec(&r, str, 1, m, 0))
72 return 1;
73
74 return 0;
75}