@@ -16,6 +16,20 @@ static int grep_source_is_binary(struct grep_source *gs,
16
16
17
17
static struct grep_opt grep_defaults ;
18
18
19
+ #ifdef USE_LIBPCRE2
20
+ static pcre2_general_context * pcre2_global_context ;
21
+
22
+ static void * pcre2_malloc (PCRE2_SIZE size , MAYBE_UNUSED void * memory_data )
23
+ {
24
+ return malloc (size );
25
+ }
26
+
27
+ static void pcre2_free (void * pointer , MAYBE_UNUSED void * memory_data )
28
+ {
29
+ return free (pointer );
30
+ }
31
+ #endif
32
+
19
33
static const char * color_grep_slots [] = {
20
34
[GREP_COLOR_CONTEXT ] = "context" ,
21
35
[GREP_COLOR_FILENAME ] = "filename" ,
@@ -150,12 +164,28 @@ int grep_config(const char *var, const char *value, void *cb)
150
164
* Initialize one instance of grep_opt and copy the
151
165
* default values from the template we read the configuration
152
166
* information in an earlier call to git_config(grep_config).
167
+ *
168
+ * If using PCRE, make sure that the library is configured
169
+ * to use the same allocator as Git (e.g. nedmalloc on Windows).
170
+ *
171
+ * Any allocated memory needs to be released in grep_destroy().
153
172
*/
154
173
void grep_init (struct grep_opt * opt , struct repository * repo , const char * prefix )
155
174
{
156
175
struct grep_opt * def = & grep_defaults ;
157
176
int i ;
158
177
178
+ #if defined(USE_LIBPCRE2 )
179
+ if (!pcre2_global_context )
180
+ pcre2_global_context = pcre2_general_context_create (
181
+ pcre2_malloc , pcre2_free , NULL );
182
+ #endif
183
+
184
+ #ifdef USE_LIBPCRE1
185
+ pcre_malloc = malloc ;
186
+ pcre_free = free ;
187
+ #endif
188
+
159
189
memset (opt , 0 , sizeof (* opt ));
160
190
opt -> repo = repo ;
161
191
opt -> prefix = prefix ;
@@ -178,6 +208,13 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix
178
208
color_set (opt -> colors [i ], def -> colors [i ]);
179
209
}
180
210
211
+ void grep_destroy (void )
212
+ {
213
+ #ifdef USE_LIBPCRE2
214
+ pcre2_general_context_free (pcre2_global_context );
215
+ #endif
216
+ }
217
+
181
218
static void grep_set_pattern_type_option (enum grep_pattern_type pattern_type , struct grep_opt * opt )
182
219
{
183
220
/*
@@ -461,7 +498,6 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
461
498
PCRE2_UCHAR errbuf [256 ];
462
499
PCRE2_SIZE erroffset ;
463
500
int options = PCRE2_MULTILINE ;
464
- const uint8_t * character_tables = NULL ;
465
501
int jitret ;
466
502
int patinforet ;
467
503
size_t jitsizearg ;
@@ -470,11 +506,15 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
470
506
471
507
p -> pcre2_compile_context = NULL ;
472
508
509
+ /* pcre2_global_context is initialized in append_grep_pattern */
473
510
if (opt -> ignore_case ) {
474
511
if (!opt -> ignore_locale && has_non_ascii (p -> pattern )) {
475
- character_tables = pcre2_maketables (NULL );
512
+ if (!pcre2_global_context )
513
+ BUG ("pcre2_global_context uninitialized" );
514
+ p -> pcre2_tables = pcre2_maketables (pcre2_global_context );
476
515
p -> pcre2_compile_context = pcre2_compile_context_create (NULL );
477
- pcre2_set_character_tables (p -> pcre2_compile_context , character_tables );
516
+ pcre2_set_character_tables (p -> pcre2_compile_context ,
517
+ p -> pcre2_tables );
478
518
}
479
519
options |= PCRE2_CASELESS ;
480
520
}
@@ -571,6 +611,7 @@ static void free_pcre2_pattern(struct grep_pat *p)
571
611
pcre2_compile_context_free (p -> pcre2_compile_context );
572
612
pcre2_code_free (p -> pcre2_pattern );
573
613
pcre2_match_data_free (p -> pcre2_match_data );
614
+ free ((void * )p -> pcre2_tables );
574
615
}
575
616
#else /* !USE_LIBPCRE2 */
576
617
static void compile_pcre2_pattern (struct grep_pat * p , const struct grep_opt * opt )
0 commit comments