1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#include <usual/regex.h>
#include <usual/string.h>
#include "test_common.h"
#define NMATCH 20
/*
* quick regex sanity check
*/
/* execute basic regex and return result as string */
static const char *b_rx(const char *regex, const char *str, int flags)
{
static char buf[512];
regex_t rx;
regmatch_t matches[NMATCH];
int nmatch, err, i;
char *dst = buf;
memset(&rx, 0, sizeof(rx));
memset(matches, -1, sizeof(&matches));
/* compile */
err = regcomp(&rx, regex, flags);
if (err)
goto fail;
nmatch = rx.re_nsub;
/* match */
err = regexec(&rx, str, NMATCH, matches, 0);
if (err)
goto fail;
/* format result */
for (i = 0; i < nmatch + 1; i++) {
regmatch_t *m = &matches[i];
*dst++ = '(';
if (m->rm_so >= 0)
dst += sprintf(dst, "%d", (int)m->rm_so);
else
*dst++ = '?';
*dst++ = ',';
if (m->rm_eo >= 0)
dst += sprintf(dst, "%d", (int)m->rm_eo);
else
*dst++ = '?';
*dst++ = ')';
}
regfree(&rx);
return buf;
fail:
/* format error */
regfree(&rx);
switch (err) {
case REG_NOMATCH: return "NOMATCH";
case REG_BADBR: return "BADBR";
case REG_BADPAT: return "BADPAT";
case REG_BADRPT: return "BADRPT";
case REG_EBRACE: return "EBRACE";
case REG_EBRACK: return "EBRACK";
case REG_ECOLLATE: return "ECOLLATE";
case REG_ECTYPE: return "ECTYPE";
#ifdef REG_EEND
case REG_EEND: return "EEND";
#endif
case REG_EESCAPE: return "EESCAPE";
case REG_EPAREN: return "EPAREN";
case REG_ERANGE: return "ERANGE";
#ifdef REG_ESIZE
case REG_ESIZE: return "ESIZE";
#endif
case REG_ESPACE: return "ESPACE";
case REG_ESUBREG: return "ESUBREG";
#ifdef REG_ENOSYS
case REG_ENOSYS: return "ENOSYS";
#endif
#ifdef REG_EMPTY
case REG_EMPTY: return "EMPTY";
#endif
default: return "UNKNOWN_ERROR";
}
}
/* execute extended regex and return result as string */
static const char *e_rx(const char *regex, const char *str, int flags)
{
return b_rx(regex, str, flags | REG_EXTENDED);
}
static void test_regex(void *ptr)
{
str_check(e_rx("foo*", "foobar", 0), "(0,3)");
str_check(e_rx("foo(x)?.*", "foobar", 0), "(0,6)(?,?)");
str_check(e_rx("foo", "bar", 0), "NOMATCH");
str_check(e_rx("foo{5,1}", "bar", 0), "BADBR");
/* str_check(e_rx("(|)", "bar", 0), "BADPAT"); */
str_check(e_rx("*", "bar", 0), "BADRPT");
str_check(e_rx("foo{", "bar", 0), "EBRACE");
str_check(e_rx("fo[o", "bar", 0), "EBRACK");
str_check(e_rx("[[:foo:]]", "bar", 0), "ECTYPE");
str_check(e_rx("foo\\", "foobar", 0), "EESCAPE");
str_check(e_rx("fo(o", "bar", 0), "EPAREN");
str_check(e_rx("[a-b-c]", "bar", 0), "ERANGE");
str_check(b_rx("(\\1)", "bar", 0), "ESUBREG");
str_check(e_rx("[[:random:]]", "bar", 0), "ECTYPE");
end:;
}
/*
* Describe
*/
struct testcase_t regex_tests[] = {
{ "minimal", test_regex },
END_OF_TESTCASES
};
|