[pcre-dev] [PATCH] Re: External memory allocator interface

Top Page
Delete this message
Author: Roman Rybalko
Date:  
To: pcre-dev
Subject: [pcre-dev] [PATCH] Re: External memory allocator interface
Philip Hazel wrote:
> If it is easy, please send me patches for what you have already done so
> that I can look at them and decide if I like them. :-) I want to check
> the impact on exising uses of PCRE that do not need to use this extra
> feature.
>

Here it is.
Without any build-system integration.

--
WBR,
Roman Rybalko

diff -urN pcre-7.7.orig/pcre_compile.c pcre-7.7/pcre_compile.c
--- pcre-7.7.orig/pcre_compile.c    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_compile.c    2008-06-10 12:08:08.000000000 +0400
@@ -5953,9 +5953,30 @@



PCRE_EXP_DEFN pcre *
+pcre_mm_compile(const pcre_mm *mm, const char *pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+{
+return pcre_mm_compile2(mm, pattern, options, NULL, errorptr, erroroffset, tables);
+}
+
+
+PCRE_EXP_DEFN pcre *
pcre_compile2(const char *pattern, int options, int *errorcodeptr,
const char **errorptr, int *erroroffset, const unsigned char *tables)
{
+pcre_mm a_mm;
+memset(&a_mm, 0, sizeof(a_mm));
+a_mm.malloc = _pcre_default_malloc;
+a_mm.free = _pcre_default_free;
+
+return pcre_mm_compile2(&a_mm, pattern, options, errorcodeptr, errorptr, erroroffset, tables);
+}
+
+
+PCRE_EXP_DEFN pcre *
+pcre_mm_compile2(const pcre_mm *mm, const char *pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+{
real_pcre *re;
int length = 1; /* For final END opcode */
int firstbyte, reqbyte, newline;
@@ -6181,7 +6202,7 @@
cd->name_entry_size. */

size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
-re = (real_pcre *)(pcre_malloc)(size);
+re = (real_pcre *)pcre_mm_malloc(mm, size);

if (re == NULL)
{
@@ -6277,7 +6298,7 @@

if (errorcode != 0)
{
- (pcre_free)(re);
+ pcre_mm_free(mm, re);
PCRE_EARLY_ERROR_RETURN:
*erroroffset = ptr - (const uschar *)pattern;
PCRE_EARLY_ERROR_RETURN2:
@@ -6365,7 +6386,7 @@

 if (code - codestart > length)
   {
-  (pcre_free)(re);
+  pcre_mm_free(mm, re);
   *errorptr = find_error_text(ERR23);
   *erroroffset = ptr - (uschar *)pattern;
   if (errorcodeptr != NULL) *errorcodeptr = ERR23;
diff -urN pcre-7.7.orig/pcre_exec.c pcre-7.7/pcre_exec.c
--- pcre-7.7.orig/pcre_exec.c    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_exec.c    2008-06-10 14:31:32.000000000 +0400
@@ -1020,7 +1020,7 @@
       else
         {
         new_recursive.offset_save =
-          (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
+          (int *)pcre_mm_malloc(md->mm, new_recursive.saved_max * sizeof(int));
         if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
         }


@@ -1043,7 +1043,7 @@
           DPRINTF(("Recursion matched\n"));
           md->recursive = new_recursive.prevrec;
           if (new_recursive.offset_save != stacksave)
-            (pcre_free)(new_recursive.offset_save);
+            pcre_mm_free(md->mm, new_recursive.offset_save);
           RRETURN(MATCH_MATCH);
           }
         else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
@@ -1062,7 +1062,7 @@
       DPRINTF(("Recursion didn't match\n"));
       md->recursive = new_recursive.prevrec;
       if (new_recursive.offset_save != stacksave)
-        (pcre_free)(new_recursive.offset_save);
+        pcre_mm_free(md->mm, new_recursive.offset_save);
       RRETURN(MATCH_NOMATCH);
       }
     /* Control never reaches here */
@@ -4365,6 +4365,19 @@
   PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
   int offsetcount)
 {
+pcre_mm a_mm;
+memset(&a_mm, 0, sizeof(a_mm));
+a_mm.malloc = _pcre_default_malloc;
+a_mm.free = _pcre_default_free;
+return pcre_mm_exec(&a_mm, argument_re, extra_data, subject, length, start_offset, options, offsets, offsetcount);
+}
+
+
+PCRE_EXP_DEFN int
+pcre_mm_exec(const pcre_mm *mm, const pcre *argument_re, const pcre_extra *extra_data,
+  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
+  int offsetcount)
+{
 int rc, resetcount, ocount;
 int first_byte = -1;
 int req_byte = -1;
@@ -4400,6 +4413,9 @@
    (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
 if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;


+/* The MM data */
+md->mm = mm;
+
/* Fish out the optional data from the extra_data structure, first setting
the default values. */

@@ -4583,7 +4599,7 @@
 if (re->top_backref > 0 && re->top_backref >= ocount/3)
   {
   ocount = re->top_backref * 3 + 3;
-  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
+  md->offset_vector = (int *)pcre_mm_malloc(mm, ocount * sizeof(int));
   if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
   using_temporary_offsets = TRUE;
   DPRINTF(("Got memory to hold back references\n"));
@@ -4902,7 +4918,7 @@
       }
     if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
     DPRINTF(("Freeing temporary memory\n"));
-    (pcre_free)(md->offset_vector);
+    pcre_mm_free(mm, md->offset_vector);
     }


/* Set the return code to the number of captured strings, or 0 if there are
@@ -4930,7 +4946,7 @@
if (using_temporary_offsets)
{
DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
+ pcre_mm_free(mm, md->offset_vector);
}

 if (rc != MATCH_NOMATCH)
diff -urN pcre-7.7.orig/pcre_internal.h pcre-7.7/pcre_internal.h
--- pcre-7.7.orig/pcre_internal.h    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_internal.h    2008-06-10 14:31:32.000000000 +0400
@@ -230,6 +230,7 @@
 values. */


#include "pcre.h"
+#include "pcre_mm.h"
#include "ucp.h"

 /* When compiling for use with the Virtual Pascal compiler, these functions
@@ -1033,6 +1034,7 @@
   int    eptrn;                 /* Next free eptrblock */
   recursion_info *recursive;    /* Linked list of recursion data */
   void  *callout_data;          /* To pass back to callouts */
+  const pcre_mm *mm;            /* MM data (malloc/free) */
 } match_data;


 /* A similar structure is used for the same purpose by the DFA matching
@@ -1133,6 +1135,10 @@
                       int *, BOOL);
 extern BOOL         _pcre_xclass(int, const uschar *);


+/* Default mm system wtappers */
+void *_pcre_default_malloc(void *_stub_ctx, size_t);
+void _pcre_default_free(void *_stub_ctx, void *);
+
#endif

 /* End of pcre_internal.h */
diff -urN pcre-7.7.orig/pcre_mm.c pcre-7.7/pcre_mm.c
--- pcre-7.7.orig/pcre_mm.c    1970-01-01 03:00:00.000000000 +0300
+++ pcre-7.7/pcre_mm.c    2008-07-02 12:33:17.000000000 +0400
@@ -0,0 +1,81 @@
+/*************************************************
+*      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
+           Copyright (c) 1997-2008 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains mm functions. */
+
+
+#ifndef DFTABLES
+#  ifdef HAVE_CONFIG_H
+#  include "config.h"
+#  endif
+#  include "pcre_internal.h"
+#endif
+
+#include <assert.h>
+
+void *_pcre_default_malloc(void *_stub_ctx, size_t size)
+{
+return pcre_malloc(size);
+}
+
+
+void _pcre_default_free(void *_stub_ctx, void *ptr)
+{
+return pcre_free(ptr);
+}
+
+
+PCRE_EXP_DECL void *pcre_mm_malloc(const pcre_mm *mm, size_t size)
+{
+assert(mm);
+assert(mm->malloc);
+return (mm->malloc)(mm->ctx, size);
+}
+
+
+PCRE_EXP_DECL void  pcre_mm_free(const pcre_mm *mm, void *ptr)
+{
+assert(mm);
+assert(mm->free);
+return (mm->free)(mm->ctx, ptr);
+}
+
+
+/* End of pcre_mm.c */
diff -urN pcre-7.7.orig/pcre_mm.h pcre-7.7/pcre_mm.h
--- pcre-7.7.orig/pcre_mm.h    1970-01-01 03:00:00.000000000 +0300
+++ pcre-7.7/pcre_mm.h    2008-07-02 12:33:17.000000000 +0400
@@ -0,0 +1,98 @@
+/*************************************************
+*       Perl-Compatible Regular Expressions      *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+           Copyright (c) 1997-2008 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.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_MM_H
+#define _PCRE_MM_H
+
+#include "pcre.h"
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Types */
+
+/* The structure with memory management functions */
+
+typedef struct pcre_mm {
+  void *(*malloc)(void *ctx, size_t);
+  void  (*free)(void *ctx, void*);
+  void *ctx;
+} pcre_mm;
+
+
+/* Memory management functions */
+
+PCRE_EXP_DECL void *pcre_mm_malloc(const pcre_mm *, size_t);
+PCRE_EXP_DECL void pcre_mm_free(const pcre_mm *, void *);
+//PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
+//PCRE_EXP_DECL void  (*pcre_stack_free)(void *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_mm_compile(const pcre_mm *, const char *, int, const char **, int *,
+                  const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_mm_compile2(const pcre_mm *, const char *, int, int *, const char **,
+                  int *, const unsigned char *);
+/*PCRE_EXP_DECL int  pcre_mm_copy_named_substring(const pcre_mm *, const pcre *, const char *,
+                  int *, int, const char *, char *, int);*/
+/*PCRE_EXP_DECL int  pcre_mm_copy_substring(const pcre_mm *, const char *, int *, int, int, char *,
+                  int);*/
+/*PCRE_EXP_DECL int  pcre_mm_dfa_exec(const pcre_mm *, const pcre *, const pcre_extra *,
+                  const char *, int, int, int, int *, int , int *, int);*/
+PCRE_EXP_DECL int  pcre_mm_exec(const pcre_mm *, const pcre *, const pcre_extra *, PCRE_SPTR,
+                   int, int, int, int *, int);
+/*PCRE_EXP_DECL void pcre_mm_free_substring(const pcre_mm *, const pcre *, const char *);*/
+/*PCRE_EXP_DECL void pcre_mm_free_substring_list(const pcre_mm *, const pcre *, const char **);*/
+/*PCRE_EXP_DECL int  pcre_mm_fullinfo(const pcre_mm *, const pcre *, const pcre_extra *, int,
+                  void *);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_named_substring(const pcre_mm *, const pcre *, const char *,
+                  int *, int, const char *, const char **);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_stringnumber(const pcre_mm *, const pcre *, const char *);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_stringtable_entries(const pcre_mm *, const pcre *, const char *,
+                  char **, char **);*/
+/*PCRE_EXP_DECL const unsigned char *pcre_maketables(pcre_mm *);*/
+/*PCRE_EXP_DECL pcre_extra *pcre_study(const pcre_mm *, const pcre *, int, const char **);*/
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* _PCRE_MM_H */