In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/a7e935015aa7c242f0e4ad14366401108880ed0b?hp=582ac935ddba404ce00c7eda1a75e8a2c0412eee>

- Log -----------------------------------------------------------------
commit a7e935015aa7c242f0e4ad14366401108880ed0b
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Sep 24 20:42:54 2010 -0700

    perldelta entries for the double-magic fixes [perl #76814]

M       pod/perldelta.pod

commit 9138d6cae0eac4fc349c2e253e64077481cf6a49
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Sep 24 20:33:47 2010 -0700

    [perl #76814] FETCH called twice - y
    
    This patch stops y from calling get-magic twice. (This has caused
    double magick since as far back as 5.6.2.)

M       doop.c
M       t/op/tie_fetch_count.t

commit a9984b10c8213b2dc4345882bd808798485d584c
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Sep 24 20:33:42 2010 -0700

    [perl #76814] FETCH called twice - m and s
    
    This fixes m and s. It modifies pp_regcomp to avoid extra magic. It
    also corrects a bug in sv_catsv_flags, which would still call
    mg_get(ssv) even without the SV_GMAGIC flag set.

M       pp_ctl.c
M       sv.c
M       t/op/tie_fetch_count.t

commit 06c841cf64c10f912e4cb0d12dbfc0add671bb81
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Sep 24 20:33:03 2010 -0700

    [perl #76814] FETCH called twice - !
    
    This fixes ! by changing sv_2bool to sv_2bool_flags (with a macro
    wrapper) and adding SvTRUE_nomg. It also corrects the docs that state
    incorrectly that SvTRUE does not handle magic.

M       embed.fnc
M       embed.h
M       global.sym
M       mathoms.c
M       pp.c
M       proto.h
M       sv.c
M       sv.h
M       t/op/tie_fetch_count.t

commit 078504b2d0c069e5cefbe4670341aa18838d452d
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Sep 24 20:31:28 2010 -0700

    [perl #76814] FETCH called twice - string comparison ops
    
    This patch changes sv_eq, sv_cmp, sv_cmp_locale and sv_collxfrm
    to _flags forms, with macros under the old names for sv_eq and
    sv_collxfrm, but functions for sv_cmp* since pp_sort.c needs them.

M       embed.fnc
M       embed.h
M       global.sym
M       mathoms.c
M       pp.c
M       proto.h
M       sv.c
M       sv.h
M       t/op/tie_fetch_count.t
-----------------------------------------------------------------------

Summary of changes:
 doop.c                 |   12 +++---
 embed.fnc              |   11 ++++--
 embed.h                |   16 +++++---
 global.sym             |    8 +++--
 mathoms.c              |   21 ++++++++++++
 pod/perldelta.pod      |   59 ++++++++++++++++++++++++++++++++-
 pp.c                   |   14 ++++----
 pp_ctl.c               |   10 +++++-
 proto.h                |   20 ++++++++---
 sv.c                   |   86 +++++++++++++++++++++++++++++++++++++----------
 sv.h                   |   25 ++++++++++++++
 t/op/tie_fetch_count.t |   32 ++++++++----------
 12 files changed, 245 insertions(+), 69 deletions(-)

diff --git a/doop.c b/doop.c
index 903144c..35efba6 100644
--- a/doop.c
+++ b/doop.c
@@ -33,7 +33,7 @@ S_do_trans_simple(pTHX_ SV * const sv)
     dVAR;
     I32 matches = 0;
     STRLEN len;
-    U8 *s = (U8*)SvPV(sv,len);
+    U8 *s = (U8*)SvPV_nomg(sv,len);
     U8 * const send = s+len;
     const short * const tbl = (short*)cPVOP->op_pv;
 
@@ -101,7 +101,7 @@ S_do_trans_count(pTHX_ SV * const sv)
 {
     dVAR;
     STRLEN len;
-    const U8 *s = (const U8*)SvPV_const(sv, len);
+    const U8 *s = (const U8*)SvPV_nomg_const(sv, len);
     const U8 * const send = s + len;
     I32 matches = 0;
     const short * const tbl = (short*)cPVOP->op_pv;
@@ -139,7 +139,7 @@ S_do_trans_complex(pTHX_ SV * const sv)
 {
     dVAR;
     STRLEN len;
-    U8 *s = (U8*)SvPV(sv, len);
+    U8 *s = (U8*)SvPV_nomg(sv, len);
     U8 * const send = s+len;
     I32 matches = 0;
     const short * const tbl = (short*)cPVOP->op_pv;
@@ -325,7 +325,7 @@ S_do_trans_simple_utf8(pTHX_ SV * const sv)
 
     PERL_ARGS_ASSERT_DO_TRANS_SIMPLE_UTF8;
 
-    s = (U8*)SvPV(sv, len);
+    s = (U8*)SvPV_nomg(sv, len);
     if (!SvUTF8(sv)) {
        const U8 *t = s;
        const U8 * const e = s + len;
@@ -426,7 +426,7 @@ S_do_trans_count_utf8(pTHX_ SV * const sv)
 
     PERL_ARGS_ASSERT_DO_TRANS_COUNT_UTF8;
 
-    s = (const U8*)SvPV_const(sv, len);
+    s = (const U8*)SvPV_nomg_const(sv, len);
     if (!SvUTF8(sv)) {
        const U8 *t = s;
        const U8 * const e = s + len;
@@ -478,7 +478,7 @@ S_do_trans_complex_utf8(pTHX_ SV * const sv)
     STRLEN len;
     U8 *dstart, *dend;
     U8 hibit = 0;
-    U8 *s = (U8*)SvPV(sv, len);
+    U8 *s = (U8*)SvPV_nomg(sv, len);
 
     PERL_ARGS_ASSERT_DO_TRANS_COMPLEX_UTF8;
 
diff --git a/embed.fnc b/embed.fnc
index 619a0be..9ba33d1 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1116,7 +1116,8 @@ Ap        |SV**   |stack_grow     |NN SV** sp|NN SV** 
p|int n
 Ap     |I32    |start_subparse |I32 is_format|U32 flags
 : Used in pp_ctl.c
 p      |void   |sub_crush_depth|NN CV* cv
-Apd    |bool   |sv_2bool       |NN SV *const sv
+Amd    |bool   |sv_2bool       |NN SV *const sv
+Apd    |bool   |sv_2bool_flags |NN SV *const sv|const I32 flags
 Apd    |CV*    |sv_2cv         |NULLOK SV* sv|NN HV **const st|NN GV **const 
gvp \
                                |const I32 lref
 Apd    |IO*    |sv_2io         |NN SV *const sv
@@ -1162,9 +1163,12 @@ pd       |I32    |sv_clean_all
 pd     |void   |sv_clean_objs
 Apd    |void   |sv_clear       |NN SV *const sv
 Apd    |I32    |sv_cmp         |NULLOK SV *const sv1|NULLOK SV *const sv2
+Apd    |I32    |sv_cmp_flags   |NULLOK SV *const sv1|NULLOK SV *const 
sv2|const I32 flags
 Apd    |I32    |sv_cmp_locale  |NULLOK SV *const sv1|NULLOK SV *const sv2
+Apd    |I32    |sv_cmp_locale_flags    |NULLOK SV *const sv1|NULLOK SV *const 
sv2|const I32 flags
 #if defined(USE_LOCALE_COLLATE)
-Apd    |char*  |sv_collxfrm    |NN SV *const sv|NN STRLEN *const nxp
+Amd    |char*  |sv_collxfrm    |NN SV *const sv|NN STRLEN *const nxp
+Apd    |char*  |sv_collxfrm_flags      |NN SV *const sv|NN STRLEN *const 
nxp|I32 const flags
 #endif
 Ap     |OP*    |sv_compile_2op |NN SV *sv|NN OP **startop \
                                |NN const char *code|NN PAD **padp
@@ -1174,7 +1178,8 @@ Apd       |void   |sv_dec_nomg    |NULLOK SV *const sv
 Ap     |void   |sv_dump        |NN SV* sv
 ApdR   |bool   |sv_derived_from|NN SV* sv|NN const char *const name
 ApdR   |bool   |sv_does        |NN SV* sv|NN const char *const name
-Apd    |I32    |sv_eq          |NULLOK SV* sv1|NULLOK SV* sv2
+Amd    |I32    |sv_eq          |NULLOK SV* sv1|NULLOK SV* sv2
+Apd    |I32    |sv_eq_flags    |NULLOK SV* sv1|NULLOK SV* sv2|const I32 flags
 Apd    |void   |sv_free        |NULLOK SV *const sv
 : FIXME Used in SvREFCNT_dec() but only
 : if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
diff --git a/embed.h b/embed.h
index d269611..0330641 100644
--- a/embed.h
+++ b/embed.h
@@ -919,7 +919,7 @@
 #ifdef PERL_CORE
 #define sub_crush_depth                Perl_sub_crush_depth
 #endif
-#define sv_2bool               Perl_sv_2bool
+#define sv_2bool_flags         Perl_sv_2bool_flags
 #define sv_2cv                 Perl_sv_2cv
 #define sv_2io                 Perl_sv_2io
 #if defined(PERL_IN_SV_C)
@@ -962,9 +962,11 @@
 #endif
 #define sv_clear               Perl_sv_clear
 #define sv_cmp                 Perl_sv_cmp
+#define sv_cmp_flags           Perl_sv_cmp_flags
 #define sv_cmp_locale          Perl_sv_cmp_locale
+#define sv_cmp_locale_flags    Perl_sv_cmp_locale_flags
 #if defined(USE_LOCALE_COLLATE)
-#define sv_collxfrm            Perl_sv_collxfrm
+#define sv_collxfrm_flags      Perl_sv_collxfrm_flags
 #endif
 #define sv_compile_2op         Perl_sv_compile_2op
 #define getcwd_sv              Perl_getcwd_sv
@@ -973,7 +975,7 @@
 #define sv_dump                        Perl_sv_dump
 #define sv_derived_from                Perl_sv_derived_from
 #define sv_does                        Perl_sv_does
-#define sv_eq                  Perl_sv_eq
+#define sv_eq_flags            Perl_sv_eq_flags
 #define sv_free                        Perl_sv_free
 #ifdef PERL_CORE
 #define sv_free_arenas         Perl_sv_free_arenas
@@ -3388,7 +3390,7 @@
 #ifdef PERL_CORE
 #define sub_crush_depth(a)     Perl_sub_crush_depth(aTHX_ a)
 #endif
-#define sv_2bool(a)            Perl_sv_2bool(aTHX_ a)
+#define sv_2bool_flags(a,b)    Perl_sv_2bool_flags(aTHX_ a,b)
 #define sv_2cv(a,b,c,d)                Perl_sv_2cv(aTHX_ a,b,c,d)
 #define sv_2io(a)              Perl_sv_2io(aTHX_ a)
 #if defined(PERL_IN_SV_C)
@@ -3430,9 +3432,11 @@
 #endif
 #define sv_clear(a)            Perl_sv_clear(aTHX_ a)
 #define sv_cmp(a,b)            Perl_sv_cmp(aTHX_ a,b)
+#define sv_cmp_flags(a,b,c)    Perl_sv_cmp_flags(aTHX_ a,b,c)
 #define sv_cmp_locale(a,b)     Perl_sv_cmp_locale(aTHX_ a,b)
+#define sv_cmp_locale_flags(a,b,c)     Perl_sv_cmp_locale_flags(aTHX_ a,b,c)
 #if defined(USE_LOCALE_COLLATE)
-#define sv_collxfrm(a,b)       Perl_sv_collxfrm(aTHX_ a,b)
+#define sv_collxfrm_flags(a,b,c)       Perl_sv_collxfrm_flags(aTHX_ a,b,c)
 #endif
 #define sv_compile_2op(a,b,c,d)        Perl_sv_compile_2op(aTHX_ a,b,c,d)
 #define getcwd_sv(a)           Perl_getcwd_sv(aTHX_ a)
@@ -3441,7 +3445,7 @@
 #define sv_dump(a)             Perl_sv_dump(aTHX_ a)
 #define sv_derived_from(a,b)   Perl_sv_derived_from(aTHX_ a,b)
 #define sv_does(a,b)           Perl_sv_does(aTHX_ a,b)
-#define sv_eq(a,b)             Perl_sv_eq(aTHX_ a,b)
+#define sv_eq_flags(a,b,c)     Perl_sv_eq_flags(aTHX_ a,b,c)
 #define sv_free(a)             Perl_sv_free(aTHX_ a)
 #ifdef PERL_CORE
 #define sv_free_arenas()       Perl_sv_free_arenas(aTHX)
diff --git a/global.sym b/global.sym
index db75a27..6c4c570 100644
--- a/global.sym
+++ b/global.sym
@@ -528,7 +528,7 @@ Perl_share_hek
 Perl_csighandler
 Perl_stack_grow
 Perl_start_subparse
-Perl_sv_2bool
+Perl_sv_2bool_flags
 Perl_sv_2cv
 Perl_sv_2io
 Perl_sv_2iv
@@ -559,8 +559,10 @@ Perl_sv_catsv
 Perl_sv_chop
 Perl_sv_clear
 Perl_sv_cmp
+Perl_sv_cmp_flags
 Perl_sv_cmp_locale
-Perl_sv_collxfrm
+Perl_sv_cmp_locale_flags
+Perl_sv_collxfrm_flags
 Perl_sv_compile_2op
 Perl_getcwd_sv
 Perl_sv_dec
@@ -568,7 +570,7 @@ Perl_sv_dec_nomg
 Perl_sv_dump
 Perl_sv_derived_from
 Perl_sv_does
-Perl_sv_eq
+Perl_sv_eq_flags
 Perl_sv_free
 Perl_sv_free2
 Perl_sv_gets
diff --git a/mathoms.c b/mathoms.c
index 1bb33d3..78516b3 100644
--- a/mathoms.c
+++ b/mathoms.c
@@ -80,6 +80,9 @@ PERL_CALLCONV HV * Perl_newHV(pTHX);
 PERL_CALLCONV IO * Perl_newIO(pTHX);
 PERL_CALLCONV I32 Perl_my_stat(pTHX);
 PERL_CALLCONV I32 Perl_my_lstat(pTHX);
+PERL_CALLCONV I32 Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2);
+PERL_CALLCONV char * Perl_sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp);
+PERL_CALLCONV bool Perl_sv_2bool(pTHX_ register SV *const sv);
 
 /* ref() is now a macro using Perl_doref;
  * this version provided for binary compatibility only.
@@ -1533,6 +1536,24 @@ Perl_my_lstat(pTHX)
     return my_lstat_flags(SV_GMAGIC);
 }
 
+I32
+Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
+{
+    return sv_eq_flags(sv1, sv2, SV_GMAGIC);
+}
+
+char *
+Perl_sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp)
+{
+    return sv_collxfrm_flags(sv, nxp, SV_GMAGIC);
+}
+
+bool
+Perl_sv_2bool(pTHX_ register SV *const sv)
+{
+    return sv_2bool_flags(sv, SV_GMAGIC);
+}
+
 #endif /* NO_MATHOMS */
 
 /*
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index a3c89ce..abbca52 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -231,7 +231,8 @@ section.
 
 =item *
 
-XXX Description of the change here
+The documentation for the C<SvTRUE> macro was simply wrong in stating that
+get-magic is not processed. It has been corrected.
 
 =back
 
@@ -388,6 +389,37 @@ be noted as well.
 See L</Regular expressions retain their localeness when interpolated>,
 above.
 
+=item *
+
+The C<sv_cmp_flags>, C<sv_cmp_locale_flags>, C<sv_eq_flags> and
+C<sv_collxfrm_flags> functions have been added. These are like their
+non-_flags counterparts, but allow one to specify whether get-magic is
+processed.
+
+The C<sv_cmp>, C<sv_cmp_locale>, C<sv_eq> and C<sv_collxfrm> functions have
+been replaced with wrappers around the new functions. 
+
+=item *
+
+A new C<sv_2bool_flags> function has been added.
+
+This is like C<sv_2bool>, but it lets the calling code decide whether
+get-magic is handled. C<sv_2bool> is now a macro that calls the new
+function.
+
+=item *
+
+A new macro, C<SvTRUE_nomg>, has been added.
+
+This is like C<SvTRUE>, except that it does not process magic. It uses the
+new C<sv_2bool_flags> function.
+
+=item *
+
+C<sv_catsv_flags> no longer calls C<mg_get> on its second argument (the
+source string) if the flags passed to it do not include SV_GMAGIC. So it
+now matches what the documentation says it does.
+
 =back
 
 =head1 Selected Bug Fixes
@@ -436,6 +468,31 @@ sometimes did not, depending on what order things happened 
to be arranged
 in memory
 L<[perl #71806]|http://rt.perl.org/rt3//Public/Bug/Display.html?id=71806>.
 
+=item *
+
+The C<y///> or C<tr///> operator now calls get-magic (e.g., the C<FETCH>
+method of a tie) on its left-hand side just once, not twice
+L<[perl #76814]|http://rt.perl.org/rt3//Public/Bug/Display.html?id=76814>.
+
+=item *
+
+String comparison (C<eq>, C<ne>, C<lt>, C<gt>, C<le>, C<ge> and
+C<cmp>) and logical not (C<not> and C<!>) operators no longer call magic
+(e.g., tie methods) twice on their operands
+L<[perl #76814]|http://rt.perl.org/rt3//Public/Bug/Display.html?id=76814>.
+
+This bug was introduced in an earlier 5.13 release, and does not affect
+perl 5.12.
+
+=item *
+
+When a tied (or other magic) variable is used as, or in, a regular
+expression, it no longer has its C<FETCH> method called twice
+L<[perl #76814]|http://rt.perl.org/rt3//Public/Bug/Display.html?id=76814>.
+
+This bug was introduced in an earlier 5.13 release, and does not affect
+perl 5.12.
+
 =back
 
 =head1 Known Problems
diff --git a/pp.c b/pp.c
index 2ee6049..476212e 100644
--- a/pp.c
+++ b/pp.c
@@ -2336,8 +2336,8 @@ PP(pp_sle)
     {
       dPOPTOPssrl;
       const int cmp = (IN_LOCALE_RUNTIME
-                ? sv_cmp_locale(left, right)
-                : sv_cmp(left, right));
+                ? sv_cmp_locale_flags(left, right, 0)
+                : sv_cmp_flags(left, right, 0));
       SETs(boolSV(cmp * multiplier < rhs));
       RETURN;
     }
@@ -2349,7 +2349,7 @@ PP(pp_seq)
     tryAMAGICbin_MG(seq_amg, AMGf_set);
     {
       dPOPTOPssrl;
-      SETs(boolSV(sv_eq(left, right)));
+      SETs(boolSV(sv_eq_flags(left, right, 0)));
       RETURN;
     }
 }
@@ -2360,7 +2360,7 @@ PP(pp_sne)
     tryAMAGICbin_MG(sne_amg, AMGf_set);
     {
       dPOPTOPssrl;
-      SETs(boolSV(!sv_eq(left, right)));
+      SETs(boolSV(!sv_eq_flags(left, right, 0)));
       RETURN;
     }
 }
@@ -2372,8 +2372,8 @@ PP(pp_scmp)
     {
       dPOPTOPssrl;
       const int cmp = (IN_LOCALE_RUNTIME
-                ? sv_cmp_locale(left, right)
-                : sv_cmp(left, right));
+                ? sv_cmp_locale_flags(left, right, 0)
+                : sv_cmp_flags(left, right, 0));
       SETi( cmp );
       RETURN;
     }
@@ -2507,7 +2507,7 @@ PP(pp_not)
 {
     dVAR; dSP;
     tryAMAGICun_MG(not_amg, AMGf_set);
-    *PL_stack_sp = boolSV(!SvTRUE(*PL_stack_sp));
+    *PL_stack_sp = boolSV(!SvTRUE_nomg(*PL_stack_sp));
     return NORMAL;
 }
 
diff --git a/pp_ctl.c b/pp_ctl.c
index 601a25c..2444452 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -127,7 +127,7 @@ PP(pp_regcomp)
               sv_setsv(tmpstr, sv);
               continue;
            }
-           sv_catsv(tmpstr, msv);
+           sv_catsv_nomg(tmpstr, msv);
        }
        SvSETMAGIC(tmpstr);
        SP = ORIGMARK;
@@ -219,6 +219,14 @@ PP(pp_regcomp)
                tmpstr = newSVpvn_flags(t, len, SVs_TEMP | SvUTF8(tmpstr));
            }
 
+           /* If it is gmagical, create a mortal copy, but without calling
+              get-magic, as we have already done that. */
+           if(SvGMAGICAL(tmpstr)) {
+               SV *mortalcopy = sv_newmortal();
+               sv_setsv_flags(mortalcopy, tmpstr, 0);
+               tmpstr = mortalcopy;
+           }
+
            if (eng)
                PM_SETRE(pm, CALLREGCOMP_ENG(eng, tmpstr, pm_flags));
            else
diff --git a/proto.h b/proto.h
index 91dae7c..a2fd1f7 100644
--- a/proto.h
+++ b/proto.h
@@ -3214,9 +3214,12 @@ PERL_CALLCONV void       Perl_sub_crush_depth(pTHX_ CV* 
cv)
 #define PERL_ARGS_ASSERT_SUB_CRUSH_DEPTH       \
        assert(cv)
 
-PERL_CALLCONV bool     Perl_sv_2bool(pTHX_ SV *const sv)
+/* PERL_CALLCONV bool  sv_2bool(pTHX_ SV *const sv)
+                       __attribute__nonnull__(pTHX_1); */
+
+PERL_CALLCONV bool     Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags)
                        __attribute__nonnull__(pTHX_1);
-#define PERL_ARGS_ASSERT_SV_2BOOL      \
+#define PERL_ARGS_ASSERT_SV_2BOOL_FLAGS        \
        assert(sv)
 
 PERL_CALLCONV CV*      Perl_sv_2cv(pTHX_ SV* sv, HV **const st, GV **const 
gvp, const I32 lref)
@@ -3359,12 +3362,18 @@ PERL_CALLCONV void      Perl_sv_clear(pTHX_ SV *const 
sv)
        assert(sv)
 
 PERL_CALLCONV I32      Perl_sv_cmp(pTHX_ SV *const sv1, SV *const sv2);
+PERL_CALLCONV I32      Perl_sv_cmp_flags(pTHX_ SV *const sv1, SV *const sv2, 
const I32 flags);
 PERL_CALLCONV I32      Perl_sv_cmp_locale(pTHX_ SV *const sv1, SV *const sv2);
+PERL_CALLCONV I32      Perl_sv_cmp_locale_flags(pTHX_ SV *const sv1, SV *const 
sv2, const I32 flags);
 #if defined(USE_LOCALE_COLLATE)
-PERL_CALLCONV char*    Perl_sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp)
+/* PERL_CALLCONV char* sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp)
+                       __attribute__nonnull__(pTHX_1)
+                       __attribute__nonnull__(pTHX_2); */
+
+PERL_CALLCONV char*    Perl_sv_collxfrm_flags(pTHX_ SV *const sv, STRLEN 
*const nxp, I32 const flags)
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2);
-#define PERL_ARGS_ASSERT_SV_COLLXFRM   \
+#define PERL_ARGS_ASSERT_SV_COLLXFRM_FLAGS     \
        assert(sv); assert(nxp)
 
 #endif
@@ -3402,7 +3411,8 @@ PERL_CALLCONV bool        Perl_sv_does(pTHX_ SV* sv, 
const char *const name)
 #define PERL_ARGS_ASSERT_SV_DOES       \
        assert(sv); assert(name)
 
-PERL_CALLCONV I32      Perl_sv_eq(pTHX_ SV* sv1, SV* sv2);
+/* PERL_CALLCONV I32   sv_eq(pTHX_ SV* sv1, SV* sv2); */
+PERL_CALLCONV I32      Perl_sv_eq_flags(pTHX_ SV* sv1, SV* sv2, const I32 
flags);
 PERL_CALLCONV void     Perl_sv_free(pTHX_ SV *const sv);
 PERL_CALLCONV void     Perl_sv_free2(pTHX_ SV *const sv)
                        __attribute__nonnull__(pTHX_1);
diff --git a/sv.c b/sv.c
index 0c78725..ad292d1 100644
--- a/sv.c
+++ b/sv.c
@@ -3072,20 +3072,28 @@ Perl_sv_2pvutf8(pTHX_ register SV *const sv, STRLEN 
*const lp)
 /*
 =for apidoc sv_2bool
 
-This function is only called on magical items, and is only used by
-sv_true() or its macro equivalent.
+This macro is only used by sv_true() or its macro equivalent, and only if
+the latter's argument is neither SvPOK, SvIOK nor SvNOK.
+It calls sv_2bool_flags with the SV_GMAGIC flag.
+
+=for apidoc sv_2bool_flags
+
+This function is only used by sv_true() and friends,  and only if
+the latter's argument is neither SvPOK, SvIOK nor SvNOK. If the flags
+contain SV_GMAGIC, then it does an mg_get() first.
+
 
 =cut
 */
 
 bool
-Perl_sv_2bool(pTHX_ register SV *const sv)
+Perl_sv_2bool_flags(pTHX_ register SV *const sv, const I32 flags)
 {
     dVAR;
 
-    PERL_ARGS_ASSERT_SV_2BOOL;
+    PERL_ARGS_ASSERT_SV_2BOOL_FLAGS;
 
-    SvGETMAGIC(sv);
+    if(flags & SV_GMAGIC) SvGETMAGIC(sv);
 
     if (!SvOK(sv))
        return 0;
@@ -4781,7 +4789,7 @@ Perl_sv_catsv_flags(pTHX_ SV *const dsv, register SV 
*const ssv, const I32 flags
 
    if (ssv) {
        STRLEN slen;
-       const char *spv = SvPV_const(ssv, slen);
+       const char *spv = SvPV_flags_const(ssv, slen, flags);
        if (spv) {
            /*  sutf8 and dutf8 were type bool, but under USE_ITHREADS,
                gcc version 2.95.2 20000220 (Debian GNU/Linux) for
@@ -6773,11 +6781,17 @@ Returns a boolean indicating whether the strings in the 
two SVs are
 identical. Is UTF-8 and 'use bytes' aware, handles get magic, and will
 coerce its args to strings if necessary.
 
+=for apidoc sv_eq_flags
+
+Returns a boolean indicating whether the strings in the two SVs are
+identical. Is UTF-8 and 'use bytes' aware and coerces its args to strings
+if necessary. If the flags include SV_GMAGIC, it handles get-magic, too.
+
 =cut
 */
 
 I32
-Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
+Perl_sv_eq_flags(pTHX_ register SV *sv1, register SV *sv2, const I32 flags)
 {
     dVAR;
     const char *pv1;
@@ -6794,12 +6808,14 @@ Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
     }
     else {
        /* if pv1 and pv2 are the same, second SvPV_const call may
-        * invalidate pv1, so we may need to make a copy */
-       if (sv1 == sv2 && (SvTHINKFIRST(sv1) || SvGMAGICAL(sv1))) {
+        * invalidate pv1 (if we are handling magic), so we may need to
+        * make a copy */
+       if (sv1 == sv2 && flags & SV_GMAGIC
+        && (SvTHINKFIRST(sv1) || SvGMAGICAL(sv1))) {
            pv1 = SvPV_const(sv1, cur1);
            sv1 = newSVpvn_flags(pv1, cur1, SVs_TEMP | SvUTF8(sv2));
        }
-       pv1 = SvPV_const(sv1, cur1);
+       pv1 = SvPV_flags_const(sv1, cur1, flags);
     }
 
     if (!sv2){
@@ -6807,7 +6823,7 @@ Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
        cur2 = 0;
     }
     else
-       pv2 = SvPV_const(sv2, cur2);
+       pv2 = SvPV_flags_const(sv2, cur2, flags);
 
     if (cur1 && cur2 && SvUTF8(sv1) != SvUTF8(sv2) && !IN_BYTES) {
         /* Differing utf8ness.
@@ -6874,12 +6890,26 @@ string in C<sv1> is less than, equal to, or greater 
than the string in
 C<sv2>. Is UTF-8 and 'use bytes' aware, handles get magic, and will
 coerce its args to strings if necessary.  See also C<sv_cmp_locale>.
 
+=for apidoc sv_cmp_flags
+
+Compares the strings in two SVs.  Returns -1, 0, or 1 indicating whether the
+string in C<sv1> is less than, equal to, or greater than the string in
+C<sv2>. Is UTF-8 and 'use bytes' aware and will coerce its args to strings
+if necessary. If the flags include SV_GMAGIC, it handles get magic. See
+also C<sv_cmp_locale_flags>.
+
 =cut
 */
 
 I32
 Perl_sv_cmp(pTHX_ register SV *const sv1, register SV *const sv2)
 {
+    return sv_cmp_flags(sv1, sv2, SV_GMAGIC);
+}
+
+I32
+Perl_sv_cmp_flags(pTHX_ register SV *const sv1, register SV *const sv2, const 
I32 flags)
+{
     dVAR;
     STRLEN cur1, cur2;
     const char *pv1, *pv2;
@@ -6892,14 +6922,14 @@ Perl_sv_cmp(pTHX_ register SV *const sv1, register SV 
*const sv2)
        cur1 = 0;
     }
     else
-       pv1 = SvPV_const(sv1, cur1);
+       pv1 = SvPV_flags_const(sv1, cur1, flags);
 
     if (!sv2) {
        pv2 = "";
        cur2 = 0;
     }
     else
-       pv2 = SvPV_const(sv2, cur2);
+       pv2 = SvPV_flags_const(sv2, cur2, flags);
 
     if (cur1 && cur2 && SvUTF8(sv1) != SvUTF8(sv2) && !IN_BYTES) {
         /* Differing utf8ness.
@@ -6956,12 +6986,24 @@ Compares the strings in two SVs in a locale-aware 
manner. Is UTF-8 and
 'use bytes' aware, handles get magic, and will coerce its args to strings
 if necessary.  See also C<sv_cmp>.
 
+=for apidoc sv_cmp_locale_flags
+
+Compares the strings in two SVs in a locale-aware manner. Is UTF-8 and
+'use bytes' aware and will coerce its args to strings if necessary. If the
+flags contain SV_GMAGIC, it handles get magic. See also C<sv_cmp_flags>.
+
 =cut
 */
 
 I32
 Perl_sv_cmp_locale(pTHX_ register SV *const sv1, register SV *const sv2)
 {
+    return sv_cmp_locale_flags(sv1, sv2, SV_GMAGIC);
+}
+
+I32
+Perl_sv_cmp_locale_flags(pTHX_ register SV *const sv1, register SV *const sv2, 
const I32 flags)
+{
     dVAR;
 #ifdef USE_LOCALE_COLLATE
 
@@ -6973,9 +7015,9 @@ Perl_sv_cmp_locale(pTHX_ register SV *const sv1, register 
SV *const sv2)
        goto raw_compare;
 
     len1 = 0;
-    pv1 = sv1 ? sv_collxfrm(sv1, &len1) : (char *) NULL;
+    pv1 = sv1 ? sv_collxfrm_flags(sv1, &len1, flags) : (char *) NULL;
     len2 = 0;
-    pv2 = sv2 ? sv_collxfrm(sv2, &len2) : (char *) NULL;
+    pv2 = sv2 ? sv_collxfrm_flags(sv2, &len2, flags) : (char *) NULL;
 
     if (!pv1 || !len1) {
        if (pv2 && len2)
@@ -7014,7 +7056,13 @@ Perl_sv_cmp_locale(pTHX_ register SV *const sv1, 
register SV *const sv2)
 /*
 =for apidoc sv_collxfrm
 
-Add Collate Transform magic to an SV if it doesn't already have it.
+This calls C<sv_collxfrm_flags> with the SV_GMAGIC flag. See
+C<sv_collxfrm_flags>.
+
+=for apidoc sv_collxfrm_flags
+
+Add Collate Transform magic to an SV if it doesn't already have it. If the
+flags contain SV_GMAGIC, it handles get-magic.
 
 Any scalar variable may carry PERL_MAGIC_collxfrm magic that contains the
 scalar data of the variable, but transformed to such a format that a normal
@@ -7025,12 +7073,12 @@ settings.
 */
 
 char *
-Perl_sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp)
+Perl_sv_collxfrm_flags(pTHX_ SV *const sv, STRLEN *const nxp, const I32 flags)
 {
     dVAR;
     MAGIC *mg;
 
-    PERL_ARGS_ASSERT_SV_COLLXFRM;
+    PERL_ARGS_ASSERT_SV_COLLXFRM_FLAGS;
 
     mg = SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_collxfrm) : (MAGIC *) NULL;
     if (!mg || !mg->mg_ptr || *(U32*)mg->mg_ptr != PL_collation_ix) {
@@ -7040,7 +7088,7 @@ Perl_sv_collxfrm(pTHX_ SV *const sv, STRLEN *const nxp)
 
        if (mg)
            Safefree(mg->mg_ptr);
-       s = SvPV_const(sv, len);
+       s = SvPV_flags_const(sv, len, flags);
        if ((xf = mem_collxfrm(s, len, &xlen))) {
            if (! mg) {
 #ifdef PERL_OLD_COPY_ON_WRITE
diff --git a/sv.h b/sv.h
index a96c6f5..c081d6a 100644
--- a/sv.h
+++ b/sv.h
@@ -1459,6 +1459,12 @@ otherwise use the more efficient C<SvUV>.
 
 =for apidoc Am|bool|SvTRUE|SV* sv
 Returns a boolean indicating whether Perl would evaluate the SV as true or
+false.  See SvOK() for a defined/undefined test.  Handles 'get' magic
+unless the scalar is already SvPOK, SvIOK or SvNOK (the public, not the
+private flags).
+
+=for apidoc Am|bool|SvTRUE_nomg|SV* sv
+Returns a boolean indicating whether Perl would evaluate the SV as true or
 false.  See SvOK() for a defined/undefined test.  Does not handle 'get' magic.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
@@ -1653,6 +1659,22 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
            :   SvNOK(sv)                                       \
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
+#  define SvTRUE_nomg(sv) (                                    \
+    !sv                                                                \
+    ? 0                                                                \
+    :    SvPOK(sv)                                             \
+       ?   (({XPV *nxpv = (XPV*)SvANY(sv);                     \
+            nxpv &&                                            \
+            (nxpv->xpv_cur > 1 ||                              \
+             (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0')); }) \
+            ? 1                                                \
+            : 0)                                               \
+       :                                                       \
+           SvIOK(sv)                                           \
+           ? SvIVX(sv) != 0                                    \
+           :   SvNOK(sv)                                       \
+               ? SvNVX(sv) != 0.0                              \
+               : sv_2bool_flags(sv,0) )
 #  define SvTRUEx(sv) ({SV *_sv = (sv); SvTRUE(_sv); })
 
 #else /* __GNUC__ */
@@ -1799,6 +1821,9 @@ mg.c:1024: warning: left-hand operand of comma expression 
has no effect
 #define sv_2iv(sv) sv_2iv_flags(sv, SV_GMAGIC)
 #define sv_2uv(sv) sv_2uv_flags(sv, SV_GMAGIC)
 #define sv_2nv(sv) sv_2nv_flags(sv, SV_GMAGIC)
+#define sv_eq(sv1, sv2) sv_eq_flags(sv1, sv2, SV_GMAGIC)
+#define sv_collxfrm(sv, nxp) sv_cmp_flags(sv, nxp, SV_GMAGIC)
+#define sv_2bool(sv) sv_2bool_flags(sv, SV_GMAGIC)
 #define sv_insert(bigstr, offset, len, little, littlelen)              \
        Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little),  \
                             (littlelen), SV_GMAGIC)
diff --git a/t/op/tie_fetch_count.t b/t/op/tie_fetch_count.t
index 42f8474..a5e652e 100644
--- a/t/op/tie_fetch_count.t
+++ b/t/op/tie_fetch_count.t
@@ -7,7 +7,7 @@ BEGIN {
     chdir 't' if -d 't';
     @INC = '../lib';
     require './test.pl';
-    plan (tests => 92);
+    plan (tests => 94);
 }
 
 use strict;
@@ -68,16 +68,13 @@ $dummy  =  $var  !=   1 ; check_count '!=';
 $dummy  =  $var <=>   1 ; check_count '<=>';
 
 # String comparison
-TODO: {
-    local $::TODO = $TODO;
-    $dummy  =  $var  lt   1 ; check_count 'lt';
-    $dummy  =  $var  le   1 ; check_count 'le';
-    $dummy  =  $var  eq   1 ; check_count 'eq';
-    $dummy  =  $var  ge   1 ; check_count 'ge';
-    $dummy  =  $var  gt   1 ; check_count 'gt';
-    $dummy  =  $var  ne   1 ; check_count 'ne';
-    $dummy  =  $var cmp   1 ; check_count 'cmp';
-}
+$dummy  =  $var  lt   1 ; check_count 'lt';
+$dummy  =  $var  le   1 ; check_count 'le';
+$dummy  =  $var  eq   1 ; check_count 'eq';
+$dummy  =  $var  ge   1 ; check_count 'ge';
+$dummy  =  $var  gt   1 ; check_count 'gt';
+$dummy  =  $var  ne   1 ; check_count 'ne';
+$dummy  =  $var cmp   1 ; check_count 'cmp';
 
 # Bitwise operators
 $dummy  =  $var   &   1 ; check_count '&';
@@ -86,9 +83,9 @@ $dummy  =  $var   |   1 ; check_count '|';
 $dummy  = ~$var         ; check_count '~';
 
 # Logical operators
+$dummy  = !$var         ; check_count '!';
 TODO: {
     local $::TODO = $TODO;
-    $dummy  = !$var         ; check_count '!';
     $dummy  =  $var  ||   1 ; check_count '||';
     $dummy  = ($var  or   1); check_count 'or';
 }
@@ -146,12 +143,11 @@ $_ = "foo";
 $dummy  =  $var =~ m/ / ; check_count 'm//';
 $dummy  =  $var =~ s/ //; check_count 's///';
 $dummy  =  $var ~~    1 ; check_count '~~';
-TODO: {
-    local $::TODO = $TODO;
-    $dummy  =  $var =~ y/ //; check_count 'y///';
-               /$var/       ; check_count 'm/pattern/';
-              s/$var//      ; check_count 's/pattern//';
-}
+$dummy  =  $var =~ y/ //; check_count 'y///';
+           /$var/       ; check_count 'm/pattern/';
+           /$var foo/   ; check_count 'm/$tied foo/';
+          s/$var//      ; check_count 's/pattern//';
+          s/$var foo//  ; check_count 's/$tied foo//';
           s/./$var/     ; check_count 's//replacement/';
 
 # Dereferencing

--
Perl5 Master Repository

Reply via email to