]>
Commit | Line | Data |
---|---|---|
9038531f | 1 | #include "test-tool.h" |
d8acfe1e NTND |
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[] = { | |
aba8187e CMAB |
10 | { "EXTENDED", REG_EXTENDED }, |
11 | { "NEWLINE", REG_NEWLINE }, | |
12 | { "ICASE", REG_ICASE }, | |
13 | { "NOTBOL", REG_NOTBOL }, | |
14 | { "NOTEOL", REG_NOTEOL }, | |
d8acfe1e | 15 | #ifdef REG_STARTEND |
aba8187e | 16 | { "STARTEND", REG_STARTEND }, |
d8acfe1e NTND |
17 | #endif |
18 | { NULL, 0 } | |
19 | }; | |
c9184159 | 20 | |
949782d8 | 21 | static int test_regex_bug(void) |
c9184159 RJ |
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 | ||
a20b0dc7 | 37 | regfree(&r); |
949782d8 NTND |
38 | return 0; |
39 | } | |
40 | ||
9038531f | 41 | int cmd__regex(int argc, const char **argv) |
949782d8 | 42 | { |
d8acfe1e NTND |
43 | const char *pat; |
44 | const char *str; | |
aba8187e | 45 | int ret, silent = 0, flags = 0; |
d8acfe1e NTND |
46 | regex_t r; |
47 | regmatch_t m[1]; | |
aba8187e | 48 | char errbuf[64]; |
d8acfe1e NTND |
49 | |
50 | argv++; | |
aba8187e CMAB |
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; | |
d8acfe1e | 64 | argv++; |
aba8187e CMAB |
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 | } | |
d8acfe1e NTND |
86 | } |
87 | git_setup_gettext(); | |
88 | ||
aba8187e CMAB |
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) | |
a20b0dc7 | 98 | goto cleanup; |
aba8187e CMAB |
99 | |
100 | ret = regexec(&r, str, 1, m, 0); | |
101 | if (ret) { | |
102 | if (silent || ret == REG_NOMATCH) | |
a20b0dc7 | 103 | goto cleanup; |
aba8187e CMAB |
104 | |
105 | regerror(ret, &r, errbuf, sizeof(errbuf)); | |
106 | die("failed regexec() for subject '%s' (%s)", str, errbuf); | |
107 | } | |
d8acfe1e | 108 | |
a20b0dc7 ÆAB |
109 | cleanup: |
110 | regfree(&r); | |
111 | return ret; | |
aba8187e CMAB |
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; | |
c9184159 | 117 | } |