regexp.c 4.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#include "clar_libgit2.h"

#include <locale.h>

#include "regexp.h"

#if LC_ALL > 0
static const char *old_locales[LC_ALL];
#endif

static git_regexp regex;

13
void test_regexp__initialize(void)
14 15 16 17 18 19
{
#if LC_ALL > 0
	memset(&old_locales, 0, sizeof(old_locales));
#endif
}

20
void test_regexp__cleanup(void)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
{
	git_regexp_dispose(&regex);
}

static void try_set_locale(int category)
{
#if LC_ALL > 0
	old_locales[category] = setlocale(category, NULL);
#endif

	if (!setlocale(category, "UTF-8") &&
	    !setlocale(category, "c.utf8") &&
	    !setlocale(category, "en_US.UTF-8"))
		cl_skip();

	if (MB_CUR_MAX == 1)
		cl_fail("Expected locale to be switched to multibyte");
}


41
void test_regexp__compile_ignores_global_locale_ctype(void)
42 43 44 45 46
{
	try_set_locale(LC_CTYPE);
	cl_git_pass(git_regexp_compile(&regex, "[\xc0-\xff][\x80-\xbf]", 0));
}

47
void test_regexp__compile_ignores_global_locale_collate(void)
48 49 50 51 52 53 54 55 56
{
#ifdef GIT_WIN32
	cl_skip();
#endif

	try_set_locale(LC_COLLATE);
	cl_git_pass(git_regexp_compile(&regex, "[\xc0-\xff][\x80-\xbf]", 0));
}

57
void test_regexp__regex_matches_digits_with_locale(void)
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
{
	char c, str[2];

#ifdef GIT_WIN32
	cl_skip();
#endif

	try_set_locale(LC_COLLATE);
	try_set_locale(LC_CTYPE);

	cl_git_pass(git_regexp_compile(&regex, "[[:digit:]]", 0));

	str[1] = '\0';
	for (c = '0'; c <= '9'; c++) {
	    str[0] = c;
	    cl_git_pass(git_regexp_match(&regex, str));
	}
}

77
void test_regexp__regex_matches_alphabet_with_locale(void)
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
{
	char c, str[2];

#ifdef GIT_WIN32
	cl_skip();
#endif

	try_set_locale(LC_COLLATE);
	try_set_locale(LC_CTYPE);

	cl_git_pass(git_regexp_compile(&regex, "[[:alpha:]]", 0));

	str[1] = '\0';
	for (c = 'a'; c <= 'z'; c++) {
	    str[0] = c;
	    cl_git_pass(git_regexp_match(&regex, str));
	}
	for (c = 'A'; c <= 'Z'; c++) {
	    str[0] = c;
	    cl_git_pass(git_regexp_match(&regex, str));
	}
}

101
void test_regexp__simple_search_matches(void)
102 103 104 105 106
{
	cl_git_pass(git_regexp_compile(&regex, "a", 0));
	cl_git_pass(git_regexp_search(&regex, "a", 0, NULL));
}

107
void test_regexp__case_insensitive_search_matches(void)
108 109 110 111 112
{
	cl_git_pass(git_regexp_compile(&regex, "a", GIT_REGEXP_ICASE));
	cl_git_pass(git_regexp_search(&regex, "A", 0, NULL));
}

113
void test_regexp__nonmatching_search_returns_error(void)
114 115 116 117 118
{
	cl_git_pass(git_regexp_compile(&regex, "a", 0));
	cl_git_fail(git_regexp_search(&regex, "b", 0, NULL));
}

119
void test_regexp__search_finds_complete_match(void)
120 121 122 123 124 125 126 127 128
{
	git_regmatch matches[1];

	cl_git_pass(git_regexp_compile(&regex, "abc", 0));
	cl_git_pass(git_regexp_search(&regex, "abc", 1, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 3);
}

129
void test_regexp__search_finds_correct_offsets(void)
130 131 132 133 134 135 136 137 138 139 140 141 142
{
	git_regmatch matches[3];

	cl_git_pass(git_regexp_compile(&regex, "(a*)(b*)", 0));
	cl_git_pass(git_regexp_search(&regex, "ab", 3, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 2);
	cl_assert_equal_i(matches[1].start, 0);
	cl_assert_equal_i(matches[1].end, 1);
	cl_assert_equal_i(matches[2].start, 1);
	cl_assert_equal_i(matches[2].end, 2);
}

143
void test_regexp__search_finds_empty_group(void)
144 145 146 147 148 149 150 151 152 153 154 155 156
{
	git_regmatch matches[3];

	cl_git_pass(git_regexp_compile(&regex, "(a*)(b*)c", 0));
	cl_git_pass(git_regexp_search(&regex, "ac", 3, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 2);
	cl_assert_equal_i(matches[1].start, 0);
	cl_assert_equal_i(matches[1].end, 1);
	cl_assert_equal_i(matches[2].start, 1);
	cl_assert_equal_i(matches[2].end, 1);
}

157
void test_regexp__search_fills_matches_with_first_matching_groups(void)
158 159 160 161 162 163 164 165 166 167 168
{
	git_regmatch matches[2];

	cl_git_pass(git_regexp_compile(&regex, "(a)(b)(c)", 0));
	cl_git_pass(git_regexp_search(&regex, "abc", 2, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 3);
	cl_assert_equal_i(matches[1].start, 0);
	cl_assert_equal_i(matches[1].end, 1);
}

169
void test_regexp__search_skips_nonmatching_group(void)
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
{
	git_regmatch matches[4];

	cl_git_pass(git_regexp_compile(&regex, "(a)(b)?(c)", 0));
	cl_git_pass(git_regexp_search(&regex, "ac", 4, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 2);
	cl_assert_equal_i(matches[1].start, 0);
	cl_assert_equal_i(matches[1].end, 1);
	cl_assert_equal_i(matches[2].start, -1);
	cl_assert_equal_i(matches[2].end, -1);
	cl_assert_equal_i(matches[3].start, 1);
	cl_assert_equal_i(matches[3].end, 2);
}

185
void test_regexp__search_initializes_trailing_nonmatching_groups(void)
186 187 188 189 190 191 192 193 194 195 196 197
{
	git_regmatch matches[3];

	cl_git_pass(git_regexp_compile(&regex, "(a)bc", 0));
	cl_git_pass(git_regexp_search(&regex, "abc", 3, matches));
	cl_assert_equal_i(matches[0].start, 0);
	cl_assert_equal_i(matches[0].end, 3);
	cl_assert_equal_i(matches[1].start, 0);
	cl_assert_equal_i(matches[1].end, 1);
	cl_assert_equal_i(matches[2].start, -1);
	cl_assert_equal_i(matches[2].end, -1);
}