1 /*
2 * Copyright (c) 2018-2019, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <algorithm>
30 #include <array>
31 #include <iostream>
32 #include <vector>
33
34 #include "gtest/gtest.h"
35 #include "hs.h"
36 #include "config.h"
37 #include "test_util.h"
38
39 using namespace std;
40
TEST(LogicalCombination,SingleComb1)41 TEST(LogicalCombination, SingleComb1) {
42 hs_database_t *db = nullptr;
43 hs_compile_error_t *compile_err = nullptr;
44 CallBackContext c;
45 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
46 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
47 "ijkl[mMn]", "(101 & 102 & 103) | (104 & !105)"};
48 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION};
49 unsigned ids[] = {101, 102, 103, 104, 105, 1001};
50 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
51 nullptr, &db, &compile_err);
52
53 ASSERT_EQ(HS_SUCCESS, err);
54 ASSERT_TRUE(db != nullptr);
55
56 hs_scratch_t *scratch = nullptr;
57 err = hs_alloc_scratch(db, &scratch);
58 ASSERT_EQ(HS_SUCCESS, err);
59 ASSERT_TRUE(scratch != nullptr);
60
61 c.halt = 0;
62 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
63 (void *)&c);
64 ASSERT_EQ(HS_SUCCESS, err);
65 ASSERT_EQ(16U, c.matches.size());
66 ASSERT_EQ(MatchRecord(3, 101), c.matches[0]);
67 ASSERT_EQ(MatchRecord(6, 102), c.matches[1]);
68 ASSERT_EQ(MatchRecord(18, 103), c.matches[2]);
69 ASSERT_EQ(MatchRecord(18, 1001), c.matches[3]);
70 ASSERT_EQ(MatchRecord(21, 101), c.matches[4]);
71 ASSERT_EQ(MatchRecord(21, 1001), c.matches[5]);
72 ASSERT_EQ(MatchRecord(25, 102), c.matches[6]);
73 ASSERT_EQ(MatchRecord(25, 1001), c.matches[7]);
74 ASSERT_EQ(MatchRecord(38, 104), c.matches[8]);
75 ASSERT_EQ(MatchRecord(38, 1001), c.matches[9]);
76 ASSERT_EQ(MatchRecord(39, 104), c.matches[10]);
77 ASSERT_EQ(MatchRecord(39, 1001), c.matches[11]);
78 ASSERT_EQ(MatchRecord(48, 105), c.matches[12]);
79 ASSERT_EQ(MatchRecord(48, 1001), c.matches[13]);
80 ASSERT_EQ(MatchRecord(53, 102), c.matches[14]);
81 ASSERT_EQ(MatchRecord(53, 1001), c.matches[15]);
82
83 hs_free_database(db);
84 err = hs_free_scratch(scratch);
85 ASSERT_EQ(HS_SUCCESS, err);
86 }
87
TEST(LogicalCombination,SingleCombQuietSub1)88 TEST(LogicalCombination, SingleCombQuietSub1) {
89 hs_database_t *db = nullptr;
90 hs_compile_error_t *compile_err = nullptr;
91 CallBackContext c;
92 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
93 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
94 "ijkl[mMn]", "(101 & 102 & 103) | (104 & !105)"};
95 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET,
96 HS_FLAG_QUIET, 0, HS_FLAG_COMBINATION};
97 unsigned ids[] = {101, 102, 103, 104, 105, 1001};
98 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
99 nullptr, &db, &compile_err);
100
101 ASSERT_EQ(HS_SUCCESS, err);
102 ASSERT_TRUE(db != nullptr);
103
104 hs_scratch_t *scratch = nullptr;
105 err = hs_alloc_scratch(db, &scratch);
106 ASSERT_EQ(HS_SUCCESS, err);
107 ASSERT_TRUE(scratch != nullptr);
108
109 c.halt = 0;
110 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
111 (void *)&c);
112 ASSERT_EQ(HS_SUCCESS, err);
113 ASSERT_EQ(8U, c.matches.size());
114 ASSERT_EQ(MatchRecord(18, 1001), c.matches[0]);
115 ASSERT_EQ(MatchRecord(21, 1001), c.matches[1]);
116 ASSERT_EQ(MatchRecord(25, 1001), c.matches[2]);
117 ASSERT_EQ(MatchRecord(38, 1001), c.matches[3]);
118 ASSERT_EQ(MatchRecord(39, 1001), c.matches[4]);
119 ASSERT_EQ(MatchRecord(48, 105), c.matches[5]);
120 ASSERT_EQ(MatchRecord(48, 1001), c.matches[6]);
121 ASSERT_EQ(MatchRecord(53, 1001), c.matches[7]);
122
123 hs_free_database(db);
124 err = hs_free_scratch(scratch);
125 ASSERT_EQ(HS_SUCCESS, err);
126 }
127
TEST(LogicalCombination,MultiCombQuietSub1)128 TEST(LogicalCombination, MultiCombQuietSub1) {
129 hs_database_t *db = nullptr;
130 hs_compile_error_t *compile_err = nullptr;
131 CallBackContext c;
132 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
133 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
134 "ijkl[mMn]", "(101 & 102 & 103) | (104 & !105)",
135 "!101 & 102", "!(!101 | 102)", "101 & !102"};
136 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET,
137 HS_FLAG_QUIET, 0, HS_FLAG_COMBINATION,
138 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
139 HS_FLAG_COMBINATION};
140 unsigned ids[] = {101, 102, 103, 104, 105, 1001, 1002, 1003, 1004};
141 hs_error_t err = hs_compile_multi(expr, flags, ids, 9, HS_MODE_NOSTREAM,
142 nullptr, &db, &compile_err);
143
144 ASSERT_EQ(HS_SUCCESS, err);
145 ASSERT_TRUE(db != nullptr);
146
147 hs_scratch_t *scratch = nullptr;
148 err = hs_alloc_scratch(db, &scratch);
149 ASSERT_EQ(HS_SUCCESS, err);
150 ASSERT_TRUE(scratch != nullptr);
151
152 c.halt = 0;
153 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
154 (void *)&c);
155 ASSERT_EQ(HS_SUCCESS, err);
156 ASSERT_EQ(10U, c.matches.size());
157 ASSERT_EQ(MatchRecord(3, 1003), c.matches[0]);
158 ASSERT_EQ(MatchRecord(3, 1004), c.matches[1]);
159 ASSERT_EQ(MatchRecord(18, 1001), c.matches[2]);
160 ASSERT_EQ(MatchRecord(21, 1001), c.matches[3]);
161 ASSERT_EQ(MatchRecord(25, 1001), c.matches[4]);
162 ASSERT_EQ(MatchRecord(38, 1001), c.matches[5]);
163 ASSERT_EQ(MatchRecord(39, 1001), c.matches[6]);
164 ASSERT_EQ(MatchRecord(48, 105), c.matches[7]);
165 ASSERT_EQ(MatchRecord(48, 1001), c.matches[8]);
166 ASSERT_EQ(MatchRecord(53, 1001), c.matches[9]);
167
168 hs_free_database(db);
169 err = hs_free_scratch(scratch);
170 ASSERT_EQ(HS_SUCCESS, err);
171 }
172
TEST(LogicalCombination,MultiHighlanderCombQuietSub1)173 TEST(LogicalCombination, MultiHighlanderCombQuietSub1) {
174 hs_database_t *db = nullptr;
175 hs_compile_error_t *compile_err = nullptr;
176 CallBackContext c;
177 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
178 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
179 "ijkl[mMn]", "(101 & 102 & 103) | (104 & !105)",
180 "!101 & 102", "!(!101 | 102)", "101 & !102"};
181 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET,
182 HS_FLAG_QUIET, 0,
183 HS_FLAG_COMBINATION | HS_FLAG_SINGLEMATCH,
184 HS_FLAG_COMBINATION,
185 HS_FLAG_COMBINATION | HS_FLAG_SINGLEMATCH,
186 HS_FLAG_COMBINATION | HS_FLAG_SINGLEMATCH};
187 unsigned ids[] = {101, 102, 103, 104, 105, 1001, 1002, 1003, 1004};
188 hs_error_t err = hs_compile_multi(expr, flags, ids, 9, HS_MODE_NOSTREAM,
189 nullptr, &db, &compile_err);
190
191 ASSERT_EQ(HS_SUCCESS, err);
192 ASSERT_TRUE(db != nullptr);
193
194 hs_scratch_t *scratch = nullptr;
195 err = hs_alloc_scratch(db, &scratch);
196 ASSERT_EQ(HS_SUCCESS, err);
197 ASSERT_TRUE(scratch != nullptr);
198
199 c.halt = 0;
200 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
201 (void *)&c);
202 ASSERT_EQ(HS_SUCCESS, err);
203 ASSERT_EQ(4U, c.matches.size());
204 ASSERT_EQ(MatchRecord(3, 1003), c.matches[0]);
205 ASSERT_EQ(MatchRecord(3, 1004), c.matches[1]);
206 ASSERT_EQ(MatchRecord(18, 1001), c.matches[2]);
207 ASSERT_EQ(MatchRecord(48, 105), c.matches[3]);
208
209 hs_free_database(db);
210 err = hs_free_scratch(scratch);
211 ASSERT_EQ(HS_SUCCESS, err);
212 }
213
TEST(LogicalCombination,MultiQuietCombQuietSub1)214 TEST(LogicalCombination, MultiQuietCombQuietSub1) {
215 hs_database_t *db = nullptr;
216 hs_compile_error_t *compile_err = nullptr;
217 CallBackContext c;
218 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
219 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
220 "ijkl[mMn]", "(101 & 102 & 103) | (104 & !105)",
221 "!101 & 102", "!(!101 | 102)", "101 & !102"};
222 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET,
223 HS_FLAG_QUIET, 0, HS_FLAG_COMBINATION | HS_FLAG_QUIET,
224 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
225 HS_FLAG_COMBINATION | HS_FLAG_QUIET};
226 unsigned ids[] = {101, 102, 103, 104, 105, 1001, 1002, 1003, 1004};
227 hs_error_t err = hs_compile_multi(expr, flags, ids, 9, HS_MODE_NOSTREAM,
228 nullptr, &db, &compile_err);
229
230 ASSERT_EQ(HS_SUCCESS, err);
231 ASSERT_TRUE(db != nullptr);
232
233 hs_scratch_t *scratch = nullptr;
234 err = hs_alloc_scratch(db, &scratch);
235 ASSERT_EQ(HS_SUCCESS, err);
236 ASSERT_TRUE(scratch != nullptr);
237
238 c.halt = 0;
239 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
240 (void *)&c);
241 ASSERT_EQ(HS_SUCCESS, err);
242 ASSERT_EQ(2U, c.matches.size());
243 ASSERT_EQ(MatchRecord(3, 1003), c.matches[0]);
244 ASSERT_EQ(MatchRecord(48, 105), c.matches[1]);
245
246 hs_free_database(db);
247 err = hs_free_scratch(scratch);
248 ASSERT_EQ(HS_SUCCESS, err);
249 }
250
TEST(LogicalCombination,SingleComb2)251 TEST(LogicalCombination, SingleComb2) {
252 hs_database_t *db = nullptr;
253 hs_compile_error_t *compile_err = nullptr;
254 CallBackContext c;
255 string data = "abbdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
256 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
257 "ijkl[mMn]", "(201 | 202 & 203) & (!204 | 205)"};
258 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION};
259 unsigned ids[] = {201, 202, 203, 204, 205, 1002};
260 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
261 nullptr, &db, &compile_err);
262
263 ASSERT_EQ(HS_SUCCESS, err);
264 ASSERT_TRUE(db != nullptr);
265
266 hs_scratch_t *scratch = nullptr;
267 err = hs_alloc_scratch(db, &scratch);
268 ASSERT_EQ(HS_SUCCESS, err);
269 ASSERT_TRUE(scratch != nullptr);
270
271 c.halt = 0;
272 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
273 (void *)&c);
274 ASSERT_EQ(HS_SUCCESS, err);
275 ASSERT_EQ(13U, c.matches.size());
276 ASSERT_EQ(MatchRecord(6, 202), c.matches[0]);
277 ASSERT_EQ(MatchRecord(18, 203), c.matches[1]);
278 ASSERT_EQ(MatchRecord(18, 1002), c.matches[2]);
279 ASSERT_EQ(MatchRecord(21, 201), c.matches[3]);
280 ASSERT_EQ(MatchRecord(21, 1002), c.matches[4]);
281 ASSERT_EQ(MatchRecord(25, 202), c.matches[5]);
282 ASSERT_EQ(MatchRecord(25, 1002), c.matches[6]);
283 ASSERT_EQ(MatchRecord(38, 204), c.matches[7]);
284 ASSERT_EQ(MatchRecord(39, 204), c.matches[8]);
285 ASSERT_EQ(MatchRecord(48, 205), c.matches[9]);
286 ASSERT_EQ(MatchRecord(48, 1002), c.matches[10]);
287 ASSERT_EQ(MatchRecord(53, 202), c.matches[11]);
288 ASSERT_EQ(MatchRecord(53, 1002), c.matches[12]);
289
290 hs_free_database(db);
291 err = hs_free_scratch(scratch);
292 ASSERT_EQ(HS_SUCCESS, err);
293 }
294
TEST(LogicalCombination,SingleCombQuietSub2)295 TEST(LogicalCombination, SingleCombQuietSub2) {
296 hs_database_t *db = nullptr;
297 hs_compile_error_t *compile_err = nullptr;
298 CallBackContext c;
299 string data = "abbdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
300 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
301 "ijkl[mMn]", "(201 | 202 & 203) & (!204 | 205)"};
302 unsigned flags[] = {0, HS_FLAG_QUIET, HS_FLAG_QUIET, 0, HS_FLAG_QUIET,
303 HS_FLAG_COMBINATION};
304 unsigned ids[] = {201, 202, 203, 204, 205, 1002};
305 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
306 nullptr, &db, &compile_err);
307
308 ASSERT_EQ(HS_SUCCESS, err);
309 ASSERT_TRUE(db != nullptr);
310
311 hs_scratch_t *scratch = nullptr;
312 err = hs_alloc_scratch(db, &scratch);
313 ASSERT_EQ(HS_SUCCESS, err);
314 ASSERT_TRUE(scratch != nullptr);
315
316 c.halt = 0;
317 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
318 (void *)&c);
319 ASSERT_EQ(HS_SUCCESS, err);
320 ASSERT_EQ(8U, c.matches.size());
321 ASSERT_EQ(MatchRecord(18, 1002), c.matches[0]);
322 ASSERT_EQ(MatchRecord(21, 201), c.matches[1]);
323 ASSERT_EQ(MatchRecord(21, 1002), c.matches[2]);
324 ASSERT_EQ(MatchRecord(25, 1002), c.matches[3]);
325 ASSERT_EQ(MatchRecord(38, 204), c.matches[4]);
326 ASSERT_EQ(MatchRecord(39, 204), c.matches[5]);
327 ASSERT_EQ(MatchRecord(48, 1002), c.matches[6]);
328 ASSERT_EQ(MatchRecord(53, 1002), c.matches[7]);
329
330 hs_free_database(db);
331 err = hs_free_scratch(scratch);
332 ASSERT_EQ(HS_SUCCESS, err);
333 }
334
TEST(LogicalCombination,SingleComb3)335 TEST(LogicalCombination, SingleComb3) {
336 hs_database_t *db = nullptr;
337 hs_compile_error_t *compile_err = nullptr;
338 CallBackContext c;
339 string data = "abcijklndefxxfoobarrrghabcxdefxteakettleeeeexxxxijklnxxdef";
340 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
341 "ijkl[mMn]", "((301 | 302) & 303) & (304 | 305)"};
342 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION};
343 unsigned ids[] = {301, 302, 303, 304, 305, 1003};
344 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
345 nullptr, &db, &compile_err);
346
347 ASSERT_EQ(HS_SUCCESS, err);
348 ASSERT_TRUE(db != nullptr);
349
350 hs_scratch_t *scratch = nullptr;
351 err = hs_alloc_scratch(db, &scratch);
352 ASSERT_EQ(HS_SUCCESS, err);
353 ASSERT_TRUE(scratch != nullptr);
354
355 c.halt = 0;
356 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
357 (void *)&c);
358 ASSERT_EQ(HS_SUCCESS, err);
359 ASSERT_EQ(17U, c.matches.size());
360 ASSERT_EQ(MatchRecord(3, 301), c.matches[0]);
361 ASSERT_EQ(MatchRecord(8, 305), c.matches[1]);
362 ASSERT_EQ(MatchRecord(11, 302), c.matches[2]);
363 ASSERT_EQ(MatchRecord(23, 303), c.matches[3]);
364 ASSERT_EQ(MatchRecord(23, 1003), c.matches[4]);
365 ASSERT_EQ(MatchRecord(26, 301), c.matches[5]);
366 ASSERT_EQ(MatchRecord(26, 1003), c.matches[6]);
367 ASSERT_EQ(MatchRecord(30, 302), c.matches[7]);
368 ASSERT_EQ(MatchRecord(30, 1003), c.matches[8]);
369 ASSERT_EQ(MatchRecord(43, 304), c.matches[9]);
370 ASSERT_EQ(MatchRecord(43, 1003), c.matches[10]);
371 ASSERT_EQ(MatchRecord(44, 304), c.matches[11]);
372 ASSERT_EQ(MatchRecord(44, 1003), c.matches[12]);
373 ASSERT_EQ(MatchRecord(53, 305), c.matches[13]);
374 ASSERT_EQ(MatchRecord(53, 1003), c.matches[14]);
375 ASSERT_EQ(MatchRecord(58, 302), c.matches[15]);
376 ASSERT_EQ(MatchRecord(58, 1003), c.matches[16]);
377
378 hs_free_database(db);
379 err = hs_free_scratch(scratch);
380 ASSERT_EQ(HS_SUCCESS, err);
381 }
382
TEST(LogicalCombination,SingleCombQuietSub3)383 TEST(LogicalCombination, SingleCombQuietSub3) {
384 hs_database_t *db = nullptr;
385 hs_compile_error_t *compile_err = nullptr;
386 CallBackContext c;
387 string data = "abcijklndefxxfoobarrrghabcxdefxteakettleeeeexxxxijklnxxdef";
388 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
389 "ijkl[mMn]", "((301 | 302) & 303) & (304 | 305)"};
390 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, 0, HS_FLAG_QUIET,
391 HS_FLAG_QUIET, HS_FLAG_COMBINATION};
392 unsigned ids[] = {301, 302, 303, 304, 305, 1003};
393 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
394 nullptr, &db, &compile_err);
395
396 ASSERT_EQ(HS_SUCCESS, err);
397 ASSERT_TRUE(db != nullptr);
398
399 hs_scratch_t *scratch = nullptr;
400 err = hs_alloc_scratch(db, &scratch);
401 ASSERT_EQ(HS_SUCCESS, err);
402 ASSERT_TRUE(scratch != nullptr);
403
404 c.halt = 0;
405 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
406 (void *)&c);
407 ASSERT_EQ(HS_SUCCESS, err);
408 ASSERT_EQ(8U, c.matches.size());
409 ASSERT_EQ(MatchRecord(23, 303), c.matches[0]);
410 ASSERT_EQ(MatchRecord(23, 1003), c.matches[1]);
411 ASSERT_EQ(MatchRecord(26, 1003), c.matches[2]);
412 ASSERT_EQ(MatchRecord(30, 1003), c.matches[3]);
413 ASSERT_EQ(MatchRecord(43, 1003), c.matches[4]);
414 ASSERT_EQ(MatchRecord(44, 1003), c.matches[5]);
415 ASSERT_EQ(MatchRecord(53, 1003), c.matches[6]);
416 ASSERT_EQ(MatchRecord(58, 1003), c.matches[7]);
417
418 hs_free_database(db);
419 err = hs_free_scratch(scratch);
420 ASSERT_EQ(HS_SUCCESS, err);
421 }
422
TEST(LogicalCombination,MultiCombDupSub4)423 TEST(LogicalCombination, MultiCombDupSub4) {
424 hs_database_t *db = nullptr;
425 hs_compile_error_t *compile_err = nullptr;
426 CallBackContext c;
427 string data = "abbdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
428 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
429 "ijkl[mMn]", "(201 & 202 & 203) | (204 & !205)",
430 "(201 | 202 & 203) & (!204 | 205)",
431 "((201 | 202) & 203) & (204 | 205)"};
432 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION,
433 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION};
434 unsigned ids[] = {201, 202, 203, 204, 205, 1001, 1002, 1003};
435 hs_error_t err = hs_compile_multi(expr, flags, ids, 8, HS_MODE_NOSTREAM,
436 nullptr, &db, &compile_err);
437
438 ASSERT_EQ(HS_SUCCESS, err);
439 ASSERT_TRUE(db != nullptr);
440
441 hs_scratch_t *scratch = nullptr;
442 err = hs_alloc_scratch(db, &scratch);
443 ASSERT_EQ(HS_SUCCESS, err);
444 ASSERT_TRUE(scratch != nullptr);
445
446 c.halt = 0;
447 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
448 (void *)&c);
449 ASSERT_EQ(HS_SUCCESS, err);
450 ASSERT_EQ(23U, c.matches.size());
451 ASSERT_EQ(MatchRecord(6, 202), c.matches[0]);
452 ASSERT_EQ(MatchRecord(18, 203), c.matches[1]);
453 ASSERT_EQ(MatchRecord(18, 1002), c.matches[2]);
454 ASSERT_EQ(MatchRecord(21, 201), c.matches[3]);
455 ASSERT_EQ(MatchRecord(21, 1001), c.matches[4]);
456 ASSERT_EQ(MatchRecord(21, 1002), c.matches[5]);
457 ASSERT_EQ(MatchRecord(25, 202), c.matches[6]);
458 ASSERT_EQ(MatchRecord(25, 1001), c.matches[7]);
459 ASSERT_EQ(MatchRecord(25, 1002), c.matches[8]);
460 ASSERT_EQ(MatchRecord(38, 204), c.matches[9]);
461 ASSERT_EQ(MatchRecord(38, 1001), c.matches[10]);
462 ASSERT_EQ(MatchRecord(38, 1003), c.matches[11]);
463 ASSERT_EQ(MatchRecord(39, 204), c.matches[12]);
464 ASSERT_EQ(MatchRecord(39, 1001), c.matches[13]);
465 ASSERT_EQ(MatchRecord(39, 1003), c.matches[14]);
466 ASSERT_EQ(MatchRecord(48, 205), c.matches[15]);
467 ASSERT_EQ(MatchRecord(48, 1001), c.matches[16]);
468 ASSERT_EQ(MatchRecord(48, 1002), c.matches[17]);
469 ASSERT_EQ(MatchRecord(48, 1003), c.matches[18]);
470 ASSERT_EQ(MatchRecord(53, 202), c.matches[19]);
471 ASSERT_EQ(MatchRecord(53, 1001), c.matches[20]);
472 ASSERT_EQ(MatchRecord(53, 1002), c.matches[21]);
473 ASSERT_EQ(MatchRecord(53, 1003), c.matches[22]);
474
475 hs_free_database(db);
476 err = hs_free_scratch(scratch);
477 ASSERT_EQ(HS_SUCCESS, err);
478 }
479
TEST(LogicalCombination,MultiCombQuietDupSub4)480 TEST(LogicalCombination, MultiCombQuietDupSub4) {
481 hs_database_t *db = nullptr;
482 hs_compile_error_t *compile_err = nullptr;
483 CallBackContext c;
484 string data = "abbdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef";
485 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
486 "ijkl[mMn]", "(201 & 202 & 203) | (204 & !205)",
487 "(201 | 202 & 203) & (!204 | 205)",
488 "((201 | 202) & 203) & (204 | 205)"};
489 unsigned flags[] = {HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET, 0,
490 HS_FLAG_QUIET, HS_FLAG_COMBINATION,
491 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION};
492 unsigned ids[] = {201, 202, 203, 204, 205, 1001, 1002, 1003};
493 hs_error_t err = hs_compile_multi(expr, flags, ids, 8, HS_MODE_NOSTREAM,
494 nullptr, &db, &compile_err);
495
496 ASSERT_EQ(HS_SUCCESS, err);
497 ASSERT_TRUE(db != nullptr);
498
499 hs_scratch_t *scratch = nullptr;
500 err = hs_alloc_scratch(db, &scratch);
501 ASSERT_EQ(HS_SUCCESS, err);
502 ASSERT_TRUE(scratch != nullptr);
503
504 c.halt = 0;
505 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
506 (void *)&c);
507 ASSERT_EQ(HS_SUCCESS, err);
508 ASSERT_EQ(17U, c.matches.size());
509 ASSERT_EQ(MatchRecord(18, 1002), c.matches[0]);
510 ASSERT_EQ(MatchRecord(21, 1001), c.matches[1]);
511 ASSERT_EQ(MatchRecord(21, 1002), c.matches[2]);
512 ASSERT_EQ(MatchRecord(25, 1001), c.matches[3]);
513 ASSERT_EQ(MatchRecord(25, 1002), c.matches[4]);
514 ASSERT_EQ(MatchRecord(38, 204), c.matches[5]);
515 ASSERT_EQ(MatchRecord(38, 1001), c.matches[6]);
516 ASSERT_EQ(MatchRecord(38, 1003), c.matches[7]);
517 ASSERT_EQ(MatchRecord(39, 204), c.matches[8]);
518 ASSERT_EQ(MatchRecord(39, 1001), c.matches[9]);
519 ASSERT_EQ(MatchRecord(39, 1003), c.matches[10]);
520 ASSERT_EQ(MatchRecord(48, 1001), c.matches[11]);
521 ASSERT_EQ(MatchRecord(48, 1002), c.matches[12]);
522 ASSERT_EQ(MatchRecord(48, 1003), c.matches[13]);
523 ASSERT_EQ(MatchRecord(53, 1001), c.matches[14]);
524 ASSERT_EQ(MatchRecord(53, 1002), c.matches[15]);
525 ASSERT_EQ(MatchRecord(53, 1003), c.matches[16]);
526
527 hs_free_database(db);
528 err = hs_free_scratch(scratch);
529 ASSERT_EQ(HS_SUCCESS, err);
530 }
531
TEST(LogicalCombination,MultiCombUniSub5)532 TEST(LogicalCombination, MultiCombUniSub5) {
533 hs_database_t *db = nullptr;
534 hs_compile_error_t *compile_err = nullptr;
535 CallBackContext c;
536 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef"
537 "-----------------------------------------------"
538 "cbbfedxxgoogleeecncbaxfedxhaystacksssssxxxxijkloxxfed"
539 "-----------------------------------------------"
540 "cabijklRfeexxgoobarrrjpcabxfeexshockwaveeeeexxxxijklsxxfee"
541 "------------------------------------------";
542 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
543 "ijkl[mMn]", "cba", "fed", "google.*cn",
544 "haystacks{4,8}", "ijkl[oOp]", "cab", "fee",
545 "goobar.*jp", "shockwave{4,6}", "ijkl[rRs]",
546 "(101 & 102 & 103) | (104 & !105)",
547 "(201 | 202 & 203) & (!204 | 205)",
548 "((301 | 302) & 303) & (304 | 305)"};
549 unsigned flags[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
551 HS_FLAG_COMBINATION};
552 unsigned ids[] = {101, 102, 103, 104, 105, 201, 202, 203, 204, 205, 301,
553 302, 303, 304, 305, 1001, 1002, 1003};
554 hs_error_t err = hs_compile_multi(expr, flags, ids, 18, HS_MODE_NOSTREAM,
555 nullptr, &db, &compile_err);
556
557 ASSERT_EQ(HS_SUCCESS, err);
558 ASSERT_TRUE(db != nullptr);
559
560 hs_scratch_t *scratch = nullptr;
561 err = hs_alloc_scratch(db, &scratch);
562 ASSERT_EQ(HS_SUCCESS, err);
563 ASSERT_TRUE(scratch != nullptr);
564
565 c.halt = 0;
566 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
567 (void *)&c);
568 ASSERT_EQ(HS_SUCCESS, err);
569 ASSERT_EQ(46U, c.matches.size());
570 ASSERT_EQ(MatchRecord(3, 101), c.matches[0]);
571 ASSERT_EQ(MatchRecord(6, 102), c.matches[1]);
572 ASSERT_EQ(MatchRecord(18, 103), c.matches[2]);
573 ASSERT_EQ(MatchRecord(18, 1001), c.matches[3]);
574 ASSERT_EQ(MatchRecord(21, 101), c.matches[4]);
575 ASSERT_EQ(MatchRecord(21, 1001), c.matches[5]);
576 ASSERT_EQ(MatchRecord(25, 102), c.matches[6]);
577 ASSERT_EQ(MatchRecord(25, 1001), c.matches[7]);
578 ASSERT_EQ(MatchRecord(38, 104), c.matches[8]);
579 ASSERT_EQ(MatchRecord(38, 1001), c.matches[9]);
580 ASSERT_EQ(MatchRecord(39, 104), c.matches[10]);
581 ASSERT_EQ(MatchRecord(39, 1001), c.matches[11]);
582 ASSERT_EQ(MatchRecord(48, 105), c.matches[12]);
583 ASSERT_EQ(MatchRecord(48, 1001), c.matches[13]);
584 ASSERT_EQ(MatchRecord(53, 102), c.matches[14]);
585 ASSERT_EQ(MatchRecord(53, 1001), c.matches[15]);
586 ASSERT_EQ(MatchRecord(106, 202), c.matches[16]);
587 ASSERT_EQ(MatchRecord(118, 203), c.matches[17]);
588 ASSERT_EQ(MatchRecord(118, 1002), c.matches[18]);
589 ASSERT_EQ(MatchRecord(121, 201), c.matches[19]);
590 ASSERT_EQ(MatchRecord(121, 1002), c.matches[20]);
591 ASSERT_EQ(MatchRecord(125, 202), c.matches[21]);
592 ASSERT_EQ(MatchRecord(125, 1002), c.matches[22]);
593 ASSERT_EQ(MatchRecord(138, 204), c.matches[23]);
594 ASSERT_EQ(MatchRecord(139, 204), c.matches[24]);
595 ASSERT_EQ(MatchRecord(148, 205), c.matches[25]);
596 ASSERT_EQ(MatchRecord(148, 1002), c.matches[26]);
597 ASSERT_EQ(MatchRecord(153, 202), c.matches[27]);
598 ASSERT_EQ(MatchRecord(153, 1002), c.matches[28]);
599 ASSERT_EQ(MatchRecord(203, 301), c.matches[29]);
600 ASSERT_EQ(MatchRecord(208, 305), c.matches[30]);
601 ASSERT_EQ(MatchRecord(211, 302), c.matches[31]);
602 ASSERT_EQ(MatchRecord(223, 303), c.matches[32]);
603 ASSERT_EQ(MatchRecord(223, 1003), c.matches[33]);
604 ASSERT_EQ(MatchRecord(226, 301), c.matches[34]);
605 ASSERT_EQ(MatchRecord(226, 1003), c.matches[35]);
606 ASSERT_EQ(MatchRecord(230, 302), c.matches[36]);
607 ASSERT_EQ(MatchRecord(230, 1003), c.matches[37]);
608 ASSERT_EQ(MatchRecord(243, 304), c.matches[38]);
609 ASSERT_EQ(MatchRecord(243, 1003), c.matches[39]);
610 ASSERT_EQ(MatchRecord(244, 304), c.matches[40]);
611 ASSERT_EQ(MatchRecord(244, 1003), c.matches[41]);
612 ASSERT_EQ(MatchRecord(253, 305), c.matches[42]);
613 ASSERT_EQ(MatchRecord(253, 1003), c.matches[43]);
614 ASSERT_EQ(MatchRecord(258, 302), c.matches[44]);
615 ASSERT_EQ(MatchRecord(258, 1003), c.matches[45]);
616
617 hs_free_database(db);
618 err = hs_free_scratch(scratch);
619 ASSERT_EQ(HS_SUCCESS, err);
620 }
621
TEST(LogicalCombination,MultiCombQuietUniSub5)622 TEST(LogicalCombination, MultiCombQuietUniSub5) {
623 hs_database_t *db = nullptr;
624 hs_compile_error_t *compile_err = nullptr;
625 CallBackContext c;
626 string data = "abcdefxxfoobarrrghabcxdefxteakettleeeeexxxxijklmxxdef"
627 "-----------------------------------------------"
628 "cbbfedxxgoogleeecncbaxfedxhaystacksssssxxxxijkloxxfed"
629 "-----------------------------------------------"
630 "cabijklRfeexxgoobarrrjpcabxfeexshockwaveeeeexxxxijklsxxfee"
631 "------------------------------------------";
632 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
633 "ijkl[mMn]", "cba", "fed", "google.*cn",
634 "haystacks{4,8}", "ijkl[oOp]", "cab", "fee",
635 "goobar.*jp", "shockwave{4,6}", "ijkl[rRs]",
636 "(101 & 102 & 103) | (104 & !105)",
637 "(201 | 202 & 203) & (!204 | 205)",
638 "((301 | 302) & 303) & (304 | 305)"};
639 unsigned flags[] = {0, HS_FLAG_QUIET, HS_FLAG_QUIET, HS_FLAG_QUIET, 0,
640 HS_FLAG_QUIET, 0, HS_FLAG_QUIET, 0, HS_FLAG_QUIET,
641 HS_FLAG_QUIET, HS_FLAG_QUIET, 0, HS_FLAG_QUIET, 0,
642 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
643 HS_FLAG_COMBINATION};
644 unsigned ids[] = {101, 102, 103, 104, 105, 201, 202, 203, 204, 205, 301,
645 302, 303, 304, 305, 1001, 1002, 1003};
646 hs_error_t err = hs_compile_multi(expr, flags, ids, 18, HS_MODE_NOSTREAM,
647 nullptr, &db, &compile_err);
648
649 ASSERT_EQ(HS_SUCCESS, err);
650 ASSERT_TRUE(db != nullptr);
651
652 hs_scratch_t *scratch = nullptr;
653 err = hs_alloc_scratch(db, &scratch);
654 ASSERT_EQ(HS_SUCCESS, err);
655 ASSERT_TRUE(scratch != nullptr);
656
657 c.halt = 0;
658 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
659 (void *)&c);
660 ASSERT_EQ(HS_SUCCESS, err);
661 ASSERT_EQ(30U, c.matches.size());
662 ASSERT_EQ(MatchRecord(3, 101), c.matches[0]);
663 ASSERT_EQ(MatchRecord(18, 1001), c.matches[1]);
664 ASSERT_EQ(MatchRecord(21, 101), c.matches[2]);
665 ASSERT_EQ(MatchRecord(21, 1001), c.matches[3]);
666 ASSERT_EQ(MatchRecord(25, 1001), c.matches[4]);
667 ASSERT_EQ(MatchRecord(38, 1001), c.matches[5]);
668 ASSERT_EQ(MatchRecord(39, 1001), c.matches[6]);
669 ASSERT_EQ(MatchRecord(48, 105), c.matches[7]);
670 ASSERT_EQ(MatchRecord(48, 1001), c.matches[8]);
671 ASSERT_EQ(MatchRecord(53, 1001), c.matches[9]);
672 ASSERT_EQ(MatchRecord(106, 202), c.matches[10]);
673 ASSERT_EQ(MatchRecord(118, 1002), c.matches[11]);
674 ASSERT_EQ(MatchRecord(121, 1002), c.matches[12]);
675 ASSERT_EQ(MatchRecord(125, 202), c.matches[13]);
676 ASSERT_EQ(MatchRecord(125, 1002), c.matches[14]);
677 ASSERT_EQ(MatchRecord(138, 204), c.matches[15]);
678 ASSERT_EQ(MatchRecord(139, 204), c.matches[16]);
679 ASSERT_EQ(MatchRecord(148, 1002), c.matches[17]);
680 ASSERT_EQ(MatchRecord(153, 202), c.matches[18]);
681 ASSERT_EQ(MatchRecord(153, 1002), c.matches[19]);
682 ASSERT_EQ(MatchRecord(208, 305), c.matches[20]);
683 ASSERT_EQ(MatchRecord(223, 303), c.matches[21]);
684 ASSERT_EQ(MatchRecord(223, 1003), c.matches[22]);
685 ASSERT_EQ(MatchRecord(226, 1003), c.matches[23]);
686 ASSERT_EQ(MatchRecord(230, 1003), c.matches[24]);
687 ASSERT_EQ(MatchRecord(243, 1003), c.matches[25]);
688 ASSERT_EQ(MatchRecord(244, 1003), c.matches[26]);
689 ASSERT_EQ(MatchRecord(253, 305), c.matches[27]);
690 ASSERT_EQ(MatchRecord(253, 1003), c.matches[28]);
691 ASSERT_EQ(MatchRecord(258, 1003), c.matches[29]);
692
693 hs_free_database(db);
694 err = hs_free_scratch(scratch);
695 ASSERT_EQ(HS_SUCCESS, err);
696 }
697
TEST(LogicalCombination,SingleCombPurelyNegative6)698 TEST(LogicalCombination, SingleCombPurelyNegative6) {
699 hs_database_t *db = nullptr;
700 hs_compile_error_t *compile_err = nullptr;
701 CallBackContext c;
702 string data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
703 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
704 "ijkl[mMn]", "(!201 | 202 & 203) & (!204 | 205)"};
705 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION};
706 unsigned ids[] = {201, 202, 203, 204, 205, 1002};
707 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
708 nullptr, &db, &compile_err);
709
710 ASSERT_EQ(HS_SUCCESS, err);
711 ASSERT_TRUE(db != nullptr);
712
713 hs_scratch_t *scratch = nullptr;
714 err = hs_alloc_scratch(db, &scratch);
715 ASSERT_EQ(HS_SUCCESS, err);
716 ASSERT_TRUE(scratch != nullptr);
717
718 c.halt = 0;
719 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
720 (void *)&c);
721 ASSERT_EQ(HS_SUCCESS, err);
722 ASSERT_EQ(1U, c.matches.size());
723 ASSERT_EQ(MatchRecord(53, 1002), c.matches[0]);
724
725 hs_free_database(db);
726 err = hs_free_scratch(scratch);
727 ASSERT_EQ(HS_SUCCESS, err);
728 }
729
TEST(LogicalCombination,SingleCombQuietPurelyNegative6)730 TEST(LogicalCombination, SingleCombQuietPurelyNegative6) {
731 hs_database_t *db = nullptr;
732 hs_compile_error_t *compile_err = nullptr;
733 CallBackContext c;
734 string data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
735 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
736 "ijkl[mMn]", "(!201 | 202 & 203) & (!204 | 205)"};
737 unsigned flags[] = {0, 0, 0, 0, 0, HS_FLAG_COMBINATION | HS_FLAG_QUIET};
738 unsigned ids[] = {201, 202, 203, 204, 205, 1002};
739 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_NOSTREAM,
740 nullptr, &db, &compile_err);
741
742 ASSERT_EQ(HS_SUCCESS, err);
743 ASSERT_TRUE(db != nullptr);
744
745 hs_scratch_t *scratch = nullptr;
746 err = hs_alloc_scratch(db, &scratch);
747 ASSERT_EQ(HS_SUCCESS, err);
748 ASSERT_TRUE(scratch != nullptr);
749
750 c.halt = 0;
751 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
752 (void *)&c);
753 ASSERT_EQ(HS_SUCCESS, err);
754 ASSERT_EQ(0U, c.matches.size());
755
756 hs_free_database(db);
757 err = hs_free_scratch(scratch);
758 ASSERT_EQ(HS_SUCCESS, err);
759 }
760
TEST(LogicalCombination,MultiCombPurelyNegativeUniSub6)761 TEST(LogicalCombination, MultiCombPurelyNegativeUniSub6) {
762 hs_database_t *db = nullptr;
763 hs_compile_error_t *compile_err = nullptr;
764 CallBackContext c;
765 string data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
766 "-----------------------------------------------"
767 "xxxfedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
768 "-----------------------------------------------"
769 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
770 "------------------------------------------";
771 const char *expr[] = {"abc", "def", "foobar.*gh", "teakettle{4,10}",
772 "ijkl[mMn]", "cba", "fed", "google.*cn",
773 "haystacks{4,8}", "ijkl[oOp]", "cab", "fee",
774 "goobar.*jp", "shockwave{4,6}", "ijkl[rRs]",
775 "(101 & 102 & 103) | (!104 & !105)",
776 "(!201 | 202 & 203) & (!204 | 205)",
777 "((301 | 302) & 303) & (304 | 305)"};
778 unsigned flags[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
779 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
780 HS_FLAG_COMBINATION};
781 unsigned ids[] = {101, 102, 103, 104, 105, 201, 202, 203, 204, 205, 301,
782 302, 303, 304, 305, 1001, 1002, 1003};
783 hs_error_t err = hs_compile_multi(expr, flags, ids, 18, HS_MODE_NOSTREAM,
784 nullptr, &db, &compile_err);
785
786 ASSERT_EQ(HS_SUCCESS, err);
787 ASSERT_TRUE(db != nullptr);
788
789 hs_scratch_t *scratch = nullptr;
790 err = hs_alloc_scratch(db, &scratch);
791 ASSERT_EQ(HS_SUCCESS, err);
792 ASSERT_TRUE(scratch != nullptr);
793
794 c.halt = 0;
795 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
796 (void *)&c);
797 ASSERT_EQ(HS_SUCCESS, err);
798 ASSERT_EQ(3U, c.matches.size());
799 ASSERT_EQ(MatchRecord(106, 202), c.matches[0]);
800 ASSERT_EQ(MatchRecord(106, 1002), c.matches[1]);
801 ASSERT_EQ(MatchRecord(300, 1001), c.matches[2]);
802
803 hs_free_database(db);
804 err = hs_free_scratch(scratch);
805 ASSERT_EQ(HS_SUCCESS, err);
806 }
807
TEST(LogicalCombination,MultiCombPurelyNegativeUniSubEOD6)808 TEST(LogicalCombination, MultiCombPurelyNegativeUniSubEOD6) {
809 hs_database_t *db = nullptr;
810 hs_compile_error_t *compile_err = nullptr;
811 CallBackContext c;
812 string data = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
813 "-----------------------------------------------"
814 "xdefedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
815 "-----------------------------------------------"
816 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
817 "-------------------------------------defed";
818 const char *expr[] = {"abc", "defed", "foobar.*gh", "teakettle{4,10}",
819 "ijkl[mMn]", "cba", "fed", "google.*cn",
820 "haystacks{4,8}", "ijkl[oOp]", "cab", "fee",
821 "goobar.*jp", "shockwave{4,6}", "ijkl[rRs]",
822 "(101 & 102 & 103) | (!104 & !105)",
823 "(!201 | 202 & 203) & (!204 | 205)",
824 "((301 | 302) & 303) & (304 | 305)"};
825 unsigned flags[] = {0, 0, 0, 0, 0, 0, HS_FLAG_MULTILINE,
826 0, 0, 0, 0, 0, 0, 0, 0,
827 HS_FLAG_COMBINATION, HS_FLAG_COMBINATION,
828 HS_FLAG_COMBINATION};
829 unsigned ids[] = {101, 102, 103, 104, 105, 201, 202, 203, 204, 205, 301,
830 302, 303, 304, 305, 1001, 1002, 1003};
831 hs_error_t err = hs_compile_multi(expr, flags, ids, 18, HS_MODE_NOSTREAM,
832 nullptr, &db, &compile_err);
833
834 ASSERT_EQ(HS_SUCCESS, err);
835 ASSERT_TRUE(db != nullptr);
836
837 hs_scratch_t *scratch = nullptr;
838 err = hs_alloc_scratch(db, &scratch);
839 ASSERT_EQ(HS_SUCCESS, err);
840 ASSERT_TRUE(scratch != nullptr);
841
842 c.halt = 0;
843 err = hs_scan(db, data.c_str(), data.size(), 0, scratch, record_cb,
844 (void *)&c);
845 ASSERT_EQ(HS_SUCCESS, err);
846 ASSERT_EQ(8U, c.matches.size());
847 ASSERT_EQ(MatchRecord(106, 102), c.matches[0]);
848 ASSERT_EQ(MatchRecord(106, 202), c.matches[1]);
849 ASSERT_EQ(MatchRecord(106, 1001), c.matches[2]);
850 ASSERT_EQ(MatchRecord(106, 1002), c.matches[3]);
851 ASSERT_EQ(MatchRecord(300, 102), c.matches[4]);
852 ASSERT_EQ(MatchRecord(300, 202), c.matches[5]);
853 ASSERT_EQ(MatchRecord(300, 1001), c.matches[6]);
854 ASSERT_EQ(MatchRecord(300, 1002), c.matches[7]);
855
856 hs_free_database(db);
857 err = hs_free_scratch(scratch);
858 ASSERT_EQ(HS_SUCCESS, err);
859 }
860
TEST(LogicalCombination,MultiCombStream1)861 TEST(LogicalCombination, MultiCombStream1) {
862 hs_database_t *db = nullptr;
863 hs_compile_error_t *compile_err = nullptr;
864 CallBackContext c;
865 string data[] = {"xxxxxxxabcxxxxxxxdefxxxghixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
866 "xxxxxxxxxxxxxxxxghixxxxxxxxxxxabcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
867 "xxxxxxxxxxxxxxxxdefxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
868 "xxxxxxxxxxxxxxxxxyzxxxxxxxxxxxxxxxxxxxxxghixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
869 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
870 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
871 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
872 "xxxxxghixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
873 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
874 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxzxy",
875 "z"};
876 const char *expr[] = {"abc", "def", "xyz", "zxyz",
877 "101 & 102", "201 & !202"};
878 unsigned flags[] = {0, 0, 0, 0, HS_FLAG_COMBINATION, HS_FLAG_COMBINATION};
879 unsigned ids[] = {101, 102, 201, 202, 1001, 1002};
880 hs_error_t err = hs_compile_multi(expr, flags, ids, 6, HS_MODE_STREAM,
881 nullptr, &db, &compile_err);
882
883 ASSERT_EQ(HS_SUCCESS, err);
884 ASSERT_TRUE(db != nullptr);
885
886 hs_scratch_t *scratch = nullptr;
887 err = hs_alloc_scratch(db, &scratch);
888 ASSERT_EQ(HS_SUCCESS, err);
889 ASSERT_TRUE(scratch != nullptr);
890
891 hs_stream_t *stream = nullptr;
892 err = hs_open_stream(db, 0, &stream);
893 ASSERT_EQ(HS_SUCCESS, err);
894 ASSERT_TRUE(stream != nullptr);
895
896 c.halt = 0;
897 int i;
898 for (i = 0; i < 11; i++) {
899 err = hs_scan_stream(stream, data[i].c_str(), data[i].size(), 0,
900 scratch, record_cb, (void *)&c);
901 ASSERT_EQ(HS_SUCCESS, err);
902 }
903 err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
904 ASSERT_EQ(HS_SUCCESS, err);
905
906 ASSERT_EQ(11U, c.matches.size());
907 ASSERT_EQ(MatchRecord(10, 101), c.matches[0]);
908 ASSERT_EQ(MatchRecord(20, 102), c.matches[1]);
909 ASSERT_EQ(MatchRecord(20, 1001), c.matches[2]);
910 ASSERT_EQ(MatchRecord(109, 101), c.matches[3]);
911 ASSERT_EQ(MatchRecord(109, 1001), c.matches[4]);
912 ASSERT_EQ(MatchRecord(171, 102), c.matches[5]);
913 ASSERT_EQ(MatchRecord(171, 1001), c.matches[6]);
914 ASSERT_EQ(MatchRecord(247, 201), c.matches[7]);
915 ASSERT_EQ(MatchRecord(247, 1002), c.matches[8]);
916 ASSERT_EQ(MatchRecord(761, 201), c.matches[9]);
917 ASSERT_EQ(MatchRecord(761, 202), c.matches[10]);
918
919 hs_free_database(db);
920 err = hs_free_scratch(scratch);
921 ASSERT_EQ(HS_SUCCESS, err);
922 }
923