]> git.proxmox.com Git - libgit2.git/blob - tests/util/regexp.c
New upstream version 1.5.0+ds
[libgit2.git] / tests / util / regexp.c
1 #include "clar_libgit2.h"
2
3 #include <locale.h>
4
5 #include "regexp.h"
6
7 #if LC_ALL > 0
8 static const char *old_locales[LC_ALL];
9 #endif
10
11 static git_regexp regex;
12
13 void test_regexp__initialize(void)
14 {
15 #if LC_ALL > 0
16 memset(&old_locales, 0, sizeof(old_locales));
17 #endif
18 }
19
20 void test_regexp__cleanup(void)
21 {
22 git_regexp_dispose(&regex);
23 }
24
25 static void try_set_locale(int category)
26 {
27 #if LC_ALL > 0
28 old_locales[category] = setlocale(category, NULL);
29 #endif
30
31 if (!setlocale(category, "UTF-8") &&
32 !setlocale(category, "c.utf8") &&
33 !setlocale(category, "en_US.UTF-8"))
34 cl_skip();
35
36 if (MB_CUR_MAX == 1)
37 cl_fail("Expected locale to be switched to multibyte");
38 }
39
40
41 void test_regexp__compile_ignores_global_locale_ctype(void)
42 {
43 try_set_locale(LC_CTYPE);
44 cl_git_pass(git_regexp_compile(&regex, "[\xc0-\xff][\x80-\xbf]", 0));
45 }
46
47 void test_regexp__compile_ignores_global_locale_collate(void)
48 {
49 #ifdef GIT_WIN32
50 cl_skip();
51 #endif
52
53 try_set_locale(LC_COLLATE);
54 cl_git_pass(git_regexp_compile(&regex, "[\xc0-\xff][\x80-\xbf]", 0));
55 }
56
57 void test_regexp__regex_matches_digits_with_locale(void)
58 {
59 char c, str[2];
60
61 #ifdef GIT_WIN32
62 cl_skip();
63 #endif
64
65 try_set_locale(LC_COLLATE);
66 try_set_locale(LC_CTYPE);
67
68 cl_git_pass(git_regexp_compile(&regex, "[[:digit:]]", 0));
69
70 str[1] = '\0';
71 for (c = '0'; c <= '9'; c++) {
72 str[0] = c;
73 cl_git_pass(git_regexp_match(&regex, str));
74 }
75 }
76
77 void test_regexp__regex_matches_alphabet_with_locale(void)
78 {
79 char c, str[2];
80
81 #ifdef GIT_WIN32
82 cl_skip();
83 #endif
84
85 try_set_locale(LC_COLLATE);
86 try_set_locale(LC_CTYPE);
87
88 cl_git_pass(git_regexp_compile(&regex, "[[:alpha:]]", 0));
89
90 str[1] = '\0';
91 for (c = 'a'; c <= 'z'; c++) {
92 str[0] = c;
93 cl_git_pass(git_regexp_match(&regex, str));
94 }
95 for (c = 'A'; c <= 'Z'; c++) {
96 str[0] = c;
97 cl_git_pass(git_regexp_match(&regex, str));
98 }
99 }
100
101 void test_regexp__simple_search_matches(void)
102 {
103 cl_git_pass(git_regexp_compile(&regex, "a", 0));
104 cl_git_pass(git_regexp_search(&regex, "a", 0, NULL));
105 }
106
107 void test_regexp__case_insensitive_search_matches(void)
108 {
109 cl_git_pass(git_regexp_compile(&regex, "a", GIT_REGEXP_ICASE));
110 cl_git_pass(git_regexp_search(&regex, "A", 0, NULL));
111 }
112
113 void test_regexp__nonmatching_search_returns_error(void)
114 {
115 cl_git_pass(git_regexp_compile(&regex, "a", 0));
116 cl_git_fail(git_regexp_search(&regex, "b", 0, NULL));
117 }
118
119 void test_regexp__search_finds_complete_match(void)
120 {
121 git_regmatch matches[1];
122
123 cl_git_pass(git_regexp_compile(&regex, "abc", 0));
124 cl_git_pass(git_regexp_search(&regex, "abc", 1, matches));
125 cl_assert_equal_i(matches[0].start, 0);
126 cl_assert_equal_i(matches[0].end, 3);
127 }
128
129 void test_regexp__search_finds_correct_offsets(void)
130 {
131 git_regmatch matches[3];
132
133 cl_git_pass(git_regexp_compile(&regex, "(a*)(b*)", 0));
134 cl_git_pass(git_regexp_search(&regex, "ab", 3, matches));
135 cl_assert_equal_i(matches[0].start, 0);
136 cl_assert_equal_i(matches[0].end, 2);
137 cl_assert_equal_i(matches[1].start, 0);
138 cl_assert_equal_i(matches[1].end, 1);
139 cl_assert_equal_i(matches[2].start, 1);
140 cl_assert_equal_i(matches[2].end, 2);
141 }
142
143 void test_regexp__search_finds_empty_group(void)
144 {
145 git_regmatch matches[3];
146
147 cl_git_pass(git_regexp_compile(&regex, "(a*)(b*)c", 0));
148 cl_git_pass(git_regexp_search(&regex, "ac", 3, matches));
149 cl_assert_equal_i(matches[0].start, 0);
150 cl_assert_equal_i(matches[0].end, 2);
151 cl_assert_equal_i(matches[1].start, 0);
152 cl_assert_equal_i(matches[1].end, 1);
153 cl_assert_equal_i(matches[2].start, 1);
154 cl_assert_equal_i(matches[2].end, 1);
155 }
156
157 void test_regexp__search_fills_matches_with_first_matching_groups(void)
158 {
159 git_regmatch matches[2];
160
161 cl_git_pass(git_regexp_compile(&regex, "(a)(b)(c)", 0));
162 cl_git_pass(git_regexp_search(&regex, "abc", 2, matches));
163 cl_assert_equal_i(matches[0].start, 0);
164 cl_assert_equal_i(matches[0].end, 3);
165 cl_assert_equal_i(matches[1].start, 0);
166 cl_assert_equal_i(matches[1].end, 1);
167 }
168
169 void test_regexp__search_skips_nonmatching_group(void)
170 {
171 git_regmatch matches[4];
172
173 cl_git_pass(git_regexp_compile(&regex, "(a)(b)?(c)", 0));
174 cl_git_pass(git_regexp_search(&regex, "ac", 4, matches));
175 cl_assert_equal_i(matches[0].start, 0);
176 cl_assert_equal_i(matches[0].end, 2);
177 cl_assert_equal_i(matches[1].start, 0);
178 cl_assert_equal_i(matches[1].end, 1);
179 cl_assert_equal_i(matches[2].start, -1);
180 cl_assert_equal_i(matches[2].end, -1);
181 cl_assert_equal_i(matches[3].start, 1);
182 cl_assert_equal_i(matches[3].end, 2);
183 }
184
185 void test_regexp__search_initializes_trailing_nonmatching_groups(void)
186 {
187 git_regmatch matches[3];
188
189 cl_git_pass(git_regexp_compile(&regex, "(a)bc", 0));
190 cl_git_pass(git_regexp_search(&regex, "abc", 3, matches));
191 cl_assert_equal_i(matches[0].start, 0);
192 cl_assert_equal_i(matches[0].end, 3);
193 cl_assert_equal_i(matches[1].start, 0);
194 cl_assert_equal_i(matches[1].end, 1);
195 cl_assert_equal_i(matches[2].start, -1);
196 cl_assert_equal_i(matches[2].end, -1);
197 }