-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcompiler.cpp
111 lines (98 loc) · 3.96 KB
/
compiler.cpp
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
#include <hypergrep/compiler.hpp>
#include <hypergrep/cpu_features.hpp>
#include <hypergrep/search_options.hpp>
unsigned int get_cpu_features_flag() {
if (has_avx512vbmi_support()) {
return HS_CPU_FEATURES_AVX512VBMI;
} else if (has_avx512_support()) {
return HS_CPU_FEATURES_AVX512;
} else if (has_avx2_support()) {
return HS_CPU_FEATURES_AVX2;
} else {
return 0;
}
}
void compile_hs_database(hs_database **database, hs_scratch **scratch,
search_options &options,
const std::vector<std::string> &pattern_list) {
hs_error_t error_code;
hs_compile_error_t *compile_error = NULL;
static const auto cpu_features_flag = get_cpu_features_flag();
if (pattern_list.size() == 1) {
const auto &pattern = pattern_list[0];
if (options.compile_pattern_as_literal) {
error_code = hs_compile_lit(
pattern.data(),
(options.ignore_case ? HS_FLAG_CASELESS : 0) |
(options.is_stdout || options.print_only_matching_parts ||
options.show_column_numbers || options.show_byte_offset
? HS_FLAG_SOM_LEFTMOST
: 0) |
cpu_features_flag,
pattern.size(), HS_MODE_BLOCK, NULL, database, &compile_error);
} else {
error_code = hs_compile(
pattern.data(),
(options.ignore_case ? HS_FLAG_CASELESS : 0) | HS_FLAG_UTF8 |
(options.use_ucp ? HS_FLAG_UCP : 0) |
(options.is_stdout || options.print_only_matching_parts ||
options.show_column_numbers || options.show_byte_offset
? HS_FLAG_SOM_LEFTMOST
: 0) |
cpu_features_flag,
HS_MODE_BLOCK, NULL, database, &compile_error);
}
} else {
// Compile multiple patterns
// using hs_compile_multi
// Search patterns
std::vector<const char *> pattern_list_c;
pattern_list_c.reserve(pattern_list.size());
for (const std::string &str : pattern_list) {
pattern_list_c.push_back(str.data());
}
// Search flags
const auto flag =
(options.ignore_case ? HS_FLAG_CASELESS : 0) |
(options.compile_pattern_as_literal ? 0 : HS_FLAG_UTF8) |
(!options.compile_pattern_as_literal && options.use_ucp ? HS_FLAG_UCP
: 0) |
(options.is_stdout || options.print_only_matching_parts ||
options.show_column_numbers || options.show_byte_offset
? HS_FLAG_SOM_LEFTMOST
: 0) |
cpu_features_flag;
std::vector<unsigned int> flags;
flags.reserve(pattern_list.size());
for (std::size_t i = 0; i < pattern_list.size(); ++i) {
flags.push_back(flag);
}
if (options.compile_pattern_as_literal) {
std::vector<size_t> lens;
lens.reserve(pattern_list.size());
for (const std::string &str : pattern_list) {
lens.push_back(str.size());
}
error_code =
hs_compile_lit_multi(pattern_list_c.data(), flags.data(),
NULL, // list of IDs - NULL means all zero
lens.data(), pattern_list.size(), HS_MODE_BLOCK,
NULL, database, &compile_error) |
cpu_features_flag;
} else {
error_code = hs_compile_multi(pattern_list_c.data(), flags.data(),
NULL, // list of IDs - NULL means all zero
pattern_list.size(), HS_MODE_BLOCK, NULL,
database, &compile_error) |
cpu_features_flag;
}
}
if (error_code != HS_SUCCESS) {
throw std::runtime_error(std::string{"Error compiling pattern: "} +
compile_error->message);
}
auto database_error = hs_alloc_scratch(*database, scratch);
if (database_error != HS_SUCCESS) {
throw std::runtime_error("Error allocating scratch space");
}
}