489 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			489 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*************************************************
 | ||
|  | *      Perl-Compatible Regular Expressions       * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | /* PCRE is a library of functions to support regular expressions whose syntax
 | ||
|  | and semantics are as close as possible to those of the Perl 5 language. | ||
|  | 
 | ||
|  |                        Written by Philip Hazel | ||
|  |      Original API code Copyright (c) 1997-2012 University of Cambridge | ||
|  |           New API code Copyright (c) 2016-2018 University of Cambridge | ||
|  | 
 | ||
|  | ----------------------------------------------------------------------------- | ||
|  | Redistribution and use in source and binary forms, with or without | ||
|  | modification, are permitted provided that the following conditions are met: | ||
|  | 
 | ||
|  |     * Redistributions of source code must retain the above copyright notice, | ||
|  |       this list of conditions and the following disclaimer. | ||
|  | 
 | ||
|  |     * Redistributions in binary form must reproduce the above copyright | ||
|  |       notice, this list of conditions and the following disclaimer in the | ||
|  |       documentation and/or other materials provided with the distribution. | ||
|  | 
 | ||
|  |     * Neither the name of the University of Cambridge nor the names of its | ||
|  |       contributors may be used to endorse or promote products derived from | ||
|  |       this software without specific prior written permission. | ||
|  | 
 | ||
|  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
|  | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
|  | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
|  | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
|  | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
|  | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
|  | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
|  | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
|  | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
|  | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
|  | POSSIBILITY OF SUCH DAMAGE. | ||
|  | ----------------------------------------------------------------------------- | ||
|  | */ | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifdef HAVE_CONFIG_H
 | ||
|  | #include "config.h"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #include "pcre2_internal.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *          Default malloc/free functions         * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | /* Ignore the "user data" argument in each case. */ | ||
|  | 
 | ||
|  | static void *default_malloc(size_t size, void *data) | ||
|  | { | ||
|  | (void)data; | ||
|  | return malloc(size); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static void default_free(void *block, void *data) | ||
|  | { | ||
|  | (void)data; | ||
|  | free(block); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *        Get a block and save memory control     * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | /* This internal function is called to get a block of memory in which the
 | ||
|  | memory control data is to be stored at the start for future use. | ||
|  | 
 | ||
|  | Arguments: | ||
|  |   size        amount of memory required | ||
|  |   memctl      pointer to a memctl block or NULL | ||
|  | 
 | ||
|  | Returns:      pointer to memory or NULL on failure | ||
|  | */ | ||
|  | 
 | ||
|  | extern void * | ||
|  | PRIV(memctl_malloc)(size_t size, pcre2_memctl *memctl) | ||
|  | { | ||
|  | pcre2_memctl *newmemctl; | ||
|  | void *yield = (memctl == NULL)? malloc(size) : | ||
|  |   memctl->malloc(size, memctl->memory_data); | ||
|  | if (yield == NULL) return NULL; | ||
|  | newmemctl = (pcre2_memctl *)yield; | ||
|  | if (memctl == NULL) | ||
|  |   { | ||
|  |   newmemctl->malloc = default_malloc; | ||
|  |   newmemctl->free = default_free; | ||
|  |   newmemctl->memory_data = NULL; | ||
|  |   } | ||
|  | else *newmemctl = *memctl; | ||
|  | return yield; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *          Create and initialize contexts        * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | /* Initializing for compile and match contexts is done in separate, private
 | ||
|  | functions so that these can be called from functions such as pcre2_compile() | ||
|  | when an external context is not supplied. The initializing functions have an | ||
|  | option to set up default memory management. */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_general_context_create(void *(*private_malloc)(size_t, void *), | ||
|  |   void (*private_free)(void *, void *), void *memory_data) | ||
|  | { | ||
|  | pcre2_general_context *gcontext; | ||
|  | if (private_malloc == NULL) private_malloc = default_malloc; | ||
|  | if (private_free == NULL) private_free = default_free; | ||
|  | gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data); | ||
|  | if (gcontext == NULL) return NULL; | ||
|  | gcontext->memctl.malloc = private_malloc; | ||
|  | gcontext->memctl.free = private_free; | ||
|  | gcontext->memctl.memory_data = memory_data; | ||
|  | return gcontext; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /* A default compile context is set up to save having to initialize at run time
 | ||
|  | when no context is supplied to the compile function. */ | ||
|  | 
 | ||
|  | const pcre2_compile_context PRIV(default_compile_context) = { | ||
|  |   { default_malloc, default_free, NULL },    /* Default memory handling */ | ||
|  |   NULL,                                      /* Stack guard */ | ||
|  |   NULL,                                      /* Stack guard data */ | ||
|  |   PRIV(default_tables),                      /* Character tables */ | ||
|  |   PCRE2_UNSET,                               /* Max pattern length */ | ||
|  |   BSR_DEFAULT,                               /* Backslash R default */ | ||
|  |   NEWLINE_DEFAULT,                           /* Newline convention */ | ||
|  |   PARENS_NEST_LIMIT,                         /* As it says */ | ||
|  |   0 };                                       /* Extra options */ | ||
|  | 
 | ||
|  | /* The create function copies the default into the new memory, but must
 | ||
|  | override the default memory handling functions if a gcontext was provided. */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_compile_context_create(pcre2_general_context *gcontext) | ||
|  | { | ||
|  | pcre2_compile_context *ccontext = PRIV(memctl_malloc)( | ||
|  |   sizeof(pcre2_real_compile_context), (pcre2_memctl *)gcontext); | ||
|  | if (ccontext == NULL) return NULL; | ||
|  | *ccontext = PRIV(default_compile_context); | ||
|  | if (gcontext != NULL) | ||
|  |   *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext); | ||
|  | return ccontext; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /* A default match context is set up to save having to initialize at run time
 | ||
|  | when no context is supplied to a match function. */ | ||
|  | 
 | ||
|  | const pcre2_match_context PRIV(default_match_context) = { | ||
|  |   { default_malloc, default_free, NULL }, | ||
|  | #ifdef SUPPORT_JIT
 | ||
|  |   NULL,          /* JIT callback */ | ||
|  |   NULL,          /* JIT callback data */ | ||
|  | #endif
 | ||
|  |   NULL,          /* Callout function */ | ||
|  |   NULL,          /* Callout data */ | ||
|  |   NULL,          /* Substitute callout function */ | ||
|  |   NULL,          /* Substitute callout data */ | ||
|  |   PCRE2_UNSET,   /* Offset limit */ | ||
|  |   HEAP_LIMIT, | ||
|  |   MATCH_LIMIT, | ||
|  |   MATCH_LIMIT_DEPTH }; | ||
|  | 
 | ||
|  | /* The create function copies the default into the new memory, but must
 | ||
|  | override the default memory handling functions if a gcontext was provided. */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_match_context_create(pcre2_general_context *gcontext) | ||
|  | { | ||
|  | pcre2_match_context *mcontext = PRIV(memctl_malloc)( | ||
|  |   sizeof(pcre2_real_match_context), (pcre2_memctl *)gcontext); | ||
|  | if (mcontext == NULL) return NULL; | ||
|  | *mcontext = PRIV(default_match_context); | ||
|  | if (gcontext != NULL) | ||
|  |   *((pcre2_memctl *)mcontext) = *((pcre2_memctl *)gcontext); | ||
|  | return mcontext; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /* A default convert context is set up to save having to initialize at run time
 | ||
|  | when no context is supplied to the convert function. */ | ||
|  | 
 | ||
|  | const pcre2_convert_context PRIV(default_convert_context) = { | ||
|  |   { default_malloc, default_free, NULL },    /* Default memory handling */ | ||
|  | #ifdef _WIN32
 | ||
|  |   CHAR_BACKSLASH,                            /* Default path separator */ | ||
|  |   CHAR_GRAVE_ACCENT                          /* Default escape character */ | ||
|  | #else  /* Not Windows */
 | ||
|  |   CHAR_SLASH,                                /* Default path separator */ | ||
|  |   CHAR_BACKSLASH                             /* Default escape character */ | ||
|  | #endif
 | ||
|  |   }; | ||
|  | 
 | ||
|  | /* The create function copies the default into the new memory, but must
 | ||
|  | override the default memory handling functions if a gcontext was provided. */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_convert_context_create(pcre2_general_context *gcontext) | ||
|  | { | ||
|  | pcre2_convert_context *ccontext = PRIV(memctl_malloc)( | ||
|  |   sizeof(pcre2_real_convert_context), (pcre2_memctl *)gcontext); | ||
|  | if (ccontext == NULL) return NULL; | ||
|  | *ccontext = PRIV(default_convert_context); | ||
|  | if (gcontext != NULL) | ||
|  |   *((pcre2_memctl *)ccontext) = *((pcre2_memctl *)gcontext); | ||
|  | return ccontext; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *              Context copy functions            * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_general_context_copy(pcre2_general_context *gcontext) | ||
|  | { | ||
|  | pcre2_general_context *new = | ||
|  |   gcontext->memctl.malloc(sizeof(pcre2_real_general_context), | ||
|  |   gcontext->memctl.memory_data); | ||
|  | if (new == NULL) return NULL; | ||
|  | memcpy(new, gcontext, sizeof(pcre2_real_general_context)); | ||
|  | return new; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_compile_context_copy(pcre2_compile_context *ccontext) | ||
|  | { | ||
|  | pcre2_compile_context *new = | ||
|  |   ccontext->memctl.malloc(sizeof(pcre2_real_compile_context), | ||
|  |   ccontext->memctl.memory_data); | ||
|  | if (new == NULL) return NULL; | ||
|  | memcpy(new, ccontext, sizeof(pcre2_real_compile_context)); | ||
|  | return new; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_match_context_copy(pcre2_match_context *mcontext) | ||
|  | { | ||
|  | pcre2_match_context *new = | ||
|  |   mcontext->memctl.malloc(sizeof(pcre2_real_match_context), | ||
|  |   mcontext->memctl.memory_data); | ||
|  | if (new == NULL) return NULL; | ||
|  | memcpy(new, mcontext, sizeof(pcre2_real_match_context)); | ||
|  | return new; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION | ||
|  | pcre2_convert_context_copy(pcre2_convert_context *ccontext) | ||
|  | { | ||
|  | pcre2_convert_context *new = | ||
|  |   ccontext->memctl.malloc(sizeof(pcre2_real_convert_context), | ||
|  |   ccontext->memctl.memory_data); | ||
|  | if (new == NULL) return NULL; | ||
|  | memcpy(new, ccontext, sizeof(pcre2_real_convert_context)); | ||
|  | return new; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *              Context free functions            * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION | ||
|  | pcre2_general_context_free(pcre2_general_context *gcontext) | ||
|  | { | ||
|  | if (gcontext != NULL) | ||
|  |   gcontext->memctl.free(gcontext, gcontext->memctl.memory_data); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION | ||
|  | pcre2_compile_context_free(pcre2_compile_context *ccontext) | ||
|  | { | ||
|  | if (ccontext != NULL) | ||
|  |   ccontext->memctl.free(ccontext, ccontext->memctl.memory_data); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION | ||
|  | pcre2_match_context_free(pcre2_match_context *mcontext) | ||
|  | { | ||
|  | if (mcontext != NULL) | ||
|  |   mcontext->memctl.free(mcontext, mcontext->memctl.memory_data); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION | ||
|  | pcre2_convert_context_free(pcre2_convert_context *ccontext) | ||
|  | { | ||
|  | if (ccontext != NULL) | ||
|  |   ccontext->memctl.free(ccontext, ccontext->memctl.memory_data); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*************************************************
 | ||
|  | *             Set values in contexts             * | ||
|  | *************************************************/ | ||
|  | 
 | ||
|  | /* All these functions return 0 for success or PCRE2_ERROR_BADDATA if invalid
 | ||
|  | data is given. Only some of the functions are able to test the validity of the | ||
|  | data. */ | ||
|  | 
 | ||
|  | 
 | ||
|  | /* ------------ Compile context ------------ */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_character_tables(pcre2_compile_context *ccontext, | ||
|  |   const uint8_t *tables) | ||
|  | { | ||
|  | ccontext->tables = tables; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_bsr(pcre2_compile_context *ccontext, uint32_t value) | ||
|  | { | ||
|  | switch(value) | ||
|  |   { | ||
|  |   case PCRE2_BSR_ANYCRLF: | ||
|  |   case PCRE2_BSR_UNICODE: | ||
|  |   ccontext->bsr_convention = value; | ||
|  |   return 0; | ||
|  | 
 | ||
|  |   default: | ||
|  |   return PCRE2_ERROR_BADDATA; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_max_pattern_length(pcre2_compile_context *ccontext, PCRE2_SIZE length) | ||
|  | { | ||
|  | ccontext->max_pattern_length = length; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline) | ||
|  | { | ||
|  | switch(newline) | ||
|  |   { | ||
|  |   case PCRE2_NEWLINE_CR: | ||
|  |   case PCRE2_NEWLINE_LF: | ||
|  |   case PCRE2_NEWLINE_CRLF: | ||
|  |   case PCRE2_NEWLINE_ANY: | ||
|  |   case PCRE2_NEWLINE_ANYCRLF: | ||
|  |   case PCRE2_NEWLINE_NUL: | ||
|  |   ccontext->newline_convention = newline; | ||
|  |   return 0; | ||
|  | 
 | ||
|  |   default: | ||
|  |   return PCRE2_ERROR_BADDATA; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit) | ||
|  | { | ||
|  | ccontext->parens_nest_limit = limit; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_compile_extra_options(pcre2_compile_context *ccontext, uint32_t options) | ||
|  | { | ||
|  | ccontext->extra_options = options; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext, | ||
|  |   int (*guard)(uint32_t, void *), void *user_data) | ||
|  | { | ||
|  | ccontext->stack_guard = guard; | ||
|  | ccontext->stack_guard_data = user_data; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /* ------------ Match context ------------ */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_callout(pcre2_match_context *mcontext, | ||
|  |   int (*callout)(pcre2_callout_block *, void *), void *callout_data) | ||
|  | { | ||
|  | mcontext->callout = callout; | ||
|  | mcontext->callout_data = callout_data; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_substitute_callout(pcre2_match_context *mcontext, | ||
|  |   int (*substitute_callout)(pcre2_substitute_callout_block *, void *), | ||
|  |     void *substitute_callout_data) | ||
|  | { | ||
|  | mcontext->substitute_callout = substitute_callout; | ||
|  | mcontext->substitute_callout_data = substitute_callout_data; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit) | ||
|  | { | ||
|  | mcontext->heap_limit = limit; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_match_limit(pcre2_match_context *mcontext, uint32_t limit) | ||
|  | { | ||
|  | mcontext->match_limit = limit; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_depth_limit(pcre2_match_context *mcontext, uint32_t limit) | ||
|  | { | ||
|  | mcontext->depth_limit = limit; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_offset_limit(pcre2_match_context *mcontext, PCRE2_SIZE limit) | ||
|  | { | ||
|  | mcontext->offset_limit = limit; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* This function became obsolete at release 10.30. It is kept as a synonym for
 | ||
|  | backwards compatibility. */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit) | ||
|  | { | ||
|  | return pcre2_set_depth_limit(mcontext, limit); | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_recursion_memory_management(pcre2_match_context *mcontext, | ||
|  |   void *(*mymalloc)(size_t, void *), void (*myfree)(void *, void *), | ||
|  |   void *mydata) | ||
|  | { | ||
|  | (void)mcontext; | ||
|  | (void)mymalloc; | ||
|  | (void)myfree; | ||
|  | (void)mydata; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* ------------ Convert context ------------ */ | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_glob_separator(pcre2_convert_context *ccontext, uint32_t separator) | ||
|  | { | ||
|  | if (separator != CHAR_SLASH && separator != CHAR_BACKSLASH && | ||
|  |     separator != CHAR_DOT) return PCRE2_ERROR_BADDATA; | ||
|  | ccontext->glob_separator = separator; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION | ||
|  | pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape) | ||
|  | { | ||
|  | if (escape > 255 || (escape != 0 && !ispunct(escape))) | ||
|  |   return PCRE2_ERROR_BADDATA; | ||
|  | ccontext->glob_escape = escape; | ||
|  | return 0; | ||
|  | } | ||
|  | 
 | ||
|  | /* End of pcre2_context.c */ | ||
|  | 
 |