This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Implement "my $_".
[perl5.git] / pp_ctl.c
index ac33adf..42d63c6 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1,6 +1,7 @@
 /*    pp_ctl.c
  *
- *    Copyright (c) 1991-2003, Larry Wall
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ *    2000, 2001, 2002, 2003, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -21,7 +22,7 @@
 #include "perl.h"
 
 #ifndef WORD_ALIGN
-#define WORD_ALIGN sizeof(U16)
+#define WORD_ALIGN sizeof(U32)
 #endif
 
 #define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o))
@@ -58,6 +59,7 @@ PP(pp_regcreset)
     /* XXXX Should store the old value to allow for tie/overload - and
        restore in regcomp, where marked with XXXX. */
     PL_reginterp_cnt = 0;
+    TAINT_NOT;
     return NORMAL;
 }
 
@@ -97,7 +99,7 @@ PP(pp_regcomp)
            memNE(PM_GETRE(pm)->precomp, t, len))
        {
            if (PM_GETRE(pm)) {
-               ReREFCNT_dec(PM_GETRE(pm));
+               ReREFCNT_dec(PM_GETRE(pm));
                PM_SETRE(pm, Null(REGEXP*));    /* crucial if regcomp aborts */
            }
            if (PL_op->op_flags & OPf_SPECIAL)
@@ -157,6 +159,12 @@ PP(pp_substcont)
     char *orig = cx->sb_orig;
     register REGEXP *rx = cx->sb_rx;
     SV *nsv = Nullsv;
+    REGEXP *old = PM_GETRE(pm);
+    if(old != rx) {
+       if(old) 
+           ReREFCNT_dec(old);
+       PM_SETRE(pm,rx);
+    }
 
     rxres_restore(&cx->sb_rxres, rx);
     RX_MATCH_UTF8_set(rx, SvUTF8(cx->sb_targ));
@@ -212,6 +220,7 @@ PP(pp_substcont)
            SvTAINT(targ);
 
            LEAVE_SCOPE(cx->sb_oldsave);
+           ReREFCNT_dec(rx);
            POPSUBST(cx);
            RETURNOP(pm->op_next);
        }
@@ -247,6 +256,8 @@ PP(pp_substcont)
            sv_pos_b2u(sv, &i);
        mg->mg_len = i;
     }
+    if (old != rx)
+       ReREFCNT_inc(rx);
     cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
     rxres_save(&cx->sb_rxres, rx);
     RETURNOP(pm->op_pmreplstart);
@@ -337,7 +348,7 @@ PP(pp_formline)
 {
     dSP; dMARK; dORIGMARK;
     register SV *tmpForm = *++MARK;
-    register U16 *fpc;
+    register U32 *fpc;
     register char *t;
     register char *f;
     register char *s;
@@ -358,15 +369,20 @@ PP(pp_formline)
     bool item_is_utf8 = FALSE;
     bool targ_is_utf8 = FALSE;
     SV * nsv = Nullsv;
+    OP * parseres = 0;
+    char *fmt;
+    bool oneline;
 
     if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) {
        if (SvREADONLY(tmpForm)) {
            SvREADONLY_off(tmpForm);
-           doparseform(tmpForm);
+           parseres = doparseform(tmpForm);
            SvREADONLY_on(tmpForm);
        }
        else
-           doparseform(tmpForm);
+           parseres = doparseform(tmpForm);
+       if (parseres)
+           return parseres;
     }
     SvPV_force(PL_formtarget, len);
     if (DO_UTF8(PL_formtarget))
@@ -377,7 +393,7 @@ PP(pp_formline)
     /* need to jump to the next word */
     s = f + len + WORD_ALIGN - SvCUR(tmpForm) % WORD_ALIGN;
 
-    fpc = (U16*)s;
+    fpc = (U32*)s;
 
     for (;;) {
        DEBUG_f( {
@@ -402,6 +418,7 @@ PP(pp_formline)
            case FF_LINEMARK:   name = "LINEMARK";      break;
            case FF_END:        name = "END";           break;
             case FF_0DECIMAL:  name = "0DECIMAL";      break;
+           case FF_LINESNGL:   name = "LINESNGL";      break;
            }
            if (arg >= 0)
                PerlIO_printf(Perl_debug_log, "%-16s%ld\n", name, (long) arg);
@@ -508,6 +525,7 @@ PP(pp_formline)
                        while (s < send) {
                            if (*s == '\r') {
                                itemsize = s - item;
+                               chophere = s;
                                break;
                            }
                            if (*s++ & ~31)
@@ -547,6 +565,7 @@ PP(pp_formline)
                while (s < send) {
                    if (*s == '\r') {
                        itemsize = s - item;
+                       chophere = s;
                        break;
                    }
                    if (*s++ & ~31)
@@ -637,7 +656,7 @@ PP(pp_formline)
                sv_catpvn_utf8_upgrade(PL_formtarget, s, arg, nsv);
                for (; t < SvEND(PL_formtarget); t++) {
 #ifdef EBCDIC
-                   int ch = *t++ = *s++;
+                   int ch = *t;
                    if (iscntrl(ch))
 #else
                    if (!(*t & ~31))
@@ -664,9 +683,16 @@ PP(pp_formline)
                    s++;
            }
            sv_chop(sv,s);
+           SvSETMAGIC(sv);
            break;
 
+       case FF_LINESNGL:
+           chopspace = 0;
+           oneline = TRUE;
+           goto ff_line;
        case FF_LINEGLOB:
+           oneline = FALSE;
+       ff_line:
            item = s = SvPV(sv, len);
            itemsize = len;
            if ((item_is_utf8 = DO_UTF8(sv)))
@@ -675,20 +701,31 @@ PP(pp_formline)
                bool chopped = FALSE;
                gotsome = TRUE;
                send = s + len;
+               chophere = s + itemsize;
                while (s < send) {
                    if (*s++ == '\n') {
-                       if (s == send) {
-                           itemsize--;
+                       if (oneline) {
                            chopped = TRUE;
+                           chophere = s;
+                           break;
+                       } else {
+                           if (s == send) {
+                               itemsize--;
+                               chopped = TRUE;
+                           } else
+                               lines++;
                        }
-                       else
-                           lines++;
                    }
                }
                SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
                if (targ_is_utf8)
                    SvUTF8_on(PL_formtarget);
-               sv_catsv(PL_formtarget, sv);
+               if (oneline) {
+                   SvCUR_set(sv, chophere - item);
+                   sv_catsv(PL_formtarget, sv);
+                   SvCUR_set(sv, itemsize);
+               } else
+                   sv_catsv(PL_formtarget, sv);
                if (chopped)
                    SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) - 1);
                SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
@@ -698,46 +735,24 @@ PP(pp_formline)
            }
            break;
 
+       case FF_0DECIMAL:
+           arg = *fpc++;
+#if defined(USE_LONG_DOUBLE)
+           fmt = (arg & 256) ? "%#0*.*" PERL_PRIfldbl : "%0*.*" PERL_PRIfldbl;
+#else
+           fmt = (arg & 256) ? "%#0*.*f"              : "%0*.*f";
+#endif
+           goto ff_dec;
        case FF_DECIMAL:
-           /* If the field is marked with ^ and the value is undefined,
-              blank it out. */
            arg = *fpc++;
-           if ((arg & 512) && !SvOK(sv)) {
-               arg = fieldsize;
-               while (arg--)
-                   *t++ = ' ';
-               break;
-           }
-           gotsome = TRUE;
-           value = SvNV(sv);
-           /* Formats aren't yet marked for locales, so assume "yes". */
-           {
-               STORE_NUMERIC_STANDARD_SET_LOCAL();
 #if defined(USE_LONG_DOUBLE)
-               if (arg & 256) {
-                   sprintf(t, "%#*.*" PERL_PRIfldbl,
-                           (int) fieldsize, (int) arg & 255, value);
-               } else {
-                   sprintf(t, "%*.0" PERL_PRIfldbl, (int) fieldsize, value);
-               }
+           fmt = (arg & 256) ? "%#*.*" PERL_PRIfldbl : "%*.*" PERL_PRIfldbl;
 #else
-               if (arg & 256) {
-                   sprintf(t, "%#*.*f",
-                           (int) fieldsize, (int) arg & 255, value);
-               } else {
-                   sprintf(t, "%*.0f",
-                           (int) fieldsize, value);
-               }
+            fmt = (arg & 256) ? "%#*.*f"              : "%*.*f";
 #endif
-               RESTORE_NUMERIC_STANDARD();
-           }
-           t += fieldsize;
-           break;
-
-       case FF_0DECIMAL:
+       ff_dec:
            /* If the field is marked with ^ and the value is undefined,
               blank it out. */
-           arg = *fpc++;
            if ((arg & 512) && !SvOK(sv)) {
                arg = fieldsize;
                while (arg--)
@@ -746,31 +761,22 @@ PP(pp_formline)
            }
            gotsome = TRUE;
            value = SvNV(sv);
+           /* overflow evidence */
+           if (num_overflow(value, fieldsize, arg)) { 
+               arg = fieldsize;
+               while (arg--)
+                   *t++ = '#';
+               break;
+           }
            /* Formats aren't yet marked for locales, so assume "yes". */
            {
                STORE_NUMERIC_STANDARD_SET_LOCAL();
-#if defined(USE_LONG_DOUBLE)
-               if (arg & 256) {
-                   sprintf(t, "%#0*.*" PERL_PRIfldbl,
-                           (int) fieldsize, (int) arg & 255, value);
-/* is this legal? I don't have long doubles */
-               } else {
-                   sprintf(t, "%0*.0" PERL_PRIfldbl, (int) fieldsize, value);
-               }
-#else
-               if (arg & 256) {
-                   sprintf(t, "%#0*.*f",
-                           (int) fieldsize, (int) arg & 255, value);
-               } else {
-                   sprintf(t, "%0*.0f",
-                           (int) fieldsize, value);
-               }
-#endif
+               sprintf(t, fmt, (int) fieldsize, (int) arg & 255, value);
                RESTORE_NUMERIC_STANDARD();
            }
            t += fieldsize;
            break;
-       
+
        case FF_NEWLINE:
            f++;
            while (t-- > linemark && *t == ' ') ;
@@ -857,14 +863,19 @@ PP(pp_grepstart)
     ENTER;                                     /* enter outer scope */
 
     SAVETMPS;
-    /* SAVE_DEFSV does *not* suffice here for USE_5005THREADS */
-    SAVESPTR(DEFSV);
+    if (PL_op->op_private & OPpGREP_LEX)
+       SAVESPTR(PAD_SVl(PL_op->op_targ));
+    else
+       SAVE_DEFSV;
     ENTER;                                     /* enter inner scope */
     SAVEVPTR(PL_curpm);
 
     src = PL_stack_base[*PL_markstack_ptr];
     SvTEMP_off(src);
-    DEFSV = src;
+    if (PL_op->op_private & OPpGREP_LEX)
+       PAD_SVl(PL_op->op_targ) = src;
+    else
+       DEFSV = src;
 
     PUTBACK;
     if (PL_op->op_type == OP_MAPSTART)
@@ -880,6 +891,7 @@ PP(pp_mapstart)
 PP(pp_mapwhile)
 {
     dSP;
+    I32 gimme = GIMME_V;
     I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */
     I32 count;
     I32 shift;
@@ -890,7 +902,7 @@ PP(pp_mapwhile)
     ++PL_markstack_ptr[-1];
 
     /* if there are new items, push them into the destination list */
-    if (items) {
+    if (items && gimme != G_VOID) {
        /* might need to make room back there first */
        if (items > PL_markstack_ptr[-1] - PL_markstack_ptr[-2]) {
            /* XXX this implementation is very pessimal because the stack
@@ -934,7 +946,6 @@ PP(pp_mapwhile)
 
     /* All done yet? */
     if (PL_markstack_ptr[-1] > *PL_markstack_ptr) {
-       I32 gimme = GIMME_V;
 
        (void)POPMARK;                          /* pop top */
        LEAVE;                                  /* exit outer scope */
@@ -959,7 +970,10 @@ PP(pp_mapwhile)
        /* set $_ to the new source item */
        src = PL_stack_base[PL_markstack_ptr[-1]];
        SvTEMP_off(src);
-       DEFSV = src;
+       if (PL_op->op_private & OPpGREP_LEX)
+           PAD_SVl(PL_op->op_targ) = src;
+       else
+           DEFSV = src;
 
        RETURNOP(cLOGOP->op_other);
     }
@@ -1019,6 +1033,16 @@ PP(pp_flip)
     }
 }
 
+/* This code tries to decide if "$left .. $right" should use the
+   magical string increment, or if the range is numeric (we make
+   an exception for .."0" [#18165]). AMS 20021031. */
+
+#define RANGE_IS_NUMERIC(left,right) ( \
+       SvNIOKp(left)  || (SvOK(left)  && !SvPOKp(left))  || \
+       SvNIOKp(right) || (SvOK(right) && !SvPOKp(right)) || \
+       (looks_like_number(left) && SvPOKp(left) && *SvPVX(left) != '0' && \
+        looks_like_number(right)))
+
 PP(pp_flop)
 {
     dSP;
@@ -1034,15 +1058,7 @@ PP(pp_flop)
        if (SvGMAGICAL(right))
            mg_get(right);
 
-       /* This code tries to decide if "$left .. $right" should use the
-          magical string increment, or if the range is numeric (we make
-          an exception for .."0" [#18165]). AMS 20021031. */
-
-       if (SvNIOKp(left) || !SvPOKp(left) ||
-           SvNIOKp(right) || !SvPOKp(right) ||
-           (looks_like_number(left) && *SvPVX(left) != '0' &&
-            looks_like_number(right)))
-       {
+       if (RANGE_IS_NUMERIC(left,right)) {
            if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
                DIE(aTHX_ "Range iterator outside integer range");
            i = SvIV(left);
@@ -1317,8 +1333,6 @@ OP *
 Perl_die_where(pTHX_ char *message, STRLEN msglen)
 {
     STRLEN n_a;
-    IO *io;
-    MAGIC *mg;
 
     if (PL_in_eval) {
        I32 cxix;
@@ -1353,8 +1367,6 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
                sv_setpvn(ERRSV, message, msglen);
            }
        }
-       else
-           message = SvPVx(ERRSV, msglen);
 
        while ((cxix = dopoptoeval(cxstack_ix)) < 0
               && PL_curstackinfo->si_prev)
@@ -1371,6 +1383,8 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
 
            POPBLOCK(cx,PL_curpm);
            if (CxTYPE(cx) != CXt_EVAL) {
+               if (!message)
+                   message = SvPVx(ERRSV, msglen);
                PerlIO_write(Perl_error_log, "panic: die ", 11);
                PerlIO_write(Perl_error_log, message, msglen);
                my_exit(1);
@@ -1391,6 +1405,9 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
 
            if (optype == OP_REQUIRE) {
                char* msg = SvPVx(ERRSV, n_a);
+               SV *nsv = cx->blk_eval.old_namesv;
+               (void)hv_store(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv),
+                               &PL_sv_undef, 0);
                DIE(aTHX_ "%sCompilation failed in require",
                    *msg ? msg : "Unknown error\n");
            }
@@ -1400,30 +1417,7 @@ Perl_die_where(pTHX_ char *message, STRLEN msglen)
     if (!message)
        message = SvPVx(ERRSV, msglen);
 
-    /* if STDERR is tied, print to it instead */
-    if (PL_stderrgv && (io = GvIOp(PL_stderrgv))
-       && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) {
-       dSP; ENTER;
-       PUSHMARK(SP);
-       XPUSHs(SvTIED_obj((SV*)io, mg));
-       XPUSHs(sv_2mortal(newSVpvn(message, msglen)));
-       PUTBACK;
-       call_method("PRINT", G_SCALAR);
-       LEAVE;
-    }
-    else {
-#ifdef USE_SFIO
-       /* SFIO can really mess with your errno */
-       int e = errno;
-#endif
-       PerlIO *serr = Perl_error_log;
-
-       PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen);
-       (void)PerlIO_flush(serr);
-#ifdef USE_SFIO
-       errno = e;
-#endif
-    }
+    write_to_stderr(message, msglen);
     my_failure_exit();
     /* NOTREACHED */
     return 0;
@@ -1715,7 +1709,6 @@ PP(pp_dbstate)
        PUSHBLOCK(cx, CXt_SUB, SP);
        PUSHSUB_DB(cx);
        CvDEPTH(cv)++;
-       (void)SvREFCNT_inc(cv);
        PAD_SET_CUR(CvPADLIST(cv),1);
        RETURNOP(CvSTART(cv));
     }
@@ -1743,6 +1736,11 @@ PP(pp_enteriter)
     SAVETMPS;
 
     if (PL_op->op_targ) {
+       if (PL_op->op_private & OPpLVAL_INTRO) { /* for my $x (...) */
+           SvPADSTALE_off(PAD_SVl(PL_op->op_targ));
+           SAVESETSVFLAGS(PAD_SVl(PL_op->op_targ),
+                   SVs_PADSTALE, SVs_PADSTALE);
+       }
 #ifndef USE_ITHREADS
        svp = &PAD_SVl(PL_op->op_targ);         /* "my" variable */
        SAVESPTR(*svp);
@@ -1774,12 +1772,7 @@ PP(pp_enteriter)
        cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
        if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
            dPOPss;
-           /* See comment in pp_flop() */
-           if (SvNIOKp(sv) || !SvPOKp(sv) ||
-               SvNIOKp(cx->blk_loop.iterary) || !SvPOKp(cx->blk_loop.iterary) ||
-               (looks_like_number(sv) && *SvPVX(sv) != '0' &&
-                looks_like_number((SV*)cx->blk_loop.iterary)))
-           {
+           if (RANGE_IS_NUMERIC(sv,(SV*)cx->blk_loop.iterary)) {
                 if (SvNV(sv) < IV_MIN ||
                     SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
                     DIE(aTHX_ "Range iterator outside integer range");
@@ -1890,6 +1883,7 @@ PP(pp_return)
     switch (CxTYPE(cx)) {
     case CXt_SUB:
        popsub2 = TRUE;
+       cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
        break;
     case CXt_EVAL:
        if (!(PL_in_eval & EVAL_KEEPERR))
@@ -1952,6 +1946,7 @@ PP(pp_return)
     LEAVE;
     /* Stack values are safe: */
     if (popsub2) {
+       cxstack_ix--;
        POPSUB(cx,sv);  /* release CV and @_ ... */
     }
     else
@@ -1992,6 +1987,7 @@ PP(pp_last)
        dounwind(cxix);
 
     POPBLOCK(cx,newpm);
+    cxstack_ix++; /* temporarily protect top context */
     mark = newsp;
     switch (CxTYPE(cx)) {
     case CXt_LOOP:
@@ -2034,6 +2030,7 @@ PP(pp_last)
     PUTBACK;
 
     LEAVE;
+    cxstack_ix--;
     /* Stack values are safe: */
     switch (pop2) {
     case CXt_LOOP:
@@ -2233,6 +2230,8 @@ PP(pp_goto)
                    AvFLAGS(av) = AVf_REIFY;
                    PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av);
                }
+               else
+                   CLEAR_ARGARRAY(av);
            }
            else if (CvXSUB(cv)) {      /* put GvAV(defgv) back onto stack */
                AV* av;
@@ -2345,7 +2344,10 @@ PP(pp_goto)
                    CV *gotocv;
                
                    if (PERLDB_SUB_NN) {
-                       SvIVX(sv) = PTR2IV(cv); /* Already upgraded, saved */
+                       (void)SvUPGRADE(sv, SVt_PVIV);
+                       (void)SvIOK_on(sv);
+                       SAVEIV(SvIVX(sv));
+                       SvIVX(sv) = PTR2IV(cv); /* Do it the quickest way */
                    } else {
                        save_item(sv);
                        gv_efullname3(sv, CvGV(cv), Nullch);
@@ -2388,7 +2390,7 @@ PP(pp_goto)
            switch (CxTYPE(cx)) {
            case CXt_EVAL:
                leaving_eval = TRUE;
-                if (CxREALEVAL(cx)) {
+                if (!CxTRYBLOCK(cx)) {
                    gotoprobe = (last_eval_cx ?
                                last_eval_cx->blk_eval.old_eval_root :
                                PL_eval_root);
@@ -2675,7 +2677,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     SAVETMPS;
     /* switch to eval mode */
 
-    if (PL_curcop == &PL_compiling) {
+    if (IN_PERL_COMPILETIME) {
        SAVECOPSTASH_FREE(&PL_compiling);
        CopSTASH_set(&PL_compiling, PL_curstash);
     }
@@ -2708,14 +2710,14 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     PL_hints &= HINT_UTF8;
 
     /* we get here either during compilation, or via pp_regcomp at runtime */
-    runtime = PL_op && (PL_op->op_type == OP_REGCOMP);
+    runtime = IN_PERL_RUNTIME;
     if (runtime)
        runcv = find_runcv(NULL);
 
     PL_op = &dummy;
     PL_op->op_type = OP_ENTEREVAL;
     PL_op->op_flags = 0;                       /* Avoid uninit warning. */
-    PUSHBLOCK(cx, CXt_EVAL|(PL_curcop == &PL_compiling ? 0 : CXp_REAL), SP);
+    PUSHBLOCK(cx, CXt_EVAL|(IN_PERL_COMPILETIME ? 0 : CXp_REAL), SP);
     PUSHEVAL(cx, 0, Nullgv);
 
     if (runtime)
@@ -2731,7 +2733,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, char *code, PAD** padp)
     /* XXX DAPM do this properly one year */
     *padp = (AV*)SvREFCNT_inc(PL_comppad);
     LEAVE;
-    if (PL_curcop == &PL_compiling)
+    if (IN_PERL_COMPILETIME)
        PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
 #ifdef OP_IN_REGISTER
     op = PL_opsave;
@@ -2839,9 +2841,8 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
     else
        sv_setpv(ERRSV,"");
     if (yyparse() || PL_error_count || !PL_eval_root) {
-       SV **newsp;
-       I32 gimme;
-       PERL_CONTEXT *cx;
+       SV **newsp;                     /* Used by POPBLOCK. */
+       PERL_CONTEXT *cx = &cxstack[cxstack_ix];
        I32 optype = 0;                 /* Might be reset by POPEVAL. */
        STRLEN n_a;
        
@@ -2860,6 +2861,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
        LEAVE;
        if (optype == OP_REQUIRE) {
            char* msg = SvPVx(ERRSV, n_a);
+           SV *nsv = cx->blk_eval.old_namesv;
+           (void)hv_store(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv),
+                          &PL_sv_undef, 0);
            DIE(aTHX_ "%sCompilation failed in require",
                *msg ? msg : "Unknown error\n");
        }
@@ -2884,7 +2888,16 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
        *startop = PL_eval_root;
     } else
        SAVEFREEOP(PL_eval_root);
-    if (gimme & G_VOID)
+
+    /* Set the context for this new optree.
+     * If the last op is an OP_REQUIRE, force scalar context.
+     * Otherwise, propagate the context from the eval(). */
+    if (PL_eval_root->op_type == OP_LEAVEEVAL
+           && cUNOPx(PL_eval_root)->op_first->op_type == OP_LINESEQ
+           && cLISTOPx(cUNOPx(PL_eval_root)->op_first)->op_last->op_type
+           == OP_REQUIRE)
+       scalar(PL_eval_root);
+    else if (gimme & G_VOID)
        scalarvoid(PL_eval_root);
     else if (gimme & G_ARRAY)
        list(PL_eval_root);
@@ -2916,8 +2929,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
 }
 
 STATIC PerlIO *
-S_doopen_pmc(pTHX_ const char *name, const char *mode)
+S_doopen_pm(pTHX_ const char *name, const char *mode)
 {
+#ifndef PERL_DISABLE_PMC
     STRLEN namelen = strlen(name);
     PerlIO *fp;
 
@@ -2945,6 +2959,9 @@ S_doopen_pmc(pTHX_ const char *name, const char *mode)
        fp = PerlIO_open(name, mode);
     }
     return fp;
+#else
+    return PerlIO_open(name, mode);
+#endif /* !PERL_DISABLE_PMC */
 }
 
 PP(pp_require)
@@ -3035,15 +3052,18 @@ PP(pp_require)
        DIE(aTHX_ "Null filename used");
     TAINT_PROPER("require");
     if (PL_op->op_type == OP_REQUIRE &&
-      (svp = hv_fetch(GvHVn(PL_incgv), name, len, 0)) &&
-      *svp != &PL_sv_undef)
-       RETPUSHYES;
+       (svp = hv_fetch(GvHVn(PL_incgv), name, len, 0))) {
+       if (*svp != &PL_sv_undef)
+           RETPUSHYES;
+       else
+           DIE(aTHX_ "Compilation failed in require");
+    }
 
     /* prepare to compile file */
 
     if (path_is_absolute(name)) {
        tryname = name;
-       tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE);
+       tryrsfp = doopen_pm(name,PERL_SCRIPT_MODE);
     }
 #ifdef MACOS_TRADITIONAL
     if (!tryrsfp) {
@@ -3052,7 +3072,7 @@ PP(pp_require)
        MacPerl_CanonDir(name, newname, 1);
        if (path_is_absolute(newname)) {
            tryname = newname;
-           tryrsfp = doopen_pmc(newname,PERL_SCRIPT_MODE);
+           tryrsfp = doopen_pm(newname,PERL_SCRIPT_MODE);
        }
     }
 #endif
@@ -3153,6 +3173,7 @@ PP(pp_require)
                                                      PERL_SCRIPT_MODE);
                            }
                        }
+                       SP--;
                    }
 
                    PUTBACK;
@@ -3207,7 +3228,7 @@ PP(pp_require)
 #endif
                    TAINT_PROPER("require");
                    tryname = SvPVX(namesv);
-                   tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
+                   tryrsfp = doopen_pm(tryname, PERL_SCRIPT_MODE);
                    if (tryrsfp) {
                        if (tryname[0] == '.' && tryname[1] == '/')
                            tryname += 2;
@@ -3537,7 +3558,7 @@ PP(pp_leavetry)
     RETURNOP(retop);
 }
 
-STATIC void
+STATIC OP *
 S_doparseform(pTHX_ SV *sv)
 {
     STRLEN len;
@@ -3548,16 +3569,26 @@ S_doparseform(pTHX_ SV *sv)
     bool noblank   = FALSE;
     bool repeat    = FALSE;
     bool postspace = FALSE;
-    U16 *fops;
-    register U16 *fpc;
-    U16 *linepc = 0;
+    U32 *fops;
+    register U32 *fpc;
+    U32 *linepc = 0;
     register I32 arg;
     bool ischop;
+    bool unchopnum = FALSE;
+    int maxops = 12; /* FF_LINEMARK + FF_END + 10 (\0 without preceding \n) */
 
     if (len == 0)
        Perl_croak(aTHX_ "Null picture in formline");
 
-    New(804, fops, (send - s)*3+10, U16);    /* Almost certainly too long... */
+    /* estimate the buffer size needed */
+    for (base = s; s <= send; s++) {
+       if (*s == '\n' || *s == '@' || *s == '^')
+           maxops += 10;
+    }
+    s = base;
+    base = Nullch;
+
+    New(804, fops, maxops, U32);
     fpc = fops;
 
     if (s < send) {
@@ -3584,8 +3615,12 @@ S_doparseform(pTHX_ SV *sv)
        case ' ': case '\t':
            skipspaces++;
            continue;
-       
-       case '\n': case 0:
+        case 0:
+           if (s < send) {
+               skipspaces = 0;
+                continue;
+            } /* else FALL THROUGH */
+       case '\n':
            arg = s - base;
            skipspaces++;
            arg -= skipspaces;
@@ -3641,8 +3676,12 @@ S_doparseform(pTHX_ SV *sv)
            *fpc++ = FF_FETCH;
            if (*s == '*') {
                s++;
-               *fpc++ = 0;
-               *fpc++ = FF_LINEGLOB;
+               *fpc++ = 2;  /* skip the @* or ^* */
+               if (ischop) {
+                   *fpc++ = FF_LINESNGL;
+                   *fpc++ = FF_CHOP;
+               } else
+                   *fpc++ = FF_LINEGLOB;
            }
            else if (*s == '#' || (*s == '.' && s[1] == '#')) {
                arg = ischop ? 512 : 0;
@@ -3660,6 +3699,7 @@ S_doparseform(pTHX_ SV *sv)
                *fpc++ = s - base;              /* fieldsize for FETCH */
                *fpc++ = FF_DECIMAL;
                 *fpc++ = (U16)arg;
+                unchopnum |= ! ischop;
             }
             else if (*s == '0' && s[1] == '#') {  /* Zero padded decimals */
                 arg = ischop ? 512 : 0;
@@ -3678,6 +3718,7 @@ S_doparseform(pTHX_ SV *sv)
                 *fpc++ = s - base;                /* fieldsize for FETCH */
                 *fpc++ = FF_0DECIMAL;
                *fpc++ = (U16)arg;
+                unchopnum |= ! ischop;
            }
            else {
                I32 prespace = 0;
@@ -3720,17 +3761,50 @@ S_doparseform(pTHX_ SV *sv)
     }
     *fpc++ = FF_END;
 
+    assert (fpc <= fops + maxops); /* ensure our buffer estimate was valid */
     arg = fpc - fops;
     { /* need to jump to the next word */
         int z;
        z = WORD_ALIGN - SvCUR(sv) % WORD_ALIGN;
-       SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U16) + 4);
+       SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U32) + 4);
        s = SvPVX(sv) + SvCUR(sv) + z;
     }
-    Copy(fops, s, arg, U16);
+    Copy(fops, s, arg, U32);
     Safefree(fops);
     sv_magic(sv, Nullsv, PERL_MAGIC_fm, Nullch, 0);
     SvCOMPILED_on(sv);
+
+    if (unchopnum && repeat) 
+        DIE(aTHX_ "Repeated format line will never terminate (~~ and @#)");
+    return 0;
+}
+
+
+STATIC bool
+S_num_overflow(NV value, I32 fldsize, I32 frcsize)
+{
+    /* Can value be printed in fldsize chars, using %*.*f ? */
+    NV pwr = 1;
+    NV eps = 0.5;
+    bool res = FALSE;
+    int intsize = fldsize - (value < 0 ? 1 : 0);
+
+    if (frcsize & 256)
+        intsize--;
+    frcsize &= 255;
+    intsize -= frcsize;
+
+    while (intsize--) pwr *= 10.0;
+    while (frcsize--) eps /= 10.0;
+
+    if( value >= 0 ){
+        if (value + eps >= pwr)
+           res = TRUE;
+    } else {
+        if (value - eps <= -pwr)
+           res = TRUE;
+    }
+    return res;
 }
 
 static I32