summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2013-11-12 23:07:16 -0500
committerTony Cook <tony@develop-help.com>2013-11-20 13:47:16 +1100
commit709aee9447f22f3f59d548d44298cca98a023f80 (patch)
tree854fbbfc0b1f3663695a24fb10fc317e5df39cae
parentafda64e875a44be5497e50f703af44b9512fb61f (diff)
downloadperl-709aee9447f22f3f59d548d44298cca98a023f80.tar.gz
remove PL_patchlevel from S_minus_v
|SvPVX(vstringify(PL_patchlevel))| is the same string as |"v" PERL_VERSION_STRING|. No need to go through the overhead of using a version object. Instead of creating a SV, then further manipulating it. Create and manipulate it at the same time with Perl_newSVpvf_nocontext or newSVpvn. "num_len >= level_len " will be folded away by the compiler, previously, since both lengths came from SVs, they were not const technically. A very smart compiler might see strncmp/strnEQ takes all const arguments, and will optimize that away also. VC 2003 didnt do that. Change SvREFCNT_dec to SvREFCNT_dec_NN for obvious reasons. There should not be any user visible changes to -v with this patch. switches.t contains a regexp for -v already so no further tests were added. This patch is part of #116296.
-rw-r--r--perl.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/perl.c b/perl.c
index 2892a877b8..e4310cdce8 100644
--- a/perl.c
+++ b/perl.c
@@ -3443,30 +3443,35 @@ STATIC void
S_minus_v(pTHX)
{
PerlIO * PIO_stdout;
- if (!sv_derived_from(PL_patchlevel, "version"))
- upg_version(PL_patchlevel, TRUE);
{
- SV* level= vstringify(PL_patchlevel);
+ const char * const level_str = "v" PERL_VERSION_STRING;
+ const STRLEN level_len = sizeof("v" PERL_VERSION_STRING)-1;
#ifdef PERL_PATCHNUM
+ SV* level;
# ifdef PERL_GIT_UNCOMMITTED_CHANGES
- SV *num = newSVpvs(PERL_PATCHNUM "*");
+ static const char num [] = PERL_PATCHNUM "*";
# else
- SV *num = newSVpvs(PERL_PATCHNUM);
+ static const char num [] = PERL_PATCHNUM;
# endif
{
- STRLEN level_len, num_len;
- char * level_str, * num_str;
- num_str = SvPV(num, num_len);
- level_str = SvPV(level, level_len);
- if (num_len>=level_len && strnEQ(num_str,level_str,level_len)) {
- SvREFCNT_dec(level);
- level= num;
+ const STRLEN num_len = sizeof(num)-1;
+ /* A very advanced compiler would fold away the strnEQ
+ and this whole conditional, but most (all?) won't do it.
+ SV level could also be replaced by with preprocessor
+ catenation.
+ */
+ if (num_len >= level_len && strnEQ(num,level_str,level_len)) {
+ /* per 46807d8e80, PERL_PATCHNUM is outside of the control
+ of the interp so it might contain format characters
+ */
+ level = newSVpvn(num, num_len);
} else {
- Perl_sv_catpvf(aTHX_ level, " (%"SVf")", num);
- SvREFCNT_dec(num);
+ level = Perl_newSVpvf_nocontext("%s (%s)", level_str, num);
}
}
- #endif
+#else
+ SV* level = newSVpvn(level_str, level_len);
+#endif /* #ifdef PERL_PATCHNUM */
PIO_stdout = PerlIO_stdout();
PerlIO_printf(PIO_stdout,
"\nThis is perl " STRINGIFY(PERL_REVISION)
@@ -3474,7 +3479,7 @@ S_minus_v(pTHX)
", subversion " STRINGIFY(PERL_SUBVERSION)
" (%"SVf") built for " ARCHNAME, level
);
- SvREFCNT_dec(level);
+ SvREFCNT_dec_NN(level);
}
#if defined(LOCAL_PATCH_COUNT)
if (LOCAL_PATCH_COUNT > 0)