const declaration fixup
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index 143888d..ed392cc 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1015,6 +1015,16 @@ PP(pp_flop)
 
 /* Control. */
 
+static char *context_name[] = {
+    "pseudo-block",
+    "subroutine",
+    "eval",
+    "loop",
+    "substitution",
+    "block",
+    "format"
+};
+
 STATIC I32
 S_dopoptolabel(pTHX_ char *label)
 {
@@ -1025,30 +1035,16 @@ S_dopoptolabel(pTHX_ char *label)
        cx = &cxstack[i];
        switch (CxTYPE(cx)) {
        case CXt_SUBST:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_SUB:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_FORMAT:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_EVAL:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_NULL:
            if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s",
-                       OP_NAME(PL_op));
-           return -1;
+               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+                       context_name[CxTYPE(cx)], OP_NAME(PL_op));
+           if (CxTYPE(cx) == CXt_NULL)
+               return -1;
+           break;
        case CXt_LOOP:
            if (!cx->blk_loop.label ||
              strNE(label, cx->blk_loop.label) ) {
@@ -1160,30 +1156,16 @@ S_dopoptoloop(pTHX_ I32 startingblock)
        cx = &cxstack[i];
        switch (CxTYPE(cx)) {
        case CXt_SUBST:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_SUB:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_FORMAT:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_EVAL:
-           if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s",
-                       OP_NAME(PL_op));
-           break;
        case CXt_NULL:
            if (ckWARN(WARN_EXITING))
-               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s",
-                       OP_NAME(PL_op));
-           return -1;
+               Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+                       context_name[CxTYPE(cx)], OP_NAME(PL_op));
+           if ((CxTYPE(cx)) == CXt_NULL)
+               return -1;
+           break;
        case CXt_LOOP:
            DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i));
            return i;
@@ -1820,7 +1802,7 @@ PP(pp_return)
            /* Unassume the success we assumed earlier. */
            SV *nsv = cx->blk_eval.old_namesv;
            (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
-           DIE(aTHX_ "%s did not return a true value", SvPVX(nsv));
+           DIE(aTHX_ "%"SVf" did not return a true value", nsv);
        }
        break;
     case CXt_FORMAT:
@@ -2048,11 +2030,15 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit)
        for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
            if (kid == PL_lastgotoprobe)
                continue;
-           if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) &&
-               (ops == opstack ||
-                (ops[-1]->op_type != OP_NEXTSTATE &&
-                 ops[-1]->op_type != OP_DBSTATE)))
-               *ops++ = kid;
+           if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
+               if (ops == opstack)
+                   *ops++ = kid;
+               else if (ops[-1]->op_type == OP_NEXTSTATE ||
+                        ops[-1]->op_type == OP_DBSTATE)
+                   ops[-1] = kid;
+               else
+                   *ops++ = kid;
+           }
            if ((o = dofindlabel(kid, label, ops, oplimit)))
                return o;
        }
@@ -2108,7 +2094,7 @@ PP(pp_goto)
                        goto retry;
                    tmpstr = sv_newmortal();
                    gv_efullname3(tmpstr, gv, Nullch);
-                   DIE(aTHX_ "Goto undefined subroutine &%s",SvPVX(tmpstr));
+                   DIE(aTHX_ "Goto undefined subroutine &%"SVf"",tmpstr);
                }
                DIE(aTHX_ "Goto undefined subroutine");
            }
@@ -2573,7 +2559,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     char *tmpbuf = tbuf;
     char *safestr;
     int runtime;
-    CV* runcv;
+    CV* runcv = Nullcv;        /* initialise to avoid compiler warnings */
 
     ENTER;
     lex_start(sv);
@@ -2615,7 +2601,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     /* we get here either during compilation, or via pp_regcomp at runtime */
     runtime = PL_op && (PL_op->op_type == OP_REGCOMP);
     if (runtime)
-       runcv = find_runcv();
+       runcv = find_runcv(NULL);
 
     PL_op = &dummy;
     PL_op->op_type = OP_ENTEREVAL;
@@ -2649,22 +2635,35 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
 =for apidoc find_runcv
 
 Locate the CV corresponding to the currently executing sub or eval.
+If db_seqp is non_null, skip CVs that are in the DB package and populate
+*db_seqp with the cop sequence number at the point that the DB:: code was
+entered. (allows debuggers to eval in the scope of the breakpoint rather
+than in in the scope of the debuger itself).
 
 =cut
 */
 
 CV*
-Perl_find_runcv(pTHX)
+Perl_find_runcv(pTHX_ U32 *db_seqp)
 {
     I32                 ix;
     PERL_SI     *si;
     PERL_CONTEXT *cx;
 
+    if (db_seqp)
+       *db_seqp = PL_curcop->cop_seq;
     for (si = PL_curstackinfo; si; si = si->si_prev) {
        for (ix = si->si_cxix; ix >= 0; ix--) {
            cx = &(si->si_cxstack[ix]);
-           if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
-               return cx->blk_sub.cv;
+           if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
+               CV *cv = cx->blk_sub.cv;
+               /* skip DB:: code */
+               if (db_seqp && PL_debstash && CvSTASH(cv) == PL_debstash) {
+                   *db_seqp = cx->blk_oldcop->cop_seq;
+                   continue;
+               }
+               return cv;
+           }
            else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx))
                return PL_compcv;
        }
@@ -3222,6 +3221,7 @@ PP(pp_entereval)
     STRLEN len;
     OP *ret;
     CV* runcv;
+    U32 seq;
 
     if (!SvPV(sv,len))
        RETPUSHUNDEF;
@@ -3269,7 +3269,12 @@ PP(pp_entereval)
         PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
         SAVEFREESV(PL_compiling.cop_io);
     }
-    runcv = find_runcv();
+    /* special case: an eval '' executed within the DB package gets lexically
+     * placed in the first non-DB CV rather than the current CV - this
+     * allows the debugger to execute code, find lexicals etc, in the
+     * scope of the code being debugged. Passing &seq gets find_runcv
+     * to do the dirty work for us */
+    runcv = find_runcv(&seq);
 
     push_return(PL_op->op_next);
     PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
@@ -3280,7 +3285,7 @@ PP(pp_entereval)
     if (PERLDB_LINE && PL_curstash != PL_debstash)
        save_lines(CopFILEAV(&PL_compiling), PL_linestr);
     PUTBACK;
-    ret = doeval(gimme, NULL, runcv, PL_curcop->cop_seq);
+    ret = doeval(gimme, NULL, runcv, seq);
     if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */
        && ret != PL_op->op_next) {     /* Successive compilation. */
        strcpy(safestr, "_<(eval )");   /* Anything fake and short. */
@@ -3344,7 +3349,7 @@ PP(pp_leaveeval)
        /* Unassume the success we assumed earlier. */
        SV *nsv = cx->blk_eval.old_namesv;
        (void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
-       retop = Perl_die(aTHX_ "%s did not return a true value", SvPVX(nsv));
+       retop = Perl_die(aTHX_ "%"SVf" did not return a true value", nsv);
        /* die_where() did LEAVE, or we won't be here */
     }
     else {