From: Jarkko Hietaniemi <jhi@iki.fi>
Date: Tue, 6 Jul 1999 09:28:48 +0000 (+0000)
Subject: Integrate with Sarathy.
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cad2e5aadfceb1a406f657488ea1c699f44a1487;p=p5sagit%2Fp5-mst-13.2.git

Integrate with Sarathy.

p4raw-id: //depot/cfgperl@3609
---

diff --git a/Changes b/Changes
index c1b80ca..87d97f4 100644
--- a/Changes
+++ b/Changes
@@ -79,6 +79,99 @@ Version 5.005_58        Development release working toward 5.006
 ----------------
 
 ____________________________________________________________________________
+[  3604] By: gsar                                  on 1999/07/06  07:08:30
+        Log: From: paul.marquess@bt.com
+             Date: Tue, 8 Jun 1999 22:37:58 +0100 
+             Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB29C6C3C@mbtlipnt02.btlabs.bt.co.uk>
+             Subject: [PATCH 5.005_57] DB_File 1.67
+     Branch: perl
+	   ! ext/DB_File/Changes ext/DB_File/DB_File.pm
+           ! ext/DB_File/DB_File.xs ext/DB_File/typemap
+____________________________________________________________________________
+[  3603] By: gsar                                  on 1999/07/06  07:04:50
+        Log: From: paul.marquess@bt.com
+             Date: Tue, 8 Jun 1999 22:34:01 +0100 
+             Message-ID: <5104D4DBC598D211B5FE0000F8FE7EB29C6C3B@mbtlipnt02.btlabs.bt.co.uk>
+             Subject: [PATCH 5.005_57] DBM Filters
+     Branch: perl
+	   ! ext/GDBM_File/GDBM_File.pm ext/GDBM_File/GDBM_File.xs
+	   ! ext/NDBM_File/NDBM_File.pm ext/NDBM_File/NDBM_File.xs
+	   ! ext/ODBM_File/ODBM_File.pm ext/ODBM_File/ODBM_File.xs
+           ! ext/SDBM_File/SDBM_File.pm ext/SDBM_File/SDBM_File.xs
+____________________________________________________________________________
+[  3602] By: gsar                                  on 1999/07/06  07:00:01
+        Log: slightly tweaked version of suggested patch
+             From: Dan Sugalski <sugalskd@ous.edu>
+             Date: Tue, 08 Jun 1999 14:09:38 -0700
+             Message-Id: <3.0.6.32.19990608140938.030f12e0@ous.edu>
+             Subject: [PATCH 5.005_57]Use NV instead of double in the core
+     Branch: perl
+	   ! av.h bytecode.pl cv.h doio.c dump.c embed.pl
+	   ! ext/ByteLoader/bytecode.h ext/ByteLoader/byterun.c hv.h
+	   ! intrpvar.h mg.c op.c perl.h pp.c pp.h pp_ctl.c pp_sys.c
+           ! proto.h sv.c sv.h toke.c universal.c util.c
+____________________________________________________________________________
+[  3601] By: gsar                                  on 1999/07/06  06:52:57
+        Log: integrate cfgperl contents into mainline
+     Branch: perl
+	  +> README.epoc epoc/config.h epoc/epoc.c epoc/epocish.h
+          +> epoc/perl.mmp epoc/perl.pkg
+          !> (integrate 30 files)
+____________________________________________________________________________
+[  3598] By: jhi                                   on 1999/07/05  20:02:55
+        Log: Integrate with mainperl.
+     Branch: cfgperl
+          +> lib/CGI/Pretty.pm
+	  !> Changes ext/B/B/Bblock.pm ext/B/B/C.pm ext/B/B/CC.pm
+	  !> ext/B/B/Stackobj.pm ext/GDBM_File/GDBM_File.xs mg.c op.c
+	  !> opcode.h opcode.pl pp_sys.c t/lib/io_udp.t thread.h toke.c
+	  !> vms/descrip_mms.template vms/subconfigure.com vms/vms.c
+          !> vms/vmsish.h
+____________________________________________________________________________
+[  3597] By: jhi                                   on 1999/07/05  19:59:48
+        Log: Hack SOCKS support some more plus a patch from Andy Dougherty
+             that addresses the notorious "Additional libraries" question.
+     Branch: cfgperl
+	   ! Configure Porting/Glossary Porting/config.sh Porting/config_H
+	   ! config_h.SH doio.c ext/Socket/Socket.xs hints/aix.sh perl.c
+           ! pp_sys.c
+____________________________________________________________________________
+[  3596] By: gsar                                  on 1999/07/05  18:30:51
+        Log: From: Ilya Zakharevich <ilya@math.ohio-state.edu>
+             Date: Tue, 8 Jun 1999 04:47:58 -0400 (EDT)
+             Message-Id: <199906080847.EAA03810@monk.mps.ohio-state.edu>
+             Subject: [PATCH 5.00557] Long-standing UDP sockets bug on OS/2
+     Branch: perl
+           ! pp_sys.c t/lib/io_udp.t
+____________________________________________________________________________
+[  3595] By: gsar                                  on 1999/07/05  18:29:08
+        Log: From: Ilya Zakharevich <ilya@math.ohio-state.edu>
+             Date: Tue, 8 Jun 1999 04:44:58 -0400 (EDT)
+             Message-Id: <199906080844.EAA03784@monk.mps.ohio-state.edu>
+             Subject: [PATCH 5.00557] Setting $^E wipes out $!
+     Branch: perl
+           ! mg.c
+____________________________________________________________________________
+[  3594] By: gsar                                  on 1999/07/05  18:24:53
+        Log: hand-apply whitespace mutiliated patch
+             From: Dan Sugalski <sugalskd@osshe.edu>
+             Date: Mon, 07 Jun 1999 14:46:42 -0700
+             Message-Id: <3.0.6.32.19990607144642.03079100@ous.edu>
+             Subject: [PATCH 5.005_57]Updated VMS patch
+     Branch: perl
+	   ! thread.h vms/descrip_mms.template vms/subconfigure.com
+           ! vms/vms.c vms/vmsish.h
+____________________________________________________________________________
+[  3593] By: gsar                                  on 1999/07/05  17:53:04
+        Log: applied parts not duplicated by previous patches
+             From: "Vishal Bhatia" <vishalb@my-deja.com>
+             Date: Sat, 05 Jun 1999 08:42:17 -0700
+             Message-ID: <JAMCAJKJEJDPAAAA@my-deja.com>
+             Subject: Fwd: [PATCH 5.005_57] consolidated compiler changes
+     Branch: perl
+	   ! Changes ext/B/B/Bblock.pm ext/B/B/C.pm ext/B/B/CC.pm
+           ! ext/B/B/Stackobj.pm
+____________________________________________________________________________
 [  3592] By: jhi                                   on 1999/07/05  17:17:22
         Log: AIX threaded build, plus few more on the side.
      Branch: cfgperl
diff --git a/av.h b/av.h
index bef763d..bacf614 100644
--- a/av.h
+++ b/av.h
@@ -12,7 +12,7 @@ struct xpvav {
     SSize_t	xav_fill;       /* Index of last element present */
     SSize_t	xav_max;        /* Number of elements for which array has space */
     IV		xof_off;	/* ptr is incremented by offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
 
diff --git a/bytecode.pl b/bytecode.pl
index 1e18d55..4d318ff 100644
--- a/bytecode.pl
+++ b/bytecode.pl
@@ -312,7 +312,7 @@ xrv		SvRV(bytecode_sv)			svindex
 xpv		bytecode_sv				none		x
 xiv32		SvIVX(bytecode_sv)			I32
 xiv64		SvIVX(bytecode_sv)			IV64
-xnv		SvNVX(bytecode_sv)			double
+xnv		SvNVX(bytecode_sv)			NV
 xlv_targoff	LvTARGOFF(bytecode_sv)			STRLEN
 xlv_targlen	LvTARGLEN(bytecode_sv)			STRLEN
 xlv_targ	LvTARG(bytecode_sv)			svindex
diff --git a/cv.h b/cv.h
index e060dc8..7042708 100644
--- a/cv.h
+++ b/cv.h
@@ -14,7 +14,7 @@ struct xpvcv {
     STRLEN	xpv_cur;	/* length of xp_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xof_off;	/* integer value */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
 
diff --git a/doio.c b/doio.c
index 0fc139c..39e2e9f 100644
--- a/doio.c
+++ b/doio.c
@@ -898,7 +898,7 @@ Perl_do_print(pTHX_ register SV *sv, PerlIO *fp)
 	if (SvGMAGICAL(sv))
 	    mg_get(sv);
         if (SvIOK(sv) && SvIVX(sv) != 0) {
-	    PerlIO_printf(fp, PL_ofmt, (double)SvIVX(sv));
+	    PerlIO_printf(fp, PL_ofmt, (NV)SvIVX(sv));
 	    return !PerlIO_error(fp);
 	}
 	if (  (SvNOK(sv) && SvNVX(sv) != 0.0)
diff --git a/dump.c b/dump.c
index 3d3a55c..12d318d 100644
--- a/dump.c
+++ b/dump.c
@@ -15,6 +15,7 @@
 #include "EXTERN.h"
 #define PERL_IN_DUMP_C
 #include "perl.h"
+#include "regcomp.h"
 
 #ifndef DBL_DIG
 #define DBL_DIG	15   /* A guess that works lots of places */
@@ -972,7 +973,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
 	    int i;
 	    int max = 0;
 	    U32 pow2 = 2, keys = HvKEYS(sv);
-	    double theoret, sum = 0;
+	    NV theoret, sum = 0;
 
 	    PerlIO_printf(file, "  (");
 	    Zero(freq, FREQ_MAX + 1, int);
diff --git a/embed.h b/embed.h
index d0ede0b..0871c6f 100644
--- a/embed.h
+++ b/embed.h
@@ -448,6 +448,8 @@
 #define pregexec		Perl_pregexec
 #define pregfree		Perl_pregfree
 #define pregcomp		Perl_pregcomp
+#define re_intuit_start		Perl_re_intuit_start
+#define re_intuit_string	Perl_re_intuit_string
 #define regexec_flags		Perl_regexec_flags
 #define regnext			Perl_regnext
 #define regprop			Perl_regprop
@@ -1762,6 +1764,8 @@
 #define pregexec(a,b,c,d,e,f,g)	Perl_pregexec(aTHX_ a,b,c,d,e,f,g)
 #define pregfree(a)		Perl_pregfree(aTHX_ a)
 #define pregcomp(a,b,c)		Perl_pregcomp(aTHX_ a,b,c)
+#define re_intuit_start(a,b,c,d,e,f)	Perl_re_intuit_start(aTHX_ a,b,c,d,e,f)
+#define re_intuit_string(a)	Perl_re_intuit_string(aTHX_ a)
 #define regexec_flags(a,b,c,d,e,f,g,h)	Perl_regexec_flags(aTHX_ a,b,c,d,e,f,g,h)
 #define regnext(a)		Perl_regnext(aTHX_ a)
 #define regprop(a,b)		Perl_regprop(aTHX_ a,b)
@@ -3486,6 +3490,10 @@
 #define pregfree		Perl_pregfree
 #define Perl_pregcomp		CPerlObj::Perl_pregcomp
 #define pregcomp		Perl_pregcomp
+#define Perl_re_intuit_start	CPerlObj::Perl_re_intuit_start
+#define re_intuit_start		Perl_re_intuit_start
+#define Perl_re_intuit_string	CPerlObj::Perl_re_intuit_string
+#define re_intuit_string	Perl_re_intuit_string
 #define Perl_regexec_flags	CPerlObj::Perl_regexec_flags
 #define regexec_flags		Perl_regexec_flags
 #define Perl_regnext		CPerlObj::Perl_regnext
diff --git a/embed.pl b/embed.pl
index d7c5a87..ed7f3e4 100755
--- a/embed.pl
+++ b/embed.pl
@@ -781,10 +781,10 @@ p	|int	|block_start	|int full
 p	|void	|boot_core_UNIVERSAL
 p	|void	|call_list	|I32 oldscope|AV* av_list
 p	|I32	|cando		|I32 bit|I32 effective|Stat_t* statbufp
-p	|U32	|cast_ulong	|double f
-p	|I32	|cast_i32	|double f
-p	|IV	|cast_iv	|double f
-p	|UV	|cast_uv	|double f
+p	|U32	|cast_ulong	|NV f
+p	|I32	|cast_i32	|NV f
+p	|IV	|cast_iv	|NV f
+p	|UV	|cast_uv	|NV f
 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP)
 p	|I32	|my_chsize	|int fd|Off_t length
 #endif
@@ -1058,7 +1058,7 @@ p	|I32	|mg_size	|SV* sv
 p	|OP*	|mod		|OP* o|I32 type
 p	|char*	|moreswitches	|char* s
 p	|OP*	|my		|OP* o
-p	|double	|my_atof	|const char *s
+p	|NV	|my_atof	|const char *s
 #if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
 p	|char*	|my_bcopy	|const char* from|char* to|I32 len
 #endif
@@ -1127,7 +1127,7 @@ p	|SV*	|newSV		|STRLEN len
 p	|OP*	|newSVREF	|OP* o
 p	|OP*	|newSVOP	|I32 type|I32 flags|SV* sv
 p	|SV*	|newSViv	|IV i
-p	|SV*	|newSVnv	|double n
+p	|SV*	|newSVnv	|NV n
 p	|SV*	|newSVpv	|const char* s|STRLEN len
 p	|SV*	|newSVpvn	|const char* s|STRLEN len
 p	|SV*	|newSVpvf	|const char* pat|...
@@ -1210,6 +1210,10 @@ p	|I32	|pregexec	|regexp* prog|char* stringarg \
 				|SV* screamer|U32 nosave
 p	|void	|pregfree	|struct regexp* r
 p	|regexp*|pregcomp	|char* exp|char* xend|PMOP* pm
+p	|char*	|re_intuit_start|regexp* prog|SV* sv|char* strpos \
+				|char* strend|U32 flags \
+				|struct re_scream_pos_data_s *data
+p	|SV*	|re_intuit_string|regexp* prog
 p	|I32	|regexec_flags	|regexp* prog|char* stringarg \
 				|char* strend|char* strbeg|I32 minend \
 				|SV* screamer|void* data|U32 flags
@@ -1289,12 +1293,12 @@ p	|CV*	|sv_2cv		|SV* sv|HV** st|GV** gvp|I32 lref
 p	|IO*	|sv_2io		|SV* sv
 p	|IV	|sv_2iv		|SV* sv
 p	|SV*	|sv_2mortal	|SV* sv
-p	|double	|sv_2nv		|SV* sv
+p	|NV	|sv_2nv		|SV* sv
 p	|char*	|sv_2pv		|SV* sv|STRLEN* lp
 p	|UV	|sv_2uv		|SV* sv
 p	|IV	|sv_iv		|SV* sv
 p	|UV	|sv_uv		|SV* sv
-p	|double	|sv_nv		|SV* sv
+p	|NV	|sv_nv		|SV* sv
 p	|char*	|sv_pvn		|SV *sv|STRLEN *len
 p	|I32	|sv_true	|SV *sv
 p	|void	|sv_add_arena	|char* ptr|U32 size|U32 flags
@@ -1346,9 +1350,9 @@ p	|void	|sv_setpvf	|SV* sv|const char* pat|...
 p	|void	|sv_setiv	|SV* sv|IV num
 p	|void	|sv_setpviv	|SV* sv|IV num
 p	|void	|sv_setuv	|SV* sv|UV num
-p	|void	|sv_setnv	|SV* sv|double num
+p	|void	|sv_setnv	|SV* sv|NV num
 p	|SV*	|sv_setref_iv	|SV* rv|const char* classname|IV iv
-p	|SV*	|sv_setref_nv	|SV* rv|const char* classname|double nv
+p	|SV*	|sv_setref_nv	|SV* rv|const char* classname|NV nv
 p	|SV*	|sv_setref_pv	|SV* rv|const char* classname|void* pv
 p	|SV*	|sv_setref_pvn	|SV* rv|const char* classname|char* pv \
 				|STRLEN n
@@ -1445,7 +1449,7 @@ p	|void	|sv_setpvf_mg	|SV *sv|const char* pat|...
 p	|void	|sv_setiv_mg	|SV *sv|IV i
 p	|void	|sv_setpviv_mg	|SV *sv|IV iv
 p	|void	|sv_setuv_mg	|SV *sv|UV u
-p	|void	|sv_setnv_mg	|SV *sv|double num
+p	|void	|sv_setnv_mg	|SV *sv|NV num
 p	|void	|sv_setpv_mg	|SV *sv|const char *ptr
 p	|void	|sv_setpvn_mg	|SV *sv|const char *ptr|STRLEN len
 p	|void	|sv_setsv_mg	|SV *dstr|SV *sstr
diff --git a/embedvar.h b/embedvar.h
index dbd94e9..f759b63 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -85,8 +85,11 @@
 #define PL_regeol		(my_perl->Tregeol)
 #define PL_regexecp		(my_perl->Tregexecp)
 #define PL_regflags		(my_perl->Tregflags)
+#define PL_regfree		(my_perl->Tregfree)
 #define PL_regindent		(my_perl->Tregindent)
 #define PL_reginput		(my_perl->Treginput)
+#define PL_regint_start		(my_perl->Tregint_start)
+#define PL_regint_string	(my_perl->Tregint_string)
 #define PL_reginterp_cnt	(my_perl->Treginterp_cnt)
 #define PL_reglastparen		(my_perl->Treglastparen)
 #define PL_regnarrate		(my_perl->Tregnarrate)
@@ -212,8 +215,11 @@
 #define PL_regeol		(PL_curinterp->Tregeol)
 #define PL_regexecp		(PL_curinterp->Tregexecp)
 #define PL_regflags		(PL_curinterp->Tregflags)
+#define PL_regfree		(PL_curinterp->Tregfree)
 #define PL_regindent		(PL_curinterp->Tregindent)
 #define PL_reginput		(PL_curinterp->Treginput)
+#define PL_regint_start		(PL_curinterp->Tregint_start)
+#define PL_regint_string	(PL_curinterp->Tregint_string)
 #define PL_reginterp_cnt	(PL_curinterp->Treginterp_cnt)
 #define PL_reglastparen		(PL_curinterp->Treglastparen)
 #define PL_regnarrate		(PL_curinterp->Tregnarrate)
@@ -854,8 +860,11 @@
 #define PL_Tregeol		PL_regeol
 #define PL_Tregexecp		PL_regexecp
 #define PL_Tregflags		PL_regflags
+#define PL_Tregfree		PL_regfree
 #define PL_Tregindent		PL_regindent
 #define PL_Treginput		PL_reginput
+#define PL_Tregint_start	PL_regint_start
+#define PL_Tregint_string	PL_regint_string
 #define PL_Treginterp_cnt	PL_reginterp_cnt
 #define PL_Treglastparen	PL_reglastparen
 #define PL_Tregnarrate		PL_regnarrate
@@ -992,8 +1001,11 @@
 #define PL_regeol		(thr->Tregeol)
 #define PL_regexecp		(thr->Tregexecp)
 #define PL_regflags		(thr->Tregflags)
+#define PL_regfree		(thr->Tregfree)
 #define PL_regindent		(thr->Tregindent)
 #define PL_reginput		(thr->Treginput)
+#define PL_regint_start		(thr->Tregint_start)
+#define PL_regint_string	(thr->Tregint_string)
 #define PL_reginterp_cnt	(thr->Treginterp_cnt)
 #define PL_reglastparen		(thr->Treglastparen)
 #define PL_regnarrate		(thr->Tregnarrate)
diff --git a/ext/ByteLoader/bytecode.h b/ext/ByteLoader/bytecode.h
index 9d597fb..04a05e4 100644
--- a/ext/ByteLoader/bytecode.h
+++ b/ext/ByteLoader/bytecode.h
@@ -70,10 +70,10 @@ typedef IV IV64;
 	arg = PL_tokenbuf;			\
     } STMT_END
 
-#define BGET_double(arg) STMT_START {	\
+#define BGET_NV(arg) STMT_START {	\
 	char *str;			\
 	BGET_strconst(str);		\
-	arg = atof(str);		\
+	arg = Perl_atonv(str);		\
     } STMT_END
 
 #define BGET_objindex(arg, type) STMT_START {	\
diff --git a/ext/ByteLoader/byterun.c b/ext/ByteLoader/byterun.c
index 544a59f..035578f 100644
--- a/ext/ByteLoader/byterun.c
+++ b/ext/ByteLoader/byterun.c
@@ -221,8 +221,8 @@ byterun(pTHXo_ struct bytestream bs)
 	    }
 	  case INSN_XNV:		/* 21 */
 	    {
-		double arg;
-		BGET_double(arg);
+		NV arg;
+		BGET_NV(arg);
 		SvNVX(bytecode_sv) = arg;
 		break;
 	    }
diff --git a/ext/DB_File/Changes b/ext/DB_File/Changes
index 82d9af5..236af0f 100644
--- a/ext/DB_File/Changes
+++ b/ext/DB_File/Changes
@@ -237,3 +237,12 @@
 1.66 15th March 1999
 
    * Added DBM Filter code
+
+1.67 6th June 1999
+
+   * Added DBM Filter documentation to DB_File.pm
+
+   * Fixed DBM Filter code to work with 5.004
+
+   * A few instances of newSVpvn were used in 1.66. This isn't available in
+     Perl 5.004_04 or earlier. Replaced with newSVpv.
diff --git a/ext/DB_File/DB_File.pm b/ext/DB_File/DB_File.pm
index 7e6c907..7dd1d26 100644
--- a/ext/DB_File/DB_File.pm
+++ b/ext/DB_File/DB_File.pm
@@ -1,10 +1,10 @@
 # DB_File.pm -- Perl 5 interface to Berkeley DB 
 #
 # written by Paul Marquess (Paul.Marquess@btinternet.com)
-# last modified 6th March 1999
-# version 1.66
+# last modified 6th June 1999
+# version 1.67
 #
-#     Copyright (c) 1995-9 Paul Marquess. All rights reserved.
+#     Copyright (c) 1995-1999 Paul Marquess. All rights reserved.
 #     This program is free software; you can redistribute it and/or
 #     modify it under the same terms as Perl itself.
 
@@ -145,7 +145,7 @@ use vars qw($VERSION @ISA @EXPORT $AUTOLOAD $DB_BTREE $DB_HASH $DB_RECNO $db_ver
 use Carp;
 
 
-$VERSION = "1.66" ;
+$VERSION = "1.67" ;
 
 #typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
 $DB_BTREE = new DB_File::BTREEINFO ;
@@ -408,6 +408,12 @@ DB_File - Perl5 access to Berkeley DB version 1.x
  $a = $X->shift;
  $X->unshift(list);
 
+ # DBM Filters
+ $old_filter = $db->filter_store_key  ( sub { ... } ) ;
+ $old_filter = $db->filter_store_value( sub { ... } ) ;
+ $old_filter = $db->filter_fetch_key  ( sub { ... } ) ;
+ $old_filter = $db->filter_fetch_value( sub { ... } ) ;
+
  untie %hash ;
  untie @array ;
 
@@ -1488,6 +1494,141 @@ R_RECNOSYNC is the only valid flag at present.
 
 =back
 
+=head1 DBM FILTERS
+
+A DBM Filter is a piece of code that is be used when you I<always>
+want to make the same transformation to all keys and/or values in a
+DBM database.
+
+There are four methods associated with DBM Filters. All work identically,
+and each is used to install (or uninstall) a single DBM Filter. Each
+expects a single parameter, namely a reference to a sub. The only
+difference between them is the place that the filter is installed.
+
+To summarise:
+
+=over 5
+
+=item B<filter_store_key>
+
+If a filter has been installed with this method, it will be invoked
+every time you write a key to a DBM database.
+
+=item B<filter_store_value>
+
+If a filter has been installed with this method, it will be invoked
+every time you write a value to a DBM database.
+
+
+=item B<filter_fetch_key>
+
+If a filter has been installed with this method, it will be invoked
+every time you read a key from a DBM database.
+
+=item B<filter_fetch_value>
+
+If a filter has been installed with this method, it will be invoked
+every time you read a value from a DBM database.
+
+=back
+
+You can use any combination of the methods, from none, to all four.
+
+All filter methods return the existing filter, if present, or C<undef>
+in not.
+
+To delete a filter pass C<undef> to it.
+
+=head2 The Filter
+
+When each filter is called by Perl, a local copy of C<$_> will contain
+the key or value to be filtered. Filtering is achieved by modifying
+the contents of C<$_>. The return code from the filter is ignored.
+
+=head2 An Example -- the NULL termination problem.
+
+Consider the following scenario. You have a DBM database
+that you need to share with a third-party C application. The C application
+assumes that I<all> keys and values are NULL terminated. Unfortunately
+when Perl writes to DBM databases it doesn't use NULL termination, so
+your Perl application will have to manage NULL termination itself. When
+you write to the database you will have to use something like this:
+
+    $hash{"$key\0"} = "$value\0" ;
+
+Similarly the NULL needs to be taken into account when you are considering
+the length of existing keys/values.
+
+It would be much better if you could ignore the NULL terminations issue
+in the main application code and have a mechanism that automatically
+added the terminating NULL to all keys and values whenever you write to
+the database and have them removed when you read from the database. As I'm
+sure you have already guessed, this is a problem that DBM Filters can
+fix very easily.
+
+    use strict ;
+    use DB_File ;
+
+    my %hash ;
+    my $filename = "/tmp/filt" ;
+    unlink $filename ;
+
+    my $db = tie %hash, 'DB_File', $filename, O_CREAT|O_RDWR, 0666, $DB_HASH 
+      or die "Cannot open $filename: $!\n" ;
+
+    # Install DBM Filters
+    $db->filter_fetch_key  ( sub { s/\0$//    } ) ;
+    $db->filter_store_key  ( sub { $_ .= "\0" } ) ;
+    $db->filter_fetch_value( sub { s/\0$//    } ) ;
+    $db->filter_store_value( sub { $_ .= "\0" } ) ;
+
+    $hash{"abc"} = "def" ;
+    my $a = $hash{"ABC"} ;
+    # ...
+    undef $db ;
+    untie %hash ;
+
+Hopefully the contents of each of the filters should be
+self-explanatory. Both "fetch" filters remove the terminating NULL,
+and both "store" filters add a terminating NULL.
+
+
+=head2 Another Example -- Key is a C int.
+
+Here is another real-life example. By default, whenever Perl writes to
+a DBM database it always writes the key and value as strings. So when
+you use this:
+
+    $hash{12345} = "soemthing" ;
+
+the key 12345 will get stored in the DBM database as the 5 byte string
+"12345". If you actually want the key to be stored in the DBM database
+as a C int, you will have to use C<pack> when writing, and C<unpack>
+when reading.
+
+Here is a DBM Filter that does it:
+
+    use strict ;
+    use DB_File ;
+    my %hash ;
+    my $filename = "/tmp/filt" ;
+    unlink $filename ;
+
+
+    my $db = tie %hash, 'DB_File', $filename, O_CREAT|O_RDWR, 0666, $DB_HASH 
+      or die "Cannot open $filename: $!\n" ;
+
+    $db->filter_fetch_key  ( sub { $_ = unpack("i", $_) } ) ;
+    $db->filter_store_key  ( sub { $_ = pack ("i", $_) } ) ;
+    $hash{123} = "def" ;
+    # ...
+    undef $db ;
+    untie %hash ;
+
+This time only two filters have been used -- we only need to manipulate
+the contents of the key, so it wasn't necessary to install any value
+filters.
+
 =head1 HINTS AND TIPS 
 
 
@@ -1557,7 +1698,7 @@ shared by both a Perl and a C application.
 
 The vast majority of problems that are reported in this area boil down
 to the fact that C strings are NULL terminated, whilst Perl strings are
-not. 
+not. See L<DBM FILTERS> for a generic way to work around this problem.
 
 Here is a real example. Netscape 2.0 keeps a record of the locations you
 visit along with the time you last visited them in a DB_HASH database.
@@ -1746,6 +1887,19 @@ double quotes, like this:
 Although it might seem like a real pain, it is really worth the effort
 of having a C<use strict> in all your scripts.
 
+=head1 REFERENCES
+
+Articles that are either about B<DB_File> or make use of it.
+
+=over 5
+
+=item 1.
+
+I<Full-Text Searching in Perl>, Tim Kientzle (tkientzle@ddj.com),
+Dr. Dobb's Journal, Issue 295, January 1999, pp 34-41
+
+=back
+
 =head1 HISTORY
 
 Moved to the Changes file.
@@ -1771,10 +1925,8 @@ F<modules/by-module/DB_File>.
 This version of B<DB_File> will work with either version 1.x or 2.x of
 Berkeley DB, but is limited to the functionality provided by version 1.
 
-The official web site for Berkeley DB is
-F<http://www.sleepycat.com/db>. The ftp equivalent is
-F<ftp.sleepycat.com:/pub>. Both versions 1 and 2 of Berkeley DB are
-available there.
+The official web site for Berkeley DB is F<http://www.sleepycat.com>.
+Both versions 1 and 2 of Berkeley DB are available there.
 
 Alternatively, Berkeley DB version 1 is available at your nearest CPAN
 archive in F<src/misc/db.1.85.tar.gz>.
@@ -1785,7 +1937,7 @@ compile properly on IRIX 5.3.
 
 =head1 COPYRIGHT
 
-Copyright (c) 1995-9 Paul Marquess. All rights reserved. This program
+Copyright (c) 1995-1999 Paul Marquess. All rights reserved. This program
 is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself.
 
diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
index be584a2..ed3a7fa 100644
--- a/ext/DB_File/DB_File.xs
+++ b/ext/DB_File/DB_File.xs
@@ -3,8 +3,8 @@
  DB_File.xs -- Perl 5 interface to Berkeley DB 
 
  written by Paul Marquess <Paul.Marquess@btinternet.com>
- last modified 6th March 1999
- version 1.66
+ last modified 6th June 1999
+ version 1.67
 
  All comments/suggestions/problems are welcome
 
@@ -66,6 +66,9 @@
         1.65 -  Fixed a bug in the PUSH logic.
 		Added BOOT check that using 2.3.4 or greater
         1.66 -  Added DBM filter code
+        1.67 -  Backed off the use of newSVpvn.
+		Fixed DBM Filter code for Perl 5.004.
+		Fixed a small memory leak in the filter code.
 
 
 
@@ -89,6 +92,11 @@
 
 #endif
 
+/* DEFSV appears first in 5.004_56 */
+#ifndef DEFSV
+#define DEFSV		GvSV(defgv)
+#endif
+
 /* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
  * shortly #included by the <db.h>) __attribute__ to the possibly
  * already defined __attribute__, for example by GNUC or by Perl. */
@@ -301,16 +309,13 @@ typedef DBT DBTKEY ;
 	    if (db->filtering)					\
 	        croak("recursion detected in %s", name) ;	\
 	    db->filtering = TRUE ;				\
-	    /* SAVE_DEFSV ;*/   /* save $_ */			\
 	    save_defsv = newSVsv(DEFSV) ;			\
 	    sv_setsv(DEFSV, arg) ;				\
 	    PUSHMARK(sp) ;					\
 	    (void) perl_call_sv(db->type, G_DISCARD|G_NOARGS); 	\
-	    /* SPAGAIN ; */						\
 	    sv_setsv(arg, DEFSV) ;				\
-	    sv_setsv(DEFSV, save_defsv) ;				\
+	    sv_setsv(DEFSV, save_defsv) ;			\
 	    SvREFCNT_dec(save_defsv) ;				\
-	    /* PUTBACK ; */						\
 	    db->filtering = FALSE ;				\
 	    /*printf("end of filtering %s\n", name) ;*/		\
 	}
@@ -417,7 +422,7 @@ btree_compare(const DBT *key1, const DBT *key2)
     
     data1 = key1->data ;
     data2 = key2->data ;
-#if 0
+
     /* As newSVpv will assume that the data pointer is a null terminated C 
        string if the size parameter is 0, make sure that data points to an 
        empty string if the length is 0
@@ -426,14 +431,14 @@ btree_compare(const DBT *key1, const DBT *key2)
         data1 = "" ; 
     if (key2->size == 0)
         data2 = "" ;
-#endif
+
     ENTER ;
     SAVETMPS;
 
     PUSHMARK(SP) ;
     EXTEND(SP,2) ;
-    PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
-    PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
+    PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
+    PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
     PUTBACK ;
 
     count = perl_call_sv(CurrentDB->compare, G_SCALAR); 
@@ -463,7 +468,7 @@ btree_prefix(const DBT *key1, const DBT *key2)
     
     data1 = key1->data ;
     data2 = key2->data ;
-#if 0
+
     /* As newSVpv will assume that the data pointer is a null terminated C 
        string if the size parameter is 0, make sure that data points to an 
        empty string if the length is 0
@@ -472,14 +477,14 @@ btree_prefix(const DBT *key1, const DBT *key2)
         data1 = "" ;
     if (key2->size == 0)
         data2 = "" ;
-#endif
+
     ENTER ;
     SAVETMPS;
 
     PUSHMARK(SP) ;
     EXTEND(SP,2) ;
-    PUSHs(sv_2mortal(newSVpvn(data1,key1->size)));
-    PUSHs(sv_2mortal(newSVpvn(data2,key2->size)));
+    PUSHs(sv_2mortal(newSVpv(data1,key1->size)));
+    PUSHs(sv_2mortal(newSVpv(data2,key2->size)));
     PUTBACK ;
 
     count = perl_call_sv(CurrentDB->prefix, G_SCALAR); 
@@ -505,17 +510,17 @@ hash_cb(const void *data, size_t size)
     dSP ;
     int retval ;
     int count ;
-#if 0
+
     if (size == 0)
         data = "" ;
-#endif
+
      /* DGH - Next two lines added to fix corrupted stack problem */
     ENTER ;
     SAVETMPS;
 
     PUSHMARK(SP) ;
 
-    XPUSHs(sv_2mortal(newSVpvn((char*)data,size)));
+    XPUSHs(sv_2mortal(newSVpv((char*)data,size)));
     PUTBACK ;
 
     count = perl_call_sv(CurrentDB->hash, G_SCALAR); 
@@ -1564,7 +1569,8 @@ db_seq(db, key, value, flags)
 #define setFilter(type)					\
 	{						\
 	    if (db->type)				\
-	        RETVAL = newSVsv(db->type) ; 		\
+	        RETVAL = sv_mortalcopy(db->type) ;	\
+	    ST(0) = RETVAL ;				\
 	    if (db->type && (code == &PL_sv_undef)) {	\
                 SvREFCNT_dec(db->type) ;		\
 	        db->type = NULL ;			\
@@ -1585,8 +1591,6 @@ filter_fetch_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_key(db, code)
@@ -1595,8 +1599,6 @@ filter_store_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_fetch_value(db, code)
@@ -1605,8 +1607,6 @@ filter_fetch_value(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_value) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_value(db, code)
@@ -1615,7 +1615,5 @@ filter_store_value(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_value) ;
-	OUTPUT:
-	    RETVAL
 
 #endif /* DBM_FILTERING */
diff --git a/ext/DB_File/typemap b/ext/DB_File/typemap
index 8e4dacb..a614cc4 100644
--- a/ext/DB_File/typemap
+++ b/ext/DB_File/typemap
@@ -1,8 +1,8 @@
 # typemap for Perl 5 interface to Berkeley 
 #
 # written by Paul Marquess <Paul.Marquess@btinternet.com>
-# last modified 20th March 1999
-# version 1.66
+# last modified 6th June 1999
+# version 1.67
 #
 #################################### DB SECTION
 #
@@ -33,6 +33,7 @@ T_dbtdatum
 	$var.size = (int)PL_na;
 	DBT_flags($var);
 
+
 OUTPUT
 
 T_dbtkeydatum
diff --git a/ext/GDBM_File/GDBM_File.pm b/ext/GDBM_File/GDBM_File.pm
index 42bb6d2..aff0152 100644
--- a/ext/GDBM_File/GDBM_File.pm
+++ b/ext/GDBM_File/GDBM_File.pm
@@ -59,7 +59,7 @@ require DynaLoader;
 	GDBM_WRITER
 );
 
-$VERSION = "1.02";
+$VERSION = "1.03";
 
 sub AUTOLOAD {
     my($constname);
diff --git a/ext/GDBM_File/GDBM_File.xs b/ext/GDBM_File/GDBM_File.xs
index db28891..be1817b 100644
--- a/ext/GDBM_File/GDBM_File.xs
+++ b/ext/GDBM_File/GDBM_File.xs
@@ -304,7 +304,8 @@ gdbm_setopt (db, optflag, optval, optlen)
 #define setFilter(type)					\
 	{						\
 	    if (db->type)				\
-	        RETVAL = newSVsv(db->type) ; 		\
+	        RETVAL = sv_mortalcopy(db->type) ; 	\
+	    ST(0) = RETVAL ;				\
 	    if (db->type && (code == &PL_sv_undef)) {	\
                 SvREFCNT_dec(db->type) ;		\
 	        db->type = NULL ;			\
@@ -326,8 +327,6 @@ filter_fetch_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_key(db, code)
@@ -336,8 +335,6 @@ filter_store_key(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_fetch_value(db, code)
@@ -346,8 +343,6 @@ filter_fetch_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_value) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_value(db, code)
@@ -356,6 +351,4 @@ filter_store_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_value) ;
-	OUTPUT:
-	    RETVAL
 
diff --git a/ext/NDBM_File/NDBM_File.pm b/ext/NDBM_File/NDBM_File.pm
index cad800a..8db59ee 100644
--- a/ext/NDBM_File/NDBM_File.pm
+++ b/ext/NDBM_File/NDBM_File.pm
@@ -12,7 +12,7 @@ require DynaLoader;
 
 @ISA = qw(Tie::Hash DynaLoader);
 
-$VERSION = "1.02";
+$VERSION = "1.03";
 
 bootstrap NDBM_File $VERSION;
 
diff --git a/ext/NDBM_File/NDBM_File.xs b/ext/NDBM_File/NDBM_File.xs
index 60b141e..29cc288 100644
--- a/ext/NDBM_File/NDBM_File.xs
+++ b/ext/NDBM_File/NDBM_File.xs
@@ -117,7 +117,8 @@ ndbm_clearerr(db)
 #define setFilter(type)					\
 	{						\
 	    if (db->type)				\
-	        RETVAL = newSVsv(db->type) ; 		\
+	        RETVAL = sv_mortalcopy(db->type) ; 	\
+	    ST(0) = RETVAL ;				\
 	    if (db->type && (code == &PL_sv_undef)) {	\
                 SvREFCNT_dec(db->type) ;		\
 	        db->type = NULL ;			\
@@ -139,8 +140,6 @@ filter_fetch_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_key(db, code)
@@ -149,8 +148,6 @@ filter_store_key(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_fetch_value(db, code)
@@ -159,8 +156,6 @@ filter_fetch_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_value) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_value(db, code)
@@ -169,6 +164,4 @@ filter_store_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_value) ;
-	OUTPUT:
-	    RETVAL
 
diff --git a/ext/ODBM_File/ODBM_File.pm b/ext/ODBM_File/ODBM_File.pm
index 572318b..0af875d 100644
--- a/ext/ODBM_File/ODBM_File.pm
+++ b/ext/ODBM_File/ODBM_File.pm
@@ -8,7 +8,7 @@ require DynaLoader;
 
 @ISA = qw(Tie::Hash DynaLoader);
 
-$VERSION = "1.01";
+$VERSION = "1.02";
 
 bootstrap ODBM_File $VERSION;
 
diff --git a/ext/ODBM_File/ODBM_File.xs b/ext/ODBM_File/ODBM_File.xs
index 9ad794d..7601c34 100644
--- a/ext/ODBM_File/ODBM_File.xs
+++ b/ext/ODBM_File/ODBM_File.xs
@@ -158,7 +158,8 @@ odbm_NEXTKEY(db, key)
 #define setFilter(type)					\
 	{						\
 	    if (db->type)				\
-	        RETVAL = newSVsv(db->type) ; 		\
+	        RETVAL = sv_mortalcopy(db->type) ; 	\
+	    ST(0) = RETVAL ;				\
 	    if (db->type && (code == &PL_sv_undef)) {	\
                 SvREFCNT_dec(db->type) ;		\
 	        db->type = Nullsv ;			\
@@ -180,8 +181,6 @@ filter_fetch_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_key(db, code)
@@ -190,8 +189,6 @@ filter_store_key(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_fetch_value(db, code)
@@ -200,8 +197,6 @@ filter_fetch_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_value) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_value(db, code)
@@ -210,6 +205,4 @@ filter_store_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_value) ;
-	OUTPUT:
-	    RETVAL
 
diff --git a/ext/SDBM_File/SDBM_File.pm b/ext/SDBM_File/SDBM_File.pm
index 006bbbd..34c9717 100644
--- a/ext/SDBM_File/SDBM_File.pm
+++ b/ext/SDBM_File/SDBM_File.pm
@@ -8,7 +8,7 @@ require DynaLoader;
 
 @ISA = qw(Tie::Hash DynaLoader);
 
-$VERSION = "1.01" ;
+$VERSION = "1.02" ;
 
 bootstrap SDBM_File $VERSION;
 
diff --git a/ext/SDBM_File/SDBM_File.xs b/ext/SDBM_File/SDBM_File.xs
index e8711f4..c2e940b 100644
--- a/ext/SDBM_File/SDBM_File.xs
+++ b/ext/SDBM_File/SDBM_File.xs
@@ -23,16 +23,13 @@ typedef datum datum_value ;
 	    if (db->filtering)					\
 	        croak("recursion detected in %s", name) ;	\
 	    db->filtering = TRUE ;				\
-	    /* SAVE_DEFSV ;*/   /* save $_ */			\
 	    save_defsv = newSVsv(DEFSV) ;			\
 	    sv_setsv(DEFSV, arg) ;				\
 	    PUSHMARK(sp) ;					\
 	    (void) perl_call_sv(db->type, G_DISCARD|G_NOARGS); 	\
-	    /* SPAGAIN ; */						\
 	    sv_setsv(arg, DEFSV) ;				\
 	    sv_setsv(DEFSV, save_defsv) ;				\
 	    SvREFCNT_dec(save_defsv) ;				\
-	    /* PUTBACK ; */						\
 	    db->filtering = FALSE ;				\
 	    /*printf("end of filtering %s\n", name) ;*/		\
 	}
@@ -143,7 +140,8 @@ sdbm_clearerr(db)
 #define setFilter(type)					\
 	{						\
 	    if (db->type)				\
-	        RETVAL = newSVsv(db->type) ; 		\
+	        RETVAL = sv_mortalcopy(db->type) ;	\
+	    ST(0) = RETVAL ;				\
 	    if (db->type && (code == &PL_sv_undef)) {	\
                 SvREFCNT_dec(db->type) ;		\
 	        db->type = NULL ;			\
@@ -165,8 +163,6 @@ filter_fetch_key(db, code)
 	SV *		RETVAL = &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_key(db, code)
@@ -175,8 +171,6 @@ filter_store_key(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_key) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_fetch_value(db, code)
@@ -185,8 +179,6 @@ filter_fetch_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_fetch_value) ;
-	OUTPUT:
-	    RETVAL
 
 SV *
 filter_store_value(db, code)
@@ -195,6 +187,4 @@ filter_store_value(db, code)
 	SV *		RETVAL =  &PL_sv_undef ;
 	CODE:
 	    setFilter(filter_store_value) ;
-	OUTPUT:
-	    RETVAL
 
diff --git a/ext/re/Makefile.PL b/ext/re/Makefile.PL
index 040b085..bd0f1f7 100644
--- a/ext/re/Makefile.PL
+++ b/ext/re/Makefile.PL
@@ -5,7 +5,7 @@ WriteMakefile(
     MAN3PODS		=> {}, 	# Pods will be built by installman.
     XSPROTOARG		=> '-noprototypes',
     OBJECT		=> 're_exec$(OBJ_EXT) re_comp$(OBJ_EXT) re$(OBJ_EXT)',
-    DEFINE		=> '-DPERL_EXT_RE_BUILD',
+    DEFINE		=> '-DPERL_EXT_RE_BUILD -DPERL_EXT_RE_DEBUG',
     clean		=> { FILES => '*$(OBJ_EXT) *.c ../../lib/re.pm' },
 );
 
diff --git a/ext/re/re.xs b/ext/re/re.xs
index b49a110..10e44f7 100644
--- a/ext/re/re.xs
+++ b/ext/re/re.xs
@@ -11,6 +11,11 @@ extern regexp*	my_regcomp (pTHX_ char* exp, char* xend, PMOP* pm);
 extern I32	my_regexec (pTHX_ regexp* prog, char* stringarg, char* strend,
 			    char* strbeg, I32 minend, SV* screamer,
 			    void* data, U32 flags);
+extern void	my_regfree (pTHX_ struct regexp* r);
+extern char*	my_re_intuit_start (pTHX_ regexp *prog, SV *sv, char *strpos,
+				    char *strend, U32 flags,
+				    struct re_scream_pos_data_s *data);
+extern SV*	my_re_intuit_string (pTHX_ regexp *prog);
 
 static int oldfl;
 
@@ -20,8 +25,12 @@ static void
 deinstall(pTHX)
 {
     dTHR;
-    PL_regexecp = &Perl_regexec_flags;
-    PL_regcompp = &Perl_pregcomp;
+    PL_regexecp = FUNC_NAME_TO_PTR(Perl_regexec_flags);
+    PL_regcompp = FUNC_NAME_TO_PTR(Perl_pregcomp);
+    PL_regint_start = FUNC_NAME_TO_PTR(Perl_re_intuit_start);
+    PL_regint_string = FUNC_NAME_TO_PTR(Perl_re_intuit_string);
+    PL_regfree = FUNC_NAME_TO_PTR(Perl_pregfree);
+
     if (!oldfl)
 	PL_debug &= ~R_DB;
 }
@@ -33,6 +42,9 @@ install(pTHX)
     PL_colorset = 0;			/* Allow reinspection of ENV. */
     PL_regexecp = &my_regexec;
     PL_regcompp = &my_regcomp;
+    PL_regint_start = &my_re_intuit_start;
+    PL_regint_string = &my_re_intuit_string;
+    PL_regfree = &my_regfree;
     oldfl = PL_debug & R_DB;
     PL_debug |= R_DB;
 }
diff --git a/global.sym b/global.sym
index efbca1d..87ece3c 100644
--- a/global.sym
+++ b/global.sym
@@ -408,6 +408,8 @@ Perl_regdump
 Perl_pregexec
 Perl_pregfree
 Perl_pregcomp
+Perl_re_intuit_start
+Perl_re_intuit_string
 Perl_regexec_flags
 Perl_regnext
 Perl_regprop
diff --git a/hv.h b/hv.h
index e9772d4..3977b1c 100644
--- a/hv.h
+++ b/hv.h
@@ -28,7 +28,7 @@ struct xpvhv {
     STRLEN	xhv_fill;	/* how full xhv_array currently is */
     STRLEN	xhv_max;	/* subscript of last element of xhv_array */
     IV		xhv_keys;	/* how many elements in the array */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* magic for scalar array */
     HV*		xmg_stash;	/* class package */
 
diff --git a/intrpvar.h b/intrpvar.h
index 0bf826e..5cff858 100644
--- a/intrpvar.h
+++ b/intrpvar.h
@@ -219,7 +219,7 @@ PERLVAR(Isighandlerp,	Sighandler_t)
 
 PERLVAR(Ixiv_arenaroot,	XPV*)		/* list of allocated xiv areas */
 PERLVAR(Ixiv_root,	IV *)		/* free xiv list--shared by interpreters */
-PERLVAR(Ixnv_root,	double *)	/* free xnv list--shared by interpreters */
+PERLVAR(Ixnv_root,	NV *)		/* free xnv list--shared by interpreters */
 PERLVAR(Ixrv_root,	XRV *)		/* free xrv list--shared by interpreters */
 PERLVAR(Ixpv_root,	XPV *)		/* free xpv list--shared by interpreters */
 PERLVAR(Ihe_root,	HE *)		/* free he list--shared by interpreters */
diff --git a/mg.c b/mg.c
index a21ea57..0e9ca19 100644
--- a/mg.c
+++ b/mg.c
@@ -498,7 +498,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 #	    include <starlet.h>
 	    char msg[255];
 	    $DESCRIPTOR(msgdsc,msg);
-	    sv_setnv(sv,(double) vaxc$errno);
+	    sv_setnv(sv,(NV) vaxc$errno);
 	    if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1)
 		sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length);
 	    else
@@ -507,7 +507,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 #else
 #ifdef OS2
 	if (!(_emx_env & 0x200)) {	/* Under DOS */
-	    sv_setnv(sv, (double)errno);
+	    sv_setnv(sv, (NV)errno);
 	    sv_setpv(sv, errno ? Strerror(errno) : "");
 	} else {
 	    if (errno != errno_isOS2) {
@@ -515,14 +515,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 		if (tmp)	/* 2nd call to _syserrno() makes it 0 */
 		    Perl_rc = tmp;
 	    }
-	    sv_setnv(sv, (double)Perl_rc);
+	    sv_setnv(sv, (NV)Perl_rc);
 	    sv_setpv(sv, os2error(Perl_rc));
 	}
 #else
 #ifdef WIN32
 	{
 	    DWORD dwErr = GetLastError();
-	    sv_setnv(sv, (double)dwErr);
+	    sv_setnv(sv, (NV)dwErr);
 	    if (dwErr)
 	    {
 		PerlProc_GetOSError(sv, dwErr);
@@ -532,7 +532,7 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 	    SetLastError(dwErr);
 	}
 #else
-	sv_setnv(sv, (double)errno);
+	sv_setnv(sv, (NV)errno);
 	sv_setpv(sv, errno ? Strerror(errno) : "");
 #endif
 #endif
@@ -701,12 +701,12 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
 	break;
     case '!':
 #ifdef VMS
-	sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno));
+	sv_setnv(sv, (NV)((errno == EVMSERR) ? vaxc$errno : errno));
 	sv_setpv(sv, errno ? Strerror(errno) : "");
 #else
 	{
 	int saveerrno = errno;
-	sv_setnv(sv, (double)errno);
+	sv_setnv(sv, (NV)errno);
 #ifdef OS2
 	if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc));
 	else
diff --git a/objXSUB.h b/objXSUB.h
index d14de86..d91f84d 100644
--- a/objXSUB.h
+++ b/objXSUB.h
@@ -546,10 +546,16 @@
 #define PL_regexecp		pPerl->PL_regexecp
 #undef  PL_regflags
 #define PL_regflags		pPerl->PL_regflags
+#undef  PL_regfree
+#define PL_regfree		pPerl->PL_regfree
 #undef  PL_regindent
 #define PL_regindent		pPerl->PL_regindent
 #undef  PL_reginput
 #define PL_reginput		pPerl->PL_reginput
+#undef  PL_regint_start
+#define PL_regint_start		pPerl->PL_regint_start
+#undef  PL_regint_string
+#define PL_regint_string	pPerl->PL_regint_string
 #undef  PL_reginterp_cnt
 #define PL_reginterp_cnt	pPerl->PL_reginterp_cnt
 #undef  PL_reglastparen
@@ -2426,6 +2432,14 @@
 #define Perl_pregcomp		pPerl->Perl_pregcomp
 #undef  pregcomp
 #define pregcomp		Perl_pregcomp
+#undef  Perl_re_intuit_start
+#define Perl_re_intuit_start	pPerl->Perl_re_intuit_start
+#undef  re_intuit_start
+#define re_intuit_start		Perl_re_intuit_start
+#undef  Perl_re_intuit_string
+#define Perl_re_intuit_string	pPerl->Perl_re_intuit_string
+#undef  re_intuit_string
+#define re_intuit_string	Perl_re_intuit_string
 #undef  Perl_regexec_flags
 #define Perl_regexec_flags	pPerl->Perl_regexec_flags
 #undef  regexec_flags
diff --git a/op.c b/op.c
index 25b17dc..091a768 100644
--- a/op.c
+++ b/op.c
@@ -192,7 +192,7 @@ Perl_pad_allocmy(pTHX_ char *name)
 	PL_sv_objcount++;
     }
     av_store(PL_comppad_name, off, sv);
-    SvNVX(sv) = (double)PAD_MAX;
+    SvNVX(sv) = (NV)PAD_MAX;
     SvIVX(sv) = 0;			/* Not yet introduced--see newSTATEOP */
     if (!PL_min_intro_pending)
 	PL_min_intro_pending = off;
@@ -255,7 +255,7 @@ S_pad_findlex(pTHX_ char *name, PADOFFSET newoff, U32 seq, CV* startcv,
 		    sv_upgrade(namesv, SVt_PVNV);
 		    sv_setpv(namesv, name);
 		    av_store(PL_comppad_name, newoff, namesv);
-		    SvNVX(namesv) = (double)PL_curcop->cop_seq;
+		    SvNVX(namesv) = (NV)PL_curcop->cop_seq;
 		    SvIVX(namesv) = PAD_MAX;	/* A ref, intro immediately */
 		    SvFAKE_on(namesv);		/* A ref, not a real var */
 		    if (SvOBJECT(sv)) {		/* A typed var */
@@ -1899,7 +1899,7 @@ Perl_fold_constants(pTHX_ register OP *o)
 	    type != OP_NEGATE)
 	{
 	    IV iv = SvIV(sv);
-	    if ((double)iv == SvNV(sv)) {
+	    if ((NV)iv == SvNV(sv)) {
 		SvREFCNT_dec(sv);
 		sv = newSViv(iv);
 	    }
@@ -3083,7 +3083,7 @@ Perl_intro_my(pTHX)
     for (i = PL_min_intro_pending; i <= PL_max_intro_pending; i++) {
 	if ((sv = svp[i]) && sv != &PL_sv_undef && !SvIVX(sv)) {
 	    SvIVX(sv) = PAD_MAX;	/* Don't know scope end yet. */
-	    SvNVX(sv) = (double)PL_cop_seqmax;
+	    SvNVX(sv) = (NV)PL_cop_seqmax;
 	}
     }
     PL_min_intro_pending = 0;
diff --git a/perl.c b/perl.c
index 39eaf30..062b334 100644
--- a/perl.c
+++ b/perl.c
@@ -2947,6 +2947,9 @@ S_init_main_thread(pTHX)
     PL_maxscream = -1;
     PL_regcompp = FUNC_NAME_TO_PTR(Perl_pregcomp);
     PL_regexecp = FUNC_NAME_TO_PTR(Perl_regexec_flags);
+    PL_regint_start = FUNC_NAME_TO_PTR(Perl_re_intuit_start);
+    PL_regint_string = FUNC_NAME_TO_PTR(Perl_re_intuit_string);
+    PL_regfree = FUNC_NAME_TO_PTR(Perl_pregfree);
     PL_regindent = 0;
     PL_reginterp_cnt = 0;
 
diff --git a/perl.h b/perl.h
index 558d423..b09660a 100644
--- a/perl.h
+++ b/perl.h
@@ -145,6 +145,9 @@ class CPerlObj;
 #define CALLRUNOPS  CALL_FPTR(PL_runops)
 #define CALLREGCOMP CALL_FPTR(PL_regcompp)
 #define CALLREGEXEC CALL_FPTR(PL_regexecp)
+#define CALLREG_INTUIT_START CALL_FPTR(PL_regint_start)
+#define CALLREG_INTUIT_STRING CALL_FPTR(PL_regint_string)
+#define CALLREGFREE CALL_FPTR(PL_regfree)
 #define CALLPROTECT CALL_FPTR(PL_protect)
 
 #define NOOP (void)0
@@ -997,6 +1000,43 @@ Free_t   Perl_mfree (Malloc_t where);
 #  endif
 #endif
 
+#ifdef USE_LONG_DOUBLE
+#  if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)
+#    define LDoub_t long double
+#  endif
+#endif
+
+#ifdef USE_LONG_DOUBLE
+#   define HAS_LDOUB
+    typedef LDoub_t NV;
+#   define Perl_modf modfl
+#   define Perl_frexp frexpl
+#   define Perl_cos cosl
+#   define Perl_sin sinl
+#   define Perl_sqrt sqrtl
+#   define Perl_exp expl
+#   define Perl_log logl
+#   define Perl_atan2 atan2l
+#   define Perl_pow powl
+#   define Perl_floor floorl
+#   define Perl_atof atof
+#   define Perl_fmod fmodl
+#else
+    typedef double NV;
+#   define Perl_modf modf
+#   define Perl_frexp frexp
+#   define Perl_cos cos
+#   define Perl_sin sin
+#   define Perl_sqrt sqrt
+#   define Perl_exp exp
+#   define Perl_log log
+#   define Perl_atan2 atan2
+#   define Perl_pow pow
+#   define Perl_floor floor
+#   define Perl_atof atof		/* At some point there may be an atolf */
+#   define Perl_fmod fmod
+#endif
+
 /* Previously these definitions used hardcoded figures. 
  * It is hoped these formula are more portable, although
  * no data one way or another is presently known to me.
@@ -1728,9 +1768,9 @@ typedef I32 CHECKPOINT;
 #define U_I(what) ((unsigned int)(what))
 #define U_L(what) ((U32)(what))
 #else
-#define U_S(what) ((U16)cast_ulong((double)(what)))
-#define U_I(what) ((unsigned int)cast_ulong((double)(what)))
-#define U_L(what) (cast_ulong((double)(what)))
+#define U_S(what) ((U16)cast_ulong((NV)(what)))
+#define U_I(what) ((unsigned int)cast_ulong((NV)(what)))
+#define U_L(what) (cast_ulong((NV)(what)))
 #endif
 
 #ifdef CASTI32
@@ -1738,9 +1778,9 @@ typedef I32 CHECKPOINT;
 #define I_V(what) ((IV)(what))
 #define U_V(what) ((UV)(what))
 #else
-#define I_32(what) (cast_i32((double)(what)))
-#define I_V(what) (cast_iv((double)(what)))
-#define U_V(what) (cast_uv((double)(what)))
+#define I_32(what) (cast_i32((NV)(what)))
+#define I_V(what) (cast_iv((NV)(what)))
+#define U_V(what) (cast_uv((NV)(what)))
 #endif
 
 /* Used with UV/IV arguments: */
@@ -2348,6 +2388,12 @@ typedef regexp*(CPERLscope(*regcomp_t)) (pTHX_ char* exp, char* xend, PMOP* pm);
 typedef I32 (CPERLscope(*regexec_t)) (pTHX_ regexp* prog, char* stringarg,
 				      char* strend, char* strbeg, I32 minend,
 				      SV* screamer, void* data, U32 flags);
+typedef char* (CPERLscope(*re_intuit_start_t)) (pTHX_ regexp *prog, SV *sv,
+						char *strpos, char *strend,
+						U32 flags,
+						struct re_scream_pos_data_s *d);
+typedef SV*	(CPERLscope(*re_intuit_string_t)) (pTHX_ regexp *prog);
+typedef void	(CPERLscope(*regfree_t)) (pTHX_ struct regexp* r);
 
 
 /* Set up PERLVAR macros for populating structs */
@@ -2879,7 +2925,7 @@ typedef struct am_table_short AMTS;
 #define IS_NUMERIC_RADIX(c)		(0)
 #define RESTORE_NUMERIC_LOCAL()		/**/
 #define RESTORE_NUMERIC_STANDARD()	/**/
-#define Atof				atof
+#define Atof				Perl_atof
 
 #endif /* !USE_LOCALE_NUMERIC */
 
diff --git a/pp.c b/pp.c
index 786733e..c112208 100644
--- a/pp.c
+++ b/pp.c
@@ -943,15 +943,15 @@ PP(pp_divide)
     djSP; dATARGET; tryAMAGICbin(div,opASSIGN);
     {
       dPOPPOPnnrl;
-      double value;
+      NV value;
       if (right == 0.0)
 	DIE(aTHX_ "Illegal division by zero");
 #ifdef SLOPPYDIVIDE
       /* insure that 20./5. == 4. */
       {
 	IV k;
-	if ((double)I_V(left)  == left &&
-	    (double)I_V(right) == right &&
+	if ((NV)I_V(left)  == left &&
+	    (NV)I_V(right) == right &&
 	    (k = I_V(left)/I_V(right))*I_V(right) == I_V(left)) {
 	    value = k;
 	}
@@ -976,8 +976,8 @@ PP(pp_modulo)
 	bool left_neg;
 	bool right_neg;
 	bool use_double = 0;
-	double dright;
-	double dleft;
+	NV dright;
+	NV dleft;
 
 	if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
 	    IV i = SvIVX(POPs);
@@ -1007,7 +1007,7 @@ PP(pp_modulo)
 	}
 
 	if (use_double) {
-	    double dans;
+	    NV dans;
 
 #if 1
 /* Somehow U_V is pessimized even if CASTFLAGS is 0 */
@@ -1034,7 +1034,7 @@ PP(pp_modulo)
 	    if (!dright)
 		DIE(aTHX_ "Illegal modulus zero");
 
-	    dans = fmod(dleft, dright);
+	    dans = Perl_fmod(dleft, dright);
 	    if ((left_neg != right_neg) && dans)
 		dans = dright - dans;
 	    if (right_neg)
@@ -1057,7 +1057,7 @@ PP(pp_modulo)
 		if (ans <= ~((UV)IV_MAX)+1)
 		    sv_setiv(TARG, ~ans+1);
 		else
-		    sv_setnv(TARG, -(double)ans);
+		    sv_setnv(TARG, -(NV)ans);
 	    }
 	    else
 		sv_setuv(TARG, ans);
@@ -1624,7 +1624,7 @@ PP(pp_atan2)
     djSP; dTARGET; tryAMAGICbin(atan2,0);
     {
       dPOPTOPnnrl;
-      SETn(atan2(left, right));
+      SETn(Perl_atan2(left, right));
       RETURN;
     }
 }
@@ -1633,9 +1633,9 @@ PP(pp_sin)
 {
     djSP; dTARGET; tryAMAGICun(sin);
     {
-      double value;
+      NV value;
       value = POPn;
-      value = sin(value);
+      value = Perl_sin(value);
       XPUSHn(value);
       RETURN;
     }
@@ -1645,9 +1645,9 @@ PP(pp_cos)
 {
     djSP; dTARGET; tryAMAGICun(cos);
     {
-      double value;
+      NV value;
       value = POPn;
-      value = cos(value);
+      value = Perl_cos(value);
       XPUSHn(value);
       RETURN;
     }
@@ -1671,7 +1671,7 @@ extern double drand48 (void);
 PP(pp_rand)
 {
     djSP; dTARGET;
-    double value;
+    NV value;
     if (MAXARG < 1)
 	value = 1.0;
     else
@@ -1787,9 +1787,9 @@ PP(pp_exp)
 {
     djSP; dTARGET; tryAMAGICun(exp);
     {
-      double value;
+      NV value;
       value = POPn;
-      value = exp(value);
+      value = Perl_exp(value);
       XPUSHn(value);
       RETURN;
     }
@@ -1799,13 +1799,13 @@ PP(pp_log)
 {
     djSP; dTARGET; tryAMAGICun(log);
     {
-      double value;
+      NV value;
       value = POPn;
       if (value <= 0.0) {
 	RESTORE_NUMERIC_STANDARD();
 	DIE(aTHX_ "Can't take log of %g", value);
       }
-      value = log(value);
+      value = Perl_log(value);
       XPUSHn(value);
       RETURN;
     }
@@ -1815,13 +1815,13 @@ PP(pp_sqrt)
 {
     djSP; dTARGET; tryAMAGICun(sqrt);
     {
-      double value;
+      NV value;
       value = POPn;
       if (value < 0.0) {
 	RESTORE_NUMERIC_STANDARD();
 	DIE(aTHX_ "Can't take sqrt of %g", value);
       }
-      value = sqrt(value);
+      value = Perl_sqrt(value);
       XPUSHn(value);
       RETURN;
     }
@@ -1831,7 +1831,7 @@ PP(pp_int)
 {
     djSP; dTARGET;
     {
-      double value = TOPn;
+      NV value = TOPn;
       IV iv;
 
       if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs)) {
@@ -1840,9 +1840,9 @@ PP(pp_int)
       }
       else {
 	if (value >= 0.0)
-	  (void)modf(value, &value);
+	  (void)Perl_modf(value, &value);
 	else {
-	  (void)modf(-value, &value);
+	  (void)Perl_modf(-value, &value);
 	  value = -value;
 	}
 	iv = I_V(value);
@@ -1859,7 +1859,7 @@ PP(pp_abs)
 {
     djSP; dTARGET; tryAMAGICun(abs);
     {
-      double value = TOPn;
+      NV value = TOPn;
       IV iv;
 
       if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs) &&
@@ -3295,7 +3295,7 @@ PP(pp_unpack)
     double adouble;
     I32 checksum = 0;
     register U32 culong;
-    double cdouble;
+    NV cdouble;
     int commas = 0;
 #ifdef PERL_NATINT_PACK
     int natint;		/* native integer */
@@ -3559,7 +3559,7 @@ PP(pp_unpack)
 		    auint = utf8_to_uv((U8*)s, &along);
 		    s += along;
 		    if (checksum > 32)
-			cdouble += (double)auint;
+			cdouble += (NV)auint;
 		    else
 			culong += auint;
 		}
@@ -3719,7 +3719,7 @@ PP(pp_unpack)
 		    Copy(s, &aint, 1, int);
 		    s += sizeof(int);
 		    if (checksum > 32)
-			cdouble += (double)aint;
+			cdouble += (NV)aint;
 		    else
 			culong += aint;
 		}
@@ -3770,7 +3770,7 @@ PP(pp_unpack)
 		    Copy(s, &auint, 1, unsigned int);
 		    s += sizeof(unsigned int);
 		    if (checksum > 32)
-			cdouble += (double)auint;
+			cdouble += (NV)auint;
 		    else
 			culong += auint;
 		}
@@ -3809,7 +3809,7 @@ PP(pp_unpack)
 			COPYNN(s, &along, sizeof(long));
 			s += sizeof(long);
 			if (checksum > 32)
-			    cdouble += (double)along;
+			    cdouble += (NV)along;
 			else
 			    culong += along;
 		    }
@@ -3825,7 +3825,7 @@ PP(pp_unpack)
 #endif
 			s += SIZE32;
 			if (checksum > 32)
-			    cdouble += (double)along;
+			    cdouble += (NV)along;
 			else
 			    culong += along;
 		    }
@@ -3879,7 +3879,7 @@ PP(pp_unpack)
 			COPYNN(s, &aulong, sizeof(unsigned long));
 			s += sizeof(unsigned long);
 			if (checksum > 32)
-			    cdouble += (double)aulong;
+			    cdouble += (NV)aulong;
 			else
 			    culong += aulong;
 		    }
@@ -3899,7 +3899,7 @@ PP(pp_unpack)
 			    aulong = vtohl(aulong);
 #endif
 			if (checksum > 32)
-			    cdouble += (double)aulong;
+			    cdouble += (NV)aulong;
 			else
 			    culong += aulong;
 		    }
@@ -4031,7 +4031,7 @@ PP(pp_unpack)
 		if (aquad >= IV_MIN && aquad <= IV_MAX)
 		    sv_setiv(sv, (IV)aquad);
 		else
-		    sv_setnv(sv, (double)aquad);
+		    sv_setnv(sv, (NV)aquad);
 		PUSHs(sv_2mortal(sv));
 	    }
 	    break;
@@ -4052,7 +4052,7 @@ PP(pp_unpack)
 		if (auquad <= UV_MAX)
 		    sv_setuv(sv, (UV)auquad);
 		else
-		    sv_setnv(sv, (double)auquad);
+		    sv_setnv(sv, (NV)auquad);
 		PUSHs(sv_2mortal(sv));
 	    }
 	    break;
@@ -4077,7 +4077,7 @@ PP(pp_unpack)
 		    Copy(s, &afloat, 1, float);
 		    s += sizeof(float);
 		    sv = NEWSV(47, 0);
-		    sv_setnv(sv, (double)afloat);
+		    sv_setnv(sv, (NV)afloat);
 		    PUSHs(sv_2mortal(sv));
 		}
 	    }
@@ -4101,7 +4101,7 @@ PP(pp_unpack)
 		    Copy(s, &adouble, 1, double);
 		    s += sizeof(double);
 		    sv = NEWSV(48, 0);
-		    sv_setnv(sv, (double)adouble);
+		    sv_setnv(sv, (NV)adouble);
 		    PUSHs(sv_2mortal(sv));
 		}
 	    }
@@ -4169,7 +4169,7 @@ PP(pp_unpack)
 	    sv = NEWSV(42, 0);
 	    if (strchr("fFdD", datumtype) ||
 	      (checksum > 32 && strchr("iIlLNU", datumtype)) ) {
-		double trouble;
+		NV trouble;
 
 		adouble = 1.0;
 		while (checksum >= 16) {
@@ -4185,7 +4185,7 @@ PP(pp_unpack)
 		along = (1 << checksum) - 1;
 		while (cdouble < 0.0)
 		    cdouble += adouble;
-		cdouble = modf(cdouble / adouble, &trouble) * adouble;
+		cdouble = Perl_modf(cdouble / adouble, &trouble) * adouble;
 		sv_setnv(sv, cdouble);
 	    }
 	    else {
@@ -4662,7 +4662,7 @@ PP(pp_pack)
 	case 'w':
             while (len-- > 0) {
 		fromstr = NEXTFROM;
-		adouble = floor(SvNV(fromstr));
+		adouble = Perl_floor(SvNV(fromstr));
 
 		if (adouble < 0)
 		    Perl_croak(aTHX_ "Cannot compress negative numbers");
@@ -4992,17 +4992,19 @@ PP(pp_split)
 	    s = m;
 	}
     }
-    else if (rx->check_substr && !rx->nparens
+    else if ((rx->reganch & RE_USE_INTUIT) && !rx->nparens
 	     && (rx->reganch & ROPT_CHECK_ALL)
 	     && !(rx->reganch & ROPT_ANCH)) {
-	int tail = SvTAIL(rx->check_substr) != 0;
+	int tail = (rx->reganch & RE_INTUIT_TAIL);
+	SV *csv = CALLREG_INTUIT_STRING(aTHX_ rx);
+	char c;
 
-	i = SvCUR(rx->check_substr);
+	i = rx->minlen;
 	if (i == 1 && !tail) {
-	    i = *SvPVX(rx->check_substr);
+	    c = *SvPV(csv,i);
 	    while (--limit) {
 		/*SUPPRESS 530*/
-		for (m = s; m < strend && *m != i; m++) ;
+		for (m = s; m < strend && *m != c; m++) ;
 		if (m >= strend)
 		    break;
 		dstr = NEWSV(30, m-s);
@@ -5016,8 +5018,8 @@ PP(pp_split)
 	else {
 #ifndef lint
 	    while (s < strend && --limit &&
-	      (m=fbm_instr((unsigned char*)s, (unsigned char*)strend,
-		    rx->check_substr, PL_multiline ? FBMrf_MULTILINE : 0)) )
+	      (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
+			     csv, PL_multiline ? FBMrf_MULTILINE : 0)) )
 #endif
 	    {
 		dstr = NEWSV(31, m-s);
@@ -5025,14 +5027,18 @@ PP(pp_split)
 		if (make_mortal)
 		    sv_2mortal(dstr);
 		XPUSHs(dstr);
-		s = m + i - tail;	/* Fake \n at the end */
+		s = m + i;		/* Fake \n at the end */
 	    }
 	}
     }
     else {
 	maxiters += (strend - s) * rx->nparens;
-	while (s < strend && --limit &&
-	       CALLREGEXEC(aTHX_ rx, s, strend, orig, 1, sv, NULL, 0))
+	while (s < strend && --limit
+/*	       && (!rx->check_substr 
+		   || ((s = CALLREG_INTUIT_START(aTHX_ rx, sv, s, strend,
+						 0, NULL))))
+*/	       && CALLREGEXEC(aTHX_ rx, s, strend, orig,
+			      1 /* minend */, sv, NULL, 0))
 	{
 	    TAINT_IF(RX_MATCH_TAINTED(rx));
 	    if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
diff --git a/pp.h b/pp.h
index ca8dc35..9fd3365 100644
--- a/pp.h
+++ b/pp.h
@@ -88,43 +88,43 @@
 #define PUSHs(s)	(*++sp = (s))
 #define PUSHTARG	STMT_START { SvSETMAGIC(TARG); PUSHs(TARG); } STMT_END
 #define PUSHp(p,l)	STMT_START { sv_setpvn(TARG, (p), (l)); PUSHTARG; } STMT_END
-#define PUSHn(n)	STMT_START { sv_setnv(TARG, (double)(n)); PUSHTARG; } STMT_END
+#define PUSHn(n)	STMT_START { sv_setnv(TARG, (NV)(n)); PUSHTARG; } STMT_END
 #define PUSHi(i)	STMT_START { sv_setiv(TARG, (IV)(i)); PUSHTARG; } STMT_END
 #define PUSHu(u)	STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END
 
 #define XPUSHs(s)	STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END
 #define XPUSHTARG	STMT_START { SvSETMAGIC(TARG); XPUSHs(TARG); } STMT_END
 #define XPUSHp(p,l)	STMT_START { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } STMT_END
-#define XPUSHn(n)	STMT_START { sv_setnv(TARG, (double)(n)); XPUSHTARG; } STMT_END
+#define XPUSHn(n)	STMT_START { sv_setnv(TARG, (NV)(n)); XPUSHTARG; } STMT_END
 #define XPUSHi(i)	STMT_START { sv_setiv(TARG, (IV)(i)); XPUSHTARG; } STMT_END
 #define XPUSHu(u)	STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
 
 #define SETs(s)		(*sp = s)
 #define SETTARG		STMT_START { SvSETMAGIC(TARG); SETs(TARG); } STMT_END
 #define SETp(p,l)	STMT_START { sv_setpvn(TARG, (p), (l)); SETTARG; } STMT_END
-#define SETn(n)		STMT_START { sv_setnv(TARG, (double)(n)); SETTARG; } STMT_END
+#define SETn(n)		STMT_START { sv_setnv(TARG, (NV)(n)); SETTARG; } STMT_END
 #define SETi(i)		STMT_START { sv_setiv(TARG, (IV)(i)); SETTARG; } STMT_END
 #define SETu(u)		STMT_START { sv_setuv(TARG, (UV)(u)); SETTARG; } STMT_END
 
 #define dTOPss		SV *sv = TOPs
 #define dPOPss		SV *sv = POPs
-#define dTOPnv		double value = TOPn
-#define dPOPnv		double value = POPn
+#define dTOPnv		NV value = TOPn
+#define dPOPnv		NV value = POPn
 #define dTOPiv		IV value = TOPi
 #define dPOPiv		IV value = POPi
 #define dTOPuv		UV value = TOPu
 #define dPOPuv		UV value = POPu
 
 #define dPOPXssrl(X)	SV *right = POPs; SV *left = CAT2(X,s)
-#define dPOPXnnrl(X)	double right = POPn; double left = CAT2(X,n)
+#define dPOPXnnrl(X)	NV right = POPn; NV left = CAT2(X,n)
 #define dPOPXiirl(X)	IV right = POPi; IV left = CAT2(X,i)
 
 #define USE_LEFT(sv) \
 	(SvOK(sv) || SvGMAGICAL(sv) || !(PL_op->op_flags & OPf_STACKED))
 #define dPOPXnnrl_ul(X)	\
-    double right = POPn;				\
+    NV right = POPn;				\
     SV *leftsv = CAT2(X,s);				\
-    double left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0
+    NV left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0
 #define dPOPXiirl_ul(X) \
     IV right = POPi;					\
     SV *leftsv = CAT2(X,s);				\
diff --git a/pp_ctl.c b/pp_ctl.c
index 64e695b..21d0335 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -276,7 +276,7 @@ PP(pp_formline)
     bool chopspace = (strchr(PL_chopset, ' ') != Nullch);
     char *chophere;
     char *linemark;
-    double value;
+    NV value;
     bool gotsome;
     STRLEN len;
     STRLEN fudge = SvCUR(tmpForm) * (IN_UTF8 ? 3 : 1) + 1;
@@ -569,6 +569,14 @@ PP(pp_formline)
 	    /* Formats aren't yet marked for locales, so assume "yes". */
 	    {
 		RESTORE_NUMERIC_LOCAL();
+#if defined(USE_LONG_DOUBLE)
+		if (arg & 256) {
+		    sprintf(t, "%#*.*Lf",
+			    (int) fieldsize, (int) arg & 255, value);
+		} else {
+		    sprintf(t, "%*.0Lf", (int) fieldsize, value);
+		}
+#else
 		if (arg & 256) {
 		    sprintf(t, "%#*.*f",
 			    (int) fieldsize, (int) arg & 255, value);
@@ -576,6 +584,7 @@ PP(pp_formline)
 		    sprintf(t, "%*.0f",
 			    (int) fieldsize, value);
 		}
+#endif
 		RESTORE_NUMERIC_STANDARD();
 	    }
 	    t += fieldsize;
@@ -749,8 +758,8 @@ PP(pp_mapwhile)
 STATIC I32
 S_sv_ncmp(pTHX_ SV *a, SV *b)
 {
-    double nv1 = SvNV(a);
-    double nv2 = SvNV(b);
+    NV nv1 = SvNV(a);
+    NV nv2 = SvNV(b);
     return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0;
 }
 
@@ -778,7 +787,7 @@ S_amagic_ncmp(pTHX_ register SV *a, register SV *b)
     SV *tmpsv;
     tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
     if (tmpsv) {
-    	double d;
+    	NV d;
     	
         if (SvIOK(tmpsv)) {
             I32 i = SvIVX(tmpsv);
@@ -800,7 +809,7 @@ S_amagic_i_ncmp(pTHX_ register SV *a, register SV *b)
     SV *tmpsv;
     tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
     if (tmpsv) {
-    	double d;
+    	NV d;
     	
         if (SvIOK(tmpsv)) {
             I32 i = SvIVX(tmpsv);
@@ -822,7 +831,7 @@ S_amagic_cmp(pTHX_ register SV *str1, register SV *str2)
     SV *tmpsv;
     tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv);
     if (tmpsv) {
-    	double d;
+    	NV d;
     	
         if (SvIOK(tmpsv)) {
             I32 i = SvIVX(tmpsv);
@@ -844,7 +853,7 @@ S_amagic_cmp_locale(pTHX_ register SV *str1, register SV *str2)
     SV *tmpsv;
     tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv);
     if (tmpsv) {
-    	double d;
+    	NV d;
     	
         if (SvIOK(tmpsv)) {
             I32 i = SvIVX(tmpsv);
@@ -2464,11 +2473,11 @@ PP(pp_exit)
 PP(pp_nswitch)
 {
     djSP;
-    double value = SvNVx(GvSV(cCOP->cop_gv));
+    NV value = SvNVx(GvSV(cCOP->cop_gv));
     register I32 match = I_32(value);
 
     if (value < 0.0) {
-	if (((double)match) > value)
+	if (((NV)match) > value)
 	    --match;		/* was fractional--truncate other way */
     }
     match -= cCOP->uop.scop.scop_offset;
diff --git a/pp_hot.c b/pp_hot.c
index d3a1f5c..697c306 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -846,10 +846,8 @@ PP(pp_match)
     register char *s;
     char *strend;
     I32 global;
-    I32 r_flags = 0;
-    char *truebase;			/* Start of string, may be
-					   relocated if REx engine
-					   copies the string.  */
+    I32 r_flags = REXEC_CHECKED;
+    char *truebase;			/* Start of string  */
     register REGEXP *rx = pm->op_pmregexp;
     bool rxtainted;
     I32 gimme = GIMME;
@@ -909,9 +907,7 @@ PP(pp_match)
     if ((gimme != G_ARRAY && !global && rx->nparens)
 	    || SvTEMP(TARG) || PL_sawampersand)
 	r_flags |= REXEC_COPY_STR;
-    if (SvSCREAM(TARG) && rx->check_substr
-	&& SvTYPE(rx->check_substr) == SVt_PVBM
-	&& SvVALID(rx->check_substr)) 
+    if (SvSCREAM(TARG)) 
 	r_flags |= REXEC_SCREAM;
 
     if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
@@ -927,76 +923,17 @@ play_it_again:
 	if (update_minmatch++)
 	    minmatch = had_zerolen;
     }
-    if (rx->check_substr) {
-	if (!(rx->reganch & ROPT_NOSCAN)) { /* Floating checkstring. */
-	    SV *c = rx->check_substr;
+    if (rx->reganch & RE_USE_INTUIT) {
+	s = CALLREG_INTUIT_START(aTHX_ rx, TARG, s, strend, r_flags, NULL);
 
-	    if (r_flags & REXEC_SCREAM) {
-		I32 p = -1;
-		char *b;
-
-		if (PL_screamfirst[BmRARE(c)] < 0
-		    && !( BmRARE(c) == '\n' && (BmPREVIOUS(c) == SvCUR(c) - 1)
-			  && SvTAIL(c) ))
-		    goto nope;
-
-		b = (char*)HOP((U8*)s, rx->check_offset_min);
-		if (!(s = screaminstr(TARG, c, b - s, 0, &p, 0)))
-		    goto nope;
-
-		if ((rx->reganch & ROPT_CHECK_ALL)
-			 && !PL_sawampersand && !SvTAIL(c))
-		    goto yup;
-	    }
-	    else if (!(s = fbm_instr((unsigned char*)HOP((U8*)s, rx->check_offset_min),
-				     (unsigned char*)strend, c, 
-				     PL_multiline ? FBMrf_MULTILINE : 0)))
-		goto nope;
-	    else if ((rx->reganch & ROPT_CHECK_ALL) && !PL_sawampersand)
-		goto yup;
-	    if (s && rx->check_offset_max < s - t) {
-		++BmUSEFUL(c);
-		s = (char*)HOP((U8*)s, -rx->check_offset_max);
-	    }
-	    else
-		s = t;
-	}
-	/* Now checkstring is fixed, i.e. at fixed offset from the
-	   beginning of match, and the match is anchored at s. */
-	else if (!PL_multiline) {	/* Anchored near beginning of string. */
-	    I32 slen;
-	    char *b = (char*)HOP((U8*)s, rx->check_offset_min);
-
-	    if (SvTAIL(rx->check_substr)) {
-		slen = SvCUR(rx->check_substr);	/* >= 1 */
-
-		if ( strend - b > slen || strend - b < slen - 1 )
-		    goto nope;
-		if ( strend - b == slen && strend[-1] != '\n')
-		    goto nope;
-		/* Now should match b[0..slen-2] */
-		slen--;
-		if (slen && (*SvPVX(rx->check_substr) != *b
-			     || (slen > 1
-				 && memNE(SvPVX(rx->check_substr), b, slen))))
-		    goto nope;
-		if ((rx->reganch & ROPT_CHECK_ALL) && !PL_sawampersand)
-		    goto yup;
-	    } else {			/* Assume len > 0 */
-		if (*SvPVX(rx->check_substr) != *b
-		    || ((slen = SvCUR(rx->check_substr)) > 1
-			&& memNE(SvPVX(rx->check_substr), b, slen)))
-		    goto nope;
-		if ((rx->reganch & ROPT_CHECK_ALL) && !PL_sawampersand)
-		    goto yup;
-	    }
-	}
-	if (!(rx->reganch & ROPT_NAUGHTY) && --BmUSEFUL(rx->check_substr) < 0
-	    && rx->check_substr == rx->float_substr) {
-	    SvREFCNT_dec(rx->check_substr);
-	    rx->check_substr = Nullsv;	/* opt is being useless */
-	    rx->float_substr = Nullsv;
-	}
+	if (!s)
+	    goto nope;
+	if ( (rx->reganch & ROPT_CHECK_ALL)
+	     && !PL_sawampersand 
+	     && ((rx->reganch & ROPT_NOSCAN)
+		 || !((rx->reganch & RE_INTUIT_TAIL)
+		      && (r_flags & REXEC_SCREAM))))
+	    goto yup;
     }
     if (CALLREGEXEC(aTHX_ rx, s, strend, truebase, minmatch, TARG, NULL, r_flags))
     {
@@ -1066,11 +1003,10 @@ play_it_again:
 	RETPUSHYES;
     }
 
-yup:					/* Confirmed by check_substr */
+yup:					/* Confirmed by INTUIT */
     if (rxtainted)
 	RX_MATCH_TAINTED_on(rx);
     TAINT_IF(RX_MATCH_TAINTED(rx));
-    ++BmUSEFUL(rx->check_substr);
     PL_curpm = pm;
     if (pm->op_pmflags & PMf_ONCE)
 	pm->op_pmdynflags |= PMdf_USED;
@@ -1081,7 +1017,7 @@ yup:					/* Confirmed by check_substr */
     if (global) {
 	rx->subbeg = truebase;
 	rx->startp[0] = s - truebase;
-	rx->endp[0] = s - truebase + SvCUR(rx->check_substr);
+	rx->endp[0] = s - truebase + rx->minlen;
 	rx->sublen = strend - truebase;
 	goto gotcha;
     } 
@@ -1092,19 +1028,16 @@ yup:					/* Confirmed by check_substr */
 	rx->sublen = strend - t;
 	RX_MATCH_COPIED_on(rx);
 	off = rx->startp[0] = s - t;
-	rx->endp[0] = off + SvCUR(rx->check_substr);
+	rx->endp[0] = off + rx->minlen;
     }
     else {			/* startp/endp are used by @- @+. */
 	rx->startp[0] = s - truebase;
-	rx->endp[0] = s - truebase + SvCUR(rx->check_substr);
+	rx->endp[0] = s - truebase + rx->minlen;
     }
     LEAVE_SCOPE(oldsave);
     RETPUSHYES;
 
 nope:
-    if (rx->check_substr)
-	++BmUSEFUL(rx->check_substr);
-
 ret_no:
     if (global && !(pm->op_pmflags & PMf_CONTINUE)) {
 	if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) {
@@ -1717,56 +1650,26 @@ PP(pp_subst)
     }
     r_flags = (rx->nparens || SvTEMP(TARG) || PL_sawampersand)
 		? REXEC_COPY_STR : 0;
-    if (SvSCREAM(TARG) && rx->check_substr
-		  && SvTYPE(rx->check_substr) == SVt_PVBM
-		  && SvVALID(rx->check_substr))
+    if (SvSCREAM(TARG))
 	r_flags |= REXEC_SCREAM;
     if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) {
 	SAVEINT(PL_multiline);
 	PL_multiline = pm->op_pmflags & PMf_MULTILINE;
     }
     orig = m = s;
-    if (rx->check_substr) {
-	if (!(rx->reganch & ROPT_NOSCAN)) { /* It floats. */
-	    if (r_flags & REXEC_SCREAM) {
-		I32 p = -1;
-		char *b;
-		
-		if (PL_screamfirst[BmRARE(rx->check_substr)] < 0)
-		    goto nope;
-
-		b = (char*)HOP((U8*)s, rx->check_offset_min);
-		if (!(s = screaminstr(TARG, rx->check_substr, b - s, 0, &p, 0)))
-		    goto nope;
-	    }
-	    else if (!(s = fbm_instr((unsigned char*)HOP((U8*)s, rx->check_offset_min), 
-				     (unsigned char*)strend,
-				     rx->check_substr, 
-				     PL_multiline ? FBMrf_MULTILINE : 0)))
-		goto nope;
-	    if (s && rx->check_offset_max < s - m) {
-		++BmUSEFUL(rx->check_substr);
-		s = (char*)HOP((U8*)s, -rx->check_offset_max);
-	    }
-	    else
-		s = m;
-	}
-	/* Now checkstring is fixed, i.e. at fixed offset from the
-	   beginning of match, and the match is anchored at s. */
-	else if (!PL_multiline) { /* Anchored at beginning of string. */
-	    I32 slen;
-	    char *b = (char*)HOP((U8*)s, rx->check_offset_min);
-	    if (*SvPVX(rx->check_substr) != *b
-		|| ((slen = SvCUR(rx->check_substr)) > 1
-		    && memNE(SvPVX(rx->check_substr), b, slen)))
-		goto nope;
-	}
-	if (!(rx->reganch & ROPT_NAUGHTY) && --BmUSEFUL(rx->check_substr) < 0
-	    && rx->check_substr == rx->float_substr) {
-	    SvREFCNT_dec(rx->check_substr);
-	    rx->check_substr = Nullsv;	/* opt is being useless */
-	    rx->float_substr = Nullsv;
-	}
+    if (rx->reganch & RE_USE_INTUIT) {
+	s = CALLREG_INTUIT_START(aTHX_ rx, TARG, s, strend, r_flags, NULL);
+
+	if (!s)
+	    goto nope;
+	/* How to do it in subst? */
+/*	if ( (rx->reganch & ROPT_CHECK_ALL)
+	     && !PL_sawampersand 
+	     && ((rx->reganch & ROPT_NOSCAN)
+		 || !((rx->reganch & RE_INTUIT_TAIL)
+		      && (r_flags & REXEC_SCREAM))))
+	    goto yup;
+*/
     }
 
     /* only replace once? */
@@ -1778,7 +1681,9 @@ PP(pp_subst)
     /* can do inplace substitution? */
     if (c && clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR))
 	&& !(rx->reganch & ROPT_LOOKBEHIND_SEEN)) {
-	if (!CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, r_flags)) {
+	if (!CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL,
+			 r_flags | REXEC_CHECKED))
+	{
 	    SPAGAIN;
 	    PUSHs(&PL_sv_no);
 	    LEAVE_SCOPE(oldsave);
@@ -1851,7 +1756,9 @@ PP(pp_subst)
 		}
 		s = rx->endp[0] + orig;
 	    } while (CALLREGEXEC(aTHX_ rx, s, strend, orig, s == m,
-				 Nullsv, NULL, REXEC_NOT_FIRST)); /* don't match same null twice */
+				 TARG, NULL,
+				 /* don't match same null twice */
+				 REXEC_NOT_FIRST|REXEC_IGNOREPOS));
 	    if (s != d) {
 		i = strend - s;
 		SvCUR_set(TARG, d - SvPVX(TARG) + i);
@@ -1873,7 +1780,9 @@ PP(pp_subst)
 	RETURN;
     }
 
-    if (CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL, r_flags)) {
+    if (CALLREGEXEC(aTHX_ rx, s, strend, orig, 0, TARG, NULL,
+		    r_flags | REXEC_CHECKED))
+    {
 	if (force_on_match) {
 	    force_on_match = 0;
 	    s = SvPV_force(TARG, len);
@@ -1933,8 +1842,6 @@ PP(pp_subst)
     goto ret_no;
 
 nope:
-    ++BmUSEFUL(rx->check_substr);
-
 ret_no:         
     SPAGAIN;
     PUSHs(&PL_sv_no);
diff --git a/pp_sys.c b/pp_sys.c
index 483ddce..ca4f464 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -906,7 +906,7 @@ PP(pp_sselect)
     register I32 j;
     register char *s;
     register SV *sv;
-    double value;
+    NV value;
     I32 maxlen = 0;
     I32 nfound;
     struct timeval timebuf;
@@ -969,7 +969,7 @@ PP(pp_sselect)
 	if (value < 0.0)
 	    value = 0.0;
 	timebuf.tv_sec = (long)value;
-	value -= (double)timebuf.tv_sec;
+	value -= (NV)timebuf.tv_sec;
 	timebuf.tv_usec = (long)(value * 1000000.0);
     }
     else
@@ -1028,8 +1028,8 @@ PP(pp_sselect)
 
     PUSHi(nfound);
     if (GIMME == G_ARRAY && tbuf) {
-	value = (double)(timebuf.tv_sec) +
-		(double)(timebuf.tv_usec) / 1000000.0;
+	value = (NV)(timebuf.tv_sec) +
+		(NV)(timebuf.tv_usec) / 1000000.0;
 	PUSHs(sv = sv_mortalcopy(&PL_sv_no));
 	sv_setnv(sv, value);
     }
@@ -3822,11 +3822,11 @@ PP(pp_tms)
                                                    /* is returned.                   */
 #endif
 
-    PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_utime)/HZ)));
+    PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_utime)/HZ)));
     if (GIMME == G_ARRAY) {
-	PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_stime)/HZ)));
-	PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_cutime)/HZ)));
-	PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_cstime)/HZ)));
+	PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_stime)/HZ)));
+	PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cutime)/HZ)));
+	PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cstime)/HZ)));
     }
     RETURN;
 #endif /* HAS_TIMES */
diff --git a/proto.h b/proto.h
index 95ffda5..7fa6424 100644
--- a/proto.h
+++ b/proto.h
@@ -39,10 +39,10 @@ VIRTUAL int	Perl_block_start(pTHX_ int full);
 VIRTUAL void	Perl_boot_core_UNIVERSAL(pTHX);
 VIRTUAL void	Perl_call_list(pTHX_ I32 oldscope, AV* av_list);
 VIRTUAL I32	Perl_cando(pTHX_ I32 bit, I32 effective, Stat_t* statbufp);
-VIRTUAL U32	Perl_cast_ulong(pTHX_ double f);
-VIRTUAL I32	Perl_cast_i32(pTHX_ double f);
-VIRTUAL IV	Perl_cast_iv(pTHX_ double f);
-VIRTUAL UV	Perl_cast_uv(pTHX_ double f);
+VIRTUAL U32	Perl_cast_ulong(pTHX_ NV f);
+VIRTUAL I32	Perl_cast_i32(pTHX_ NV f);
+VIRTUAL IV	Perl_cast_iv(pTHX_ NV f);
+VIRTUAL UV	Perl_cast_uv(pTHX_ NV f);
 #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP)
 VIRTUAL I32	Perl_my_chsize(pTHX_ int fd, Off_t length);
 #endif
@@ -307,7 +307,7 @@ VIRTUAL I32	Perl_mg_size(pTHX_ SV* sv);
 VIRTUAL OP*	Perl_mod(pTHX_ OP* o, I32 type);
 VIRTUAL char*	Perl_moreswitches(pTHX_ char* s);
 VIRTUAL OP*	Perl_my(pTHX_ OP* o);
-VIRTUAL double	Perl_my_atof(pTHX_ const char *s);
+VIRTUAL NV	Perl_my_atof(pTHX_ const char *s);
 #if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY)
 VIRTUAL char*	Perl_my_bcopy(pTHX_ const char* from, char* to, I32 len);
 #endif
@@ -375,7 +375,7 @@ VIRTUAL SV*	Perl_newSV(pTHX_ STRLEN len);
 VIRTUAL OP*	Perl_newSVREF(pTHX_ OP* o);
 VIRTUAL OP*	Perl_newSVOP(pTHX_ I32 type, I32 flags, SV* sv);
 VIRTUAL SV*	Perl_newSViv(pTHX_ IV i);
-VIRTUAL SV*	Perl_newSVnv(pTHX_ double n);
+VIRTUAL SV*	Perl_newSVnv(pTHX_ NV n);
 VIRTUAL SV*	Perl_newSVpv(pTHX_ const char* s, STRLEN len);
 VIRTUAL SV*	Perl_newSVpvn(pTHX_ const char* s, STRLEN len);
 VIRTUAL SV*	Perl_newSVpvf(pTHX_ const char* pat, ...);
@@ -452,6 +452,8 @@ VIRTUAL void	Perl_regdump(pTHX_ regexp* r);
 VIRTUAL I32	Perl_pregexec(pTHX_ regexp* prog, char* stringarg, char* strend, char* strbeg, I32 minend, SV* screamer, U32 nosave);
 VIRTUAL void	Perl_pregfree(pTHX_ struct regexp* r);
 VIRTUAL regexp*	Perl_pregcomp(pTHX_ char* exp, char* xend, PMOP* pm);
+VIRTUAL char*	Perl_re_intuit_start(pTHX_ regexp* prog, SV* sv, char* strpos, char* strend, U32 flags, struct re_scream_pos_data_s *data);
+VIRTUAL SV*	Perl_re_intuit_string(pTHX_ regexp* prog);
 VIRTUAL I32	Perl_regexec_flags(pTHX_ regexp* prog, char* stringarg, char* strend, char* strbeg, I32 minend, SV* screamer, void* data, U32 flags);
 VIRTUAL regnode*	Perl_regnext(pTHX_ regnode* p);
 VIRTUAL void	Perl_regprop(pTHX_ SV* sv, regnode* o);
@@ -527,12 +529,12 @@ VIRTUAL CV*	Perl_sv_2cv(pTHX_ SV* sv, HV** st, GV** gvp, I32 lref);
 VIRTUAL IO*	Perl_sv_2io(pTHX_ SV* sv);
 VIRTUAL IV	Perl_sv_2iv(pTHX_ SV* sv);
 VIRTUAL SV*	Perl_sv_2mortal(pTHX_ SV* sv);
-VIRTUAL double	Perl_sv_2nv(pTHX_ SV* sv);
+VIRTUAL NV	Perl_sv_2nv(pTHX_ SV* sv);
 VIRTUAL char*	Perl_sv_2pv(pTHX_ SV* sv, STRLEN* lp);
 VIRTUAL UV	Perl_sv_2uv(pTHX_ SV* sv);
 VIRTUAL IV	Perl_sv_iv(pTHX_ SV* sv);
 VIRTUAL UV	Perl_sv_uv(pTHX_ SV* sv);
-VIRTUAL double	Perl_sv_nv(pTHX_ SV* sv);
+VIRTUAL NV	Perl_sv_nv(pTHX_ SV* sv);
 VIRTUAL char*	Perl_sv_pvn(pTHX_ SV *sv, STRLEN *len);
 VIRTUAL I32	Perl_sv_true(pTHX_ SV *sv);
 VIRTUAL void	Perl_sv_add_arena(pTHX_ char* ptr, U32 size, U32 flags);
@@ -582,9 +584,9 @@ VIRTUAL void	Perl_sv_setpvf(pTHX_ SV* sv, const char* pat, ...);
 VIRTUAL void	Perl_sv_setiv(pTHX_ SV* sv, IV num);
 VIRTUAL void	Perl_sv_setpviv(pTHX_ SV* sv, IV num);
 VIRTUAL void	Perl_sv_setuv(pTHX_ SV* sv, UV num);
-VIRTUAL void	Perl_sv_setnv(pTHX_ SV* sv, double num);
+VIRTUAL void	Perl_sv_setnv(pTHX_ SV* sv, NV num);
 VIRTUAL SV*	Perl_sv_setref_iv(pTHX_ SV* rv, const char* classname, IV iv);
-VIRTUAL SV*	Perl_sv_setref_nv(pTHX_ SV* rv, const char* classname, double nv);
+VIRTUAL SV*	Perl_sv_setref_nv(pTHX_ SV* rv, const char* classname, NV nv);
 VIRTUAL SV*	Perl_sv_setref_pv(pTHX_ SV* rv, const char* classname, void* pv);
 VIRTUAL SV*	Perl_sv_setref_pvn(pTHX_ SV* rv, const char* classname, char* pv, STRLEN n);
 VIRTUAL void	Perl_sv_setpv(pTHX_ SV* sv, const char* ptr);
@@ -674,7 +676,7 @@ VIRTUAL void	Perl_sv_setpvf_mg(pTHX_ SV *sv, const char* pat, ...);
 VIRTUAL void	Perl_sv_setiv_mg(pTHX_ SV *sv, IV i);
 VIRTUAL void	Perl_sv_setpviv_mg(pTHX_ SV *sv, IV iv);
 VIRTUAL void	Perl_sv_setuv_mg(pTHX_ SV *sv, UV u);
-VIRTUAL void	Perl_sv_setnv_mg(pTHX_ SV *sv, double num);
+VIRTUAL void	Perl_sv_setnv_mg(pTHX_ SV *sv, NV num);
 VIRTUAL void	Perl_sv_setpv_mg(pTHX_ SV *sv, const char *ptr);
 VIRTUAL void	Perl_sv_setpvn_mg(pTHX_ SV *sv, const char *ptr, STRLEN len);
 VIRTUAL void	Perl_sv_setsv_mg(pTHX_ SV *dstr, SV *sstr);
diff --git a/regcomp.c b/regcomp.c
index 76ae523..59fe5a7 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -25,7 +25,7 @@
 #    define PERL_IN_XSUB_RE
 #  endif
 /* need access to debugger hooks */
-#  ifndef DEBUGGING
+#  if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
 #    define DEBUGGING
 #  endif
 #endif
@@ -35,8 +35,9 @@
 #  define Perl_pregcomp my_regcomp
 #  define Perl_regdump my_regdump
 #  define Perl_regprop my_regprop
-/* *These* symbols are masked to allow static link. */
 #  define Perl_pregfree my_regfree
+#  define Perl_re_intuit_string my_re_intuit_string
+/* *These* symbols are masked to allow static link. */
 #  define Perl_regnext my_regnext
 #  define Perl_save_re_context my_save_re_context
 #  define Perl_reginitcolors my_reginitcolors 
@@ -898,7 +899,11 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 		 PL_regkind[(U8)OP(first)] == NBOUND)
 	    r->regstclass = first;
 	else if (PL_regkind[(U8)OP(first)] == BOL) {
-	    r->reganch |= (OP(first) == MBOL ? ROPT_ANCH_MBOL: ROPT_ANCH_BOL);
+	    r->reganch |= (OP(first) == MBOL
+			   ? ROPT_ANCH_MBOL
+			   : (OP(first) == SBOL
+			      ? ROPT_ANCH_SBOL
+			      : ROPT_ANCH_BOL));
 	    first = NEXTOPER(first);
 	    goto again;
 	}
@@ -912,12 +917,21 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 	    !(r->reganch & ROPT_ANCH) )
 	{
 	    /* turn .* into ^.* with an implied $*=1 */
-	    r->reganch |= ROPT_ANCH_BOL | ROPT_IMPLICIT;
+	    int type = OP(NEXTOPER(first));
+
+	    if (type == REG_ANY || type == ANYUTF8)
+		type = ROPT_ANCH_MBOL;
+	    else
+		type = ROPT_ANCH_SBOL;
+
+	    r->reganch |= type | ROPT_IMPLICIT;
 	    first = NEXTOPER(first);
 	    goto again;
 	}
-	if (sawplus && (!sawopen || !PL_regsawback))
-	    r->reganch |= ROPT_SKIP;	/* x+ must match 1st of run */
+	if (sawplus && (!sawopen || !PL_regsawback) 
+	    && !(PL_regseen & REG_SEEN_EVAL)) /* May examine pos and $& */
+	    /* x+ must match at the 1st pos of run of x's */
+	    r->reganch |= ROPT_SKIP;
 
 	/* Scan is after the zeroth branch, first is atomic matcher. */
 	DEBUG_r(PerlIO_printf(Perl_debug_log, "first at %d\n", 
@@ -1010,6 +1024,11 @@ Perl_pregcomp(pTHX_ char *exp, char *xend, PMOP *pm)
 	    r->check_offset_min = data.offset_float_min;
 	    r->check_offset_max = data.offset_float_max;
 	}
+	if (r->check_substr) {
+	    r->reganch |= RE_USE_INTUIT;
+	    if (SvTAIL(r->check_substr))
+		r->reganch |= RE_INTUIT_TAIL;
+	}
     }
     else {
 	/* Several toplevels. Best we can is to set minlen. */
@@ -2846,6 +2865,8 @@ Perl_regdump(pTHX_ regexp *r)
 	    PerlIO_printf(Perl_debug_log, "(BOL)");
 	if (r->reganch & ROPT_ANCH_MBOL)
 	    PerlIO_printf(Perl_debug_log, "(MBOL)");
+	if (r->reganch & ROPT_ANCH_SBOL)
+	    PerlIO_printf(Perl_debug_log, "(SBOL)");
 	if (r->reganch & ROPT_ANCH_GPOS)
 	    PerlIO_printf(Perl_debug_log, "(GPOS)");
 	PerlIO_putc(Perl_debug_log, ' ');
@@ -2896,10 +2917,37 @@ Perl_regprop(pTHX_ SV *sv, regnode *o)
 #endif	/* DEBUGGING */
 }
 
+SV *
+Perl_re_intuit_string(pTHX_ regexp *prog)
+{				/* Assume that RE_INTUIT is set */
+    DEBUG_r(
+	{   STRLEN n_a;
+	    char *s = SvPV(prog->check_substr,n_a);
+
+	    if (!PL_colorset) reginitcolors();
+	    PerlIO_printf(Perl_debug_log,
+		      "%sUsing REx substr:%s `%s%.60s%s%s'\n",
+		      PL_colors[4],PL_colors[5],PL_colors[0],
+		      s,
+		      PL_colors[1],
+		      (strlen(s) > 60 ? "..." : ""));
+	} );
+
+    return prog->check_substr;
+}
+
 void
 Perl_pregfree(pTHX_ struct regexp *r)
 {
     dTHR;
+    DEBUG_r(PerlIO_printf(Perl_debug_log,
+		      "%sFreeing REx:%s `%s%.60s%s%s'\n",
+		      PL_colors[4],PL_colors[5],PL_colors[0],
+		      r->precomp,
+		      PL_colors[1],
+		      (strlen(r->precomp) > 60 ? "..." : "")));
+
+
     if (!r || (--r->refcnt > 0))
 	return;
     if (r->precomp)
diff --git a/regcomp.h b/regcomp.h
index 7c5c13a..518add0 100644
--- a/regcomp.h
+++ b/regcomp.h
@@ -237,3 +237,34 @@ EXTCONST char PL_simple[] = {
 #endif
 
 END_EXTERN_C
+
+typedef struct re_scream_pos_data_s
+{
+    char **scream_olds;		/* match pos */
+    I32 *scream_pos;		/* Internal iterator of scream. */
+} re_scream_pos_data;
+
+struct reg_data {
+    U32 count;
+    U8 *what;
+    void* data[1];
+};
+
+struct reg_substr_datum {
+    I32 min_offset;
+    I32 max_offset;
+    SV *substr;
+};
+
+struct reg_substr_data {
+    struct reg_substr_datum data[3];	/* Actual array */
+};
+
+#define anchored_substr substrs->data[0].substr
+#define anchored_offset substrs->data[0].min_offset
+#define float_substr substrs->data[1].substr
+#define float_min_offset substrs->data[1].min_offset
+#define float_max_offset substrs->data[1].max_offset
+#define check_substr substrs->data[2].substr
+#define check_offset_min substrs->data[2].min_offset
+#define check_offset_max substrs->data[2].max_offset
diff --git a/regexec.c b/regexec.c
index 7dbf6dc..c97f89e 100644
--- a/regexec.c
+++ b/regexec.c
@@ -25,7 +25,7 @@
 #    define PERL_IN_XSUB_RE
 #  endif
 /* need access to debugger hooks */
-#  ifndef DEBUGGING
+#  if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
 #    define DEBUGGING
 #  endif
 #endif
@@ -35,6 +35,7 @@
 #  define Perl_regexec_flags my_regexec
 #  define Perl_regdump my_regdump
 #  define Perl_regprop my_regprop
+#  define Perl_re_intuit_start my_re_intuit_start
 /* *These* symbols are masked to allow static link. */
 #  define Perl_pregexec my_pregexec
 #  define Perl_reginitcolors my_reginitcolors 
@@ -258,6 +259,192 @@ S_restore_pos(pTHX_ void *arg)
     }	
 }
 
+/* 
+ * Need to implement the following flags for reg_anch:
+ *
+ * USE_INTUIT_NOML		- Useful to call re_intuit_start() first
+ * USE_INTUIT_ML
+ * INTUIT_AUTORITATIVE_NOML	- Can trust a positive answer
+ * INTUIT_AUTORITATIVE_ML
+ * INTUIT_ONCE_NOML		- Intuit can match in one location only.
+ * INTUIT_ONCE_ML
+ *
+ * Another flag for this function: SECOND_TIME (so that float substrs
+ * with giant delta may be not rechecked).
+ */
+
+/* Assumptions: if ANCH_GPOS, then strpos is anchored. XXXX Check GPOS logic */
+
+/* If SCREAM, then sv should be compatible with strpos and strend.
+   Otherwise, only SvCUR(sv) is used to get strbeg. */
+
+/* XXXX We assume that strpos is strbeg unless sv. */
+
+char *
+Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
+		     char *strend, U32 flags, re_scream_pos_data *data)
+{
+    I32 start_shift;
+    /* Should be nonnegative! */
+    I32 end_shift;
+    char *s;
+    char *t;
+    I32 ml_anch;
+
+    DEBUG_r( if (!PL_colorset) reginitcolors() );
+    DEBUG_r(PerlIO_printf(Perl_debug_log,
+		      "%sGuessing start of match:%s `%s%.60s%s%s' against `%s%.*s%s%s'\n",
+		      PL_colors[4],PL_colors[5],PL_colors[0],
+		      prog->precomp,
+		      PL_colors[1],
+		      (strlen(prog->precomp) > 60 ? "..." : ""),
+		      PL_colors[0],
+		      (strend - strpos > 60 ? 60 : strend - strpos),
+		      strpos, PL_colors[1],
+		      (strend - strpos > 60 ? "..." : ""))
+	);
+
+    if (prog->minlen > strend - strpos)
+	goto fail;
+
+    /* XXXX Move further down? */
+    start_shift = prog->check_offset_min;	/* okay to underestimate on CC */
+    /* Should be nonnegative! */
+    end_shift = prog->minlen - start_shift -
+	CHR_SVLEN(prog->check_substr) + (SvTAIL(prog->check_substr) != 0);
+
+    if (prog->reganch & ROPT_ANCH) {
+	ml_anch = !( (prog->reganch & ROPT_ANCH_SINGLE)
+		     || ( (prog->reganch & ROPT_ANCH_BOL)
+			  && !PL_multiline ) );
+
+	if ((prog->check_offset_min == prog->check_offset_max) && !ml_anch) {
+	    /* Anchored... */
+	    I32 slen;
+
+	    if ( !(prog->reganch & ROPT_ANCH_GPOS) /* Checked by the caller */
+		 && (sv && (strpos + SvCUR(sv) != strend)) )
+		goto fail;
+
+	    s = (char*)HOP((U8*)strpos, prog->check_offset_min);
+	    if (SvTAIL(prog->check_substr)) {
+		slen = SvCUR(prog->check_substr);	/* >= 1 */
+
+		if ( strend - s > slen || strend - s < slen - 1 ) {
+		    s = Nullch;
+		    goto finish;
+		}
+		if ( strend - s == slen && strend[-1] != '\n') {
+		    s = Nullch;
+		    goto finish;
+		}
+		/* Now should match s[0..slen-2] */
+		slen--;
+		if (slen && (*SvPVX(prog->check_substr) != *s
+			     || (slen > 1
+				 && memNE(SvPVX(prog->check_substr), s, slen))))
+		    s = Nullch;
+	    }
+	    else if (*SvPVX(prog->check_substr) != *s
+		     || ((slen = SvCUR(prog->check_substr)) > 1
+			 && memNE(SvPVX(prog->check_substr), s, slen)))
+		    s = Nullch;
+	    else
+		    s = strpos;
+	    goto finish;
+	}
+	s = strpos;
+	if (!ml_anch && (s + prog->check_offset_max < strend - prog->minlen))
+	    end_shift += strend - s - prog->minlen - prog->check_offset_max;
+    }
+    else {
+	ml_anch = 0;
+	s = strpos;
+    }
+
+  restart:
+    if (flags & REXEC_SCREAM) {
+	SV *c = prog->check_substr;
+	char *strbeg = SvPVX(sv);	/* XXXX Assume PV_force() on SCREAM! */
+	I32 p = -1;			/* Internal iterator of scream. */
+	I32 *pp = data ? data->scream_pos : &p;
+
+	if (PL_screamfirst[BmRARE(c)] >= 0
+	    || ( BmRARE(c) == '\n'
+		 && (BmPREVIOUS(c) == SvCUR(c) - 1)
+		 && SvTAIL(c) ))
+	    s = screaminstr(sv, prog->check_substr, 
+			    start_shift + (strpos - strbeg), end_shift, pp, 0);
+	else
+	    s = Nullch;
+	if (data)
+	    *data->scream_olds = s;
+    }
+    else
+	s = fbm_instr((unsigned char*)s + start_shift,
+		      (unsigned char*)strend - end_shift,
+		      prog->check_substr, PL_multiline ? FBMrf_MULTILINE : 0);
+
+    /* Update the count-of-usability, remove useless subpatterns,
+	unshift s.  */
+  finish:
+    if (!s) {
+	++BmUSEFUL(prog->check_substr);	/* hooray */
+	goto fail;			/* not present */
+    }
+    else if (s - strpos > prog->check_offset_max &&
+	     ((prog->reganch & ROPT_UTF8)
+	      ? ((t = reghopmaybe_c(s, -(prog->check_offset_max)))
+		 && t >= strpos)
+	      : (t = s - prog->check_offset_max) != 0) ) {
+	if (ml_anch && t[-1] != '\n') {
+	  find_anchor:
+	    while (t < strend - end_shift - prog->minlen) {
+		if (*t == '\n') {
+		    if (t < s - prog->check_offset_min) {
+			s = t + 1;
+			goto set_useful;
+		    }
+		    s = t + 1;
+		    goto restart;
+		}
+		t++;
+	    }
+	    s = Nullch;
+	    goto finish;
+	}
+	s = t;
+      set_useful:
+	++BmUSEFUL(prog->check_substr);	/* hooray/2 */
+    }
+    else {
+	if (ml_anch && sv 
+	    && (strpos + SvCUR(sv) != strend) && strpos[-1] != '\n') {
+	    t = strpos;
+	    goto find_anchor;
+	}
+	if (!(prog->reganch & ROPT_NAUGHTY)
+	    && --BmUSEFUL(prog->check_substr) < 0
+	    && prog->check_substr == prog->float_substr) { /* boo */
+	    /* If flags & SOMETHING - do not do it many times on the same match */
+	    SvREFCNT_dec(prog->check_substr);
+	    prog->check_substr = Nullsv;	/* disable */
+	    prog->float_substr = Nullsv;	/* clear */
+	    s = strpos;
+	    prog->reganch &= ~RE_USE_INTUIT;
+	}
+	else
+	    s = strpos;
+    }
+
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "%sFound%s at offset %ld\n",
+			  PL_colors[4],PL_colors[5], (long)(s - strpos)) );
+    return s;
+  fail:
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "%sNot found...%s\n",
+			  PL_colors[4],PL_colors[5]));
+    return Nullch;
+}
 
 /*
  - regexec_flags - match a regexp against a string
@@ -339,103 +526,78 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
 
     /* If there is a "must appear" string, look for it. */
     s = startpos;
-    if (!(flags & REXEC_CHECKED) 
-	&& prog->check_substr != Nullsv &&
-	!(prog->reganch & ROPT_ANCH_GPOS) &&
-	(!(prog->reganch & (ROPT_ANCH_BOL | ROPT_ANCH_MBOL))
-	 || (PL_multiline && prog->check_substr == prog->anchored_substr)) )
-    {
-	char *t;
-	start_shift = prog->check_offset_min;	/* okay to underestimate on CC */
-	/* Should be nonnegative! */
-	end_shift = minlen - start_shift -
-	    CHR_SVLEN(prog->check_substr) + (SvTAIL(prog->check_substr) != 0);
-	if (flags & REXEC_SCREAM) {
-	    SV *c = prog->check_substr;
-
-	    if (PL_screamfirst[BmRARE(c)] >= 0
-		|| ( BmRARE(c) == '\n'
-		     && (BmPREVIOUS(c) == SvCUR(c) - 1)
-		     && SvTAIL(c) ))
-		    s = screaminstr(sv, prog->check_substr, 
-				    start_shift + (stringarg - strbeg),
-				    end_shift, &scream_pos, 0);
-	    else
-		    s = Nullch;
-	    scream_olds = s;
-	}
+
+    if (prog->reganch & ROPT_GPOS_SEEN) {
+	MAGIC *mg;
+
+	if (!(flags & REXEC_IGNOREPOS) && sv && SvTYPE(sv) >= SVt_PVMG
+	    && SvMAGIC(sv) && (mg = mg_find(sv, 'g')) && mg->mg_len >= 0)
+	    PL_reg_ganch = strbeg + mg->mg_len;
 	else
-	    s = fbm_instr((unsigned char*)s + start_shift,
-			  (unsigned char*)strend - end_shift,
-		prog->check_substr, PL_multiline ? FBMrf_MULTILINE : 0);
-	if (!s) {
-	    ++BmUSEFUL(prog->check_substr);	/* hooray */
-	    goto phooey;	/* not present */
-	}
-	else if (s - stringarg > prog->check_offset_max &&
-		 (UTF 
-		    ? ((t = reghopmaybe_c(s, -(prog->check_offset_max))) && t >= stringarg)
-		    : (t = s - prog->check_offset_max) != 0
-		 )
-		)
-	{
-	    ++BmUSEFUL(prog->check_substr);	/* hooray/2 */
-	    s = t;
-	}
-	else if (!(prog->reganch & ROPT_NAUGHTY)
-		   && --BmUSEFUL(prog->check_substr) < 0
-		   && prog->check_substr == prog->float_substr) { /* boo */
-	    SvREFCNT_dec(prog->check_substr);
-	    prog->check_substr = Nullsv;	/* disable */
-	    prog->float_substr = Nullsv;	/* clear */
-	    s = startpos;
+	    PL_reg_ganch = startpos;
+	if (prog->reganch & ROPT_ANCH_GPOS) {
+	    if (s > PL_reg_ganch)
+		goto phooey;
+	    s = PL_reg_ganch;
 	}
-	else
-	    s = startpos;
     }
 
-    DEBUG_r(if (!PL_colorset) reginitcolors());
-    DEBUG_r(PerlIO_printf(Perl_debug_log, 
+    if (!(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
+	re_scream_pos_data d;
+
+	d.scream_olds = &scream_olds;
+	d.scream_pos = &scream_pos;
+	s = re_intuit_start(prog, sv, s, strend, flags, &d);
+	if (!s)
+	    goto phooey;	/* not present */
+    }
+
+    DEBUG_r( if (!PL_colorset) reginitcolors() );
+    DEBUG_r(PerlIO_printf(Perl_debug_log,
 		      "%sMatching%s `%s%.60s%s%s' against `%s%.*s%s%s'\n",
 		      PL_colors[4],PL_colors[5],PL_colors[0],
 		      prog->precomp,
 		      PL_colors[1],
 		      (strlen(prog->precomp) > 60 ? "..." : ""),
-		      PL_colors[0], 
+		      PL_colors[0],
 		      (strend - startpos > 60 ? 60 : strend - startpos),
 		      startpos, PL_colors[1],
 		      (strend - startpos > 60 ? "..." : ""))
 	);
 
-    if (prog->reganch & ROPT_GPOS_SEEN) {
-	MAGIC *mg;
-
-	if (!(flags & REXEC_IGNOREPOS) && sv && SvTYPE(sv) >= SVt_PVMG
-	    && SvMAGIC(sv) && (mg = mg_find(sv, 'g')) && mg->mg_len >= 0)
-	    PL_reg_ganch = strbeg + mg->mg_len;
-	else
-	    PL_reg_ganch = startpos;
-    }
-
     /* Simplest case:  anchored match need be tried only once. */
     /*  [unless only anchor is BOL and multiline is set] */
     if (prog->reganch & (ROPT_ANCH & ~ROPT_ANCH_GPOS)) {
-	if (regtry(prog, startpos))
+	if (s == startpos && regtry(prog, startpos))
 	    goto got_it;
 	else if (PL_multiline || (prog->reganch & ROPT_IMPLICIT)
 		 || (prog->reganch & ROPT_ANCH_MBOL)) /* XXXX SBOL? */
 	{
+	    char *end;
+
 	    if (minlen)
 		dontbother = minlen - 1;
-	    strend = HOPc(strend, -dontbother);
+	    end = HOPc(strend, -dontbother) - 1;
 	    /* for multiline we only have to try after newlines */
-	    if (s > startpos)
-		s--;
-	    while (s < strend) {
-		if (*s++ == '\n') {	/* don't need PL_utf8skip here */
-		    if (s < strend && regtry(prog, s))
+	    if (prog->check_substr) {
+		while (1) {
+		    if (regtry(prog, s))
 			goto got_it;
-		}
+		    if (s >= end)
+			goto phooey;
+		    s = re_intuit_start(prog, sv, s + 1, strend, flags, NULL);
+		    if (!s)
+			goto phooey;
+		}		
+	    } else {
+		if (s > startpos)
+		    s--;
+		while (s < end) {
+		    if (*s++ == '\n') {	/* don't need PL_utf8skip here */
+			if (regtry(prog, s))
+			    goto got_it;
+		    }
+		}		
 	    }
 	}
 	goto phooey;
@@ -448,7 +610,7 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
     /* Messy cases:  unanchored match. */
     if (prog->anchored_substr && prog->reganch & ROPT_SKIP) { 
 	/* we have /x+whatever/ */
-	/* it must be a one character string */
+	/* it must be a one character string (XXXX Except UTF?) */
 	char ch = SvPVX(prog->anchored_substr)[0];
 	if (UTF) {
 	    while (s < strend) {
diff --git a/regexp.h b/regexp.h
index 9da5bd4..5d787e0 100644
--- a/regexp.h
+++ b/regexp.h
@@ -17,38 +17,13 @@ struct regnode {
 
 typedef struct regnode regnode;
 
-struct reg_data {
-    U32 count;
-    U8 *what;
-    void* data[1];
-};
-
-struct reg_substr_datum {
-    I32 min_offset;
-    I32 max_offset;
-    SV *substr;
-};
-
-struct reg_substr_data {
-    struct reg_substr_datum data[3];	/* Actual array */
-};
+struct reg_substr_data;
 
 typedef struct regexp {
 	I32 *startp;
 	I32 *endp;
 	regnode *regstclass;
-#if 0
-        SV *anchored_substr;	/* Substring at fixed position wrt start. */
-	I32 anchored_offset;	/* Position of it. */
-        SV *float_substr;	/* Substring at variable position wrt start. */
-	I32 float_min_offset;	/* Minimal position of it. */
-	I32 float_max_offset;	/* Maximal position of it. */
-        SV *check_substr;	/* Substring to check before matching. */
-        I32 check_offset_min;	/* Offset of the above. */
-        I32 check_offset_max;	/* Offset of the above. */
-#else
         struct reg_substr_data *substrs;
-#endif
 	char *precomp;		/* pre-compilation regular expression */
         struct reg_data *data;	/* Additional data. */
 	char *subbeg;		/* saved or original string 
@@ -64,29 +39,20 @@ typedef struct regexp {
 	regnode program[1];	/* Unwarranted chumminess with compiler. */
 } regexp;
 
-#define anchored_substr substrs->data[0].substr
-#define anchored_offset substrs->data[0].min_offset
-#define float_substr substrs->data[1].substr
-#define float_min_offset substrs->data[1].min_offset
-#define float_max_offset substrs->data[1].max_offset
-#define check_substr substrs->data[2].substr
-#define check_offset_min substrs->data[2].min_offset
-#define check_offset_max substrs->data[2].max_offset
-
-#define ROPT_ANCH		(ROPT_ANCH_BOL|ROPT_ANCH_MBOL|ROPT_ANCH_GPOS)
-#define ROPT_ANCH_SINGLE	(ROPT_ANCH_BOL|ROPT_ANCH_GPOS)
+#define ROPT_ANCH		(ROPT_ANCH_BOL|ROPT_ANCH_MBOL|ROPT_ANCH_GPOS|ROPT_ANCH_SBOL)
+#define ROPT_ANCH_SINGLE	(ROPT_ANCH_SBOL|ROPT_ANCH_GPOS)
 #define ROPT_ANCH_BOL	 	0x00001
 #define ROPT_ANCH_MBOL	 	0x00002
-#define ROPT_ANCH_GPOS	 	0x00004
-#define ROPT_SKIP		0x00008
-#define ROPT_IMPLICIT		0x00010	/* Converted .* to ^.* */
-#define ROPT_NOSCAN		0x00020	/* Check-string always at start. */
-#define ROPT_GPOS_SEEN		0x00040
-#define ROPT_CHECK_ALL		0x00080
-#define ROPT_LOOKBEHIND_SEEN	0x00100
-#define ROPT_EVAL_SEEN		0x00200
-#define ROPT_TAINTED_SEEN	0x00400
-#define ROPT_ANCH_SBOL	 	0x00800
+#define ROPT_ANCH_SBOL	 	0x00004
+#define ROPT_ANCH_GPOS	 	0x00008
+#define ROPT_SKIP		0x00010
+#define ROPT_IMPLICIT		0x00020	/* Converted .* to ^.* */
+#define ROPT_NOSCAN		0x00040	/* Check-string always at start. */
+#define ROPT_GPOS_SEEN		0x00080
+#define ROPT_CHECK_ALL		0x00100
+#define ROPT_LOOKBEHIND_SEEN	0x00200
+#define ROPT_EVAL_SEEN		0x00400
+#define ROPT_TAINTED_SEEN	0x00800
 
 /* 0xf800 of reganch is used by PMf_COMPILETIME */
 
@@ -94,6 +60,19 @@ typedef struct regexp {
 #define ROPT_NAUGHTY		0x20000 /* how exponential is this pattern? */
 #define ROPT_COPY_DONE		0x40000	/* subbeg is a copy of the string */
 
+#define RE_USE_INTUIT_NOML	0x0100000 /* Best to intuit before matching */
+#define RE_USE_INTUIT_ML	0x0200000
+#define REINT_AUTORITATIVE_NOML	0x0400000 /* Can trust a positive answer */
+#define REINT_AUTORITATIVE_ML	0x0800000 
+#define REINT_ONCE_NOML		0x1000000 /* Intuit can succed once only. */
+#define REINT_ONCE_ML		0x2000000
+#define RE_INTUIT_ONECHAR	0x4000000
+#define RE_INTUIT_TAIL		0x8000000
+
+#define RE_USE_INTUIT		(RE_USE_INTUIT_NOML|RE_USE_INTUIT_ML)
+#define REINT_AUTORITATIVE	(REINT_AUTORITATIVE_NOML|REINT_AUTORITATIVE_ML)
+#define REINT_ONCE		(REINT_ONCE_NOML|REINT_ONCE_ML)
+
 #define RX_MATCH_TAINTED(prog)	((prog)->reganch & ROPT_TAINTED_SEEN)
 #define RX_MATCH_TAINTED_on(prog) ((prog)->reganch |= ROPT_TAINTED_SEEN)
 #define RX_MATCH_TAINTED_off(prog) ((prog)->reganch &= ~ROPT_TAINTED_SEEN)
@@ -108,18 +87,22 @@ typedef struct regexp {
 					 ? RX_MATCH_COPIED_on(prog) \
 					 : RX_MATCH_COPIED_off(prog))
 
-#define REXEC_COPY_STR	1		/* Need to copy the string. */
-#define REXEC_CHECKED	2		/* check_substr already checked. */
-#define REXEC_SCREAM	4		/* use scream table. */
-#define REXEC_IGNOREPOS	8		/* \G matches at start. */
+#define REXEC_COPY_STR	0x01		/* Need to copy the string. */
+#define REXEC_CHECKED	0x02		/* check_substr already checked. */
+#define REXEC_SCREAM	0x04		/* use scream table. */
+#define REXEC_IGNOREPOS	0x08		/* \G matches at start. */
 #define REXEC_NOT_FIRST	0x10		/* This is another iteration of //g. */
+#define REXEC_ML	0x20		/* $* was set. */
 
 #define ReREFCNT_inc(re) ((re && re->refcnt++), re)
-#define ReREFCNT_dec(re) pregfree(re)
+#define ReREFCNT_dec(re) CALLREGFREE(aTHX_ re)
 
 #define FBMcf_TAIL_DOLLAR	1
-#define FBMcf_TAIL_Z		2
-#define FBMcf_TAIL_z		4
-#define FBMcf_TAIL		(FBMcf_TAIL_DOLLAR|FBMcf_TAIL_Z|FBMcf_TAIL_z)
+#define FBMcf_TAIL_DOLLARM	2
+#define FBMcf_TAIL_Z		4
+#define FBMcf_TAIL_z		8
+#define FBMcf_TAIL		(FBMcf_TAIL_DOLLAR|FBMcf_TAIL_DOLLARM|FBMcf_TAIL_Z|FBMcf_TAIL_z)
 
 #define FBMrf_MULTILINE	1
+
+struct re_scream_pos_data_s;
diff --git a/sv.c b/sv.c
index 282baf9..a61d2ea 100644
--- a/sv.c
+++ b/sv.c
@@ -435,12 +435,12 @@ S_more_xiv(pTHX)
 STATIC XPVNV*
 S_new_xnv(pTHX)
 {
-    double* xnv;
+    NV* xnv;
     LOCK_SV_MUTEX;
     if (!PL_xnv_root)
 	more_xnv();
     xnv = PL_xnv_root;
-    PL_xnv_root = *(double**)xnv;
+    PL_xnv_root = *(NV**)xnv;
     UNLOCK_SV_MUTEX;
     return (XPVNV*)((char*)xnv - STRUCT_OFFSET(XPVNV, xnv_nv));
 }
@@ -448,9 +448,9 @@ S_new_xnv(pTHX)
 STATIC void
 S_del_xnv(pTHX_ XPVNV *p)
 {
-    double* xnv = (double*)((char*)(p) + STRUCT_OFFSET(XPVNV, xnv_nv));
+    NV* xnv = (NV*)((char*)(p) + STRUCT_OFFSET(XPVNV, xnv_nv));
     LOCK_SV_MUTEX;
-    *(double**)xnv = PL_xnv_root;
+    *(NV**)xnv = PL_xnv_root;
     PL_xnv_root = xnv;
     UNLOCK_SV_MUTEX;
 }
@@ -458,17 +458,17 @@ S_del_xnv(pTHX_ XPVNV *p)
 STATIC void
 S_more_xnv(pTHX)
 {
-    register double* xnv;
-    register double* xnvend;
-    New(711, xnv, 1008/sizeof(double), double);
-    xnvend = &xnv[1008 / sizeof(double) - 1];
-    xnv += (sizeof(XPVIV) - 1) / sizeof(double) + 1; /* fudge by sizeof XPVIV */
+    register NV* xnv;
+    register NV* xnvend;
+    New(711, xnv, 1008/sizeof(NV), NV);
+    xnvend = &xnv[1008 / sizeof(NV) - 1];
+    xnv += (sizeof(XPVIV) - 1) / sizeof(NV) + 1; /* fudge by sizeof XPVIV */
     PL_xnv_root = xnv;
     while (xnv < xnvend) {
-	*(double**)xnv = (double*)(xnv + 1);
+	*(NV**)xnv = (NV*)(xnv + 1);
 	xnv++;
     }
-    *(double**)xnv = 0;
+    *(NV**)xnv = 0;
 }
 
 STATIC XRV*
@@ -631,7 +631,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
     U32		cur;
     U32		len;
     IV		iv;
-    double	nv;
+    NV		nv;
     MAGIC*	magic;
     HV*		stash;
 
@@ -656,7 +656,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
 	cur	= 0;
 	len	= 0;
 	iv	= SvIVX(sv);
-	nv	= (double)SvIVX(sv);
+	nv	= (NV)SvIVX(sv);
 	del_XIV(SvANY(sv));
 	magic	= 0;
 	stash	= 0;
@@ -683,7 +683,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
 	cur	= 0;
 	len	= 0;
 	iv	= (IV)pv;
-	nv	= (double)(unsigned long)pv;
+	nv	= (NV)(unsigned long)pv;
 	del_XRV(SvANY(sv));
 	magic	= 0;
 	stash	= 0;
@@ -1017,7 +1017,7 @@ Perl_sv_setuv_mg(pTHX_ register SV *sv, UV u)
 }
 
 void
-Perl_sv_setnv(pTHX_ register SV *sv, double num)
+Perl_sv_setnv(pTHX_ register SV *sv, NV num)
 {
     SV_CHECK_THINKFIRST(sv);
     switch (SvTYPE(sv)) {
@@ -1049,7 +1049,7 @@ Perl_sv_setnv(pTHX_ register SV *sv, double num)
 }
 
 void
-Perl_sv_setnv_mg(pTHX_ register SV *sv, double num)
+Perl_sv_setnv_mg(pTHX_ register SV *sv, NV num)
 {
     sv_setnv(sv,num);
     SvSETMAGIC(sv);
@@ -1181,7 +1181,7 @@ Perl_sv_2iv(pTHX_ register SV *sv)
 	    sv_upgrade(sv, SVt_PVNV);
 
 	(void)SvIOK_on(sv);
-	if (SvNVX(sv) < (double)IV_MAX + 0.5)
+	if (SvNVX(sv) < (NV)IV_MAX + 0.5)
 	    SvIVX(sv) = I_V(SvNVX(sv));
 	else {
 	    SvUVX(sv) = U_V(SvNVX(sv));
@@ -1208,7 +1208,7 @@ Perl_sv_2iv(pTHX_ register SV *sv)
 	if (numtype & IS_NUMBER_NOT_IV) {
 	    /* May be not an integer.  Need to cache NV if we cache IV
 	     * - otherwise future conversion to NV will be wrong.  */
-	    double d;
+	    NV d;
 
 	    d = Atof(SvPVX(sv));
 
@@ -1217,10 +1217,14 @@ Perl_sv_2iv(pTHX_ register SV *sv)
 	    SvNVX(sv) = d;
 	    (void)SvNOK_on(sv);
 	    (void)SvIOK_on(sv);
-	    DEBUG_c(PerlIO_printf(Perl_debug_log,
-				  "0x%lx 2nv(%g)\n",(unsigned long)sv,
-				  SvNVX(sv)));
-	    if (SvNVX(sv) < (double)IV_MAX + 0.5)
+#if defined(USE_LONG_DOUBLE)
+	    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2nv(%Lg)\n",
+				  (unsigned long)sv, SvNVX(sv)));
+#else
+	    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2nv(%g)\n",
+				  (unsigned long)sv, SvNVX(sv)));
+#endif
+	    if (SvNVX(sv) < (NV)IV_MAX + 0.5)
 		SvIVX(sv) = I_V(SvNVX(sv));
 	    else {
 		SvUVX(sv) = U_V(SvNVX(sv));
@@ -1348,7 +1352,7 @@ Perl_sv_2uv(pTHX_ register SV *sv)
 	if (numtype & IS_NUMBER_NOT_IV) {
 	    /* May be not an integer.  Need to cache NV if we cache IV
 	     * - otherwise future conversion to NV will be wrong.  */
-	    double d;
+	    NV d;
 
 	    d = Atof(SvPVX(sv));	/* XXXX 64-bit? */
 
@@ -1357,9 +1361,13 @@ Perl_sv_2uv(pTHX_ register SV *sv)
 	    SvNVX(sv) = d;
 	    (void)SvNOK_on(sv);
 	    (void)SvIOK_on(sv);
-	    DEBUG_c(PerlIO_printf(Perl_debug_log,
-				  "0x%lx 2nv(%g)\n",(unsigned long)sv,
-				  SvNVX(sv)));
+#if defined(USE_LONG_DOUBLE)
+	    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2nv(%Lg)\n",
+				  (unsigned long)sv, SvNVX(sv)));
+#else
+	    DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2nv(%g)\n",
+				  (unsigned long)sv, SvNVX(sv)));
+#endif
 	    if (SvNVX(sv) < -0.5) {
 		SvIVX(sv) = I_V(SvNVX(sv));
 		goto ret_zero;
@@ -1420,7 +1428,7 @@ Perl_sv_2uv(pTHX_ register SV *sv)
     return SvIsUV(sv) ? SvUVX(sv) : (UV)SvIVX(sv);
 }
 
-double
+NV
 Perl_sv_2nv(pTHX_ register SV *sv)
 {
     if (!sv)
@@ -1437,9 +1445,9 @@ Perl_sv_2nv(pTHX_ register SV *sv)
 	}
 	if (SvIOKp(sv)) {
 	    if (SvIsUV(sv)) 
-		return (double)SvUVX(sv);
+		return (NV)SvUVX(sv);
 	    else
-		return (double)SvIVX(sv);
+		return (NV)SvIVX(sv);
 	}	
         if (!SvROK(sv)) {
 	    if (!(SvFLAGS(sv) & SVs_PADTMP)) {
@@ -1455,7 +1463,7 @@ Perl_sv_2nv(pTHX_ register SV *sv)
 	  SV* tmpstr;
 	  if (SvAMAGIC(sv) && (tmpstr=AMG_CALLun(sv,numer)))
 	      return SvNV(tmpstr);
-	  return (double)(unsigned long)SvRV(sv);
+	  return (NV)(unsigned long)SvRV(sv);
 	}
 	if (SvREADONLY(sv)) {
 	    dTHR;
@@ -1466,9 +1474,9 @@ Perl_sv_2nv(pTHX_ register SV *sv)
 	    }
 	    if (SvIOKp(sv)) {
 		if (SvIsUV(sv)) 
-		    return (double)SvUVX(sv);
+		    return (NV)SvUVX(sv);
 		else
-		    return (double)SvIVX(sv);
+		    return (NV)SvIVX(sv);
 	    }
 	    if (ckWARN(WARN_UNINITIALIZED))
 		Perl_warner(aTHX_ WARN_UNINITIALIZED, PL_warn_uninit);
@@ -1480,19 +1488,28 @@ Perl_sv_2nv(pTHX_ register SV *sv)
 	    sv_upgrade(sv, SVt_PVNV);
 	else
 	    sv_upgrade(sv, SVt_NV);
+#if defined(USE_LONG_DOUBLE)
+	DEBUG_c({
+	    RESTORE_NUMERIC_STANDARD();
+	    PerlIO_printf(Perl_debug_log, "0x%lx num(%Lg)\n",
+			  (unsigned long)sv, SvNVX(sv));
+	    RESTORE_NUMERIC_LOCAL();
+	});
+#else
 	DEBUG_c({
 	    RESTORE_NUMERIC_STANDARD();
-	    PerlIO_printf(Perl_debug_log,
-			  "0x%lx num(%g)\n",(unsigned long)sv,SvNVX(sv));
+	    PerlIO_printf(Perl_debug_log, "0x%lx num(%g)\n",
+			  (unsigned long)sv, SvNVX(sv));
 	    RESTORE_NUMERIC_LOCAL();
 	});
+#endif
     }
     else if (SvTYPE(sv) < SVt_PVNV)
 	sv_upgrade(sv, SVt_PVNV);
     if (SvIOKp(sv) &&
 	    (!SvPOKp(sv) || !strchr(SvPVX(sv),'.') || !looks_like_number(sv)))
     {
-	SvNVX(sv) = SvIsUV(sv) ? (double)SvUVX(sv) : (double)SvIVX(sv);
+	SvNVX(sv) = SvIsUV(sv) ? (NV)SvUVX(sv) : (NV)SvIVX(sv);
     }
     else if (SvPOKp(sv) && SvLEN(sv)) {
 	dTHR;
@@ -1510,12 +1527,21 @@ Perl_sv_2nv(pTHX_ register SV *sv)
 	return 0.0;
     }
     SvNOK_on(sv);
+#if defined(USE_LONG_DOUBLE)
+    DEBUG_c({
+	RESTORE_NUMERIC_STANDARD();
+	PerlIO_printf(Perl_debug_log, "0x%lx 2nv(%Lg)\n",
+		      (unsigned long)sv, SvNVX(sv));
+	RESTORE_NUMERIC_LOCAL();
+    });
+#else
     DEBUG_c({
 	RESTORE_NUMERIC_STANDARD();
-	PerlIO_printf(Perl_debug_log,
-		      "0x%lx 2nv(%g)\n",(unsigned long)sv,SvNVX(sv));
+	PerlIO_printf(Perl_debug_log, "0x%lx 1nv(%g)\n",
+		      (unsigned long)sv, SvNVX(sv));
 	RESTORE_NUMERIC_LOCAL();
     });
+#endif
     return SvNVX(sv);
 }
 
@@ -1523,7 +1549,7 @@ STATIC IV
 S_asIV(pTHX_ SV *sv)
 {
     I32 numtype = looks_like_number(sv);
-    double d;
+    NV d;
 
     if (numtype & IS_NUMBER_TO_INT_BY_ATOL)
 	return atol(SvPVX(sv));		/* XXXX 64-bit? */
@@ -3754,13 +3780,13 @@ Perl_sv_inc(pTHX_ register SV *sv)
     if (flags & SVp_IOK) {
 	if (SvIsUV(sv)) {
 	    if (SvUVX(sv) == UV_MAX)
-		sv_setnv(sv, (double)UV_MAX + 1.0);
+		sv_setnv(sv, (NV)UV_MAX + 1.0);
 	    else
 		(void)SvIOK_only_UV(sv);
 		++SvUVX(sv);
 	} else {
 	    if (SvIVX(sv) == IV_MAX)
-		sv_setnv(sv, (double)IV_MAX + 1.0);
+		sv_setnv(sv, (NV)IV_MAX + 1.0);
 	    else {
 		(void)SvIOK_only(sv);
 		++SvIVX(sv);
@@ -3863,7 +3889,7 @@ Perl_sv_dec(pTHX_ register SV *sv)
 	    }	    
 	} else {
 	    if (SvIVX(sv) == IV_MIN)
-		sv_setnv(sv, (double)IV_MIN - 1.0);
+		sv_setnv(sv, (NV)IV_MIN - 1.0);
 	    else {
 		(void)SvIOK_only(sv);
 		--SvIVX(sv);
@@ -3981,7 +4007,7 @@ Perl_newSVpvf(pTHX_ const char* pat, ...)
 }
 
 SV *
-Perl_newSVnv(pTHX_ double n)
+Perl_newSVnv(pTHX_ NV n)
 {
     register SV *sv;
 
@@ -4273,7 +4299,7 @@ Perl_sv_uv(pTHX_ register SV *sv)
     return sv_2uv(sv);
 }
 
-double
+NV
 Perl_sv_nv(pTHX_ register SV *sv)
 {
     if (SvNOK(sv))
@@ -4449,7 +4475,7 @@ Perl_sv_setref_iv(pTHX_ SV *rv, const char *classname, IV iv)
 }
 
 SV*
-Perl_sv_setref_nv(pTHX_ SV *rv, const char *classname, double nv)
+Perl_sv_setref_nv(pTHX_ SV *rv, const char *classname, NV nv)
 {
     sv_setnv(newSVrv(rv,classname), nv);
     return rv;
@@ -4733,7 +4759,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
 	unsigned base;
 	IV iv;
 	UV uv;
-	double nv;
+	NV nv;
 	STRLEN have;
 	STRLEN need;
 	STRLEN gap;
@@ -5051,7 +5077,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
 	    /* This is evil, but floating point is even more evil */
 
 	    if (args)
-		nv = va_arg(*args, double);
+		nv = va_arg(*args, NV);
 	    else
 		nv = (svix < svmax) ? SvNVx(svargs[svix++]) : 0.0;
 
@@ -5078,6 +5104,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
 	    eptr = ebuf + sizeof ebuf;
 	    *--eptr = '\0';
 	    *--eptr = c;
+#ifdef USE_LONG_DOUBLE
+	    *--eptr = 'L';
+#endif
 	    if (has_precis) {
 		base = precis;
 		do { *--eptr = '0' + (base % 10); } while (base /= 10);
diff --git a/sv.h b/sv.h
index 8eddc57..5787da3 100644
--- a/sv.h
+++ b/sv.h
@@ -196,7 +196,7 @@ struct xpvnv {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV    	xnv_nv;		/* numeric value, if any */
 };
 
 /* These structure must match the beginning of struct xpvhv in hv.h. */
@@ -205,7 +205,7 @@ struct xpvmg {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV    	xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 };
@@ -215,7 +215,7 @@ struct xpvlv {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV    	xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -230,7 +230,7 @@ struct xpvgv {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -246,7 +246,7 @@ struct xpvbm {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -264,7 +264,7 @@ struct xpvfm {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
@@ -292,7 +292,7 @@ struct xpvio {
     STRLEN	xpv_cur;	/* length of xpv_pv as a C string */
     STRLEN	xpv_len;	/* allocated size */
     IV		xiv_iv;		/* integer value or pv offset */
-    double	xnv_nv;		/* numeric value, if any */
+    NV		xnv_nv;		/* numeric value, if any */
     MAGIC*	xmg_magic;	/* linked list of magicalness */
     HV*		xmg_stash;	/* class package */
 
diff --git a/thrdvar.h b/thrdvar.h
index a442367..c823393 100644
--- a/thrdvar.h
+++ b/thrdvar.h
@@ -170,9 +170,16 @@ PERLVAR(Treg_oldsaved,	char*)		/* old saved substr during match */
 PERLVAR(Treg_oldsavedlen, STRLEN)	/* old length of saved substr during match */
 
 PERLVARI(Tregcompp,	regcomp_t, FUNC_NAME_TO_PTR(Perl_pregcomp))
-					/* Pointer to RE compiler */
+					/* Pointer to REx compiler */
 PERLVARI(Tregexecp,	regexec_t, FUNC_NAME_TO_PTR(Perl_regexec_flags))
-					/* Pointer to RE executer */
+					/* Pointer to REx executer */
+PERLVARI(Tregint_start,	re_intuit_start_t, FUNC_NAME_TO_PTR(Perl_re_intuit_start))
+					/* Pointer to optimized REx executer */
+PERLVARI(Tregint_string,re_intuit_string_t, FUNC_NAME_TO_PTR(Perl_re_intuit_string))
+					/* Pointer to optimized REx string */
+PERLVARI(Tregfree,	regfree_t, FUNC_NAME_TO_PTR(Perl_pregfree))
+					/* Pointer to REx free()er */
+
 PERLVARI(Treginterp_cnt,int,	    0)	/* Whether `Regexp'
 						   was interpolated. */
 PERLVARI(Treg_starttry,	char *,	    0)	/* -Dr: where regtry was called. */
diff --git a/toke.c b/toke.c
index dd8742b..7849152 100644
--- a/toke.c
+++ b/toke.c
@@ -5953,7 +5953,7 @@ Perl_scan_num(pTHX_ char *start)
     register char *d;			/* destination in temp buffer */
     register char *e;			/* end of temp buffer */
     I32 tryiv;				/* used to see if it can be an int */
-    double value;			/* number read, as a double */
+    NV value;				/* number read, as a double */
     SV *sv;				/* place to put the converted number */
     I32 floatit;			/* boolean: int or float? */
     char *lastub = 0;			/* position of last underbar */
@@ -6169,7 +6169,7 @@ Perl_scan_num(pTHX_ char *start)
 	   conversion at all.
 	*/
 	tryiv = I_V(value);
-	if (!floatit && (double)tryiv == value)
+	if (!floatit && (NV)tryiv == value)
 	    sv_setiv(sv, tryiv);
 	else
 	    sv_setnv(sv, value);
diff --git a/universal.c b/universal.c
index 3e5547a..032a536 100644
--- a/universal.c
+++ b/universal.c
@@ -183,7 +183,7 @@ XS(XS_UNIVERSAL_VERSION)
     GV *gv;
     SV *sv;
     char *undef;
-    double req;
+    NV req;
 
     if(SvROK(ST(0))) {
         sv = (SV*)SvRV(ST(0));
diff --git a/util.c b/util.c
index 3655cef..242a308 100644
--- a/util.c
+++ b/util.c
@@ -2630,7 +2630,7 @@ Perl_repeatcpy(pTHX_ register char *to, register const char *from, I32 len, regi
 }
 
 U32
-Perl_cast_ulong(pTHX_ double f)
+Perl_cast_ulong(pTHX_ NV f)
 {
     long along;
 
@@ -2667,7 +2667,7 @@ Perl_cast_ulong(pTHX_ double f)
 #endif
 
 I32
-Perl_cast_i32(pTHX_ double f)
+Perl_cast_i32(pTHX_ NV f)
 {
     if (f >= I32_MAX)
 	return (I32) I32_MAX;
@@ -2677,12 +2677,12 @@ Perl_cast_i32(pTHX_ double f)
 }
 
 IV
-Perl_cast_iv(pTHX_ double f)
+Perl_cast_iv(pTHX_ NV f)
 {
     if (f >= IV_MAX) {
 	UV uv;
 	
-	if (f >= (double)UV_MAX)
+	if (f >= (NV)UV_MAX)
 	    return (IV) UV_MAX;	
 	uv = (UV) f;
 	return (IV)uv;
@@ -2693,7 +2693,7 @@ Perl_cast_iv(pTHX_ double f)
 }
 
 UV
-Perl_cast_uv(pTHX_ double f)
+Perl_cast_uv(pTHX_ NV f)
 {
     if (f >= MY_UV_MAX)
 	return (UV) MY_UV_MAX;
@@ -3235,6 +3235,9 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
     PL_maxscream = -1;
     PL_regcompp = FUNC_NAME_TO_PTR(Perl_pregcomp);
     PL_regexecp = FUNC_NAME_TO_PTR(Perl_regexec_flags);
+    PL_regint_start = FUNC_NAME_TO_PTR(Perl_re_intuit_start);
+    PL_regint_string = FUNC_NAME_TO_PTR(Perl_re_intuit_string);
+    PL_regfree = FUNC_NAME_TO_PTR(Perl_pregfree);
     PL_regindent = 0;
     PL_reginterp_cnt = 0;
     PL_lastscream = Nullsv;
@@ -3303,7 +3306,7 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
  * So it is in perl for (say) POSIX to use. 
  * Needed for SunOS with Sun's 'acc' for example.
  */
-double 
+NV 
 Perl_huge(void)
 {
  return HUGE_VAL;
@@ -3506,22 +3509,23 @@ Perl_my_fflush_all(pTHX)
 #endif
 }
 
-double
+NV
 Perl_my_atof(pTHX_ const char* s) {
 #ifdef USE_LOCALE_NUMERIC
     if ((PL_hints & HINT_LOCALE) && PL_numeric_local) {
-	double x, y;
+	NV x, y;
 
-	x = atof(s);
+	x = Perl_atof(s);
 	SET_NUMERIC_STANDARD();
-	y = atof(s);
+	y = Perl_atof(s);
 	SET_NUMERIC_LOCAL();
 	if ((y < 0.0 && y < x) || (y > 0.0 && y > x))
 	    return y;
 	return x;
-    } else
-	return atof(s);
+    }
+    else
+	return Perl_atof(s);
 #else
-    return atof(s);
+    return Perl_atof(s);
 #endif
 }