Merge branch 'sg/completion-worktree'
[git] / t / helper / test-regex.c
1 #include "test-tool.h"
2 #include "git-compat-util.h"
3 #include "gettext.h"
4
5 struct reg_flag {
6         const char *name;
7         int flag;
8 };
9
10 static 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
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         /* 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
40 int 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 }