@@ -40,20 +40,6 @@ static struct grep_opt grep_defaults = {
4040 .output = std_output ,
4141};
4242
43- #ifdef USE_LIBPCRE2
44- static pcre2_general_context * pcre2_global_context ;
45-
46- static void * pcre2_malloc (PCRE2_SIZE size , MAYBE_UNUSED void * memory_data )
47- {
48- return malloc (size );
49- }
50-
51- static void pcre2_free (void * pointer , MAYBE_UNUSED void * memory_data )
52- {
53- free (pointer );
54- }
55- #endif
56-
5743static const char * color_grep_slots [] = {
5844 [GREP_COLOR_CONTEXT ] = "context" ,
5945 [GREP_COLOR_FILENAME ] = "filename" ,
@@ -152,20 +138,9 @@ int grep_config(const char *var, const char *value, void *cb)
152138 * Initialize one instance of grep_opt and copy the
153139 * default values from the template we read the configuration
154140 * information in an earlier call to git_config(grep_config).
155- *
156- * If using PCRE, make sure that the library is configured
157- * to use the same allocator as Git (e.g. nedmalloc on Windows).
158- *
159- * Any allocated memory needs to be released in grep_destroy().
160141 */
161142void grep_init (struct grep_opt * opt , struct repository * repo , const char * prefix )
162143{
163- #if defined(USE_LIBPCRE2 )
164- if (!pcre2_global_context )
165- pcre2_global_context = pcre2_general_context_create (
166- pcre2_malloc , pcre2_free , NULL );
167- #endif
168-
169144 * opt = grep_defaults ;
170145
171146 opt -> repo = repo ;
@@ -175,13 +150,6 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix
175150 opt -> header_tail = & opt -> header_list ;
176151}
177152
178- void grep_destroy (void )
179- {
180- #ifdef USE_LIBPCRE2
181- pcre2_general_context_free (pcre2_global_context );
182- #endif
183- }
184-
185153static void grep_set_pattern_type_option (enum grep_pattern_type pattern_type , struct grep_opt * opt )
186154{
187155 /*
@@ -363,6 +331,28 @@ static int is_fixed(const char *s, size_t len)
363331}
364332
365333#ifdef USE_LIBPCRE2
334+ #define GREP_PCRE2_DEBUG_MALLOC 0
335+
336+ static void * pcre2_malloc (PCRE2_SIZE size , MAYBE_UNUSED void * memory_data )
337+ {
338+ void * pointer = malloc (size );
339+ #if GREP_PCRE2_DEBUG_MALLOC
340+ static int count = 1 ;
341+ fprintf (stderr , "PCRE2:%p -> #%02d: alloc(%lu)\n" , pointer , count ++ , size );
342+ #endif
343+ return pointer ;
344+ }
345+
346+ static void pcre2_free (void * pointer , MAYBE_UNUSED void * memory_data )
347+ {
348+ #if GREP_PCRE2_DEBUG_MALLOC
349+ static int count = 1 ;
350+ if (pointer )
351+ fprintf (stderr , "PCRE2:%p -> #%02d: free()\n" , pointer , count ++ );
352+ #endif
353+ free (pointer );
354+ }
355+
366356static void compile_pcre2_pattern (struct grep_pat * p , const struct grep_opt * opt )
367357{
368358 int error ;
@@ -373,17 +363,20 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
373363 int patinforet ;
374364 size_t jitsizearg ;
375365
376- assert (opt -> pcre2 );
377-
378- p -> pcre2_compile_context = NULL ;
366+ /*
367+ * Call pcre2_general_context_create() before calling any
368+ * other pcre2_*(). It sets up our malloc()/free() functions
369+ * with which everything else is allocated.
370+ */
371+ p -> pcre2_general_context = pcre2_general_context_create (
372+ pcre2_malloc , pcre2_free , NULL );
373+ if (!p -> pcre2_general_context )
374+ die ("Couldn't allocate PCRE2 general context" );
379375
380- /* pcre2_global_context is initialized in append_grep_pattern */
381376 if (opt -> ignore_case ) {
382377 if (!opt -> ignore_locale && has_non_ascii (p -> pattern )) {
383- if (!pcre2_global_context )
384- BUG ("pcre2_global_context uninitialized" );
385- p -> pcre2_tables = pcre2_maketables (pcre2_global_context );
386- p -> pcre2_compile_context = pcre2_compile_context_create (NULL );
378+ p -> pcre2_tables = pcre2_maketables (p -> pcre2_general_context );
379+ p -> pcre2_compile_context = pcre2_compile_context_create (p -> pcre2_general_context );
387380 pcre2_set_character_tables (p -> pcre2_compile_context ,
388381 p -> pcre2_tables );
389382 }
@@ -393,28 +386,18 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
393386 !(!opt -> ignore_case && (p -> fixed || p -> is_fixed )))
394387 options |= (PCRE2_UTF | PCRE2_MATCH_INVALID_UTF );
395388
389+ #ifdef GIT_PCRE2_VERSION_10_36_OR_HIGHER
396390 /* Work around https://bugs.exim.org/show_bug.cgi?id=2642 fixed in 10.36 */
397- if (PCRE2_MATCH_INVALID_UTF && options & (PCRE2_UTF | PCRE2_CASELESS )) {
398- struct strbuf buf ;
399- int len ;
400- int err ;
401-
402- if ((len = pcre2_config (PCRE2_CONFIG_VERSION , NULL )) < 0 )
403- BUG ("pcre2_config(..., NULL) failed: %d" , len );
404- strbuf_init (& buf , len + 1 );
405- if ((err = pcre2_config (PCRE2_CONFIG_VERSION , buf .buf )) < 0 )
406- BUG ("pcre2_config(..., buf.buf) failed: %d" , err );
407- if (versioncmp (buf .buf , "10.36" ) < 0 )
408- options |= PCRE2_NO_START_OPTIMIZE ;
409- strbuf_release (& buf );
410- }
391+ if (PCRE2_MATCH_INVALID_UTF && options & (PCRE2_UTF | PCRE2_CASELESS ))
392+ options |= PCRE2_NO_START_OPTIMIZE ;
393+ #endif
411394
412395 p -> pcre2_pattern = pcre2_compile ((PCRE2_SPTR )p -> pattern ,
413396 p -> patternlen , options , & error , & erroffset ,
414397 p -> pcre2_compile_context );
415398
416399 if (p -> pcre2_pattern ) {
417- p -> pcre2_match_data = pcre2_match_data_create_from_pattern (p -> pcre2_pattern , NULL );
400+ p -> pcre2_match_data = pcre2_match_data_create_from_pattern (p -> pcre2_pattern , p -> pcre2_general_context );
418401 if (!p -> pcre2_match_data )
419402 die ("Couldn't allocate PCRE2 match data" );
420403 } else {
@@ -493,7 +476,12 @@ static void free_pcre2_pattern(struct grep_pat *p)
493476 pcre2_compile_context_free (p -> pcre2_compile_context );
494477 pcre2_code_free (p -> pcre2_pattern );
495478 pcre2_match_data_free (p -> pcre2_match_data );
479+ #ifdef GIT_PCRE2_VERSION_10_34_OR_HIGHER
480+ pcre2_maketables_free (p -> pcre2_general_context , p -> pcre2_tables );
481+ #else
496482 free ((void * )p -> pcre2_tables );
483+ #endif
484+ pcre2_general_context_free (p -> pcre2_general_context );
497485}
498486#else /* !USE_LIBPCRE2 */
499487static void compile_pcre2_pattern (struct grep_pat * p , const struct grep_opt * opt )
@@ -555,7 +543,6 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
555543#endif
556544 if (p -> fixed || p -> is_fixed ) {
557545#ifdef USE_LIBPCRE2
558- opt -> pcre2 = 1 ;
559546 if (p -> is_fixed ) {
560547 compile_pcre2_pattern (p , opt );
561548 } else {
0 commit comments