#define R4_DEBUG_a
#include "rrex4.h"
#include "rlib.h"
#include <regex.h>
bool bench_r4(unsigned int times, char *str, char *expr) {
RBENCH(times, {
r4_t *r = r4(str, expr);
if (r->valid == false) {
printf("Bench r4 error\n");
exit(1);
}
r4_free(r);
});
return true;
}
void bench_c(unsigned int times, char *str, char *expr) {
regex_t regex;
if (regcomp(&regex, expr, REG_EXTENDED)) {
printf("Creg: error in regular expression.\n");
exit(1);
}
RBENCH(times, {
if (regexec(&regex, str, 0, NULL, 0)) {
printf("Creg: error executing regular expression.\n");
exit(1);
}
});
regfree(&regex);
}
bool bench(unsigned int times, char *str, char *expr) {
printf("%d:(%s)<%s>\n", times, str, expr);
printf("c:");
bench_c(times, str, expr);
printf("r:");
bench_r4(times, str, expr);
return true;
}
void test_r4_next() {
r4_t *r = r4_new();
char *str = "abcdefghijklmnop";
char *reg = "(\\w\\w\\w\\w)";
r = r4(str, reg);
assert(r->valid);
assert(r->match_count == 1);
assert(!strcmp(r->matches[0], "abcd"));
// Again with same regex as parameter
r = r4_next(r, reg);
assert(r->valid);
assert(r->match_count == 1);
assert(!strcmp(r->matches[0], "efgh"));
// Again with same regex as parameter
r = r4_next(r, reg);
assert(r->valid);
assert(r->match_count == 1);
assert(!strcmp(r->matches[0], "ijkl"));
// Reuse expression, NULL parameter
r = r4_next(r, NULL);
assert(r->valid);
assert(r->match_count == 1);
assert(!strcmp(r->matches[0], "mnop"));
// No results using r4_next
r = r4_next(r, NULL);
assert(r->valid);
assert(r->match_count == 0);
// Again no results using r4_next, Shouldn't crash
r = r4_next(r, NULL);
assert(r->valid);
assert(r->match_count == 0);
r4_free(r);
}
void bench_all(unsigned int times) {
assert(bench(times, "suvw",
"[abcdefghijklmnopqrstuvw][abcdefghijklmnopqrstuvw]["
"abcdefghijklmnopqrstuvw][abcdefghijklmnopqrstuvw]"));
assert(bench(times, "ponyyy", "^p+o.*yyy$$$$"));
assert(bench(times, " ponyyzd", "p+o.*yyzd$$$$"));
assert(bench(times, "abc", "def|gek|abc"));
assert(bench(times, "abc", "def|a?b?c|def"));
assert(bench(times, "NL18RABO0322309700",
"([A-Z]{2})([0-9]{2})([A-Z]{4}[0-9])([0-9]+)$"));
assert(bench(times, "a 1 b 2 c 3 d 4 ", "([A-Z0-9 ]+)"));
}
bool r4_match_stats(char *str, char *expr) {
r4_t *r = r4(str, expr);
bool result = r->valid;
printf("%d:(%s)<%s>\n", r->validation_count, r->_str, r->_expr);
if (result) {
printf(" - match(0)\t: \"%s\"\n", r->match);
}
for (unsigned i = 0; i < r->match_count; i++) {
printf(" - match(%d)\t: \"%s\"\n", i + 1, r->matches[i]);
}
r4_free(r);
return result;
}
void test_r4_bug_check_capture_overflow() {
// This is a former bug in r4.
// Case one
r4_t *r = r4("test", "(test)+");
assert(r->match_count == 1);
r4_free(r);
// Case two
r = r4("tester", "(t\\est\\e\\r)+");
assert(r->match_count == 1);
printf("%s\n", r->matches[0]);
r4_free(r);
// Case three
r = r4("test", "(t\\est\\e\\r)+");
assert(r->match_count == 0);
r4_free(r);
}
void test_r4_capture_main_group() {
// Case 1
r4_t *r = r4("testtesttesttest", "(test)+test$");
// printf("%s\n",r->match);
// assert(!strcmp(r->match,"testtesttesttest"));
assert(r->match_count == 3);
assert(!strcmp(r->matches[0], "test"));
assert(!strcmp(r->matches[1], "test"));
assert(!strcmp(r->matches[2], "test"));
r4_free(r);
// Case 2 (with search)
/*
r = r4(" testtesttesttest","(test)+test$");
printf("%s\n",r->match);
assert(!strcmp(r->match,"testtesttesttest"));
assert(r->match_count == 3);
assert(!strcmp(r->matches[0], "test"));
assert(!strcmp(r->matches[1], "test"));
assert(!strcmp(r->matches[2], "test"));
r4_free(r); */
}
char test_r4_capture_dynamic_amount() {
r4_t *r = r4("testtesttesttest", "(test)+test$");
assert(r->match_count == 3);
assert(!strcmp(r->matches[0], "test"));
assert(!strcmp(r->matches[1], "test"));
assert(!strcmp(r->matches[2], "test"));
r4_free(r);
return true;
// Some advanced capturing
// Fails
r = r4("testtesttesttest", "([tes]+)+test$");
printf("%d\n", r->match_count);
assert(r->match_count == 1);
assert(!strcmp(r->matches[0], "testtesttest"));
r4_free(r);
}
int main(int argc, char *argv[]) {
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], "--debug")) {
r4_enable_debug();
}
}
// Has to be fixed
r4_match_stats("r4@r4.net",
"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]*$");
// r4_match_stats("r4@r4.net", "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$");
// exit(0);
test_r4_capture_main_group();
assert(r4_match_stats("testtesttesttest", "(test)+test$"));
assert(r4_match_stats("testtest", "test"));
// Group testing
assert(r4_match_stats("aaadddd", "(a+)(d+)$"));
assert(r4_match_stats("aaa", "(a+)$"));
assert(r4_match_stats("aaadddd", "(d+)$"));
assert(r4_match_stats("aaadddd", "(d+)"));
assert(r4_match_stats("aaa\"dddd\"", "\"(d+)\""));
assert(r4_match_stats("aaadddd", "(a*)(d+)$"));
assert(r4_match_stats("aaa", "(a*)$"));
assert(r4_match_stats("aaadddd", "(d*)$"));
assert(r4_match_stats("aaadddd", "(d*)"));
assert(r4_match_stats("aaa\"dddd\" ", "\"(d*)\"\\s*"));
// Words
assert(r4_match_stats("a", "\\w"));
assert(!r4_match_stats("1", "\\w"));
assert(r4_match_stats("1", "\\W"));
assert(!r4_match_stats("a", "\\W"));
assert(r4_match_stats("aa", "\\w{2}"));
assert(r4_match_stats("11", "\\W{2}"));
assert(r4_match_stats("1", "[\\W]"));
// Digits
assert(r4_match_stats("1", "\\d"));
assert(!r4_match_stats("a", "\\d"));
assert(r4_match_stats("a", "\\D"));
assert(!r4_match_stats("1", "\\D"));
assert(r4_match_stats("11", "\\d{2}$"));
assert(r4_match_stats("aa", "\\D{2}$"));
assert(r4_match_stats("a", "[\\D]"));
// Whitespace
assert(r4_match_stats(" ", "\\s"));
assert(r4_match_stats(" a", "\\s"));
assert(!r4_match_stats("a", "[\\s]"));
assert(r4_match_stats("a ", "[\\s]"));
assert(r4_match_stats("a", "\\S"));
assert(!r4_match_stats(" ", "\\S"));
assert(!r4_match_stats(" ", "[\\S]"));
assert(r4_match_stats("b ", "[\\S]"));
assert(r4_match_stats(" b", "[\\S]"));
// Boundaries
assert(r4_match_stats("a", "\\b"));
assert(r4_match_stats("a", "\\ba$"));
assert(r4_match_stats("a", "^\\ba$"));
assert(r4_match_stats("aa", "\\b"));
assert(!r4_match_stats("aa", "\\b$"));
assert(r4_match_stats("aa", "[\\b]"));
assert(r4_match_stats("a", "\\B"));
assert(r4_match_stats("a", "\\Ba$"));
assert(r4_match_stats("a", "^\\Ba$"));
assert(r4_match_stats("aa", "\\B"));
assert(!r4_match_stats("aa", "^\\B"));
assert(!r4_match_stats("a1", "a[\\B]$"));
// Optional
assert(!r4_match_stats("a", "?"));
assert(r4_match_stats("a", "a?"));
assert(r4_match_stats("a", "b?"));
assert(r4_match_stats("a", "^b?"));
assert(r4_match_stats("a", "a?$"));
assert(!r4_match_stats("a", "b?$"));
assert(r4_match_stats("a", "[def]?a$"));
// Range
assert(r4_match_stats("a", "a{1}"));
assert(r4_match_stats("ab", "a{1}"));
assert(r4_match_stats("aa", "a{2}"));
assert(!r4_match_stats("aab", "a{3}"));
assert(!r4_match_stats("a1", "a{2}"));
assert(r4_match_stats("ab", "a{1,2}"));
assert(r4_match_stats("aa", "a{2,}"));
// Group (Custom function set)
r4_match_stats("*?+$^.|\\[{()}]@ ", "[*?+$^.|\\\\[{()}]]+$@\\s");
// Miscellaneous tests
bool debug_mode_original = _r4_debug;
_r4_debug = false;
r4_enable_debug();
assert(_r4_debug);
r4_disable_debug();
assert(!_r4_debug);
_r4_debug = debug_mode_original;
assert(r4_match("a", "a"));
assert(!r4_match("b", "a"));
r4_init(NULL);
r4_free(NULL);
r4_free_matches(NULL);
// Next tests
test_r4_next();
// Check if former known bugs are still fixed
test_r4_bug_check_capture_overflow();
// Check if capture amount is dynamic
test_r4_capture_dynamic_amount();
char *c_function_regex =
"(\\w[\\w\\d]*[\\s\\*]*)\\s*\\w[\\w\\d]*\\s*\\((.*)\\)\\s*\\{";
r4_match_stats("int **main() {}", c_function_regex);
r4_match_stats("int main(int argc, char *argv[],(void *)aaa) {}",
c_function_regex);
assert(r4_match_stats("NL18RABO0322309700",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d{10})"));
// exit(0);
unsigned int times = 1;
bench_all(times);
RBENCH(1, {
assert(r4_match_stats("#define DEFINETEST 1",
"#define\\s(+[\\w\\d_]+)\\s+[\\w\\d_]+"));
// assert(r4_match_stats("#define DEFINETEST 1\n",
// s "#define\\s+\\w[\\d\\w_]+\\s+[\\w\\d_]\\s*"));
assert(!r4_match_stats("aa", "aaaa"));
assert(r4_match_stats("ponyyy", "^p+o.*yyy$$$$"));
assert(!r4_match_stats("ponyyy", "p%+o.*yyy$$$$"));
assert(!r4_match_stats("ponyyyd", "^p+o.*yyz$$$$"));
assert(r4_match_stats("123", "[0-2][2-2][1-3]$"));
assert(r4_match_stats("aaaabC5", "(a)(\\w)a*(a)\\w[A-Z][0-9]$"));
assert(r4_match_stats("abcdeeeeee", "ab(cdeee)e"));
assert(r4_match_stats("1234567", "12(.*)67$"));
assert(r4_match_stats("12111678993", "12(.*)67(.*)3$"));
assert(r4_match_stats("NL18RABO0322309700", "NL(.*)R(.*)0(.*)0(.*)$"));
assert(r4_match_stats("NL18RABO0322309700",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d+)$"));
assert(r4_match_stats("NL18RABO0322309700garbage",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d+)"));
assert(r4_match_stats("NL18RABO0322309700",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d+)$"));
assert(r4_match_stats(" NL18RABO0322309700",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d+)$"));
assert(r4_match_stats(" NL18RABO0322309700",
"(\\w{2})(\\d{2})(\\w{4}\\d)(\\d+)$"));
assert(
r4_match_stats("NL18RABO0", "(\\w\\w)(\\d\\d)(\\w\\w\\w\\w\\d)$"));
assert(r4_match_stats("q", "\\q$"));
assert(r4_match_stats("ab123", "[a-z0-9]+$"));
assert(r4_match_stats("ppppony", "p*pppony"));
assert(r4_match_stats("aa", "a{2}$"));
assert(r4_match_stats("A23", "[0-2A-z][2-2][1-3]$"));
assert(r4_match_stats("z23", "[0-2A-z][2-2][1-3]$"));
assert(r4_match_stats("r23", "[0-2Ar][2-2][1-3]$"));
assert(r4_match_stats("test", "\\w\\w\\w\\w$"));
assert(!r4_match_stats("test", "\\W\\w\\w\\w$"));
assert(r4_match_stats("1est", "\\W\\w\\w\\w$"));
assert(r4_match_stats("1est", "\\d\\w\\w\\w$"));
assert(r4_match_stats("Aest", "\\D\\w\\w\\w$"));
assert(r4_match_stats("abc", "[ab]+"));
assert(!r4_match_stats("abc", "[ab]+$"));
assert(r4_match_stats("abc", "[abc]+$"));
assert(!r4_match_stats("a", "[^ba]"));
assert(!r4_match_stats("a", "[^ab]"));
assert(r4_match_stats(" ponyyzd", "p+o.*yyzd$$$$"));
assert(r4_match_stats("abc", "def|gek|abc"));
assert(!r4_match_stats("abc", "def|gek|abd"));
assert(r4_match_stats("abc", "def|abc|def"));
assert(r4_match_stats(
"suwv", "[abcdesfghijklmnopqrtuvw][abcdefghijklmnopqrstuvw]["
"abcdefghijklmnopqrstuvw][abcdefghijklmnopqrstuvw]"));
assert(r4_match_stats("123", "(.*)(.*)(.*)"));
assert(r4_match_stats("1234", "(.*)(.*)(.*)"));
assert(r4_match_stats("#include \"test.c\"", "#include\\s+\"(.*)\""));
assert(r4_match_stats("#define TEST_JE VALUE",
"#define\\s+([A-Za-z_0-9]+)\\s+([A-Za-z_0-9]+)"));
//
assert(r4_match_stats("bbb", "a*(bbb)"));
// Tests added for coverage
assert(!r4_match_stats("1", "[\\D]"));
assert(!r4_match_stats("11", "\\D{2}"));
assert(!r4_match_stats("ab", "ba"));
assert(r4_match_stats("2", "[4-2]"));
});
return 0;
}