Rework diagnostics in the regex engine
authorYves Orton <demerphq@gmail.com>
Fri, 11 Mar 2016 09:36:25 +0000 (10:36 +0100)
committerYves Orton <demerphq@gmail.com>
Sun, 13 Mar 2016 11:39:23 +0000 (12:39 +0100)
This introduces three new subs:

Perl_re_printf() which is a wrapper for

    PerlIO_printf( Perl_debug_log, ... ),

which cuts down on clutter in the code. Arguably this could be moved
to util.c and renamed something like PerlIO_debugf() and then we could
declutter all the statements that write to the Perl_debug_log
filehandle. But that is a bit too ambituous for me right now, so
I leave this as a regex engine only sub for now.

Perl_re_indentf() which is a wrapper for PerlIO_re_printf(),
which adds an indent argument and automatically indents the
line appropriately, and is used in regcomp.c for trace diagnostics
during compilation.

Perl_re_indentfo() which is similar to Perl_re_indentf() but
is used in regexec.c which adds a specific prefix to each indented
line to account for the fact that during execution we normally have
string position information on the left.

The end result of this patch is that a lot of clutter in the debugging
statements in the regex engine is reduced, exposing what is actually
going on. It should also now be easier to add new diagnostics which
"do the right thing".

Over time the debugging trace output in regexec has become
very cluttered and confusing. This patch cleans much of it up,
if something happens at a given recursion depth it is output
at the right depth, etc, and formats have been changed to not have
leading spaces so you can actually see the indentation properly.

embed.fnc
embed.h
proto.h
regcomp.c
regexec.c

index f918622..7ce99fd 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -2118,6 +2118,7 @@ p |OP *   |tied_method|NN SV *methname|NN SV **sp \
 #if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
 Ep     |void   |regprop        |NULLOK const regexp *prog|NN SV* sv|NN const regnode* o|NULLOK const regmatch_info *reginfo \
                                |NULLOK const RExC_state_t *pRExC_state
+Epno   |int    |re_printf      |NN const char *fmt|...
 #endif
 #if defined(PERL_IN_REGCOMP_C)
 Es     |regnode*|reg           |NN RExC_state_t *pRExC_state \
@@ -2264,6 +2265,7 @@ EnPs      |int    |edit_distance  |NN const UV *src                   \
                                |const STRLEN y                     \
                                |const SSize_t maxDistance
 #  ifdef DEBUGGING
+Epno   |int    |re_indentf     |NN const char *fmt|U32 depth|...
 Es        |void        |regdump_intflags|NULLOK const char *lead| const U32 flags
 Es     |void   |regdump_extflags|NULLOK const char *lead| const U32 flags
 Es     |const regnode*|dumpuntil|NN const regexp *r|NN const regnode *start \
@@ -2375,10 +2377,12 @@ EsR     |WB_enum|backup_one_WB  |NN WB_enum * previous                  \
                                |const bool utf8_target
 #  ifdef DEBUGGING
 Es     |void   |dump_exec_pos  |NN const char *locinput|NN const regnode *scan|NN const char *loc_regeol\
-                               |NN const char *loc_bostr|NN const char *loc_reg_starttry|const bool do_utf8
+                               |NN const char *loc_bostr|NN const char *loc_reg_starttry|const bool do_utf8|U32 depth
 Es     |void   |debug_start_match|NN const REGEXP *prog|const bool do_utf8\
                                |NN const char *start|NN const char *end\
                                |NN const char *blurb
+
+Epno   |int    |re_indentfo    |NN const char *fmt|U32 depth|...
 #  endif
 #endif
 
diff --git a/embed.h b/embed.h
index 93cdfd9..ca421c9 100644 (file)
--- a/embed.h
+++ b/embed.h
 #    endif
 #    if defined(PERL_IN_REGEXEC_C)
 #define debug_start_match(a,b,c,d,e)   S_debug_start_match(aTHX_ a,b,c,d,e)
-#define dump_exec_pos(a,b,c,d,e,f)     S_dump_exec_pos(aTHX_ a,b,c,d,e,f)
+#define dump_exec_pos(a,b,c,d,e,f,g)   S_dump_exec_pos(aTHX_ a,b,c,d,e,f,g)
 #    endif
 #  endif
 #  if defined(PERL_ANY_COW)
diff --git a/proto.h b/proto.h
index 2e7cb43..d50c430 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -3854,6 +3854,9 @@ STATIC void       S_put_code_point(pTHX_ SV* sv, UV c);
 STATIC void    S_put_range(pTHX_ SV* sv, UV start, const UV end, const bool allow_literals);
 #define PERL_ARGS_ASSERT_PUT_RANGE     \
        assert(sv)
+PERL_CALLCONV int      Perl_re_indentf(const char *fmt, U32 depth, ...);
+#define PERL_ARGS_ASSERT_RE_INDENTF    \
+       assert(fmt)
 STATIC void    S_regdump_extflags(pTHX_ const char *lead, const U32 flags);
 STATIC void    S_regdump_intflags(pTHX_ const char *lead, const U32 flags);
 STATIC U8      S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p, const regnode *val, U32 depth);
@@ -3864,9 +3867,12 @@ STATIC U8        S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p, const reg
 STATIC void    S_debug_start_match(pTHX_ const REGEXP *prog, const bool do_utf8, const char *start, const char *end, const char *blurb);
 #define PERL_ARGS_ASSERT_DEBUG_START_MATCH     \
        assert(prog); assert(start); assert(end); assert(blurb)
-STATIC void    S_dump_exec_pos(pTHX_ const char *locinput, const regnode *scan, const char *loc_regeol, const char *loc_bostr, const char *loc_reg_starttry, const bool do_utf8);
+STATIC void    S_dump_exec_pos(pTHX_ const char *locinput, const regnode *scan, const char *loc_regeol, const char *loc_bostr, const char *loc_reg_starttry, const bool do_utf8, U32 depth);
 #define PERL_ARGS_ASSERT_DUMP_EXEC_POS \
        assert(locinput); assert(scan); assert(loc_regeol); assert(loc_bostr); assert(loc_reg_starttry)
+PERL_CALLCONV int      Perl_re_indentfo(const char *fmt, U32 depth, ...);
+#define PERL_ARGS_ASSERT_RE_INDENTFO   \
+       assert(fmt)
 #  endif
 #  if defined(PERL_IN_SV_C)
 STATIC void    S_del_sv(pTHX_ SV *p);
@@ -4938,6 +4944,9 @@ PERL_CALLCONV SV* Perl__get_regclass_nonbitmap_data(pTHX_ const regexp *prog, co
 #define PERL_ARGS_ASSERT__GET_REGCLASS_NONBITMAP_DATA  \
        assert(node)
 PERL_CALLCONV void     Perl__load_PL_utf8_foldclosures(pTHX);
+PERL_CALLCONV int      Perl_re_printf(const char *fmt, ...);
+#define PERL_ARGS_ASSERT_RE_PRINTF     \
+       assert(fmt)
 PERL_CALLCONV void     Perl_regprop(pTHX_ const regexp *prog, SV* sv, const regnode* o, const regmatch_info *reginfo, const RExC_state_t *pRExC_state);
 #define PERL_ARGS_ASSERT_REGPROP       \
        assert(sv); assert(o)
index e1dc3c8..64a8021 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -898,49 +898,78 @@ static const scan_data_t zero_scan_data =
 #define EXPERIMENTAL_INPLACESCAN
 #endif /*PERL_ENABLE_EXPERIMENTAL_REGEX_OPTIMISATIONS*/
 
+#ifdef DEBUGGING
+int
+Perl_re_printf(const char *fmt, ...)
+{
+    va_list ap;
+    int result;
+    PerlIO *f= Perl_debug_log;
+    PERL_ARGS_ASSERT_RE_PRINTF;
+    va_start(ap, fmt);
+    result = PerlIO_vprintf(f, fmt, ap);
+    va_end(ap);
+    return result;
+}
+
+int
+Perl_re_indentf(const char *fmt, U32 depth, ...)
+{
+    va_list ap;
+    int result;
+    PerlIO *f= Perl_debug_log;
+    PERL_ARGS_ASSERT_RE_INDENTF;
+    va_start(ap, depth);
+    PerlIO_printf(f, "%*s", ( depth % 20 ) * 2, "");
+    result = PerlIO_vprintf(f, fmt, ap);
+    va_end(ap);
+    return result;
+}
+#endif /* DEBUGGING */
+
 #define DEBUG_RExC_seen() \
         DEBUG_OPTIMISE_MORE_r({                                             \
-            PerlIO_printf(Perl_debug_log,"RExC_seen: ");                    \
+            Perl_re_printf("RExC_seen: ");                    \
                                                                             \
             if (RExC_seen & REG_ZERO_LEN_SEEN)                              \
-                PerlIO_printf(Perl_debug_log,"REG_ZERO_LEN_SEEN ");         \
+                Perl_re_printf("REG_ZERO_LEN_SEEN ");         \
                                                                             \
             if (RExC_seen & REG_LOOKBEHIND_SEEN)                            \
-                PerlIO_printf(Perl_debug_log,"REG_LOOKBEHIND_SEEN ");       \
+                Perl_re_printf("REG_LOOKBEHIND_SEEN ");       \
                                                                             \
             if (RExC_seen & REG_GPOS_SEEN)                                  \
-                PerlIO_printf(Perl_debug_log,"REG_GPOS_SEEN ");             \
+                Perl_re_printf("REG_GPOS_SEEN ");             \
                                                                             \
             if (RExC_seen & REG_RECURSE_SEEN)                               \
-                PerlIO_printf(Perl_debug_log,"REG_RECURSE_SEEN ");          \
+                Perl_re_printf("REG_RECURSE_SEEN ");          \
                                                                             \
             if (RExC_seen & REG_TOP_LEVEL_BRANCHES_SEEN)                         \
-                PerlIO_printf(Perl_debug_log,"REG_TOP_LEVEL_BRANCHES_SEEN ");    \
+                Perl_re_printf("REG_TOP_LEVEL_BRANCHES_SEEN ");    \
                                                                             \
             if (RExC_seen & REG_VERBARG_SEEN)                               \
-                PerlIO_printf(Perl_debug_log,"REG_VERBARG_SEEN ");          \
+                Perl_re_printf("REG_VERBARG_SEEN ");          \
                                                                             \
             if (RExC_seen & REG_CUTGROUP_SEEN)                              \
-                PerlIO_printf(Perl_debug_log,"REG_CUTGROUP_SEEN ");         \
+                Perl_re_printf("REG_CUTGROUP_SEEN ");         \
                                                                             \
             if (RExC_seen & REG_RUN_ON_COMMENT_SEEN)                        \
-                PerlIO_printf(Perl_debug_log,"REG_RUN_ON_COMMENT_SEEN ");   \
+                Perl_re_printf("REG_RUN_ON_COMMENT_SEEN ");   \
                                                                             \
             if (RExC_seen & REG_UNFOLDED_MULTI_SEEN)                        \
-                PerlIO_printf(Perl_debug_log,"REG_UNFOLDED_MULTI_SEEN ");   \
+                Perl_re_printf("REG_UNFOLDED_MULTI_SEEN ");   \
                                                                             \
             if (RExC_seen & REG_UNBOUNDED_QUANTIFIER_SEEN)                               \
-                PerlIO_printf(Perl_debug_log,"REG_UNBOUNDED_QUANTIFIER_SEEN ");          \
+                Perl_re_printf("REG_UNBOUNDED_QUANTIFIER_SEEN ");          \
                                                                             \
-            PerlIO_printf(Perl_debug_log,"\n");                             \
+            Perl_re_printf("\n");                             \
         });
 
 #define DEBUG_SHOW_STUDY_FLAG(flags,flag) \
-  if ((flags) & flag) PerlIO_printf(Perl_debug_log, "%s ", #flag)
+  if ((flags) & flag) Perl_re_printf( "%s ", #flag)
 
 #define DEBUG_SHOW_STUDY_FLAGS(flags,open_str,close_str)                    \
     if ( ( flags ) ) {                                                      \
-        PerlIO_printf(Perl_debug_log, "%s", open_str);                      \
+        Perl_re_printf( "%s", open_str);                      \
         DEBUG_SHOW_STUDY_FLAG(flags,SF_FL_BEFORE_SEOL);                     \
         DEBUG_SHOW_STUDY_FLAG(flags,SF_FL_BEFORE_MEOL);                     \
         DEBUG_SHOW_STUDY_FLAG(flags,SF_IS_INF);                             \
@@ -956,29 +985,28 @@ static const scan_data_t zero_scan_data =
         DEBUG_SHOW_STUDY_FLAG(flags,SCF_SEEN_ACCEPT);                       \
         DEBUG_SHOW_STUDY_FLAG(flags,SCF_TRIE_DOING_RESTUDY);                \
         DEBUG_SHOW_STUDY_FLAG(flags,SCF_IN_DEFINE);                         \
-        PerlIO_printf(Perl_debug_log, "%s", close_str);                     \
+        Perl_re_printf( "%s", close_str);                     \
     }
 
 
 #define DEBUG_STUDYDATA(str,data,depth)                              \
 DEBUG_OPTIMISE_MORE_r(if(data){                                      \
-    PerlIO_printf(Perl_debug_log,                                    \
-        "%*s" str "Pos:%"IVdf"/%"IVdf                                \
+    Perl_re_indentf( "" str "Pos:%"IVdf"/%"IVdf               \
         " Flags: 0x%"UVXf,                                           \
-        (int)(depth)*2, "",                                          \
+        depth,                                      \
         (IV)((data)->pos_min),                                       \
         (IV)((data)->pos_delta),                                     \
         (UV)((data)->flags)                                          \
     );                                                               \
     DEBUG_SHOW_STUDY_FLAGS((data)->flags," [ ","]");                 \
-    PerlIO_printf(Perl_debug_log,                                    \
+    Perl_re_printf(                                    \
         " Whilem_c: %"IVdf" Lcp: %"IVdf" %s",                        \
         (IV)((data)->whilem_c),                                      \
         (IV)((data)->last_closep ? *((data)->last_closep) : -1),     \
         is_inf ? "INF " : ""                                         \
     );                                                               \
     if ((data)->last_found)                                          \
-        PerlIO_printf(Perl_debug_log,                                \
+        Perl_re_printf(                                \
             "Last:'%s' %"IVdf":%"IVdf"/%"IVdf" %sFixed:'%s' @ %"IVdf \
             " %sFloat: '%s' @ %"IVdf"/%"IVdf"",                      \
             SvPVX_const((data)->last_found),                         \
@@ -995,9 +1023,10 @@ DEBUG_OPTIMISE_MORE_r(if(data){                                      \
             (IV)((data)->offset_float_min),                          \
             (IV)((data)->offset_float_max)                           \
         );                                                           \
-    PerlIO_printf(Perl_debug_log,"\n");                              \
+    Perl_re_printf("\n");                              \
 });
 
+
 /* =========================================================
  * BEGIN edit_distance stuff.
  *
@@ -1948,14 +1977,14 @@ S_dump_trie(pTHX_ const struct _reg_trie_data *trie, HV *widecharmap,
 
     PERL_ARGS_ASSERT_DUMP_TRIE;
 
-    PerlIO_printf( Perl_debug_log, "%*sChar : %-6s%-6s%-4s ",
-        (int)depth * 2 + 2,"",
+    Perl_re_indentf( "Char : %-6s%-6s%-4s ",
+        depth+1,
         "Match","Base","Ofs" );
 
     for( state = 0 ; state < trie->uniquecharcount ; state++ ) {
        SV ** const tmp = av_fetch( revcharmap, state, 0);
         if ( tmp ) {
-            PerlIO_printf( Perl_debug_log, "%*s",
+            Perl_re_printf( "%*s",
                 colwidth,
                 pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), colwidth,
                            PL_colors[0], PL_colors[1],
@@ -1965,27 +1994,27 @@ S_dump_trie(pTHX_ const struct _reg_trie_data *trie, HV *widecharmap,
             );
         }
     }
-    PerlIO_printf( Perl_debug_log, "\n%*sState|-----------------------",
-        (int)depth * 2 + 2,"");
+    Perl_re_printf( "\n%*sState|-----------------------",
+        depth+1);
 
     for( state = 0 ; state < trie->uniquecharcount ; state++ )
-        PerlIO_printf( Perl_debug_log, "%.*s", colwidth, "--------");
-    PerlIO_printf( Perl_debug_log, "\n");
+        Perl_re_printf( "%.*s", colwidth, "--------");
+    Perl_re_printf( "\n");
 
     for( state = 1 ; state < trie->statecount ; state++ ) {
        const U32 base = trie->states[ state ].trans.base;
 
-        PerlIO_printf( Perl_debug_log, "%*s#%4"UVXf"|",
-                                       (int)depth * 2 + 2,"", (UV)state);
+        Perl_re_indentf( "#%4"UVXf"|",
+                                       depth+1, (UV)state);
 
         if ( trie->states[ state ].wordnum ) {
-            PerlIO_printf( Perl_debug_log, " W%4X",
+            Perl_re_printf( " W%4X",
                                            trie->states[ state ].wordnum );
         } else {
-            PerlIO_printf( Perl_debug_log, "%6s", "" );
+            Perl_re_printf( "%6s", "" );
         }
 
-        PerlIO_printf( Perl_debug_log, " @%4"UVXf" ", (UV)base );
+        Perl_re_printf( " @%4"UVXf" ", (UV)base );
 
         if ( base ) {
             U32 ofs = 0;
@@ -1996,7 +2025,7 @@ S_dump_trie(pTHX_ const struct _reg_trie_data *trie, HV *widecharmap,
                                                                     != state))
                     ofs++;
 
-            PerlIO_printf( Perl_debug_log, "+%2"UVXf"[ ", (UV)ofs);
+            Perl_re_printf( "+%2"UVXf"[ ", (UV)ofs);
 
             for ( ofs = 0 ; ofs < trie->uniquecharcount ; ofs++ ) {
                 if ( ( base + ofs >= trie->uniquecharcount )
@@ -2005,28 +2034,28 @@ S_dump_trie(pTHX_ const struct _reg_trie_data *trie, HV *widecharmap,
                         && trie->trans[ base + ofs
                                     - trie->uniquecharcount ].check == state )
                 {
-                   PerlIO_printf( Perl_debug_log, "%*"UVXf,
+                   Perl_re_printf( "%*"UVXf,
                     colwidth,
                     (UV)trie->trans[ base + ofs
                                              - trie->uniquecharcount ].next );
                 } else {
-                    PerlIO_printf( Perl_debug_log, "%*s",colwidth,"   ." );
+                    Perl_re_printf( "%*s",colwidth,"   ." );
                 }
             }
 
-            PerlIO_printf( Perl_debug_log, "]");
+            Perl_re_printf( "]");
 
         }
-        PerlIO_printf( Perl_debug_log, "\n" );
+        Perl_re_printf( "\n" );
     }
-    PerlIO_printf(Perl_debug_log, "%*sword_info N:(prev,len)=",
-                                (int)depth*2, "");
+    Perl_re_indentf( "word_info N:(prev,len)=",
+                                depth);
     for (word=1; word <= trie->wordcount; word++) {
-       PerlIO_printf(Perl_debug_log, " %d:(%d,%d)",
+        Perl_re_printf( " %d:(%d,%d)",
            (int)word, (int)(trie->wordinfo[word].prev),
            (int)(trie->wordinfo[word].len));
     }
-    PerlIO_printf(Perl_debug_log, "\n" );
+    Perl_re_printf( "\n" );
 }
 /*
   Dumps a fully constructed but uncompressed trie in list form.
@@ -2047,19 +2076,20 @@ S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie,
     PERL_ARGS_ASSERT_DUMP_TRIE_INTERIM_LIST;
 
     /* print out the table precompression.  */
-    PerlIO_printf( Perl_debug_log, "%*sState :Word | Transition Data\n%*s%s",
-        (int)depth * 2 + 2,"", (int)depth * 2 + 2,"",
-        "------:-----+-----------------\n" );
+    Perl_re_indentf( "State :Word | Transition Data\n",
+            depth+1 );
+    Perl_re_indentf( "%s",
+            depth+1, "------:-----+-----------------\n" );
 
     for( state=1 ; state < next_alloc ; state ++ ) {
         U16 charid;
 
-        PerlIO_printf( Perl_debug_log, "%*s %4"UVXf" :",
-            (int)depth * 2 + 2,"", (UV)state  );
+        Perl_re_indentf( " %4"UVXf" :",
+            depth+1, (UV)state  );
         if ( ! trie->states[ state ].wordnum ) {
-            PerlIO_printf( Perl_debug_log, "%5s| ","");
+            Perl_re_printf( "%5s| ","");
         } else {
-            PerlIO_printf( Perl_debug_log, "W%4x| ",
+            Perl_re_printf( "W%4x| ",
                 trie->states[ state ].wordnum
             );
         }
@@ -2067,7 +2097,7 @@ S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie,
            SV ** const tmp = av_fetch( revcharmap,
                                         TRIE_LIST_ITEM(state,charid).forid, 0);
            if ( tmp ) {
-                PerlIO_printf( Perl_debug_log, "%*s:%3X=%4"UVXf" | ",
+                Perl_re_printf( "%*s:%3X=%4"UVXf" | ",
                     colwidth,
                     pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp),
                               colwidth,
@@ -2079,11 +2109,11 @@ S_dump_trie_interim_list(pTHX_ const struct _reg_trie_data *trie,
                     (UV)TRIE_LIST_ITEM(state,charid).newstate
                 );
                 if (!(charid % 10))
-                    PerlIO_printf(Perl_debug_log, "\n%*s| ",
+                    Perl_re_printf( "\n%*s| ",
                         (int)((depth * 2) + 14), "");
             }
         }
-        PerlIO_printf( Perl_debug_log, "\n");
+        Perl_re_printf( "\n");
     }
 }
 
@@ -2111,12 +2141,12 @@ S_dump_trie_interim_table(pTHX_ const struct _reg_trie_data *trie,
        that they are identical.
      */
 
-    PerlIO_printf( Perl_debug_log, "%*sChar : ",(int)depth * 2 + 2,"" );
+    Perl_re_indentf( "Char : ", depth+1 );
 
     for( charid = 0 ; charid < trie->uniquecharcount ; charid++ ) {
        SV ** const tmp = av_fetch( revcharmap, charid, 0);
         if ( tmp ) {
-            PerlIO_printf( Perl_debug_log, "%*s",
+            Perl_re_printf( "%*s",
                 colwidth,
                 pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), colwidth,
                            PL_colors[0], PL_colors[1],
@@ -2127,32 +2157,32 @@ S_dump_trie_interim_table(pTHX_ const struct _reg_trie_data *trie,
         }
     }
 
-    PerlIO_printf( Perl_debug_log, "\n%*sState+-",(int)depth * 2 + 2,"" );
+    Perl_re_printf( "\n%*sState+-",depth+1 );
 
     for( charid=0 ; charid < trie->uniquecharcount ; charid++ ) {
-        PerlIO_printf( Perl_debug_log, "%.*s", colwidth,"--------");
+        Perl_re_printf( "%.*s", colwidth,"--------");
     }
 
-    PerlIO_printf( Perl_debug_log, "\n" );
+    Perl_re_printf( "\n" );
 
     for( state=1 ; state < next_alloc ; state += trie->uniquecharcount ) {
 
-        PerlIO_printf( Perl_debug_log, "%*s%4"UVXf" : ",
-            (int)depth * 2 + 2,"",
+        Perl_re_indentf( "%4"UVXf" : ",
+            depth+1,
             (UV)TRIE_NODENUM( state ) );
 
         for( charid = 0 ; charid < trie->uniquecharcount ; charid++ ) {
             UV v=(UV)SAFE_TRIE_NODENUM( trie->trans[ state + charid ].next );
             if (v)
-                PerlIO_printf( Perl_debug_log, "%*"UVXf, colwidth, v );
+                Perl_re_printf( "%*"UVXf, colwidth, v );
             else
-                PerlIO_printf( Perl_debug_log, "%*s", colwidth, "." );
+                Perl_re_printf( "%*s", colwidth, "." );
         }
         if ( ! trie->states[ TRIE_NODENUM( state ) ].wordnum ) {
-            PerlIO_printf( Perl_debug_log, " (%4"UVXf")\n",
+            Perl_re_printf( " (%4"UVXf")\n",
                                             (UV)trie->trans[ state ].check );
         } else {
-            PerlIO_printf( Perl_debug_log, " (%4"UVXf") W%4X\n",
+            Perl_re_printf( " (%4"UVXf") W%4X\n",
                                             (UV)trie->trans[ state ].check,
             trie->states[ TRIE_NODENUM( state ) ].wordnum );
         }
@@ -2464,9 +2494,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
         sv_setiv(re_trie_maxbuff, RE_TRIE_MAXBUF_INIT);
     }
     DEBUG_TRIE_COMPILE_r({
-        PerlIO_printf( Perl_debug_log,
-          "%*smake_trie start==%d, first==%d, last==%d, tail==%d depth=%d\n",
-          (int)depth * 2 + 2, "",
+        Perl_re_indentf(
+          "make_trie start==%d, first==%d, last==%d, tail==%d depth=%d\n",
+          depth+1,
           REG_NODE_NUM(startbranch),REG_NODE_NUM(first),
           REG_NODE_NUM(last), REG_NODE_NUM(tail), (int)depth);
     });
@@ -2671,9 +2701,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
         }
     } /* end first pass */
     DEBUG_TRIE_COMPILE_r(
-        PerlIO_printf( Perl_debug_log,
-                "%*sTRIE(%s): W:%d C:%d Uq:%d Min:%d Max:%d\n",
-                (int)depth * 2 + 2,"",
+        Perl_re_indentf(
+                "TRIE(%s): W:%d C:%d Uq:%d Min:%d Max:%d\n",
+                depth+1,
                 ( widecharmap ? "UTF8" : "NATIVE" ), (int)word_count,
                (int)TRIE_CHARCOUNT(trie), trie->uniquecharcount,
                (int)trie->minlen, (int)trie->maxlen )
@@ -2721,9 +2751,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
 
         STRLEN transcount = 1;
 
-        DEBUG_TRIE_COMPILE_MORE_r( PerlIO_printf( Perl_debug_log,
-            "%*sCompiling trie using list compiler\n",
-            (int)depth * 2 + 2, ""));
+        DEBUG_TRIE_COMPILE_MORE_r( Perl_re_indentf( "Compiling trie using list compiler\n",
+            depth+1));
 
        trie->states = (reg_trie_state *)
            PerlMemShared_calloc( TRIE_CHARCOUNT(trie) + 2,
@@ -2829,7 +2858,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
 
                 /*
                 DEBUG_TRIE_COMPILE_MORE_r(
-                    PerlIO_printf( Perl_debug_log, "tp: %d zp: %d ",tp,zp)
+                    Perl_re_printf( "tp: %d zp: %d ",tp,zp)
                 );
                 */
 
@@ -2891,7 +2920,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                 }
                 /*
                 DEBUG_TRIE_COMPILE_MORE_r(
-                    PerlIO_printf( Perl_debug_log, " base: %d\n",base);
+                    Perl_re_printf( " base: %d\n",base);
                 );
                 */
                 trie->states[ state ].trans.base=base;
@@ -2934,9 +2963,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
            we have to use TRIE_NODENUM() to convert.
 
         */
-        DEBUG_TRIE_COMPILE_MORE_r( PerlIO_printf( Perl_debug_log,
-            "%*sCompiling trie using table compiler\n",
-            (int)depth * 2 + 2, ""));
+        DEBUG_TRIE_COMPILE_MORE_r( Perl_re_indentf( "Compiling trie using table compiler\n",
+            depth+1));
 
        trie->trans = (reg_trie_trans *)
            PerlMemShared_calloc( ( TRIE_CHARCOUNT(trie) + 1 )
@@ -3126,9 +3154,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
            PerlMemShared_realloc( trie->states, laststate
                                   * sizeof(reg_trie_state) );
         DEBUG_TRIE_COMPILE_MORE_r(
-            PerlIO_printf( Perl_debug_log,
-                "%*sAlloc: %d Orig: %"IVdf" elements, Final:%"IVdf". Savings of %%%5.2f\n",
-                (int)depth * 2 + 2,"",
+            Perl_re_indentf( "Alloc: %d Orig: %"IVdf" elements, Final:%"IVdf". Savings of %%%5.2f\n",
+                depth+1,
                 (int)( ( TRIE_CHARCOUNT(trie) + 1 ) * trie->uniquecharcount
                        + 1 ),
                 (IV)next_alloc,
@@ -3139,9 +3166,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
         } /* end table compress */
     }
     DEBUG_TRIE_COMPILE_MORE_r(
-            PerlIO_printf(Perl_debug_log,
-                "%*sStatecount:%"UVxf" Lasttrans:%"UVxf"\n",
-                (int)depth * 2 + 2, "",
+            Perl_re_indentf( "Statecount:%"UVxf" Lasttrans:%"UVxf"\n",
+                depth+1,
                 (UV)trie->statecount,
                 (UV)trie->lasttrans)
     );
@@ -3191,9 +3217,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
             });
         }
         DEBUG_OPTIMISE_r(
-            PerlIO_printf(Perl_debug_log,
-                "%*sMJD offset:%"UVuf" MJD length:%"UVuf"\n",
-                (int)depth * 2 + 2, "",
+            Perl_re_indentf( "MJD offset:%"UVuf" MJD length:%"UVuf"\n",
+                depth+1,
                 (UV)mjd_offset, (UV)mjd_nodelen)
         );
 #endif
@@ -3223,9 +3248,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                             if ( count == 2 ) {
                                 Zero(trie->bitmap, ANYOF_BITMAP_SIZE, char);
                                 DEBUG_OPTIMISE_r(
-                                    PerlIO_printf(Perl_debug_log,
-                                       "%*sNew Start State=%"UVuf" Class: [",
-                                        (int)depth * 2 + 2, "",
+                                    Perl_re_indentf( "New Start State=%"UVuf" Class: [",
+                                        depth+1,
                                         (UV)state));
                                if (idx >= 0) {
                                    SV ** const tmp = av_fetch( revcharmap, idx, 0);
@@ -3235,14 +3259,14 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                                     if ( folder )
                                         TRIE_BITMAP_SET(trie, folder[ *ch ]);
                                     DEBUG_OPTIMISE_r(
-                                        PerlIO_printf(Perl_debug_log, "%s", (char*)ch)
+                                        Perl_re_printf( "%s", (char*)ch)
                                     );
                                }
                            }
                            TRIE_BITMAP_SET(trie,*ch);
                            if ( folder )
                                TRIE_BITMAP_SET(trie,folder[ *ch ]);
-                           DEBUG_OPTIMISE_r(PerlIO_printf( Perl_debug_log,"%s", ch));
+                            DEBUG_OPTIMISE_r(Perl_re_printf("%s", ch));
                        }
                         idx = ofs;
                    }
@@ -3253,9 +3277,8 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                     char *ch = SvPV( *tmp, len );
                     DEBUG_OPTIMISE_r({
                         SV *sv=sv_newmortal();
-                        PerlIO_printf( Perl_debug_log,
-                           "%*sPrefix State: %"UVuf" Idx:%"UVuf" Char='%s'\n",
-                            (int)depth * 2 + 2, "",
+                        Perl_re_indentf( "Prefix State: %"UVuf" Idx:%"UVuf" Char='%s'\n",
+                            depth+1,
                             (UV)state, (UV)idx,
                             pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 6,
                                PL_colors[0], PL_colors[1],
@@ -3275,7 +3298,7 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
                } else {
 #ifdef DEBUGGING
                    if (state>1)
-                       DEBUG_OPTIMISE_r(PerlIO_printf( Perl_debug_log,"]\n"));
+                        DEBUG_OPTIMISE_r(Perl_re_printf("]\n"));
 #endif
                    break;
                }
@@ -3547,14 +3570,13 @@ S_construct_ahocorasick_from_trie(pTHX_ RExC_state_t *pRExC_state, regnode *sour
      */
     fail[ 0 ] = fail[ 1 ] = 0;
     DEBUG_TRIE_COMPILE_r({
-        PerlIO_printf(Perl_debug_log,
-                     "%*sStclass Failtable (%"UVuf" states): 0",
-                     (int)(depth * 2), "", (UV)numstates
+        Perl_re_indentf( "Stclass Failtable (%"UVuf" states): 0",
+                      depth, (UV)numstates
         );
         for( q_read=1; q_read<numstates; q_read++ ) {
-            PerlIO_printf(Perl_debug_log, ", %"UVuf, (UV)fail[q_read]);
+            Perl_re_printf( ", %"UVuf, (UV)fail[q_read]);
         }
-        PerlIO_printf(Perl_debug_log, "\n");
+        Perl_re_printf( "\n");
     });
     Safefree(q);
     /*RExC_seen |= REG_TRIEDFA_SEEN;*/
@@ -3566,11 +3588,11 @@ S_construct_ahocorasick_from_trie(pTHX_ RExC_state_t *pRExC_state, regnode *sour
     DEBUG_OPTIMISE_r({if (scan){ \
        regnode *Next = regnext(scan); \
        regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state); \
-       PerlIO_printf(Perl_debug_log, "%*s" str ">%3d: %s (%d)", \
-           (int)depth*2, "", REG_NODE_NUM(scan), SvPV_nolen_const(RExC_mysv),\
+       Perl_re_indentf( "" str ">%3d: %s (%d)", \
+           depth, REG_NODE_NUM(scan), SvPV_nolen_const(RExC_mysv),\
            Next ? (REG_NODE_NUM(Next)) : 0 ); \
        DEBUG_SHOW_STUDY_FLAGS(flags," [ ","]");\
-       PerlIO_printf(Perl_debug_log, "\n"); \
+       Perl_re_printf( "\n"); \
    }});
 
 /* The below joins as many adjacent EXACTish nodes as possible into a single
@@ -4084,9 +4106,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
     );
     DEBUG_OPTIMISE_MORE_r(
     {
-        PerlIO_printf(Perl_debug_log,
-            "%*sstudy_chunk stopparen=%ld recursed_count=%lu depth=%lu recursed_depth=%lu scan=%p last=%p",
-            (int)(depth*2), "", (long)stopparen,
+        Perl_re_indentf( "study_chunk stopparen=%ld recursed_count=%lu depth=%lu recursed_depth=%lu scan=%p last=%p",
+            depth, (long)stopparen,
             (unsigned long)RExC_study_chunk_recursed_count,
             (unsigned long)depth, (unsigned long)recursed_depth,
             scan,
@@ -4105,16 +4126,16 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                                    (( j - 1 ) * RExC_study_chunk_recursed_bytes), i)
                         )
                     ) {
-                        PerlIO_printf(Perl_debug_log," %d",(int)i);
+                        Perl_re_printf(" %d",(int)i);
                         break;
                     }
                 }
                 if ( j + 1 < recursed_depth ) {
-                    PerlIO_printf(Perl_debug_log, ",");
+                    Perl_re_printf( ",");
                 }
             }
         }
-        PerlIO_printf(Perl_debug_log,"\n");
+        Perl_re_printf("\n");
     }
     );
     while ( scan && OP(scan) != END && scan < last ){
@@ -4390,8 +4411,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
 
                         DEBUG_TRIE_COMPILE_r({
                             regprop(RExC_rx, RExC_mysv, tail, NULL, pRExC_state);
-                            PerlIO_printf( Perl_debug_log, "%*s%s %"UVuf":%s\n",
-                              (int)depth * 2 + 2, "",
+                            Perl_re_indentf( "%s %"UVuf":%s\n",
+                              depth+1,
                               "Looking for TRIE'able sequences. Tail node is ",
                               (UV)(tail - RExC_emit_start),
                               SvPV_nolen_const( RExC_mysv )
@@ -4482,20 +4503,20 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
 
                             DEBUG_TRIE_COMPILE_r({
                                 regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
-                                PerlIO_printf( Perl_debug_log, "%*s- %d:%s (%d)",
-                                   (int)depth * 2 + 2,"",
+                                Perl_re_indentf( "- %d:%s (%d)",
+                                   depth+1,
                                    REG_NODE_NUM(cur), SvPV_nolen_const( RExC_mysv ), REG_NODE_NUM(cur) );
 
                                 regprop(RExC_rx, RExC_mysv, noper, NULL, pRExC_state);
-                                PerlIO_printf( Perl_debug_log, " -> %d:%s",
+                                Perl_re_printf( " -> %d:%s",
                                     REG_NODE_NUM(noper), SvPV_nolen_const(RExC_mysv));
 
                                 if ( noper_next ) {
                                   regprop(RExC_rx, RExC_mysv, noper_next, NULL, pRExC_state);
-                                  PerlIO_printf( Perl_debug_log,"\t=> %d:%s\t",
+                                  Perl_re_printf("\t=> %d:%s\t",
                                     REG_NODE_NUM(noper_next), SvPV_nolen_const(RExC_mysv));
                                 }
-                                PerlIO_printf( Perl_debug_log, "(First==%d,Last==%d,Cur==%d,tt==%s,ntt==%s,nntt==%s)\n",
+                                Perl_re_printf( "(First==%d,Last==%d,Cur==%d,tt==%s,ntt==%s,nntt==%s)\n",
                                    REG_NODE_NUM(first), REG_NODE_NUM(last), REG_NODE_NUM(cur),
                                   PL_reg_name[trietype], PL_reg_name[noper_trietype], PL_reg_name[noper_next_trietype]
                                );
@@ -4591,11 +4612,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                         } /* loop over branches */
                         DEBUG_TRIE_COMPILE_r({
                             regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
-                            PerlIO_printf( Perl_debug_log,
-                              "%*s- %s (%d) <SCAN FINISHED> ",
-                              (int)depth * 2 + 2,
-                              "", SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
-                            PerlIO_printf( Perl_debug_log, "(First==%d, Last==%d, Cur==%d, tt==%s)\n",
+                            Perl_re_indentf( "- %s (%d) <SCAN FINISHED> ",
+                              depth+1, SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
+                            Perl_re_printf( "(First==%d, Last==%d, Cur==%d, tt==%s)\n",
                                REG_NODE_NUM(first), REG_NODE_NUM(last), REG_NODE_NUM(cur),
                                PL_reg_name[trietype]
                             );
@@ -4635,9 +4654,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                                      * turn it into a plain NOTHING op. */
                                     DEBUG_TRIE_COMPILE_r({
                                         regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
-                                        PerlIO_printf( Perl_debug_log,
-                                          "%*s- %s (%d) <NOTHING BRANCH SEQUENCE>\n", (int)depth * 2 + 2,
-                                          "", SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
+                                        Perl_re_indentf( "- %s (%d) <NOTHING BRANCH SEQUENCE>\n",
+                                          depth+1,
+                                          SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
 
                                     });
                                     OP(startbranch)= NOTHING;
@@ -5225,13 +5244,13 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
                    /* It is counted once already... */
                    data->pos_min += minnext * (mincount - counted);
 #if 0
-PerlIO_printf(Perl_debug_log, "counted=%"UVuf" deltanext=%"UVuf
+Perl_re_printf( "counted=%"UVuf" deltanext=%"UVuf
                               " SSize_t_MAX=%"UVuf" minnext=%"UVuf
                               " maxcount=%"UVuf" mincount=%"UVuf"\n",
     (UV)counted, (UV)deltanext, (UV)SSize_t_MAX, (UV)minnext, (UV)maxcount,
     (UV)mincount);
 if (deltanext != SSize_t_MAX)
-PerlIO_printf(Perl_debug_log, "LHS=%"UVuf" RHS=%"UVuf"\n",
+Perl_re_printf( "LHS=%"UVuf" RHS=%"UVuf"\n",
     (UV)(-counted * deltanext + (minnext + deltanext) * maxcount
           - minnext * mincount), (UV)(SSize_t_MAX - data->pos_delta));
 #endif
@@ -6045,7 +6064,7 @@ Perl_pregcomp(pTHX_ SV * const pattern, const U32 flags)
 
     /* Dispatch a request to compile a regexp to correct regexp engine. */
     DEBUG_COMPILE_r({
-       PerlIO_printf(Perl_debug_log, "Using engine %"UVxf"\n",
+        Perl_re_printf( "Using engine %"UVxf"\n",
                        PTR2UV(eng));
     });
     return CALLREGCOMP_ENG(eng, pattern, flags);
@@ -6090,7 +6109,7 @@ S_pat_upgrade_to_utf8(pTHX_ RExC_state_t * const pRExC_state,
     bool do_end = 0;
     GET_RE_DEBUG_FLAGS_DECL;
 
-    DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+    DEBUG_PARSE_r(Perl_re_printf(
         "UTF8 mismatch! Converting to utf8 for resizing and compile\n"));
 
     Newx(dst, *plen_p * 2 + 1, U8);
@@ -6458,7 +6477,7 @@ S_compile_runtime_code(pTHX_ RExC_state_t * const pRExC_state,
            *p++ = 'x';
        *p++ = '\0';
        DEBUG_COMPILE_r({
-           PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                "%sre-parsing pattern for runtime code:%s %s\n",
                PL_colors[4],PL_colors[5],newpat);
        });
@@ -6793,7 +6812,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
 
     }
 
-    DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+    DEBUG_PARSE_r(Perl_re_printf(
         "Assembling pattern from %d elements%s\n", pat_count,
             orig_rx_flags & RXf_SPLIT ? " for split" : ""));
 
@@ -6822,7 +6841,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
                 *is_bare_re = TRUE;
             SvREFCNT_inc(re);
             Safefree(pRExC_state->code_blocks);
-            DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_PARSE_r(Perl_re_printf(
                 "Precompiled pattern%s\n",
                     orig_rx_flags & RXf_SPLIT ? " for split" : ""));
 
@@ -6865,7 +6884,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     DEBUG_COMPILE_r({
             SV *dsv= sv_newmortal();
             RE_PV_QUOTED_DECL(s, RExC_utf8, dsv, exp, plen, 60);
-            PerlIO_printf(Perl_debug_log, "%sCompiling REx%s %s\n",
+            Perl_re_printf( "%sCompiling REx%s %s\n",
                           PL_colors[4],PL_colors[5],s);
         });
 
@@ -6981,7 +7000,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     assert(*RExC_end == '\0');
 
     DEBUG_PARSE_r(
-       PerlIO_printf(Perl_debug_log, "Starting first pass (sizing)\n");
+        Perl_re_printf( "Starting first pass (sizing)\n");
         RExC_lastnum=0;
         RExC_lastparse=NULL;
     );
@@ -7011,7 +7030,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
                                     pRExC_state->num_code_blocks);
             }
             else {
-                DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_PARSE_r(Perl_re_printf(
                 "Need to redo pass 1\n"));
             }
 
@@ -7023,7 +7042,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
        SvLEN_set(code_blocksv,0); /* no you can't have it, sv_clear */
 
     DEBUG_PARSE_r({
-        PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
             "Required size %"IVdf" nodes\n"
             "Starting second pass (creation)\n",
             (IV)RExC_size);
@@ -7161,7 +7180,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     /* Useful during FAIL. */
 #ifdef RE_TRACK_PATTERN_OFFSETS
     Newxz(ri->u.offsets, 2*RExC_size+1, U32); /* MJD 20001228 */
-    DEBUG_OFFSETS_r(PerlIO_printf(Perl_debug_log,
+    DEBUG_OFFSETS_r(Perl_re_printf(
                           "%s %"UVuf" bytes for offset annotations.\n",
                           ri->u.offsets ? "Got" : "Couldn't get",
                           (UV)((2*RExC_size+1) * sizeof(U32))));
@@ -7186,7 +7205,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     /* setup various meta data about recursion, this all requires
      * RExC_npar to be correctly set, and a bit later on we clear it */
     if (RExC_seen & REG_RECURSE_SEEN) {
-        DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_OPTIMISE_MORE_r(Perl_re_printf(
             "%*s%*s Setting up open/close parens\n",
                   22, "|    |", (int)(0 * 2 + 1), ""));
 
@@ -7219,7 +7238,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
         Perl_croak(aTHX_ "panic: reg returned NULL to re_op_compile for generation pass, flags=%#"UVxf"", (UV) flags);
     }
     DEBUG_OPTIMISE_r(
-        PerlIO_printf(Perl_debug_log, "Starting post parse optimization\n");
+        Perl_re_printf( "Starting post parse optimization\n");
     );
 
     /* XXXX To minimize changes to RE engine we always allocate
@@ -7248,7 +7267,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
         copyRExC_state = RExC_state;
     } else {
         U32 seen=RExC_seen;
-        DEBUG_OPTIMISE_r(PerlIO_printf(Perl_debug_log,"Restudying\n"));
+        DEBUG_OPTIMISE_r(Perl_re_printf("Restudying\n"));
 
         RExC_state = copyRExC_state;
         if (seen & REG_TOP_LEVEL_BRANCHES_SEEN)
@@ -7382,12 +7401,12 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
 #ifdef TRIE_STUDY_OPT
        DEBUG_PARSE_r(
            if (!restudied)
-               PerlIO_printf(Perl_debug_log, "first at %"IVdf"\n",
+                Perl_re_printf( "first at %"IVdf"\n",
                              (IV)(first - scan + 1))
         );
 #else
        DEBUG_PARSE_r(
-           PerlIO_printf(Perl_debug_log, "first at %"IVdf"\n",
+            Perl_re_printf( "first at %"IVdf"\n",
                (IV)(first - scan + 1))
         );
 #endif
@@ -7516,7 +7535,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
            r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
            DEBUG_COMPILE_r({ SV *sv = sv_newmortal();
                       regprop(r, sv, (regnode*)data.start_class, NULL, pRExC_state);
-                     PerlIO_printf(Perl_debug_log,
+                      Perl_re_printf(
                                    "synthetic stclass \"%s\".\n",
                                    SvPVX_const(sv));});
             data.start_class = NULL;
@@ -7561,7 +7580,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
        regnode_ssc ch_class;
        SSize_t last_close = 0;
 
-       DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log, "\nMulti Top Level\n"));
+        DEBUG_PARSE_r(Perl_re_printf( "\nMulti Top Level\n"));
 
        scan = ri->program + 1;
        ssc_init(pRExC_state, &ch_class);
@@ -7596,7 +7615,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
            r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
            DEBUG_COMPILE_r({ SV* sv = sv_newmortal();
                       regprop(r, sv, (regnode*)data.start_class, NULL, pRExC_state);
-                     PerlIO_printf(Perl_debug_log,
+                      Perl_re_printf(
                                    "synthetic stclass \"%s\".\n",
                                    SvPVX_const(sv));});
             data.start_class = NULL;
@@ -7614,7 +7633,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     /* Guard against an embedded (?=) or (?<=) with a longer minlen than
        the "real" pattern. */
     DEBUG_OPTIMISE_r({
-        PerlIO_printf(Perl_debug_log,"minlen: %"IVdf" r->minlen:%"IVdf" maxlen:%"IVdf"\n",
+        Perl_re_printf("minlen: %"IVdf" r->minlen:%"IVdf" maxlen:%"IVdf"\n",
                       (IV)minlen, (IV)r->minlen, (IV)RExC_maxlen);
     });
     r->minlenret = minlen;
@@ -7708,12 +7727,12 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
     Newxz(r->offs, RExC_npar, regexp_paren_pair);
     /* assume we don't need to swap parens around before we match */
     DEBUG_TEST_r({
-        PerlIO_printf(Perl_debug_log,"study_chunk_recursed_count: %lu\n",
+        Perl_re_printf("study_chunk_recursed_count: %lu\n",
             (unsigned long)RExC_study_chunk_recursed_count);
     });
     DEBUG_DUMP_r({
         DEBUG_RExC_seen();
-        PerlIO_printf(Perl_debug_log,"Final program:\n");
+        Perl_re_printf("Final program:\n");
         regdump(r);
     });
 #ifdef RE_TRACK_PATTERN_OFFSETS
@@ -7721,14 +7740,14 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
         const STRLEN len = ri->u.offsets[0];
         STRLEN i;
         GET_RE_DEBUG_FLAGS_DECL;
-        PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                       "Offsets: [%"UVuf"]\n\t", (UV)ri->u.offsets[0]);
         for (i = 1; i <= len; i++) {
             if (ri->u.offsets[i*2-1] || ri->u.offsets[i*2])
-                PerlIO_printf(Perl_debug_log, "%"UVuf":%"UVuf"[%"UVuf"] ",
+                Perl_re_printf( "%"UVuf":%"UVuf"[%"UVuf"] ",
                 (UV)i, (UV)ri->u.offsets[i*2-1], (UV)ri->u.offsets[i*2]);
             }
-        PerlIO_printf(Perl_debug_log, "\n");
+        Perl_re_printf( "\n");
     });
 #endif
 
@@ -8246,7 +8265,7 @@ S_reg_scan_name(pTHX_ RExC_state_t *pRExC_state, U32 flags)
 #define DEBUG_PARSE_MSG(funcname)     DEBUG_PARSE_r({           \
     int num;                                                    \
     if (RExC_lastparse!=RExC_parse) {                           \
-        PerlIO_printf(Perl_debug_log, "%s",                     \
+        Perl_re_printf( "%s",                     \
             Perl_pv_pretty(aTHX_ RExC_mysv1, RExC_parse,        \
                 RExC_end - RExC_parse, 16,                      \
                 "", "",                                         \
@@ -8258,17 +8277,17 @@ S_reg_scan_name(pTHX_ RExC_state_t *pRExC_state, U32 flags)
             )                                                   \
         );                                                      \
     } else                                                      \
-        PerlIO_printf(Perl_debug_log,"%16s","");                \
+        Perl_re_printf("%16s","");                \
                                                                 \
     if (SIZE_ONLY)                                              \
        num = RExC_size + 1;                                     \
     else                                                        \
        num=REG_NODE_NUM(RExC_emit);                             \
     if (RExC_lastnum!=num)                                      \
-       PerlIO_printf(Perl_debug_log,"|%4d",num);                \
+       Perl_re_printf("|%4d",num);                \
     else                                                        \
-       PerlIO_printf(Perl_debug_log,"|%4s","");                 \
-    PerlIO_printf(Perl_debug_log,"|%*s%-4s",                    \
+       Perl_re_printf("|%4s","");                 \
+    Perl_re_printf("|%*s%-4s",                    \
         (int)((depth*2)), "",                                   \
         (funcname)                                              \
     );                                                          \
@@ -8280,11 +8299,11 @@ S_reg_scan_name(pTHX_ RExC_state_t *pRExC_state, U32 flags)
 
 #define DEBUG_PARSE(funcname)     DEBUG_PARSE_r({           \
     DEBUG_PARSE_MSG((funcname));                            \
-    PerlIO_printf(Perl_debug_log,"%4s","\n");               \
+    Perl_re_printf("%4s","\n");               \
 })
 #define DEBUG_PARSE_FMT(funcname,fmt,args)     DEBUG_PARSE_r({           \
     DEBUG_PARSE_MSG((funcname));                            \
-    PerlIO_printf(Perl_debug_log,fmt "\n",args);               \
+    Perl_re_printf(fmt "\n",args);               \
 })
 
 /* This section of code defines the inversion list object and its methods.  The
@@ -10717,7 +10736,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                        vFAIL("Reference to nonexistent group");
                    }
                    RExC_recurse_count++;
-                   DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+                    DEBUG_OPTIMISE_MORE_r(Perl_re_printf(
                         "%*s%*s Recurse #%"UVuf" to %"IVdf"\n",
                               22, "|    |", (int)(depth * 2 + 1), "",
                               (UV)ARG(ret), (IV)ARG2L(ret)));
@@ -11030,7 +11049,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                    RExC_nestroot = parno;
                 if (RExC_open_parens && !RExC_open_parens[parno])
                {
-                   DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+                    DEBUG_OPTIMISE_MORE_r(Perl_re_printf(
                         "%*s%*s Setting open paren #%"IVdf" to %d\n",
                         22, "|    |", (int)(depth * 2 + 1), "",
                        (IV)parno, REG_NODE_NUM(ret)));
@@ -11124,7 +11143,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
        case 1: case 2:
            ender = reganode(pRExC_state, CLOSE, parno);
             if ( RExC_close_parens ) {
-               DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_OPTIMISE_MORE_r(Perl_re_printf(
                         "%*s%*s Setting close paren #%"IVdf" to %d\n",
                         22, "|    |", (int)(depth * 2 + 1), "", (IV)parno, REG_NODE_NUM(ender)));
                 RExC_close_parens[parno]= ender;
@@ -11149,7 +11168,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                 assert(!RExC_end_op); /* there can only be one! */
                 RExC_end_op = ender;
                 if (RExC_close_parens) {
-                    DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+                    DEBUG_OPTIMISE_MORE_r(Perl_re_printf(
                         "%*s%*s Setting close paren #0 (END) to %d\n",
                         22, "|    |", (int)(depth * 2 + 1), "", REG_NODE_NUM(ender)));
 
@@ -11162,7 +11181,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
             DEBUG_PARSE_MSG("lsbr");
             regprop(RExC_rx, RExC_mysv1, lastbr, NULL, pRExC_state);
             regprop(RExC_rx, RExC_mysv2, ender, NULL, pRExC_state);
-            PerlIO_printf(Perl_debug_log, "~ tying lastbr %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
+            Perl_re_printf( "~ tying lastbr %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
                           SvPV_nolen_const(RExC_mysv1),
                           (IV)REG_NODE_NUM(lastbr),
                           SvPV_nolen_const(RExC_mysv2),
@@ -11201,7 +11220,7 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
                     DEBUG_PARSE_MSG("NADA");
                     regprop(RExC_rx, RExC_mysv1, ret, NULL, pRExC_state);
                     regprop(RExC_rx, RExC_mysv2, ender, NULL, pRExC_state);
-                    PerlIO_printf(Perl_debug_log, "~ converting ret %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
+                    Perl_re_printf( "~ converting ret %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
                                   SvPV_nolen_const(RExC_mysv1),
                                   (IV)REG_NODE_NUM(ret),
                                   SvPV_nolen_const(RExC_mysv2),
@@ -18321,7 +18340,7 @@ S_regtail(pTHX_ RExC_state_t * pRExC_state,
         DEBUG_PARSE_r({
             DEBUG_PARSE_MSG((scan==p ? "tail" : ""));
             regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state);
-            PerlIO_printf(Perl_debug_log, "~ %s (%d) %s %s\n",
+            Perl_re_printf( "~ %s (%d) %s %s\n",
                 SvPV_nolen_const(RExC_mysv), REG_NODE_NUM(scan),
                     (temp == NULL ? "->" : ""),
                     (temp == NULL ? PL_reg_name[OP(val)] : "")
@@ -18411,7 +18430,7 @@ S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p,
         DEBUG_PARSE_r({
             DEBUG_PARSE_MSG((scan==p ? "tsdy" : ""));
             regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state);
-            PerlIO_printf(Perl_debug_log, "~ %s (%d) -> %s\n",
+            Perl_re_printf( "~ %s (%d) -> %s\n",
                 SvPV_nolen_const(RExC_mysv),
                 REG_NODE_NUM(scan),
                 PL_reg_name[exact]);
@@ -18423,7 +18442,7 @@ S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p,
     DEBUG_PARSE_r({
         DEBUG_PARSE_MSG("");
         regprop(RExC_rx, RExC_mysv, val, NULL, pRExC_state);
-        PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                       "~ attach to %s (%"IVdf") offset to %"IVdf"\n",
                      SvPV_nolen_const(RExC_mysv),
                      (IV)REG_NODE_NUM(val),
@@ -18457,15 +18476,15 @@ S_regdump_intflags(pTHX_ const char *lead, const U32 flags)
     for (bit=0; bit<REG_INTFLAGS_NAME_SIZE; bit++) {
         if (flags & (1<<bit)) {
             if (!set++ && lead)
-                PerlIO_printf(Perl_debug_log, "%s",lead);
-            PerlIO_printf(Perl_debug_log, "%s ",PL_reg_intflags_name[bit]);
+                Perl_re_printf( "%s",lead);
+            Perl_re_printf( "%s ",PL_reg_intflags_name[bit]);
         }
     }
     if (lead)  {
         if (set)
-            PerlIO_printf(Perl_debug_log, "\n");
+            Perl_re_printf( "\n");
         else
-            PerlIO_printf(Perl_debug_log, "%s[none-set]\n",lead);
+            Perl_re_printf( "%s[none-set]\n",lead);
     }
 }
 
@@ -18484,37 +18503,37 @@ S_regdump_extflags(pTHX_ const char *lead, const U32 flags)
                continue;
            }
             if (!set++ && lead)
-                PerlIO_printf(Perl_debug_log, "%s",lead);
-            PerlIO_printf(Perl_debug_log, "%s ",PL_reg_extflags_name[bit]);
+                Perl_re_printf( "%s",lead);
+            Perl_re_printf( "%s ",PL_reg_extflags_name[bit]);
         }
     }
     if ((cs = get_regex_charset(flags)) != REGEX_DEPENDS_CHARSET) {
             if (!set++ && lead) {
-                PerlIO_printf(Perl_debug_log, "%s",lead);
+                Perl_re_printf( "%s",lead);
             }
             switch (cs) {
                 case REGEX_UNICODE_CHARSET:
-                    PerlIO_printf(Perl_debug_log, "UNICODE");
+                    Perl_re_printf( "UNICODE");
                     break;
                 case REGEX_LOCALE_CHARSET:
-                    PerlIO_printf(Perl_debug_log, "LOCALE");
+                    Perl_re_printf( "LOCALE");
                     break;
                 case REGEX_ASCII_RESTRICTED_CHARSET:
-                    PerlIO_printf(Perl_debug_log, "ASCII-RESTRICTED");
+                    Perl_re_printf( "ASCII-RESTRICTED");
                     break;
                 case REGEX_ASCII_MORE_RESTRICTED_CHARSET:
-                    PerlIO_printf(Perl_debug_log, "ASCII-MORE_RESTRICTED");
+                    Perl_re_printf( "ASCII-MORE_RESTRICTED");
                     break;
                 default:
-                    PerlIO_printf(Perl_debug_log, "UNKNOWN CHARACTER SET");
+                    Perl_re_printf( "UNKNOWN CHARACTER SET");
                     break;
             }
     }
     if (lead)  {
         if (set)
-            PerlIO_printf(Perl_debug_log, "\n");
+            Perl_re_printf( "\n");
         else
-            PerlIO_printf(Perl_debug_log, "%s[none-set]\n",lead);
+            Perl_re_printf( "%s[none-set]\n",lead);
     }
 }
 #endif
@@ -18536,14 +18555,14 @@ Perl_regdump(pTHX_ const regexp *r)
     if (r->anchored_substr) {
        RE_PV_QUOTED_DECL(s, 0, dsv, SvPVX_const(r->anchored_substr),
            RE_SV_DUMPLEN(r->anchored_substr), 30);
-       PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                      "anchored %s%s at %"IVdf" ",
                      s, RE_SV_TAIL(r->anchored_substr),
                      (IV)r->anchored_offset);
     } else if (r->anchored_utf8) {
        RE_PV_QUOTED_DECL(s, 1, dsv, SvPVX_const(r->anchored_utf8),
            RE_SV_DUMPLEN(r->anchored_utf8), 30);
-       PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                      "anchored utf8 %s%s at %"IVdf" ",
                      s, RE_SV_TAIL(r->anchored_utf8),
                      (IV)r->anchored_offset);
@@ -18551,55 +18570,55 @@ Perl_regdump(pTHX_ const regexp *r)
     if (r->float_substr) {
        RE_PV_QUOTED_DECL(s, 0, dsv, SvPVX_const(r->float_substr),
            RE_SV_DUMPLEN(r->float_substr), 30);
-       PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                      "floating %s%s at %"IVdf"..%"UVuf" ",
                      s, RE_SV_TAIL(r->float_substr),
                      (IV)r->float_min_offset, (UV)r->float_max_offset);
     } else if (r->float_utf8) {
        RE_PV_QUOTED_DECL(s, 1, dsv, SvPVX_const(r->float_utf8),
            RE_SV_DUMPLEN(r->float_utf8), 30);
-       PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                      "floating utf8 %s%s at %"IVdf"..%"UVuf" ",
                      s, RE_SV_TAIL(r->float_utf8),
                      (IV)r->float_min_offset, (UV)r->float_max_offset);
     }
     if (r->check_substr || r->check_utf8)
-       PerlIO_printf(Perl_debug_log,
+        Perl_re_printf(
                      (const char *)
                      (r->check_substr == r->float_substr
                       && r->check_utf8 == r->float_utf8
                       ? "(checking floating" : "(checking anchored"));
     if (r->intflags & PREGf_NOSCAN)
-       PerlIO_printf(Perl_debug_log, " noscan");
+        Perl_re_printf( " noscan");
     if (r->extflags & RXf_CHECK_ALL)
-       PerlIO_printf(Perl_debug_log, " isall");
+        Perl_re_printf( " isall");
     if (r->check_substr || r->check_utf8)
-       PerlIO_printf(Perl_debug_log, ") ");
+        Perl_re_printf( ") ");
 
     if (ri->regstclass) {
         regprop(r, sv, ri->regstclass, NULL, NULL);
-       PerlIO_printf(Perl_debug_log, "stclass %s ", SvPVX_const(sv));
+        Perl_re_printf( "stclass %s ", SvPVX_const(sv));
     }
     if (r->intflags & PREGf_ANCH) {
-       PerlIO_printf(Perl_debug_log, "anchored");
+        Perl_re_printf( "anchored");
         if (r->intflags & PREGf_ANCH_MBOL)
-           PerlIO_printf(Perl_debug_log, "(MBOL)");
+            Perl_re_printf( "(MBOL)");
         if (r->intflags & PREGf_ANCH_SBOL)
-           PerlIO_printf(Perl_debug_log, "(SBOL)");
+            Perl_re_printf( "(SBOL)");
         if (r->intflags & PREGf_ANCH_GPOS)
-           PerlIO_printf(Perl_debug_log, "(GPOS)");
-       (void)PerlIO_putc(Perl_debug_log, ' ');
+            Perl_re_printf( "(GPOS)");
+        Perl_re_printf(" ");
     }
     if (r->intflags & PREGf_GPOS_SEEN)
-       PerlIO_printf(Perl_debug_log, "GPOS:%"UVuf" ", (UV)r->gofs);
+        Perl_re_printf( "GPOS:%"UVuf" ", (UV)r->gofs);
     if (r->intflags & PREGf_SKIP)
-       PerlIO_printf(Perl_debug_log, "plus ");
+        Perl_re_printf( "plus ");
     if (r->intflags & PREGf_IMPLICIT)
-       PerlIO_printf(Perl_debug_log, "implicit ");
-    PerlIO_printf(Perl_debug_log, "minlen %"IVdf" ", (IV)r->minlen);
+        Perl_re_printf( "implicit ");
+    Perl_re_printf( "minlen %"IVdf" ", (IV)r->minlen);
     if (r->extflags & RXf_EVAL_SEEN)
-       PerlIO_printf(Perl_debug_log, "with eval ");
-    PerlIO_printf(Perl_debug_log, "\n");
+        Perl_re_printf( "with eval ");
+    Perl_re_printf( "\n");
     DEBUG_FLAGS_r({
         regdump_extflags("r->extflags: ",r->extflags);
         regdump_intflags("r->intflags: ",r->intflags);
@@ -19006,7 +19025,7 @@ Perl_re_intuit_string(pTHX_ REGEXP * const r)
                      ? prog->check_utf8 : prog->check_substr);
 
            if (!PL_colorset) reginitcolors();
-           PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                      "%sUsing REx %ssubstr:%s \"%s%.60s%s%s\"\n",
                      PL_colors[4],
                      RX_UTF8(r) ? "utf8 " : "",
@@ -19187,7 +19206,7 @@ Perl_regfree_internal(pTHX_ REGEXP * const rx)
            SV *dsv= sv_newmortal();
             RE_PV_QUOTED_DECL(s, RX_UTF8(rx),
                 dsv, RX_PRECOMP(rx), RX_PRELEN(rx), 60);
-            PerlIO_printf(Perl_debug_log,"%sFreeing REx:%s %s\n",
+            Perl_re_printf("%sFreeing REx:%s %s\n",
                 PL_colors[4],PL_colors[5],s);
         }
     });
@@ -20184,7 +20203,7 @@ S_put_charclass_bitmap_innards(pTHX_ SV *sv,
 
 #define CLEAR_OPTSTART \
     if (optstart) STMT_START {                                               \
-        DEBUG_OPTIMISE_r(PerlIO_printf(Perl_debug_log,                       \
+        DEBUG_OPTIMISE_r(Perl_re_printf(                       \
                               " (%"IVdf" nodes)\n", (IV)(node - optstart))); \
        optstart=NULL;                                                       \
     } STMT_END
@@ -20208,7 +20227,7 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
     PERL_ARGS_ASSERT_DUMPUNTIL;
 
 #ifdef DEBUG_DUMPUNTIL
-    PerlIO_printf(Perl_debug_log, "--- %d : %d - %d - %d\n",indent,node-start,
+    Perl_re_printf( "--- %d : %d - %d - %d\n",indent,node-start,
         last ? last-start : 0,plast ? plast-start : 0);
 #endif
 
@@ -20234,18 +20253,18 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
            CLEAR_OPTSTART;
 
         regprop(r, sv, node, NULL, NULL);
-       PerlIO_printf(Perl_debug_log, "%4"IVdf":%*s%s", (IV)(node - start),
+        Perl_re_printf( "%4"IVdf":%*s%s", (IV)(node - start),
                      (int)(2*indent + 1), "", SvPVX_const(sv));
 
         if (OP(node) != OPTIMIZED) {
             if (next == NULL)          /* Next ptr. */
-                PerlIO_printf(Perl_debug_log, " (0)");
+                Perl_re_printf( " (0)");
             else if (PL_regkind[(U8)op] == BRANCH
                      && PL_regkind[OP(next)] != BRANCH )
-                PerlIO_printf(Perl_debug_log, " (FAIL)");
+                Perl_re_printf( " (FAIL)");
             else
-                PerlIO_printf(Perl_debug_log, " (%"IVdf")", (IV)(next - start));
-            (void)PerlIO_putc(Perl_debug_log, '\n');
+                Perl_re_printf( " (%"IVdf")", (IV)(next - start));
+            Perl_re_printf("\n");
         }
 
       after_print:
@@ -20283,8 +20302,8 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
            for (word_idx= 0; word_idx < (I32)trie->wordcount; word_idx++) {
                SV ** const elem_ptr = av_fetch(trie_words,word_idx,0);
 
-                PerlIO_printf(Perl_debug_log, "%*s%s ",
-                   (int)(2*(indent+3)), "",
+                Perl_re_indentf( "%s ",
+                    indent+3,
                     elem_ptr
                     ? pv_pretty(sv, SvPV_nolen_const(*elem_ptr),
                                 SvCUR(*elem_ptr), 60,
@@ -20299,7 +20318,7 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
                 );
                 if (trie->jump) {
                     U16 dist= trie->jump[word_idx+1];
-                   PerlIO_printf(Perl_debug_log, "(%"UVuf")\n",
+                    Perl_re_printf( "(%"UVuf")\n",
                                (UV)((dist ? this_trie + dist : next) - start));
                     if (dist) {
                         if (!nextbranch)
@@ -20309,7 +20328,7 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
                     if (nextbranch && PL_regkind[OP(nextbranch)]==BRANCH)
                         nextbranch= regnext((regnode *)nextbranch);
                 } else {
-                    PerlIO_printf(Perl_debug_log, "\n");
+                    Perl_re_printf( "\n");
                }
            }
            if (last && next > last)
@@ -20349,7 +20368,7 @@ S_dumpuntil(pTHX_ const regexp *r, const regnode *start, const regnode *node,
     }
     CLEAR_OPTSTART;
 #ifdef DEBUG_DUMPUNTIL
-    PerlIO_printf(Perl_debug_log, "--- %d\n", (int)indent);
+    Perl_re_printf( "--- %d\n", (int)indent);
 #endif
     return node;
 }
index 13dcf91..8a1a0ad 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -97,7 +97,7 @@ static const char* const non_utf8_target_but_utf8_required
 #endif
 
 #define NON_UTF8_TARGET_BUT_UTF8_REQUIRED(target) STMT_START { \
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%s", non_utf8_target_but_utf8_required));\
+    DEBUG_EXECUTE_r(Perl_re_printf( "%s", non_utf8_target_but_utf8_required));\
     goto target; \
 } STMT_END
 
@@ -300,7 +300,7 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen)
     
     DEBUG_BUFFERS_r(
        if ((int)maxopenparen > (int)parenfloor)
-           PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                "rex=0x%"UVxf" offs=0x%"UVxf": saving capture indices:\n",
                PTR2UV(rex),
                PTR2UV(rex->offs)
@@ -311,7 +311,7 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen)
        SSPUSHIV(rex->offs[p].end);
        SSPUSHIV(rex->offs[p].start);
        SSPUSHINT(rex->offs[p].start_tmp);
-       DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_BUFFERS_r(Perl_re_printf(
            "    \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"\n",
            (UV)p,
            (IV)rex->offs[p].start,
@@ -331,17 +331,21 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen)
 /* These are needed since we do not localize EVAL nodes: */
 #define REGCP_SET(cp)                                           \
     DEBUG_STATE_r(                                              \
-            PerlIO_printf(Perl_debug_log,                      \
-               "  Setting an EVAL scope, savestack=%"IVdf"\n", \
-               (IV)PL_savestack_ix));                          \
+        Perl_re_indentfo(                                       \
+            "Setting an EVAL scope, savestack=%"IVdf",\n",      \
+            depth, (IV)PL_savestack_ix                          \
+        )                                                       \
+    );                                                          \
     cp = PL_savestack_ix
 
 #define REGCP_UNWIND(cp)                                        \
     DEBUG_STATE_r(                                              \
-        if (cp != PL_savestack_ix)                             \
-           PerlIO_printf(Perl_debug_log,                       \
-               "  Clearing an EVAL scope, savestack=%"IVdf"..%"IVdf"\n", \
-               (IV)(cp), (IV)PL_savestack_ix));                \
+        if (cp != PL_savestack_ix)                              \
+            Perl_re_indentfo(                                   \
+                "Clearing an EVAL scope, savestack=%"IVdf"..%"IVdf"\n",\
+                depth, (IV)(cp), (IV)PL_savestack_ix            \
+            )                                                   \
+    );                                                          \
     regcpblow(cp)
 
 #define UNWIND_PAREN(lp, lcp)               \
@@ -372,7 +376,7 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p)
     /* Now restore the parentheses context. */
     DEBUG_BUFFERS_r(
        if (i || rex->lastparen + 1 <= rex->nparens)
-           PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                "rex=0x%"UVxf" offs=0x%"UVxf": restoring capture indices to:\n",
                PTR2UV(rex),
                PTR2UV(rex->offs)
@@ -386,7 +390,7 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p)
        tmps = SSPOPIV;
        if (paren <= rex->lastparen)
            rex->offs[paren].end = tmps;
-       DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
+        DEBUG_BUFFERS_r( Perl_re_printf(
            "    \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"%s\n",
            (UV)paren,
            (IV)rex->offs[paren].start,
@@ -410,7 +414,7 @@ S_regcppop(pTHX_ regexp *rex, U32 *maxopenparen_p)
        if (i > *maxopenparen_p)
            rex->offs[i].start = -1;
        rex->offs[i].end = -1;
-       DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
+        DEBUG_BUFFERS_r( Perl_re_printf(
            "    \\%"UVuf": %s   ..-1 undeffing\n",
            (UV)i,
            (i > *maxopenparen_p) ? "-1" : "  "
@@ -652,7 +656,7 @@ Perl_re_intuit_start(pTHX_
     PERL_UNUSED_ARG(flags);
     PERL_UNUSED_ARG(data);
 
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+    DEBUG_EXECUTE_r(Perl_re_printf(
                 "Intuit: trying to determine minimum start position...\n"));
 
     /* for now, assume that all substr offsets are positive. If at some point
@@ -683,7 +687,7 @@ Perl_re_intuit_start(pTHX_
      * to quickly reject some cases that can't match, but will reject
      * them later after doing full char arithmetic */
     if (prog->minlen > strend - strpos) {
-       DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
                              "  String too short...\n"));
        goto fail;
     }
@@ -720,7 +724,7 @@ Perl_re_intuit_start(pTHX_
             if (!sv)
                 continue;
 
-            PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                 "  substrs[%d]: min=%"IVdf" max=%"IVdf" end shift=%"IVdf
                 " useful=%"IVdf" utf8=%d [%s]\n",
                 i,
@@ -760,7 +764,7 @@ Perl_re_intuit_start(pTHX_
             if (   strpos != strbeg
                 && (prog->intflags & PREGf_ANCH_SBOL))
             {
-               DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                                 "  Not at start...\n"));
                goto fail;
            }
@@ -780,7 +784,7 @@ Perl_re_intuit_start(pTHX_
                SSize_t slen = SvCUR(check);
                 char *s = HOP3c(strpos, prog->check_offset_min, strend);
            
-                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                     "  Looking for check substr at fixed offset %"IVdf"...\n",
                     (IV)prog->check_offset_min));
 
@@ -794,7 +798,7 @@ Perl_re_intuit_start(pTHX_
                             || strend - s < slen - 1
                             || (strend - s == slen && strend[-1] != '\n')))
                     {
-                        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                        DEBUG_EXECUTE_r(Perl_re_printf(
                                             "  String too long...\n"));
                         goto fail_finish;
                     }
@@ -804,7 +808,7 @@ Perl_re_intuit_start(pTHX_
                 if (slen && (*SvPVX_const(check) != *s
                     || (slen > 1 && memNE(SvPVX_const(check), s, slen))))
                 {
-                    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                    DEBUG_EXECUTE_r(Perl_re_printf(
                                     "  String not equal...\n"));
                     goto fail_finish;
                 }
@@ -855,7 +859,7 @@ Perl_re_intuit_start(pTHX_
         U8* end_point;
 
         DEBUG_OPTIMISE_MORE_r({
-            PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                 "  At restart: rx_origin=%"IVdf" Check offset min: %"IVdf
                 " Start shift: %"IVdf" End shift %"IVdf
                 " Real end Shift: %"IVdf"\n",
@@ -903,7 +907,7 @@ Perl_re_intuit_start(pTHX_
        check_at = fbm_instr( start_point, end_point,
                      check, multiline ? FBMrf_MULTILINE : 0);
 
-       DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "  doing 'check' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
             (IV)((char*)start_point - strbeg),
             (IV)((char*)end_point   - strbeg),
@@ -916,7 +920,7 @@ Perl_re_intuit_start(pTHX_
         DEBUG_EXECUTE_r({
             RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
                 SvPVX_const(check), RE_SV_DUMPLEN(check), 30);
-            PerlIO_printf(Perl_debug_log, "  %s %s substr %s%s%s",
+            Perl_re_printf( "  %s %s substr %s%s%s",
                               (check_at ? "Found" : "Did not find"),
                 (check == (utf8_target ? prog->anchored_utf8 : prog->anchored_substr)
                     ? "anchored" : "floating"),
@@ -935,7 +939,7 @@ Perl_re_intuit_start(pTHX_
         if (check_at - rx_origin > prog->check_offset_max)
             rx_origin = HOP3c(check_at, -prog->check_offset_max, rx_origin);
         /* Finish the diagnostic message */
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "%ld (rx_origin now %"IVdf")...\n",
             (long)(check_at - strbeg),
             (IV)(rx_origin - strbeg)
@@ -1049,7 +1053,7 @@ Perl_re_intuit_start(pTHX_
 
             if (from > to) {
                 s = NULL;
-                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                     "  skipping 'other' fbm scan: %"IVdf" > %"IVdf"\n",
                     (IV)(from - strbeg),
                     (IV)(to   - strbeg)
@@ -1062,7 +1066,7 @@ Perl_re_intuit_start(pTHX_
                     must,
                     multiline ? FBMrf_MULTILINE : 0
                 );
-                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                     "  doing 'other' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
                     (IV)(from - strbeg),
                     (IV)(to   - strbeg),
@@ -1074,7 +1078,7 @@ Perl_re_intuit_start(pTHX_
         DEBUG_EXECUTE_r({
             RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
                 SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
-            PerlIO_printf(Perl_debug_log, "  %s %s substr %s%s",
+            Perl_re_printf( "  %s %s substr %s%s",
                 s ? "Found" : "Contradicts",
                 other_ix ? "floating" : "anchored",
                 quoted, RE_SV_TAIL(must));
@@ -1085,7 +1089,7 @@ Perl_re_intuit_start(pTHX_
             /* last1 is latest possible substr location. If we didn't
              * find it before there, we never will */
             if (last >= last1) {
-                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                                         "; giving up...\n"));
                 goto fail_finish;
             }
@@ -1098,7 +1102,7 @@ Perl_re_intuit_start(pTHX_
                 other_ix /* i.e. if other-is-float */
                     ? HOP3c(rx_origin, 1, strend)
                     : HOP4c(last, 1 - other->min_offset, strbeg, strend);
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                 "; about to retry %s at offset %ld (rx_origin now %"IVdf")...\n",
                 (other_ix ? "floating" : "anchored"),
                 (long)(HOP3c(check_at, 1, strend) - strbeg),
@@ -1122,7 +1126,7 @@ Perl_re_intuit_start(pTHX_
                 rx_origin = HOP3c(s, -other->min_offset, strbeg);
                 other_last = HOP3c(s, 1, strend);
             }
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                 " at offset %ld (rx_origin now %"IVdf")...\n",
                   (long)(s - strbeg),
                 (IV)(rx_origin - strbeg)
@@ -1132,7 +1136,7 @@ Perl_re_intuit_start(pTHX_
     }
     else {
         DEBUG_OPTIMISE_MORE_r(
-            PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                 "  Check-only match: offset min:%"IVdf" max:%"IVdf
                 " check_at:%"IVdf" rx_origin:%"IVdf" rx_origin-check_at:%"IVdf
                 " strend:%"IVdf"\n",
@@ -1153,7 +1157,7 @@ Perl_re_intuit_start(pTHX_
     if (ml_anch && rx_origin != strbeg && rx_origin[-1] != '\n') {
         char *s;
 
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
                         "  looking for /^/m anchor"));
 
         /* we have failed the constraint of a \n before rx_origin.
@@ -1173,7 +1177,7 @@ Perl_re_intuit_start(pTHX_
         if (s <= rx_origin ||
             ! ( rx_origin = (char *)memchr(rx_origin, '\n', s - rx_origin)))
         {
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                             "  Did not find /%s^%s/m...\n",
                             PL_colors[0], PL_colors[1]));
             goto fail_finish;
@@ -1190,7 +1194,7 @@ Perl_re_intuit_start(pTHX_
             /* Position contradicts check-string; either because
              * check was anchored (and thus has no wiggle room),
              * or check was float and rx_origin is above the float range */
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                 "  Found /%s^%s/m, about to restart lookup for check-string with rx_origin %ld...\n",
                 PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
             goto restart;
@@ -1206,7 +1210,7 @@ Perl_re_intuit_start(pTHX_
              * contradict. On the other hand, the float "check" substr
              * didn't contradict, so just retry the anchored "other"
              * substr */
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                 "  Found /%s^%s/m, rescanning for anchored from offset %"IVdf" (rx_origin now %"IVdf")...\n",
                 PL_colors[0], PL_colors[1],
                 (IV)(rx_origin - strbeg + prog->anchored_offset),
@@ -1217,12 +1221,12 @@ Perl_re_intuit_start(pTHX_
 
         /* success: we don't contradict the found floating substring
          * (and there's no anchored substr). */
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "  Found /%s^%s/m with rx_origin %ld...\n",
             PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
     }
     else {
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "  (multiline anchor test skipped)\n"));
     }
 
@@ -1280,7 +1284,7 @@ Perl_re_intuit_start(pTHX_
         else 
             endpos= strend;
                    
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "  looking for class: start_shift: %"IVdf" check_at: %"IVdf
             " rx_origin: %"IVdf" endpos: %"IVdf"\n",
               (IV)start_shift, (IV)(check_at - strbeg),
@@ -1290,11 +1294,11 @@ Perl_re_intuit_start(pTHX_
                             reginfo);
        if (!s) {
            if (endpos == strend) {
-               DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r( Perl_re_printf(
                                "  Could not match STCLASS...\n") );
                goto fail;
            }
-           DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r( Perl_re_printf(
                                "  This position contradicts STCLASS...\n") );
             if ((prog->intflags & PREGf_ANCH) && !ml_anch
                         && !(prog->intflags & PREGf_IMPLICIT))
@@ -1315,7 +1319,7 @@ Perl_re_intuit_start(pTHX_
                          * an extra anchored search may get done, but in
                          * practice the extra fbm_instr() is likely to
                          * get skipped anyway. */
-                        DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+                        DEBUG_EXECUTE_r( Perl_re_printf(
                             "  about to retry anchored at offset %ld (rx_origin now %"IVdf")...\n",
                             (long)(other_last - strbeg),
                             (IV)(rx_origin - strbeg)
@@ -1336,7 +1340,7 @@ Perl_re_intuit_start(pTHX_
                      * but since we goto a block of code that's going to
                      * search for the next \n if any, its safe here */
                     rx_origin++;
-                    DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+                    DEBUG_EXECUTE_r( Perl_re_printf(
                               "  about to look for /%s^%s/m starting at rx_origin %ld...\n",
                               PL_colors[0], PL_colors[1],
                               (long)(rx_origin - strbeg)) );
@@ -1360,11 +1364,11 @@ Perl_re_intuit_start(pTHX_
              * It's conservative: it errs on the side of doing 'goto restart',
              * where there is code that does a proper char-based test */
             if (rx_origin + start_shift + end_shift > strend) {
-                DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r( Perl_re_printf(
                                        "  Could not match STCLASS...\n") );
                 goto fail;
             }
-            DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r( Perl_re_printf(
                 "  about to look for %s substr starting at offset %ld (rx_origin now %"IVdf")...\n",
                 (prog->substrs->check_ix ? "floating" : "anchored"),
                 (long)(rx_origin + start_shift - strbeg),
@@ -1376,13 +1380,13 @@ Perl_re_intuit_start(pTHX_
         /* Success !!! */
 
        if (rx_origin != s) {
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                        "  By STCLASS: moving %ld --> %ld\n",
                                   (long)(rx_origin - strbeg), (long)(s - strbeg))
                    );
         }
         else {
-            DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_EXECUTE_r(Perl_re_printf(
                                   "  Does not contradict STCLASS...\n");
                    );
         }
@@ -1394,7 +1398,7 @@ Perl_re_intuit_start(pTHX_
        /* Fixed substring is found far enough so that the match
           cannot start at strpos. */
 
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "  try at offset...\n"));
+        DEBUG_EXECUTE_r(Perl_re_printf( "  try at offset...\n"));
        ++BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr);        /* hooray/5 */
     }
     else {
@@ -1414,7 +1418,7 @@ Perl_re_intuit_start(pTHX_
            )))
        {
            /* If flags & SOMETHING - do not do it many times on the same match */
-           DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "  ... Disabling check substring...\n"));
+            DEBUG_EXECUTE_r(Perl_re_printf( "  ... Disabling check substring...\n"));
            /* XXX Does the destruction order has to change with utf8_target? */
            SvREFCNT_dec(utf8_target ? prog->check_utf8 : prog->check_substr);
            SvREFCNT_dec(utf8_target ? prog->check_substr : prog->check_utf8);
@@ -1428,7 +1432,7 @@ Perl_re_intuit_start(pTHX_
        }
     }
 
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+    DEBUG_EXECUTE_r(Perl_re_printf(
             "Intuit: %sSuccessfully guessed:%s match at offset %ld\n",
              PL_colors[4], PL_colors[5], (long)(rx_origin - strbeg)) );
 
@@ -1438,7 +1442,7 @@ Perl_re_intuit_start(pTHX_
     if (prog->check_substr || prog->check_utf8)                /* could be removed already */
        BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr) += 5; /* hooray */
   fail:
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch rejected by optimizer%s\n",
+    DEBUG_EXECUTE_r(Perl_re_printf( "%sMatch rejected by optimizer%s\n",
                          PL_colors[4], PL_colors[5]));
     return NULL;
 }
@@ -1535,9 +1539,9 @@ STMT_START {
     }                                                                               \
 } STMT_END
 
-#define DUMP_EXEC_POS(li,s,doutf8)                          \
+#define DUMP_EXEC_POS(li,s,doutf8,depth)                    \
     dump_exec_pos(li,s,(reginfo->strend),(reginfo->strbeg), \
-                startpos, doutf8)
+                startpos, doutf8, depth)
 
 #define REXEC_FBC_EXACTISH_SCAN(COND)                     \
 STMT_START {                                              \
@@ -2565,8 +2569,8 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                             DEBUG_TRIE_EXECUTE_r(
                                 if ( uc <= (U8*)last_start && !BITMAP_TEST(bitmap,*uc) ) {
                                     dump_exec_pos( (char *)uc, c, strend, real_start,
-                                        (char *)uc, utf8_target );
-                                    PerlIO_printf( Perl_debug_log,
+                                        (char *)uc, utf8_target, 0 );
+                                    Perl_re_printf(
                                         " Scanning for legal start char...\n");
                                 }
                             );
@@ -2601,8 +2605,8 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                                          foldbuf, uniflags);
                         DEBUG_TRIE_EXECUTE_r({
                             dump_exec_pos( (char *)uc, c, strend,
-                                        real_start, s, utf8_target);
-                            PerlIO_printf(Perl_debug_log,
+                                        real_start, s, utf8_target, 0);
+                            Perl_re_printf(
                                 " Charid:%3u CP:%4"UVxf" ",
                                  charid, uvc);
                         });
@@ -2622,8 +2626,8 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                         DEBUG_TRIE_EXECUTE_r({
                             if (failed)
                                 dump_exec_pos( (char *)uc, c, strend, real_start,
-                                    s,   utf8_target );
-                            PerlIO_printf( Perl_debug_log,
+                                    s,   utf8_target, 0 );
+                            Perl_re_printf(
                                 "%sState: %4"UVxf", word=%"UVxf,
                                 failed ? " Fail transition to " : "",
                                 (UV)state, (UV)word);
@@ -2639,13 +2643,13 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                                  && (tmp=trie->trans[offset].next))
                             {
                                 DEBUG_TRIE_EXECUTE_r(
-                                    PerlIO_printf( Perl_debug_log," - legal\n"));
+                                    Perl_re_printf(" - legal\n"));
                                 state = tmp;
                                 break;
                             }
                             else {
                                 DEBUG_TRIE_EXECUTE_r(
-                                    PerlIO_printf( Perl_debug_log," - fail\n"));
+                                    Perl_re_printf(" - fail\n"));
                                 failed = 1;
                                 state = aho->fail[state];
                             }
@@ -2653,7 +2657,7 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                         else {
                             /* we must be accepting here */
                             DEBUG_TRIE_EXECUTE_r(
-                                    PerlIO_printf( Perl_debug_log," - accepting\n"));
+                                    Perl_re_printf(" - accepting\n"));
                             failed = 1;
                             break;
                         }
@@ -2675,8 +2679,7 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                 if (leftmost) {
                     s = (char*)leftmost;
                     DEBUG_TRIE_EXECUTE_r({
-                        PerlIO_printf(
-                            Perl_debug_log,"Matches word #%"UVxf" at position %"IVdf". Trying full pattern...\n",
+                        Perl_re_printf( "Matches word #%"UVxf" at position %"IVdf". Trying full pattern...\n",
                             (UV)accepted_word, (IV)(s - real_start)
                         );
                     });
@@ -2687,11 +2690,11 @@ S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
                     }
                     s = HOPc(s,1);
                     DEBUG_TRIE_EXECUTE_r({
-                        PerlIO_printf( Perl_debug_log,"Pattern failed. Looking for new start point...\n");
+                        Perl_re_printf("Pattern failed. Looking for new start point...\n");
                     });
                 } else {
                     DEBUG_TRIE_EXECUTE_r(
-                        PerlIO_printf( Perl_debug_log,"No match.\n"));
+                        Perl_re_printf("No match.\n"));
                     break;
                 }
             }
@@ -2724,7 +2727,7 @@ S_reg_set_capture_string(pTHX_ REGEXP * const rx,
 #ifdef PERL_ANY_COW
         if (SvCANCOW(sv)) {
             if (DEBUG_C_TEST) {
-                PerlIO_printf(Perl_debug_log,
+                Perl_re_printf(
                               "Copy on write: regexp capture, type %d\n",
                               (int) SvTYPE(sv));
             }
@@ -2923,7 +2926,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
             ? strbeg + MgBYTEPOS(mg, sv, strbeg, strend-strbeg)
             : strbeg; /* pos() not defined; use start of string */
 
-        DEBUG_GPOS_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_GPOS_r(Perl_re_printf(
             "GPOS ganch set to strbeg[%"IVdf"]\n", (IV)(reginfo->ganch - strbeg)));
 
         /* in the presence of \G, we may need to start looking earlier in
@@ -2942,7 +2945,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                 if (!startpos ||
                     ((flags & REXEC_FAIL_ON_UNDERFLOW) && startpos < stringarg))
                 {
-                    DEBUG_r(PerlIO_printf(Perl_debug_log,
+                    DEBUG_r(Perl_re_printf(
                             "fail: ganch-gofs before earliest possible start\n"));
                     return 0;
                 }
@@ -2961,7 +2964,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
 
     minlen = prog->minlen;
     if ((startpos + minlen) > strend || startpos < strbeg) {
-        DEBUG_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_r(Perl_re_printf(
                     "Regex match can't succeed, so not even tried\n"));
         return 0;
     }
@@ -2996,7 +2999,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
             {
                 /* this should only be possible under \G */
                 assert(prog->intflags & PREGf_GPOS_SEEN);
-                DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+                DEBUG_EXECUTE_r(Perl_re_printf(
                     "matched, but failing for REXEC_FAIL_ON_UNDERFLOW\n"));
                 goto phooey;
             }
@@ -3021,7 +3024,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
     multiline = prog->extflags & RXf_PMf_MULTILINE;
     
     if (strend - s < (minlen+(prog->check_offset_min<0?prog->check_offset_min:0))) {
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
                              "String too short [regexec_flags]...\n"));
        goto phooey;
     }
@@ -3118,7 +3121,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
         swap = prog->offs;
         /* do we need a save destructor here for eval dies? */
         Newxz(prog->offs, (prog->nparens + 1), regexp_paren_pair);
-       DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_BUFFERS_r(Perl_re_printf(
            "rex=0x%"UVxf" saving  offs: orig=0x%"UVxf" new=0x%"UVxf"\n",
            PTR2UV(prog),
            PTR2UV(swap),
@@ -3229,7 +3232,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
            );
        }
        DEBUG_EXECUTE_r(if (!did_match)
-               PerlIO_printf(Perl_debug_log,
+                Perl_re_printf(
                                   "Did not find anchored character...\n")
                );
     }
@@ -3334,7 +3337,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
        DEBUG_EXECUTE_r(if (!did_match) {
             RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
                 SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
-            PerlIO_printf(Perl_debug_log, "Did not find %s substr %s%s...\n",
+            Perl_re_printf( "Did not find %s substr %s%s...\n",
                              ((must == prog->anchored_substr || must == prog->anchored_utf8)
                               ? "anchored" : "floating"),
                 quoted, RE_SV_TAIL(must));
@@ -3354,7 +3357,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
            {
                RE_PV_QUOTED_DECL(quoted,utf8_target,PERL_DEBUG_PAD_ZERO(1),
                    s,strend-s,60);
-               PerlIO_printf(Perl_debug_log,
+                Perl_re_printf(
                    "Matching stclass %.*s against %s (%d bytes)\n",
                    (int)SvCUR(prop), SvPVX_const(prop),
                     quoted, (int)(strend - s));
@@ -3362,7 +3365,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
        });
         if (find_byclass(prog, c, s, strend, reginfo))
            goto got_it;
-       DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Contradicts stclass... [regexec_flags]\n"));
+        DEBUG_EXECUTE_r(Perl_re_printf( "Contradicts stclass... [regexec_flags]\n"));
     }
     else {
        dontbother = 0;
@@ -3401,14 +3404,14 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                      * the \n. */
                    char *checkpos= strend - len;
                    DEBUG_OPTIMISE_r(
-                       PerlIO_printf(Perl_debug_log,
+                        Perl_re_printf(
                            "%sChecking for float_real.%s\n",
                            PL_colors[4], PL_colors[5]));
                    if (checkpos + 1 < strbeg) {
                         /* can't match, even if we remove the trailing \n
                          * string is too short to match */
                        DEBUG_EXECUTE_r(
-                           PerlIO_printf(Perl_debug_log,
+                            Perl_re_printf(
                                "%sString shorter than required trailing substring, cannot match.%s\n",
                                PL_colors[4], PL_colors[5]));
                        goto phooey;
@@ -3420,7 +3423,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                         /* cant match, string is too short when the "\n" is
                          * included */
                        DEBUG_EXECUTE_r(
-                           PerlIO_printf(Perl_debug_log,
+                            Perl_re_printf(
                                "%sString does not contain required trailing substring, cannot match.%s\n",
                                PL_colors[4], PL_colors[5]));
                        goto phooey;
@@ -3431,7 +3434,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                            last= checkpos;
                        } else {
                            DEBUG_EXECUTE_r(
-                               PerlIO_printf(Perl_debug_log,
+                                Perl_re_printf(
                                    "%sString does not contain required trailing substring, cannot match.%s\n",
                                    PL_colors[4], PL_colors[5]));
                            goto phooey;
@@ -3455,7 +3458,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                  * pretty sure it is not anymore, so I have removed the comment
                  * and replaced it with this one. Yves */
                DEBUG_EXECUTE_r(
-                   PerlIO_printf(Perl_debug_log,
+                    Perl_re_printf(
                        "%sString does not contain required substring, cannot match.%s\n",
                         PL_colors[4], PL_colors[5]
                    ));
@@ -3495,14 +3498,14 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
     {
         /* this should only be possible under \G */
         assert(prog->intflags & PREGf_GPOS_SEEN);
-        DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_EXECUTE_r(Perl_re_printf(
             "matched, but failing for REXEC_FAIL_ON_UNDERFLOW\n"));
         goto phooey;
     }
 
     DEBUG_BUFFERS_r(
        if (swap)
-           PerlIO_printf(Perl_debug_log,
+            Perl_re_printf(
                "rex=0x%"UVxf" freeing offs: 0x%"UVxf"\n",
                PTR2UV(prog),
                PTR2UV(swap)
@@ -3528,7 +3531,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
     return 1;
 
   phooey:
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch failed%s\n",
+    DEBUG_EXECUTE_r(Perl_re_printf( "%sMatch failed%s\n",
                          PL_colors[4], PL_colors[5]));
 
     /* clean up; this will trigger destructors that will free all slabs
@@ -3539,7 +3542,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
 
     if (swap) {
         /* we failed :-( roll it back */
-       DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+        DEBUG_BUFFERS_r(Perl_re_printf(
            "rex=0x%"UVxf" rolling back offs: freeing=0x%"UVxf" restoring=0x%"UVxf"\n",
            PTR2UV(prog),
            PTR2UV(prog->offs),
@@ -3572,6 +3575,9 @@ S_regtry(pTHX_ regmatch_info *reginfo, char **startposp)
     REGEXP *const rx = reginfo->prog;
     regexp *const prog = ReANY(rx);
     SSize_t result;
+#ifdef DEBUGGING
+    U32 depth = 0; /* used by REGCP_SET */
+#endif
     RXi_GET_DECL(prog,progi);
     GET_RE_DEBUG_FLAGS_DECL;
 
@@ -3632,10 +3638,26 @@ S_regtry(pTHX_ regmatch_info *reginfo, char **startposp)
     sayNO
 
 /* this is used to determine how far from the left messages like
-   'failed...' are printed. It should be set such that messages 
-   are inline with the regop output that created them.
+   'failed...' are printed in regexec.c. It should be set such that
+   messages are inline with the regop output that created them.
 */
-#define REPORT_CODE_OFF 32
+#define REPORT_CODE_OFF 29
+#define INDENT_CHARS(depth) ((depth) % 20)
+#ifdef DEBUGGING
+int
+Perl_re_indentfo(const char *fmt, U32 depth, ...)
+{
+    va_list ap;
+    int result;
+    PerlIO *f= Perl_debug_log;
+    PERL_ARGS_ASSERT_RE_INDENTFO;
+    va_start(ap, depth);
+    PerlIO_printf(f, "%*s|%4d| %*s", REPORT_CODE_OFF, "", depth, INDENT_CHARS(depth), "" );
+    result = PerlIO_vprintf(f, fmt, ap);
+    va_end(ap);
+    return result;
+}
+#endif /* DEBUGGING */
 
 
 #define CHRTEST_UNINIT -1001 /* c1/c2 haven't been calculated yet */
@@ -3816,18 +3838,18 @@ regmatch(), slabs allocated since entry are freed.
 */
  
 
-#define DEBUG_STATE_pp(pp)                                 \
-    DEBUG_STATE_r({                                        \
-       DUMP_EXEC_POS(locinput, scan, utf8_target);         \
-       PerlIO_printf(Perl_debug_log,                       \
-           "    %*s"pp" %s%s%s%s%s\n",                     \
-           depth*2, "",                                    \
-           PL_reg_name[st->resume_state],                  \
-           ((st==yes_state||st==mark_state) ? "[" : ""),   \
-           ((st==yes_state) ? "Y" : ""),                   \
-           ((st==mark_state) ? "M" : ""),                  \
-           ((st==yes_state||st==mark_state) ? "]" : "")    \
-       );                                                  \
+#define DEBUG_STATE_pp(pp)                                  \
+    DEBUG_STATE_r({                                         \
+        DUMP_EXEC_POS(locinput, scan, utf8_target,depth);   \
+        Perl_re_printf(                                     \
+            "%*s" pp " %s%s%s%s%s\n",                       \
+            INDENT_CHARS(depth), "",                        \
+            PL_reg_name[st->resume_state],                  \
+            ((st==yes_state||st==mark_state) ? "[" : ""),   \
+            ((st==yes_state) ? "Y" : ""),                   \
+            ((st==mark_state) ? "M" : ""),                  \
+            ((st==yes_state||st==mark_state) ? "]" : "")    \
+        );                                                  \
     });
 
 
@@ -3852,12 +3874,12 @@ S_debug_start_match(pTHX_ const REGEXP *prog, const bool utf8_target,
         RE_PV_QUOTED_DECL(s1, utf8_target, PERL_DEBUG_PAD_ZERO(1),
             start, end - start, 60); 
         
-        PerlIO_printf(Perl_debug_log, 
+        Perl_re_printf(
             "%s%s REx%s %s against %s\n", 
                       PL_colors[4], blurb, PL_colors[5], s0, s1); 
         
         if (utf8_target||utf8_pat)
-            PerlIO_printf(Perl_debug_log, "UTF-8 %s%s%s...\n",
+            Perl_re_printf( "UTF-8 %s%s%s...\n",
                 utf8_pat ? "pattern" : "",
                 utf8_pat && utf8_target ? " and " : "",
                 utf8_target ? "string" : ""
@@ -3871,7 +3893,9 @@ S_dump_exec_pos(pTHX_ const char *locinput,
                       const char *loc_regeol, 
                       const char *loc_bostr, 
                       const char *loc_reg_starttry,
-                      const bool utf8_target)
+                      const bool utf8_target,
+                      const U32 depth
+                )
 {
     const int docolor = *PL_colors[0] || *PL_colors[2] || *PL_colors[4];
     const int taill = (docolor ? 10 : 7); /* 3 chars for "> <" */
@@ -3914,15 +3938,16 @@ S_dump_exec_pos(pTHX_ const char *locinput,
                    locinput, loc_regeol - locinput, 10, 0, 1);
 
        const STRLEN tlen=len0+len1+len2;
-       PerlIO_printf(Perl_debug_log,
-                   "%4"IVdf" <%.*s%.*s%s%.*s>%*s|",
+        Perl_re_printf(
+                    "%4"IVdf" <%.*s%.*s%s%.*s>%*s|%4u| ",
                    (IV)(locinput - loc_bostr),
                    len0, s0,
                    len1, s1,
                    (docolor ? "" : "> <"),
                    len2, s2,
                    (int)(tlen > 19 ? 0 :  19 - tlen),
-                   "");
+                    "",
+                    depth);
     }
 }
 
@@ -4482,7 +4507,7 @@ S_isLB(pTHX_ LB_enum before,
     }
 
 #ifdef DEBUGGING
-    PerlIO_printf(Perl_error_log, "Unhandled LB pair: LB_table[%d, %d] = %d\n",
+    Perl_re_printf( "Unhandled LB pair: LB_table[%d, %d] = %d\n",
                                   before, after, LB_table[before][after]);
     assert(0);
 #endif
@@ -4989,7 +5014,7 @@ S_isWB(pTHX_ WB_enum previous,
     }
 
 #ifdef DEBUGGING
-    PerlIO_printf(Perl_error_log, "Unhandled WB pair: WB_table[%d, %d] = %d\n",
+    Perl_re_printf( "Unhandled WB pair: WB_table[%d, %d] = %d\n",
                                   before, after, WB_table[before][after]);
     assert(0);
 #endif
@@ -5201,7 +5226,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
     PERL_ARGS_ASSERT_REGMATCH;
 
     DEBUG_OPTIMISE_r( DEBUG_EXECUTE_r({
-           PerlIO_printf(Perl_debug_log,"regmatch start\n");
+            Perl_re_printf("regmatch start\n");
     }));
 
     st = PL_regmatch_state;
@@ -5211,19 +5236,6 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
     scan = prog;
     while (scan != NULL) {
 
-        DEBUG_EXECUTE_r( {
-           SV * const prop = sv_newmortal();
-           regnode *rnext=regnext(scan);
-           DUMP_EXEC_POS( locinput, scan, utf8_target );
-            regprop(rex, prop, scan, reginfo, NULL);
-            
-           PerlIO_printf(Perl_debug_log,
-                   "%3"IVdf":%*s%s(%"IVdf")\n",
-                   (IV)(scan - rexi->program), depth*2, "",
-                   SvPVX_const(prop),
-                   (PL_regkind[OP(scan)] == END || !rnext) ? 
-                       0 : (IV)(rnext - rexi->program));
-       });
 
        next = scan + NEXT_OFF(scan);
        if (next == scan)
@@ -5231,6 +5243,23 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
        state_num = OP(scan);
 
       reenter_switch:
+        DEBUG_EXECUTE_r(
+            if (state_num <= REGNODE_MAX) {
+                SV * const prop = sv_newmortal();
+                regnode *rnext = regnext(scan);
+
+                DUMP_EXEC_POS( locinput, scan, utf8_target, depth );
+                regprop(rex, prop, scan, reginfo, NULL);
+                Perl_re_printf(
+                    "%*s%"IVdf":%s(%"IVdf")\n",
+                    INDENT_CHARS(depth), "",
+                    (IV)(scan - rexi->program),
+                    SvPVX_const(prop),
+                    (PL_regkind[OP(scan)] == END || !rnext) ?
+                        0 : (IV)(rnext - rexi->program));
+            }
+        );
+
         to_complement = 0;
 
         SET_nextchr;
@@ -5304,9 +5333,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
              */
             if(!NEXTCHR_IS_EOS && !ANYOF_BITMAP_TEST(scan, nextchr)) {
                 DEBUG_EXECUTE_r(
-                    PerlIO_printf(Perl_debug_log,
-                              "%*s  %sfailed to match trie start class...%s\n",
-                              REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+                    Perl_re_indentfo( "%sfailed to match trie start class...%s\n",
+                              depth, PL_colors[4], PL_colors[5])
                 );
                 sayNO_SILENT;
                 NOT_REACHED; /* NOTREACHED */
@@ -5385,17 +5413,15 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                 {
                    if (trie->states[ state ].wordnum) {
                         DEBUG_EXECUTE_r(
-                            PerlIO_printf(Perl_debug_log,
-                                         "%*s  %smatched empty string...%s\n",
-                                         REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+                            Perl_re_indentfo( "%smatched empty string...%s\n",
+                                          depth, PL_colors[4], PL_colors[5])
                         );
                        if (!trie->jump)
                            break;
                    } else {
                        DEBUG_EXECUTE_r(
-                            PerlIO_printf(Perl_debug_log,
-                                         "%*s  %sfailed to match trie start class...%s\n",
-                                         REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+                            Perl_re_indentfo( "%sfailed to match trie start class...%s\n",
+                                          depth, PL_colors[4], PL_colors[5])
                         );
                        sayNO_SILENT;
                   }
@@ -5447,10 +5473,10 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                    }
 
                    DEBUG_TRIE_EXECUTE_r({
-                               DUMP_EXEC_POS( (char *)uc, scan, utf8_target );
-                               PerlIO_printf( Perl_debug_log,
-                                   "%*s  %sState: %4"UVxf" Accepted: %c ",
-                                   2+depth * 2, "", PL_colors[4],
+                                DUMP_EXEC_POS( (char *)uc, scan, utf8_target, depth );
+                                Perl_re_indentfo(
+                                    "%sState: %4"UVxf" Accepted: %c ",
+                                    depth, PL_colors[4],
                                    (UV)state, (accepted ? 'Y' : 'N'));
                    });
 
@@ -5482,7 +5508,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                        state = 0;
                    }
                    DEBUG_TRIE_EXECUTE_r(
-                       PerlIO_printf( Perl_debug_log,
+                        Perl_re_printf(
                            "Charid:%3x CP:%4"UVxf" After State: %4"UVxf"%s\n",
                            charid, uvc, (UV)state, PL_colors[5] );
                    );
@@ -5502,9 +5528,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                }
 
                DEBUG_EXECUTE_r(
-                   PerlIO_printf( Perl_debug_log,
-                       "%*s  %sgot %"IVdf" possible matches%s\n",
-                       REPORT_CODE_OFF + depth * 2, "",
+                    Perl_re_indentfo( "%sgot %"IVdf" possible matches%s\n",
+                        depth,
                        PL_colors[4], (IV)ST.accepted, PL_colors[5] );
                );
                goto trie_first_try; /* jump into the fail handler */
@@ -5520,9 +5545,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
            }
            if (!--ST.accepted) {
                DEBUG_EXECUTE_r({
-                   PerlIO_printf( Perl_debug_log,
-                       "%*s  %sTRIE failed...%s\n",
-                       REPORT_CODE_OFF+depth*2, "", 
+                    Perl_re_indentfo( "%sTRIE failed...%s\n",
+                        depth,
                        PL_colors[4],
                        PL_colors[5] );
                });
@@ -5612,9 +5636,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                            : NEXT_OFF(ST.me));
 
            DEBUG_EXECUTE_r({
-               PerlIO_printf( Perl_debug_log,
-                   "%*s  %sTRIE matched word #%d, continuing%s\n",
-                   REPORT_CODE_OFF+depth*2, "", 
+                Perl_re_indentfo( "%sTRIE matched word #%d, continuing%s\n",
+                    depth,
                    PL_colors[4],
                    ST.nextword,
                    PL_colors[5]
@@ -5633,9 +5656,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                         ? av_fetch(trie_words, ST.nextword - 1, 0) : NULL;
                SV *sv= tmp ? sv_newmortal() : NULL;
 
-               PerlIO_printf( Perl_debug_log,
-                   "%*s  %sonly one match left, short-circuiting: #%d <%s>%s\n",
-                   REPORT_CODE_OFF+depth*2, "", PL_colors[4],
+                Perl_re_indentfo( "%sonly one match left, short-circuiting: #%d <%s>%s\n",
+                    depth, PL_colors[4],
                    ST.nextword,
                    tmp ? pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 0,
                            PL_colors[0], PL_colors[1],
@@ -6527,9 +6549,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                 DEBUG_r({
                     GET_RE_DEBUG_FLAGS_DECL;
                     DEBUG_EXECUTE_r({
-                        PerlIO_printf(Perl_debug_log,
-                                    "%*s  pattern left-recursion without consuming input always fails...\n",
-                                    REPORT_CODE_OFF + depth*2, "");
+                        Perl_re_indentfo( "  pattern left-recursion without consuming input always fails...\n",
+                                    depth);
                     });
                 });
                 /* this would be infinite recursion, so we fail */
@@ -6656,7 +6677,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                }
                nop = nop->op_next;
 
-               DEBUG_STATE_r( PerlIO_printf(Perl_debug_log, 
+                DEBUG_STATE_r( Perl_re_printf(
                    "  re EVAL PL_op=0x%"UVxf"\n", PTR2UV(nop)) );
 
                rex->offs[0].end = locinput - reginfo->strbeg;
@@ -6892,7 +6913,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
            rex->offs[n].start_tmp = locinput - reginfo->strbeg;
            if (n > maxopenparen)
                maxopenparen = n;
-           DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+            DEBUG_BUFFERS_r(Perl_re_printf(
                "rex=0x%"UVxf" offs=0x%"UVxf": \\%"UVuf": set %"IVdf" tmp; maxopenparen=%"UVuf"\n",
                PTR2UV(rex),
                PTR2UV(rex->offs),
@@ -6907,7 +6928,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
 #define CLOSE_CAPTURE \
     rex->offs[n].start = rex->offs[n].start_tmp; \
     rex->offs[n].end = locinput - reginfo->strbeg; \
-    DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log, \
+    DEBUG_BUFFERS_r(Perl_re_printf( \
        "rex=0x%"UVxf" offs=0x%"UVxf": \\%"UVuf": set %"IVdf"..%"IVdf"\n", \
        PTR2UV(rex), \
        PTR2UV(rex->offs), \
@@ -7136,9 +7157,8 @@ NULL
            ST.cache_mask = 0;
            
 
-           DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
-                 "%*s  whilem: matched %ld out of %d..%d\n",
-                 REPORT_CODE_OFF+depth*2, "", (long)n, min, max)
+            DEBUG_EXECUTE_r( Perl_re_indentfo( "whilem: matched %ld out of %d..%d\n",
+                  depth, (long)n, min, max)
            );
 
            /* First just match a string of min A's. */
@@ -7156,9 +7176,8 @@ NULL
            /* If degenerate A matches "", assume A done. */
 
            if (locinput == cur_curlyx->u.curlyx.lastloc) {
-               DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
-                  "%*s  whilem: empty match detected, trying continuation...\n",
-                  REPORT_CODE_OFF+depth*2, "")
+                DEBUG_EXECUTE_r( Perl_re_indentfo( "whilem: empty match detected, trying continuation...\n",
+                   depth)
                );
                goto do_whilem_B_max;
            }
@@ -7224,7 +7243,7 @@ NULL
                        reginfo->poscache_size = size;
                        Newxz(aux->poscache, size, char);
                    }
-                   DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+                    DEBUG_EXECUTE_r( Perl_re_printf(
       "%swhilem: Detected a super-linear match, switching on caching%s...\n",
                              PL_colors[4], PL_colors[5])
                    );
@@ -7241,9 +7260,8 @@ NULL
                    mask    = 1 << (offset % 8);
                    offset /= 8;
                    if (reginfo->info_aux->poscache[offset] & mask) {
-                       DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
-                           "%*s  whilem: (cache) already tried at this position...\n",
-                           REPORT_CODE_OFF+depth*2, "")
+                        DEBUG_EXECUTE_r( Perl_re_indentfo( "whilem: (cache) already tried at this position...\n",
+                            depth)
                        );
                        sayNO; /* cache records failure */
                    }
@@ -7305,9 +7323,8 @@ NULL
        case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
            REGCP_UNWIND(ST.lastcp);
            regcppop(rex, &maxopenparen); /* Restore some previous $<digit>s? */
-           DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
-               "%*s  whilem: failed, trying continuation...\n",
-               REPORT_CODE_OFF+depth*2, "")
+            DEBUG_EXECUTE_r(Perl_re_indentfo( "whilem: failed, trying continuation...\n",
+                depth)
            );
          do_whilem_B_max:
            if (cur_curlyx->u.curlyx.count >= REG_INFTY
@@ -7349,8 +7366,7 @@ NULL
                CACHEsayNO;
            }
 
-           DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
-               "%*s  trying longer...\n", REPORT_CODE_OFF+depth*2, "")
+            DEBUG_EXECUTE_r(Perl_re_indentfo( "trying longer...\n", depth)
            );
            /* Try grabbing another A and see if it helps. */
            cur_curlyx->u.curlyx.lastloc = locinput;
@@ -7417,9 +7433,8 @@ NULL
            /* no more branches? */
            if (!scan || (OP(scan) != BRANCH && OP(scan) != BRANCHJ)) {
                DEBUG_EXECUTE_r({
-                   PerlIO_printf( Perl_debug_log,
-                       "%*s  %sBRANCH failed...%s\n",
-                       REPORT_CODE_OFF+depth*2, "", 
+                    Perl_re_indentfo( "%sBRANCH failed...%s\n",
+                        depth,
                        PL_colors[4],
                        PL_colors[5] );
                });
@@ -7490,10 +7505,8 @@ NULL
                    ST.count = ST.minmod ? ARG1(ST.me) : ARG2(ST.me);
            }
            DEBUG_EXECUTE_r(
-               PerlIO_printf(Perl_debug_log,
-                         "%*s  CURLYM now matched %"IVdf" times, len=%"IVdf"...\n",
-                         (int)(REPORT_CODE_OFF+(depth*2)), "",
-                         (IV) ST.count, (IV)ST.alen)
+                Perl_re_indentfo( "CURLYM now matched %"IVdf" times, len=%"IVdf"...\n",
+                          depth, (IV) ST.count, (IV)ST.alen)
            );
 
             if (EVAL_CLOSE_PAREN_IS(cur_eval,(U32)ST.me->flags))
@@ -7545,10 +7558,8 @@ NULL
            }
 
            DEBUG_EXECUTE_r(
-               PerlIO_printf(Perl_debug_log,
-                   "%*s  CURLYM trying tail with matches=%"IVdf"...\n",
-                   (int)(REPORT_CODE_OFF+(depth*2)),
-                   "", (IV)ST.count)
+                Perl_re_indentfo( "CURLYM trying tail with matches=%"IVdf"...\n",
+                    depth, (IV)ST.count)
                );
            if (! NEXTCHR_IS_EOS && ST.c1 != CHRTEST_VOID) {
                 if (! UTF8_IS_INVARIANT(nextchr) && utf8_target) {
@@ -7557,9 +7568,8 @@ NULL
                     {
                         /* simulate B failing */
                         DEBUG_OPTIMISE_r(
-                            PerlIO_printf(Perl_debug_log,
-                                "%*s  CURLYM Fast bail next target=0x%"UVXf" c1=0x%"UVXf" c2=0x%"UVXf"\n",
-                                (int)(REPORT_CODE_OFF+(depth*2)),"",
+                            Perl_re_indentfo( "CURLYM Fast bail next target=0x%"UVXf" c1=0x%"UVXf" c2=0x%"UVXf"\n",
+                                depth,
                                 valid_utf8_to_uvchr((U8 *) locinput, NULL),
                                 valid_utf8_to_uvchr(ST.c1_utf8, NULL),
                                 valid_utf8_to_uvchr(ST.c2_utf8, NULL))
@@ -7571,9 +7581,8 @@ NULL
                 else if (nextchr != ST.c1 && nextchr != ST.c2) {
                     /* simulate B failing */
                     DEBUG_OPTIMISE_r(
-                        PerlIO_printf(Perl_debug_log,
-                            "%*s  CURLYM Fast bail next target=0x%X c1=0x%X c2=0x%X\n",
-                            (int)(REPORT_CODE_OFF+(depth*2)),"",
+                        Perl_re_indentfo( "CURLYM Fast bail next target=0x%X c1=0x%X c2=0x%X\n",
+                            depth,
                             (int) nextchr, ST.c1, ST.c2)
                     );
                     state_num = CURLYM_B_fail;
@@ -7962,8 +7971,8 @@ NULL
                st->u.eval.prev_eval = cur_eval;
                cur_eval = cur_eval->u.eval.prev_eval;
                DEBUG_EXECUTE_r(
-                   PerlIO_printf(Perl_debug_log, "%*s  EVAL trying tail ... %"UVxf"\n",
-                                     REPORT_CODE_OFF+depth*2, "",PTR2UV(cur_eval)););
+                    Perl_re_indentfo( "  EVAL trying tail ... %"UVxf"\n",
+                                      depth,PTR2UV(cur_eval)););
                 if ( nochange_depth )
                    nochange_depth--;
 
@@ -7972,8 +7981,8 @@ NULL
            }
 
            if (locinput < reginfo->till) {
-               DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
-                                     "%sMatch possible, but length=%ld is smaller than requested=%ld, failing!%s\n",
+                DEBUG_EXECUTE_r(Perl_re_printf(
+                                      "%sMatch possible, but length=%ld is smaller than requested=%ld, failing!%s\n",
                                      PL_colors[4],
                                      (long)(locinput - startpos),
                                      (long)(reginfo->till - startpos),
@@ -7985,9 +7994,8 @@ NULL
 
        case SUCCEED: /* successful SUSPEND/UNLESSM/IFMATCH/CURLYM */
            DEBUG_EXECUTE_r(
-           PerlIO_printf(Perl_debug_log,
-               "%*s  %ssubpattern success...%s\n",
-               REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5]));
+            Perl_re_indentfo( "%ssubpattern success...%s\n",
+                depth, PL_colors[4], PL_colors[5]));
            sayYES;                     /* Success! */
 
 #undef  ST
@@ -8121,9 +8129,8 @@ NULL
                 sv_commit = ST.mark_name;
 
                 DEBUG_EXECUTE_r({
-                        PerlIO_printf(Perl_debug_log,
-                           "%*s  %ssetting cutpoint to mark:%"SVf"...%s\n",
-                           REPORT_CODE_OFF+depth*2, "", 
+                        Perl_re_indentfo( "%ssetting cutpoint to mark:%"SVf"...%s\n",
+                            depth,
                            PL_colors[4], SVfARG(sv_commit), PL_colors[5]);
                });
             }
@@ -8227,13 +8234,13 @@ NULL
                regmatch_state *curyes = yes_state;
                int curd = depth;
                regmatch_slab *slab = PL_regmatch_slab;
-                for (;curd > -1;cur--,curd--) {
+                for (;curd > -1 && (depth-curd < 3);cur--,curd--) {
                     if (cur < SLAB_FIRST(slab)) {
                        slab = slab->prev;
                        cur = SLAB_LAST(slab);
                     }
-                    PerlIO_printf(Perl_error_log, "%*s#%-3d %-10s %s\n",
-                        REPORT_CODE_OFF + 2 + depth * 2,"",
+                    Perl_re_indentfo("#%-3d %-10s %s\n",
+                        depth,
                         curd, PL_reg_name[cur->resume_state],
                         (curyes == cur) ? "yes" : ""
                     );
@@ -8306,7 +8313,7 @@ NULL
        goto reenter_switch;
     }
 
-    DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch successful!%s\n",
+    DEBUG_EXECUTE_r(Perl_re_printf( "%sMatch successful!%s\n",
                          PL_colors[4], PL_colors[5]));
 
     if (reginfo->info_aux_eval) {
@@ -8327,9 +8334,8 @@ NULL
 
   no:
     DEBUG_EXECUTE_r(
-       PerlIO_printf(Perl_debug_log,
-            "%*s  %sfailed...%s\n",
-            REPORT_CODE_OFF+depth*2, "", 
+        Perl_re_indentfo( "%sfailed...%s\n",
+            depth,
             PL_colors[4], PL_colors[5])
        );
 
@@ -8915,9 +8921,8 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
        DEBUG_EXECUTE_r({
            SV * const prop = sv_newmortal();
             regprop(prog, prop, p, reginfo, NULL);
-           PerlIO_printf(Perl_debug_log,
-                       "%*s  %s can match %"IVdf" times out of %"IVdf"...\n",
-                       REPORT_CODE_OFF + depth*2, "", SvPVX_const(prop),(IV)c,(IV)max);
+            Perl_re_indentfo( "%s can match %"IVdf" times out of %"IVdf"...\n",
+                        depth, SvPVX_const(prop),(IV)c,(IV)max);
        });
     });