Add "framesize" to pcre2test to display pcre2_match() frame size, using the new 
PCRE2_INFO_FRAMESIZE option for pcre2_pattern_info().

diff --git a/ChangeLog b/ChangeLog
index cbfe783..1893bfe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -52,6 +52,10 @@
 other options were set. An example assertion is (?<!\1(abc)) where the 
 reference \1 precedes the group (abc). This fixes oss-fuzz issue 865.
 
+6. Added the PCRE2_INFO_FRAMESIZE item to pcre2_pattern_info() and arranged for 
+pcre2test to use it to output the frame size when the "framesize" modifier is
+given.
+
 
 Version 10.23 14-February-2017
 ------------------------------
diff --git a/RunTest b/RunTest
index f5b388b..88c6e85 100755
--- a/RunTest
+++ b/RunTest
@@ -463,7 +463,7 @@
 
   if [ $do0 = yes ] ; then
     echo $title0
-    echo '/abc/jit,memory' >testSinput
+    echo '/abc/jit,memory,framesize' >testSinput
     echo '   abc' >>testSinput
     echo '' >testtry
     checkspecial '-C'
diff --git a/src/pcre2.h b/src/pcre2.h
index 4f07bc4..f14fcb2 100644
--- a/src/pcre2.h
+++ b/src/pcre2.h
@@ -295,6 +295,7 @@
 #define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */
 #define PCRE2_INFO_SIZE                 22
 #define PCRE2_INFO_HASBACKSLASHC        23
+#define PCRE2_INFO_FRAMESIZE            24
 
 /* Request types for pcre2_config(). */
 
diff --git a/src/pcre2.h.in b/src/pcre2.h.in
index d007f66..643879f 100644
--- a/src/pcre2.h.in
+++ b/src/pcre2.h.in
@@ -295,6 +295,7 @@
 #define PCRE2_INFO_RECURSIONLIMIT       21  /* Obsolete synonym */
 #define PCRE2_INFO_SIZE                 22
 #define PCRE2_INFO_HASBACKSLASHC        23
+#define PCRE2_INFO_FRAMESIZE            24
 
 /* Request types for pcre2_config(). */
 
diff --git a/src/pcre2_pattern_info.c b/src/pcre2_pattern_info.c
index 98482f9..0392a0b 100644
--- a/src/pcre2_pattern_info.c
+++ b/src/pcre2_pattern_info.c
@@ -97,6 +97,7 @@
 
     case PCRE2_INFO_JITSIZE:
     case PCRE2_INFO_SIZE:
+    case PCRE2_INFO_FRAMESIZE:
     return sizeof(size_t);
 
     case PCRE2_INFO_NAMETABLE:
@@ -157,6 +158,11 @@
     &(re->start_bitmap[0]) : NULL;
   break;
 
+  case PCRE2_INFO_FRAMESIZE:
+  *((size_t *)where) = sizeof(heapframe) +
+    ((re->top_bracket - 1) * 2 * sizeof(PCRE2_SIZE));
+  break;
+
   case PCRE2_INFO_HASBACKSLASHC:
   *((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
   break;
diff --git a/src/pcre2test.c b/src/pcre2test.c
index 8c6cd9d..6c0ee42 100644
--- a/src/pcre2test.c
+++ b/src/pcre2test.c
@@ -422,25 +422,26 @@
 #define CTL_DFA                          0x00000200u
 #define CTL_EXPAND                       0x00000400u
 #define CTL_FINDLIMITS                   0x00000800u
-#define CTL_FULLBINCODE                  0x00001000u
-#define CTL_GETALL                       0x00002000u
-#define CTL_GLOBAL                       0x00004000u
-#define CTL_HEXPAT                       0x00008000u  /* Same word as USE_LENGTH */
-#define CTL_INFO                         0x00010000u
-#define CTL_JITFAST                      0x00020000u
-#define CTL_JITVERIFY                    0x00040000u
-#define CTL_MARK                         0x00080000u
-#define CTL_MEMORY                       0x00100000u
-#define CTL_NULLCONTEXT                  0x00200000u
-#define CTL_POSIX                        0x00400000u
-#define CTL_POSIX_NOSUB                  0x00800000u
-#define CTL_PUSH                         0x01000000u  /* These three must be */
-#define CTL_PUSHCOPY                     0x02000000u  /*   all in the same */
-#define CTL_PUSHTABLESCOPY               0x04000000u  /*     word. */
-#define CTL_STARTCHAR                    0x08000000u
-#define CTL_USE_LENGTH                   0x10000000u  /* Same word as HEXPAT */
-#define CTL_UTF8_INPUT                   0x20000000u
-#define CTL_ZERO_TERMINATE               0x40000000u
+#define CTL_FRAMESIZE                    0x00001000u
+#define CTL_FULLBINCODE                  0x00002000u
+#define CTL_GETALL                       0x00004000u
+#define CTL_GLOBAL                       0x00008000u
+#define CTL_HEXPAT                       0x00010000u  /* Same word as USE_LENGTH */
+#define CTL_INFO                         0x00020000u
+#define CTL_JITFAST                      0x00040000u
+#define CTL_JITVERIFY                    0x00080000u
+#define CTL_MARK                         0x00100000u
+#define CTL_MEMORY                       0x00200000u
+#define CTL_NULLCONTEXT                  0x00400000u
+#define CTL_POSIX                        0x00800000u
+#define CTL_POSIX_NOSUB                  0x01000000u
+#define CTL_PUSH                         0x02000000u  /* These three must be */
+#define CTL_PUSHCOPY                     0x04000000u  /*   all in the same */
+#define CTL_PUSHTABLESCOPY               0x08000000u  /*     word. */
+#define CTL_STARTCHAR                    0x10000000u
+#define CTL_USE_LENGTH                   0x20000000u  /* Same word as HEXPAT */
+#define CTL_UTF8_INPUT                   0x40000000u
+#define CTL_ZERO_TERMINATE               0x80000000u
 
 /* Second control word */
 
@@ -466,6 +467,7 @@
                     CTL_ALLCAPTURES|\
                     CTL_ALLUSEDTEXT|\
                     CTL_ALTGLOBAL|\
+                    CTL_FRAMESIZE|\
                     CTL_GLOBAL|\
                     CTL_MARK|\
                     CTL_MEMORY|\
@@ -575,6 +577,7 @@
   { "extended",                   MOD_PATP, MOD_OPT, PCRE2_EXTENDED,             PO(options) },
   { "find_limits",                MOD_DAT,  MOD_CTL, CTL_FINDLIMITS,             DO(control) },
   { "firstline",                  MOD_PAT,  MOD_OPT, PCRE2_FIRSTLINE,            PO(options) },
+  { "framesize",                  MOD_PD,   MOD_CTL, CTL_FRAMESIZE,              PD(control) },
   { "fullbincode",                MOD_PAT,  MOD_CTL, CTL_FULLBINCODE,            PO(control) },
   { "get",                        MOD_DAT,  MOD_NN,  DO(get_numbers),            DO(get_names) },
   { "getall",                     MOD_DAT,  MOD_CTL, CTL_GETALL,                 DO(control) },
@@ -663,8 +666,8 @@
 
 #define PUSH_SUPPORTED_COMPILE_CONTROLS ( \
   CTL_BINCODE|CTL_CALLOUT_INFO|CTL_FULLBINCODE|CTL_HEXPAT|CTL_INFO| \
-  CTL_JITVERIFY|CTL_MEMORY|CTL_PUSH|CTL_PUSHCOPY|CTL_PUSHTABLESCOPY| \
-  CTL_USE_LENGTH)
+  CTL_JITVERIFY|CTL_MEMORY|CTL_FRAMESIZE|CTL_PUSH|CTL_PUSHCOPY| \
+  CTL_PUSHTABLESCOPY|CTL_USE_LENGTH)
 
 #define PUSH_SUPPORTED_COMPILE_CONTROLS2 (CTL_BSR_SET|CTL_NL_SET)
 
@@ -1366,7 +1369,7 @@
   (test_mode == PCRE8_MODE && G(x,8)->f r (y)) || \
   (test_mode == PCRE16_MODE && G(x,16)->f r (y)) || \
   (test_mode == PCRE32_MODE && G(x,32)->f r (y)))
-  
+
 
 /* ----- Two out of three modes are supported ----- */
 
@@ -1775,7 +1778,7 @@
 #define TESTFLD(x,f,r,y) ( \
   (test_mode == G(G(PCRE,BITONE),_MODE) && G(x,BITONE)->f r (y)) || \
   (test_mode == G(G(PCRE,BITTWO),_MODE) && G(x,BITTWO)->f r (y)))
-  
+
 
 #endif  /* Two out of three modes */
 
@@ -3701,7 +3704,7 @@
 static void
 show_controls(uint32_t controls, uint32_t controls2, const char *before)
 {
-fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+fprintf(outfile, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
   before,
   ((controls & CTL_AFTERTEXT) != 0)? " aftertext" : "",
   ((controls & CTL_ALLAFTERTEXT) != 0)? " allaftertext" : "",
@@ -3716,6 +3719,7 @@
   ((controls & CTL_DFA) != 0)? " dfa" : "",
   ((controls & CTL_EXPAND) != 0)? " expand" : "",
   ((controls & CTL_FINDLIMITS) != 0)? " find_limits" : "",
+  ((controls & CTL_FRAMESIZE) != 0)? " framesize" : "",
   ((controls & CTL_FULLBINCODE) != 0)? " fullbincode" : "",
   ((controls & CTL_GETALL) != 0)? " getall" : "",
   ((controls & CTL_GLOBAL) != 0)? " global" : "",
@@ -3860,6 +3864,20 @@
 
 
 /*************************************************
+*       Show frame size info for a pattern       *
+*************************************************/
+
+static void
+show_framesize(void)
+{
+size_t frame_size;
+(void)pattern_info(PCRE2_INFO_FRAMESIZE, &frame_size, FALSE);
+fprintf(outfile, "Frame size for pcre2_match(): %d\n", (int)frame_size);
+}
+
+
+
+/*************************************************
 *     Callback function for callout enumeration  *
 *************************************************/
 
@@ -4414,6 +4432,7 @@
     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
     }
   if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
+  if ((pat_patctl.control & CTL_FRAMESIZE) != 0) show_framesize();
   if ((pat_patctl.control & CTL_ANYINFO) != 0)
     {
     rc = show_pattern_info();
@@ -5182,6 +5201,7 @@
 /* Output code size and other information if requested. */
 
 if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
+if ((pat_patctl.control & CTL_FRAMESIZE) != 0) show_framesize();
 if ((pat_patctl.control & CTL_ANYINFO) != 0)
   {
   int rc = show_pattern_info();
@@ -6149,16 +6169,16 @@
   if (msg[0] == 0) fprintf(outfile, "\n");
 
   if (dat_datctl.oveccount > 0)
-    { 
+    {
     pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * dat_datctl.oveccount);
     if (pmatch == NULL)
       {
       fprintf(outfile, "** Failed to get memory for recording matching "
         "information (size set = %du)\n", dat_datctl.oveccount);
-      return PR_OK;     
-      }     
-    }   
- 
+      return PR_OK;
+      }
+    }
+
   if ((dat_datctl.options & PCRE2_NOTBOL) != 0) eflags |= REG_NOTBOL;
   if ((dat_datctl.options & PCRE2_NOTEOL) != 0) eflags |= REG_NOTEOL;
   if ((dat_datctl.options & PCRE2_NOTEMPTY) != 0) eflags |= REG_NOTEMPTY;
@@ -6298,9 +6318,9 @@
   {
   fprintf(outfile, "** Failed to get memory for recording matching "
     "information (size requested: %d)\n", dat_datctl.oveccount);
-  max_oveccount = 0;   
-  return PR_OK;     
-  }     
+  max_oveccount = 0;
+  return PR_OK;
+  }
 
 /* Replacement processing is ignored for DFA matching. */