This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix htmllink.t to cater for the case where perladmin isn't an empty
[perl5.git] / pp_ctl.c
index 7ff4858..43db9de 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -284,8 +284,12 @@ PP(pp_substcont)
        if (SvTYPE(sv) < SVt_PVMG)
            SvUPGRADE(sv, SVt_PVMG);
        if (!(mg = mg_find(sv, PERL_MAGIC_regex_global))) {
-           sv_magic(sv, NULL, PERL_MAGIC_regex_global, NULL, 0);
-           mg = mg_find(sv, PERL_MAGIC_regex_global);
+#ifdef PERL_OLD_COPY_ON_WRITE
+           if (SvIsCOW(lsv))
+               sv_force_normal_flags(sv, 0);
+#endif
+           mg = sv_magicext(sv, NULL, PERL_MAGIC_regex_global, &PL_vtbl_mglob,
+                            NULL, 0);
        }
        i = m - orig;
        if (DO_UTF8(sv))
@@ -376,7 +380,7 @@ Perl_rxres_free(pTHX_ void **rsp)
        void *tmp = INT2PTR(char*,*p);
        Safefree(tmp);
        if (*p)
-           Poison(*p, 1, sizeof(*p));
+           PoisonFree(*p, 1, sizeof(*p));
 #else
        Safefree(INT2PTR(char*,*p));
 #endif
@@ -1616,7 +1620,7 @@ PP(pp_caller)
        RETURN;
     }
 
-    EXTEND(SP, 10);
+    EXTEND(SP, 11);
 
     if (!stashname)
        PUSHs(&PL_sv_undef);
@@ -1691,11 +1695,10 @@ PP(pp_caller)
     /* XXX only hints propagated via op_private are currently
      * visible (others are not easily accessible, since they
      * use the global PL_hints) */
-    PUSHs(sv_2mortal(newSViv((I32)cx->blk_oldcop->op_private &
-                            HINT_PRIVATE_MASK)));
+    PUSHs(sv_2mortal(newSViv(CopHINTS_get(cx->blk_oldcop))));
     {
        SV * mask ;
-       SV * const old_warnings = cx->blk_oldcop->cop_warnings ;
+       STRLEN * const old_warnings = cx->blk_oldcop->cop_warnings ;
 
        if  (old_warnings == pWARN_NONE ||
                (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
@@ -1714,9 +1717,15 @@ PP(pp_caller)
            }
        }
         else
-            mask = newSVsv(old_warnings);
+            mask = newSVpvn((char *) (old_warnings + 1), old_warnings[0]);
         PUSHs(sv_2mortal(mask));
     }
+
+    PUSHs(cx->blk_oldcop->cop_hints ?
+         sv_2mortal(newRV_noinc(
+               (SV*)Perl_refcounted_he_chain_2hv(aTHX_
+                                                 cx->blk_oldcop->cop_hints)))
+         : &PL_sv_undef);
     RETURN;
 }
 
@@ -2498,7 +2507,7 @@ PP(pp_goto)
 
        /* find label */
 
-       PL_lastgotoprobe = 0;
+       PL_lastgotoprobe = NULL;
        *enterops = 0;
        for (ix = cxstack_ix; ix >= 0; ix--) {
            cx = &cxstack[ix];
@@ -2805,7 +2814,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
     *padp = (AV*)SvREFCNT_inc_simple(PL_comppad);
     LEAVE;
     if (IN_PERL_COMPILETIME)
-       PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
+       CopHINTS_set(&PL_compiling, PL_hints);
 #ifdef OP_IN_REGISTER
     op = PL_opsave;
 #endif
@@ -2915,7 +2924,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
     PL_eval_root = NULL;
     PL_error_count = 0;
     PL_curcop = &PL_compiling;
-    PL_curcop->cop_arybase = 0;
+    CopARYBASE_set(PL_curcop, 0);
     if (saveop && (saveop->op_type != OP_REQUIRE) && (saveop->op_flags & OPf_SPECIAL))
        PL_in_eval |= EVAL_KEEPERR;
     else
@@ -3011,14 +3020,10 @@ S_check_type_and_open(pTHX_ const char *name, const char *mode)
 {
     Stat_t st;
     const int st_rc = PerlLIO_stat(name, &st);
-    if (st_rc < 0) {
+    if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
        return NULL;
     }
 
-    if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
-       Perl_die(aTHX_ "%s %s not allowed in require",
-           S_ISDIR(st.st_mode) ? "Directory" : "Block device", name);
-    }
     return PerlIO_open(name, mode);
 }
 
@@ -3037,15 +3042,7 @@ S_doopen_pm(pTHX_ const char *name, const char *mode)
            fp = check_type_and_open(name, mode);
        }
        else {
-           Stat_t pmstat;
-           if (PerlLIO_stat(name, &pmstat) < 0 ||
-               pmstat.st_mtime < pmcstat.st_mtime)
-           {
-               fp = check_type_and_open(pmc, mode);
-           }
-           else {
-               fp = check_type_and_open(name, mode);
-           }
+           fp = check_type_and_open(pmc, mode);
        }
        SvREFCNT_dec(pmcsv);
     }
@@ -3070,7 +3067,6 @@ PP(pp_require)
     const I32 gimme = GIMME_V;
     int filter_has_file = 0;
     PerlIO *tryrsfp = NULL;
-    GV *filter_child_proc = NULL;
     SV *filter_state = NULL;
     SV *filter_sub = NULL;
     SV *hook_sv = NULL;
@@ -3189,23 +3185,11 @@ PP(pp_require)
 
                            if (io) {
                                tryrsfp = IoIFP(io);
-                               if (IoTYPE(io) == IoTYPE_PIPE) {
-                                   /* reading from a child process doesn't
-                                      nest -- when returning from reading
-                                      the inner module, the outer one is
-                                      unreadable (closed?)  I've tried to
-                                      save the gv to manage the lifespan of
-                                      the pipe, but this didn't help. XXX */
-                                   filter_child_proc = (GV *)arg;
-                                   SvREFCNT_inc_simple_void(filter_child_proc);
-                               }
-                               else {
-                                   if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
-                                       PerlIO_close(IoOFP(io));
-                                   }
-                                   IoIFP(io) = NULL;
-                                   IoOFP(io) = NULL;
+                               if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
+                                   PerlIO_close(IoOFP(io));
                                }
+                               IoIFP(io) = NULL;
+                               IoOFP(io) = NULL;
                            }
 
                            if (i < count) {
@@ -3223,7 +3207,8 @@ PP(pp_require)
                            }
 
                            if (!tryrsfp) {
-                               tryrsfp = PerlIO_open("/dev/null", PERL_SCRIPT_MODE);
+                               tryrsfp = PerlIO_open(BIT_BUCKET,
+                                                     PERL_SCRIPT_MODE);
                            }
                        }
                        SP--;
@@ -3239,10 +3224,6 @@ PP(pp_require)
                    }
 
                    filter_has_file = 0;
-                   if (filter_child_proc) {
-                       SvREFCNT_dec(filter_child_proc);
-                       filter_child_proc = NULL;
-                   }
                    if (filter_state) {
                        SvREFCNT_dec(filter_state);
                        filter_state = NULL;
@@ -3366,22 +3347,23 @@ PP(pp_require)
     PL_rsfp = tryrsfp;
     SAVEHINTS();
     PL_hints = 0;
-    SAVESPTR(PL_compiling.cop_warnings);
+    SAVECOMPILEWARNINGS();
     if (PL_dowarn & G_WARN_ALL_ON)
         PL_compiling.cop_warnings = pWARN_ALL ;
     else if (PL_dowarn & G_WARN_ALL_OFF)
         PL_compiling.cop_warnings = pWARN_NONE ;
-    else if (PL_taint_warn)
-        PL_compiling.cop_warnings = newSVpvn(WARN_TAINTstring, WARNsize);
+    else if (PL_taint_warn) {
+        PL_compiling.cop_warnings
+           = Perl_new_warnings_bitfield(aTHX_ NULL, WARN_TAINTstring, WARNsize);
+    }
     else
         PL_compiling.cop_warnings = pWARN_STD ;
     SAVESPTR(PL_compiling.cop_io);
     PL_compiling.cop_io = NULL;
 
-    if (filter_sub || filter_child_proc) {
+    if (filter_sub) {
        SV * const datasv = filter_add(S_run_user_filter, NULL);
        IoLINES(datasv) = filter_has_file;
-       IoFMT_GV(datasv) = (GV *)filter_child_proc;
        IoTOP_GV(datasv) = (GV *)filter_state;
        IoBOTTOM_GV(datasv) = (GV *)filter_sub;
     }
@@ -3464,13 +3446,8 @@ PP(pp_entereval)
     PL_hints = PL_op->op_targ;
     if (saved_hh)
        GvHV(PL_hintgv) = saved_hh;
-    SAVESPTR(PL_compiling.cop_warnings);
-    if (specialWARN(PL_curcop->cop_warnings))
-        PL_compiling.cop_warnings = PL_curcop->cop_warnings;
-    else {
-        PL_compiling.cop_warnings = newSVsv(PL_curcop->cop_warnings);
-        SAVEFREESV(PL_compiling.cop_warnings);
-    }
+    SAVECOMPILEWARNINGS();
+    PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
     SAVESPTR(PL_compiling.cop_io);
     if (specialCopIO(PL_curcop->cop_io))
         PL_compiling.cop_io = PL_curcop->cop_io;
@@ -3478,6 +3455,15 @@ PP(pp_entereval)
         PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
         SAVEFREESV(PL_compiling.cop_io);
     }
+    if (PL_compiling.cop_hints) {
+       Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints);
+    }
+    PL_compiling.cop_hints = PL_curcop->cop_hints;
+    if (PL_compiling.cop_hints) {
+       HINTS_REFCNT_LOCK;
+       PL_compiling.cop_hints->refcounted_he_refcnt++;
+       HINTS_REFCNT_UNLOCK;
+    }
     /* 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
@@ -3570,22 +3556,57 @@ PP(pp_leaveeval)
     RETURNOP(retop);
 }
 
-PP(pp_entertry)
+/* Common code for Perl_call_sv and Perl_fold_constants, put here to keep it
+   close to the related Perl_create_eval_scope.  */
+void
+Perl_delete_eval_scope(pTHX)
 {
-    dVAR; dSP;
+    SV **newsp;
+    PMOP *newpm;
+    I32 gimme;
     register PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    I32 optype;
+       
+    POPBLOCK(cx,newpm);
+    POPEVAL(cx);
+    PL_curpm = newpm;
+    LEAVE;
+    PERL_UNUSED_VAR(newsp);
+    PERL_UNUSED_VAR(gimme);
+    PERL_UNUSED_VAR(optype);
+}
 
+/* Common-ish code salvaged from Perl_call_sv and pp_entertry, because it was
+   also needed by Perl_fold_constants.  */
+PERL_CONTEXT *
+Perl_create_eval_scope(pTHX_ U32 flags)
+{
+    PERL_CONTEXT *cx;
+    const I32 gimme = GIMME_V;
+       
     ENTER;
     SAVETMPS;
 
-    PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP);
+    PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
     PUSHEVAL(cx, 0, 0);
-    cx->blk_eval.retop = cLOGOP->op_other->op_next;
+    PL_eval_root = PL_op;      /* Only needed so that goto works right. */
 
     PL_in_eval = EVAL_INEVAL;
-    sv_setpvn(ERRSV,"",0);
-    PUTBACK;
+    if (flags & G_KEEPERR)
+       PL_in_eval |= EVAL_KEEPERR;
+    else
+       sv_setpvn(ERRSV,"",0);
+    if (flags & G_FAKINGEVAL) {
+       PL_eval_root = PL_op; /* Only needed so that goto works right. */
+    }
+    return cx;
+}
+    
+PP(pp_entertry)
+{
+    dVAR;
+    PERL_CONTEXT *cx = create_eval_scope(0);
+    cx->blk_eval.retop = cLOGOP->op_other->op_next;
     return DOCATCH(PL_op->op_next);
 }
 
@@ -4035,7 +4056,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
                PUSHs(other);
                PUSHs(*svp);
                PUTBACK;
-               if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+               if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
                    (void) pp_i_eq();
                else
                    (void) pp_eq();
@@ -4129,7 +4150,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
        /* Otherwise, numeric comparison */
        PUSHs(d); PUSHs(e);
        PUTBACK;
-       if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+       if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
            (void) pp_i_eq();
        else
            (void) pp_eq();
@@ -4495,21 +4516,70 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
     dVAR;
     SV * const datasv = FILTER_DATA(idx);
     const int filter_has_file = IoLINES(datasv);
-    GV * const filter_child_proc = (GV *)IoFMT_GV(datasv);
     SV * const filter_state = (SV *)IoTOP_GV(datasv);
     SV * const filter_sub = (SV *)IoBOTTOM_GV(datasv);
-    int len = 0;
+    int status = 0;
+    /* Filter API says that the filter appends to the contents of the buffer.
+       Usually the buffer is "", so the details don't matter. But if it's not,
+       then clearly what it contains is already filtered by this filter, so we
+       don't want to pass it in a second time.
+       I'm going to use a mortal in case the upstream filter croaks.  */
+    SV *upstream;
+    STRLEN got_len;
+    const char *got_p;
+    const char *prune_from = NULL;
 
     /* I was having segfault trouble under Linux 2.2.5 after a
        parse error occured.  (Had to hack around it with a test
        for PL_error_count == 0.)  Solaris doesn't segfault --
        not sure where the trouble is yet.  XXX */
 
+    if (IoFMT_GV(datasv)) {
+       SV *const cache = (SV *)IoFMT_GV(datasv);
+       if (SvOK(cache)) {
+           STRLEN cache_len;
+           const char *cache_p = SvPV(cache, cache_len);
+           STRLEN take = 0;
+
+           if (maxlen) {
+               /* Running in block mode and we have some cached data already.
+                */
+               if (cache_len >= maxlen) {
+                   /* In fact, so much data we don't even need to call
+                      filter_read.  */
+                   take = maxlen;
+               }
+           } else {
+               const char *const first_nl = memchr(cache_p, '\n', cache_len);
+               if (first_nl) {
+                   take = first_nl + 1 - cache_p;
+               }
+           }
+           if (take) {
+               sv_catpvn(buf_sv, cache_p, take);
+               sv_chop(cache, cache_p + take);
+               /* Definately not EOF  */
+               return 1;
+           }
+
+           sv_catsv(buf_sv, cache);
+           if (maxlen) {
+               maxlen -= cache_len;
+           }
+           SvOK_off(cache);
+       }
+    }
+
+    upstream = ((SvOK(buf_sv) && sv_len(buf_sv)) || SvGMAGICAL(buf_sv))
+       ? sv_newmortal() : buf_sv;
+    SvUPGRADE(upstream, SVt_PV);
+       
     if (filter_has_file) {
-       len = FILTER_READ(idx+1, buf_sv, maxlen);
+       status = FILTER_READ(idx+1, upstream, 0);
     }
 
-    if (filter_sub && len >= 0) {
+    assert(filter_sub);
+    if (status >= 0) {
        dSP;
        int count;
 
@@ -4518,9 +4588,9 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        SAVETMPS;
        EXTEND(SP, 2);
 
-       DEFSV = buf_sv;
+       DEFSV = upstream;
        PUSHMARK(SP);
-       PUSHs(sv_2mortal(newSViv(maxlen)));
+       PUSHs(sv_2mortal(newSViv(0)));
        if (filter_state) {
            PUSHs(filter_state);
        }
@@ -4531,7 +4601,7 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        if (count > 0) {
            SV *out = POPs;
            if (SvOK(out)) {
-               len = SvIV(out);
+               status = SvIV(out);
            }
        }
 
@@ -4540,12 +4610,53 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        LEAVE;
     }
 
-    if (len <= 0) {
-       IoLINES(datasv) = 0;
-       if (filter_child_proc) {
-           SvREFCNT_dec(filter_child_proc);
-           IoFMT_GV(datasv) = NULL;
+    if(SvOK(upstream)) {
+       got_p = SvPV(upstream, got_len);
+       if (maxlen) {
+           if (got_len > maxlen) {
+               prune_from = got_p + maxlen;
+           }
+       } else {
+           const char *const first_nl = memchr(got_p, '\n', got_len);
+           if (first_nl && first_nl + 1 < got_p + got_len) {
+               /* There's a second line here... */
+               prune_from = first_nl + 1;
+           }
+       }
+    }
+    if (prune_from) {
+       /* Oh. Too long. Stuff some in our cache.  */
+       STRLEN cached_len = got_p + got_len - prune_from;
+       SV *cache = (SV *)IoFMT_GV(datasv);
+
+       if (!cache) {
+           IoFMT_GV(datasv) = (GV*) (cache = newSV(got_len - maxlen));
+       } else if (SvOK(cache)) {
+           /* Cache should be empty.  */
+           assert(!SvCUR(cache));
+       }
+
+       sv_setpvn(cache, prune_from, cached_len);
+       /* If you ask for block mode, you may well split UTF-8 characters.
+          "If it breaks, you get to keep both parts"
+          (Your code is broken if you  don't put them back together again
+          before something notices.) */
+       if (SvUTF8(upstream)) {
+           SvUTF8_on(cache);
        }
+       SvCUR_set(upstream, got_len - cached_len);
+       /* Can't yet be EOF  */
+       if (status == 0)
+           status = 1;
+    }
+
+    if (upstream != buf_sv) {
+       sv_catsv(buf_sv, upstream);
+    }
+
+    if (status <= 0) {
+       IoLINES(datasv) = 0;
+       SvREFCNT_dec(IoFMT_GV(datasv));
        if (filter_state) {
            SvREFCNT_dec(filter_state);
            IoTOP_GV(datasv) = NULL;
@@ -4556,8 +4667,7 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        }
        filter_del(S_run_user_filter);
     }
-
-    return len;
+    return status;
 }
 
 /* perhaps someone can come up with a better name for