1 #define CTRE_MSVC_GREEDY_WORKAROUND
2 
3 #include <ctre.hpp>
4 #include <string_view>
5 
empty_symbol()6 void empty_symbol() { }
7 
8 #if !CTRE_CNTTP_COMPILER_CHECK
9 #define CTRE_CREATE(pattern) (pattern ## _ctre)
10 #define CTRE_SYNTAX(pattern) (pattern ## _ctre_syntax)
11 #else
12 
create()13 template <ctll::fixed_string input> constexpr auto create() {
14 	constexpr auto _input = input;
15 
16 	using tmp = typename ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template output<ctre::pcre_context<>>;
17 	static_assert(tmp(), "Regular Expression contains syntax error.");
18 	using re = decltype(front(typename tmp::output_type::stack_type()));
19 	return ctre::regular_expression(re());
20 }
21 
syntax()22 template <ctll::fixed_string input> constexpr bool syntax() {
23 	constexpr auto _input = input;
24 
25 	return ctll::parser<ctre::pcre, _input, ctre::pcre_actions>::template correct_with<ctre::pcre_context<>>;
26 }
27 
28 
29 #define CTRE_CREATE(pattern) create<pattern>()
30 #define CTRE_SYNTAX(pattern) syntax<pattern>()
31 
32 #endif
33 
34 using namespace ctre::literals;
35 using namespace ctre::test_literals;
36 using namespace std::string_view_literals;
37 
38 static_assert(CTRE_CREATE("").search("abc"sv));
39 static_assert(CTRE_CREATE("abc").match("abc"sv));
40 
41 static_assert(CTRE_CREATE("a").match("a"sv));
42 static_assert(CTRE_CREATE("a").search("abc"sv));
43 static_assert(CTRE_CREATE("b").search("abc"sv));
44 static_assert(!CTRE_CREATE("^b").match("abc"sv));
45 static_assert(!CTRE_CREATE("b").match("a"sv));
46 static_assert(CTRE_CREATE(".").match("a"sv));
47 static_assert(CTRE_CREATE(".").search("abc"sv));
48 static_assert(CTRE_CREATE("[\\-]").match("-"sv));
49 static_assert(CTRE_CREATE("[\\\\]").match("\\"sv));
50 static_assert(CTRE_CREATE("[a-z]").match("a"sv));
51 static_assert(CTRE_CREATE("[a-z]").match("f"sv));
52 static_assert(CTRE_CREATE("[a-z]").match("z"sv));
53 static_assert(!CTRE_CREATE("[a-z]").match("Z"sv));
54 static_assert(CTRE_CREATE("\\u0050").match("P"sv));
55 static_assert(CTRE_CREATE("[\\u0050-\\u0051]").match("Q"sv));
56 static_assert(CTRE_CREATE("\u0050").match("P"sv)); // be aware!
57 
58 static_assert(CTRE_CREATE("^[\\x30-\\x39]+?$").match("123456789"sv));
59 static_assert(CTRE_CREATE("[a-z0-9]").match("0"sv));
60 static_assert(!CTRE_CREATE("[a-z0-9]").match("A"sv));
61 static_assert(CTRE_CREATE("[[:xdigit:]]").match("0"sv));
62 static_assert(CTRE_CREATE("[[:xdigit:]]").match("9"sv));
63 static_assert(CTRE_CREATE("[[:xdigit:]]").match("a"sv));
64 static_assert(CTRE_CREATE("[[:xdigit:]]").match("A"sv));
65 static_assert(CTRE_CREATE("[[:xdigit:]]").match("f"sv));
66 static_assert(!CTRE_CREATE("[[:xdigit:]]").match("g"sv));
67 static_assert(CTRE_CREATE("abcdef").match("abcdef"sv));
68 static_assert(!CTRE_CREATE("abcdef").match("abcGef"sv));
69 static_assert(CTRE_CREATE("").match(""sv));
70 static_assert(CTRE_CREATE("(?:a|b|c)").match("a"sv));
71 static_assert(CTRE_CREATE("(?:a|b|c)").match("b"sv));
72 static_assert(CTRE_CREATE("(?:a|b|c)").match("c"sv));
73 static_assert(!CTRE_CREATE("(?:a|b|c)").match("d"sv));
74 static_assert(CTRE_CREATE("(?:xy)?").match("xy"sv));
75 static_assert(CTRE_CREATE("(?:xy)?").match(""sv));
76 static_assert(CTRE_CREATE("(?:xy)?").search("zxy"sv));
77 static_assert(CTRE_CREATE("(?:xy)?$").search("zxy"sv));
78 static_assert(!CTRE_CREATE("~(?:xy)?$").match("zxy"sv));
79 
80 static_assert(CTRE_CREATE("^abc").match("abc"sv));
81 static_assert(CTRE_CREATE("^def$").match("def"sv));
82 static_assert(!CTRE_CREATE("a^").match("a"sv));
83 static_assert(!CTRE_CREATE("$a").match("a"sv));
84 
85 static_assert(CTRE_CREATE("a+?").search("aaax"sv));
86 static_assert(CTRE_CREATE("a+?").search("ax"sv));
87 static_assert(!CTRE_CREATE("a+?").match("x"sv));
88 
89 static_assert(CTRE_CREATE("a++").search("aaax"sv));
90 static_assert(CTRE_CREATE("a++").search("ax"sv));
91 static_assert(!CTRE_CREATE("a++").match("x"sv));
92 
93 static_assert(CTRE_CREATE("a*?x").match("aaax"sv));
94 static_assert(CTRE_CREATE("a*?x").match("ax"sv));
95 static_assert(CTRE_CREATE("a*?x").match("x"sv));
96 static_assert(!CTRE_CREATE("a*?x").match("y"sv));
97 
98 static_assert(CTRE_CREATE("a*+x").match("aaax"sv));
99 static_assert(CTRE_CREATE("a*+x").match("ax"sv));
100 static_assert(CTRE_CREATE("a*+x").match("x"sv));
101 static_assert(!CTRE_CREATE("a*+x").match("y"sv));
102 
103 static_assert(!CTRE_CREATE("a*+ab").match("aaab"sv));
104 static_assert(!CTRE_CREATE("a++ab").match("aaab"sv));
105 static_assert(!CTRE_CREATE("a*+ab").match("ab"sv));
106 static_assert(!CTRE_CREATE("a++ab").match("aab"sv));
107 
108 static_assert(CTRE_CREATE("a*+ba").match("aaba"sv));
109 static_assert(CTRE_CREATE("a++ba").match("aaba"sv));
110 static_assert(CTRE_CREATE("a*+ba").match("ba"sv));
111 static_assert(CTRE_CREATE("a++ba").match("aba"sv));
112 
113 static_assert(CTRE_CREATE("a{3,}x").match("aaax"sv));
114 static_assert(CTRE_CREATE("a{3,}x").match("aaaax"sv));
115 
116 static_assert(CTRE_CREATE("^a{5}").match("aaaaa"sv));
117 static_assert(CTRE_CREATE("^a{5}").search("aaaaaa"sv));
118 static_assert(!CTRE_CREATE("^a{5}$").match("aaaaaa"sv));
119 
120 static_assert(CTRE_CREATE("a*").match("aaa"sv));
121 static_assert(CTRE_CREATE("a+").match("aaa"sv));
122 static_assert(CTRE_CREATE("a*").match(""sv));
123 static_assert(CTRE_CREATE("a+").match("a"sv));
124 
125 static_assert(CTRE_CREATE("a*$").match("aaa"sv));
126 static_assert(CTRE_CREATE("a+$").match("aaa"sv));
127 static_assert(CTRE_CREATE("a*$").match(""sv));
128 static_assert(CTRE_CREATE("a+$").match("a"sv));
129 
130 static_assert(CTRE_CREATE("a*xb").match("aaxb"sv));
131 static_assert(CTRE_CREATE("a+xb").match("aaxb"sv));
132 static_assert(CTRE_CREATE("a*xb").match("xb"sv));
133 static_assert(CTRE_CREATE("a+xb").match("axb"sv));
134 
135 static_assert(CTRE_CREATE("a*ab").match("aaab"sv));
136 static_assert(CTRE_CREATE("a+ab").match("aaab"sv));
137 static_assert(CTRE_CREATE("a*ab").match("ab"sv));
138 static_assert(CTRE_CREATE("a+ab").match("aab"sv));
139 
140 static_assert(!CTRE_CREATE("^a{2,5}ab").match("aab"sv));
141 static_assert(CTRE_CREATE("^a{2,5}ab").match("aaab"sv));
142 static_assert(CTRE_CREATE("^a{2,5}ab").match("aaaab"sv));
143 static_assert(CTRE_CREATE("^a{2,5}ab").match("aaaaab"sv));
144 static_assert(CTRE_CREATE("^a{2,5}ab").match("aaaaaab"sv));
145 static_assert(!CTRE_CREATE("^a{2,5}ab").match("aaaaaaab"sv));
146 
147 static_assert(CTRE_CREATE("[a-z]+[^a-z]+").match("abcdef123456"sv));
148 
149 static_assert(CTRE_CREATE("(abc)").match("abc"sv));
150 static_assert(CTRE_CREATE("(abc)+").match("abc"sv));
151 static_assert(CTRE_CREATE("(abc)+").match("abcabc"sv));
152 static_assert(CTRE_CREATE("(abc)+").match("abcabcabc"sv));
153 
154 static_assert(CTRE_CREATE("(?<name>abc)").match("abc"sv));
155 static_assert(CTRE_CREATE("(?<name>abc)+").match("abc"sv));
156 static_assert(CTRE_CREATE("(?<name>abc)+").match("abcabc"sv));
157 static_assert(CTRE_CREATE("(?<name>abc)+").match("abcabcabc"sv));
158 static_assert(!CTRE_CREATE("(?<name>abc)+").match("name"sv));
159 
160 static_assert(std::string_view{CTRE_CREATE("^([a-z]+)").search("abcdef1234"sv)} == "abcdef"sv);
161 static_assert(std::string_view{CTRE_CREATE("^([a-z]+)1234").match("abcdef1234"sv)} == "abcdef1234"sv);
162 static_assert(std::string_view{CTRE_CREATE("^([a-z])").search("abcdef1234"sv)} == "a"sv);
163 
164 static_assert(CTRE_CREATE("^([0-9]+[a-z]+)+").match("123abc456def"sv));
165 static_assert(CTRE_CREATE("^([0-9]+[a-z]+)+").match("123abc456def"sv).template get<1>() == "456def"sv);
166 static_assert(CTRE_CREATE("^([0-9]+[a-z]+)+").match("123abc456def"sv).template get<0>() == "123abc456def"sv);
167 
168 static_assert(CTRE_CREATE("^([0-9]++[a-z]++)+").match("123abc456def"sv));
169 static_assert(CTRE_CREATE("^([0-9]++[a-z]++)+").match("123abc456def"sv).template get<1>() == "456def"sv);
170 static_assert(CTRE_CREATE("^([0-9]++[a-z]++)+").match("123abc456def"sv).template get<0>() == "123abc456def"sv);
171 
172 static_assert(CTRE_CREATE("^([0-9]+?[a-z]+?)+").search("123abc456def"sv));
173 static_assert(CTRE_CREATE("^([0-9]+?[a-z]+?)+").search("123abc456def"sv).template get<1>() == "123a"sv);
174 static_assert(CTRE_CREATE("^([0-9]+?[a-z]+?)+").search("123abc456def"sv).template get<0>() == "123a"sv);
175 
176 static_assert(CTRE_CREATE("^([0-9]+?[a-z]++)+").match("123abc456def"sv));
177 static_assert(CTRE_CREATE("^([0-9]+?[a-z]++)+").match("123abc456def"sv).template get<1>() == "456def"sv);
178 static_assert(CTRE_CREATE("^([0-9]+?[a-z]++)+").match("123abc456def"sv).template get<0>() == "123abc456def"sv);
179 
180 static_assert(CTRE_CREATE("^([a-z]{2})([a-z]{2})").match("abcd"sv).template get<2>() == "cd"sv);
181 // FIXME  ID support
182 //static_assert(CTRE_CREATE("^([a-z]{2})(?<second>[a-z]{2})").match("abcd"sv).template get<decltype("second")_id)>() == "cd"sv);
183 
184 static_assert(CTRE_CREATE("^([a-z]+):\\g{1}$").match("abc:abc"sv));
185 static_assert(CTRE_CREATE("^([a-z]+):\\g{1}$").match("abc:abc"sv).template get<1>() == "abc"sv);
186 static_assert(!CTRE_CREATE("^([a-z]+):\\g{1}$").match("abc:abce"sv));
187 static_assert(CTRE_CREATE("^([a-z]+)\\g{1}$").match("abcabc"sv));
188 static_assert(!CTRE_CREATE("^([a-z]+)\\g{1}$").match("abcabcd"sv));
189 static_assert(CTRE_SYNTAX("^([a-z]+)\\g{-1}$"));
190 static_assert(CTRE_CREATE("^([a-z]+)\\g{-1}$").match("abcabc"sv));
191 static_assert(!CTRE_SYNTAX("^([a-z]+)\\g{-2}$"));
192 // TODO check for existence of named capture too
193 
194 static_assert(CTRE_CREATE("^(?<text>[a-z]+):\\g{text}$").match("abc:abc"sv));
195 
196 static_assert(CTRE_CREATE("^abc$").match("abc"sv));
197 static_assert(CTRE_CREATE("^abc$").match(L"abc"sv));
198 // static_assert(CTRE_CREATE("^abc$").match(u8"abc"sv)); // GCC9.0.1 doesn't support a char8_t string_view literals
199 static_assert(CTRE_CREATE("^abc$").match(u"abc"sv));
200 static_assert(CTRE_CREATE("^abc$").match(U"abc"sv));
201 
202 static_assert(CTRE_CREATE(R"(\(\))").match("()"sv));
203 static_assert(CTRE_CREATE("\\[\\]").match("[]"sv));
204 static_assert(CTRE_CREATE(R"(\[\])").match("[]"sv));
205 
206 static_assert(CTRE_CREATE(R"(\[([A-Z]*?)\])").match("[]"sv));
207 static_assert(CTRE_CREATE(R"(\[([A-Z]*?)\])").match("[URL]"sv));
208 
209 static_assert(CTRE_CREATE(R"(\[([\s\S]*?)\]\(([\s\S]*?)\))").match("[URL](https://cpp.fail/ctre)"));
210 
211 static_assert(CTRE_CREATE("abc").match("abc"));
212 static_assert(CTRE_CREATE("[_]").match("_"));
213 static_assert(CTRE_CREATE("[()]").match("("));
214 static_assert(CTRE_CREATE("[$]").match("$"));
215 static_assert(CTRE_CREATE("[*]").match("*"));
216 static_assert(CTRE_CREATE("[+]").match("+"));
217 static_assert(CTRE_CREATE("[?]").match("?"));
218 static_assert(CTRE_CREATE("[{}]").match("{"));
219 static_assert(CTRE_CREATE("[(-)]").match("("));
220 static_assert(CTRE_CREATE("[(-)]").match(")"));
221 
222 static_assert(CTRE_CREATE("[A-Z_a-z]").match("a"));
223 static_assert(CTRE_CREATE("[A-Z_a-z]").match("_"));
224 static_assert(CTRE_CREATE("[A-Z_a-z]").match("Z"));
225 // FIXME: maybe in future I will allow this again
226 // static_assert(CTRE_CREATE("[-]").match("-"));
227 // static_assert(CTRE_CREATE("[-x]").match("x"));
228 // FIXME: due current limitation of LL1 grammar parser I can make this work "[x-]" without significant change in grammar
229 static_assert(CTRE_CREATE("<").match("<"));
230 static_assert(CTRE_CREATE("(<)").match("<"));
231 static_assert(CTRE_CREATE("(<>)").match("<>"));
232 static_assert(CTRE_CREATE("(<>?)").match("<"));
233 static_assert(CTRE_CREATE("(<?>)").match(">"));
234 static_assert(CTRE_CREATE("()").match(""));
235 
236 
237 static_assert((CTRE_CREATE("[a-z]") >> CTRE_CREATE("[0-9]")).match("a9"));
238 static_assert((CTRE_CREATE("a") | CTRE_CREATE("b")).match("a"));
239 static_assert((CTRE_CREATE("a") | CTRE_CREATE("b")).match("b"));
240 static_assert(!(CTRE_CREATE("a") | CTRE_CREATE("b")).match("c"));
241 
242 static_assert(CTRE_CREATE("((a)(b))").match("ab"sv).template get<0>() == "ab"sv);
243 static_assert(CTRE_CREATE("((a)(b))").match("ab"sv).template get<1>() == "ab"sv);
244 static_assert(CTRE_CREATE("((a)(b))").match("ab"sv).template get<2>() == "a"sv);
245 static_assert(CTRE_CREATE("((a)(b))").match("ab"sv).template get<3>() == "b"sv);
246 
247 static_assert(CTRE_CREATE("^x(?=y)").search("xy"sv).template get<0>() == "x"sv);
248 static_assert(CTRE_CREATE("^x(?!a)").search("xy"sv).template get<0>() == "x"sv);
249 
250 static_assert(CTRE_CREATE("a(?!3)[0-9]").match("a0"sv));
251 static_assert(CTRE_CREATE("a(?!3)[0-9]").match("a9"sv));
252 static_assert(!CTRE_CREATE("a(?!3)[0-9]").match("a3"sv));
253 
254 static_assert(!CTRE_CREATE(".*(.)\\g{1}.*").match("abcdefghijk"sv));
255 static_assert(CTRE_CREATE(".*(.)\\g{1}.*").match("aabcdefghijk"sv));
256 static_assert(CTRE_CREATE(".*(.)\\g{1}.*").match("abcdeffghijk"sv));
257 
258 static_assert(CTRE_CREATE("(?=.*(.)\\g{1})[a-z]+").match("abcdeffghijk"sv));
259 static_assert(!CTRE_CREATE("(?=.*(.)\\g{1}{2})[a-z]+").match("abcddeffghijk"sv));
260 static_assert(CTRE_CREATE("(?=.*(.)\\g{1}{2})[a-z]+").match("abcdddeffghijk"sv));
261 
262 static_assert( CTRE_CREATE("(?!.*(.)\\g{1})[a-z]+").match("abcdefgh"sv));
263 static_assert(!CTRE_CREATE("(?!.*(.)\\g{1})[a-z]+").match("abcdeefgh"sv));
264 
265 static_assert(CTRE_CREATE("_").match("_"sv));
266 static_assert(CTRE_CREATE("[<]").match("<"sv));
267 static_assert(CTRE_CREATE("[>]").match(">"sv));
268 static_assert(CTRE_CREATE("[<>]").match("<"sv));
269 static_assert(CTRE_CREATE("[<>]+").match("><"sv));
270 
271 static_assert(CTRE_CREATE("<[a-z]+>").match("<aloha>"sv));
272 static_assert(CTRE_CREATE("(<[a-z]+>)\\g{1}").match("<aloha><aloha>"sv));
273 
274 // issue #60
275 static_assert(CTRE_CREATE("[^\\^]").match("a"sv));
276 static_assert(CTRE_CREATE("[^^]").match("a"sv));
277 static_assert(CTRE_CREATE("[\\-]").match("-"sv));
278 static_assert(CTRE_CREATE("[\\--\\-]").match("-"sv));
279 
280 // msvc
281 static_assert(CTRE_CREATE("[a-z]+abc").match("xxxabc"));
282