/* pp_sort.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
+ * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
static IV
-dynprep(pTHX_ gptr *list1, gptr *list2, size_t nmemb, SVCOMPARE_t cmp)
+dynprep(pTHX_ gptr *list1, gptr *list2, size_t nmemb, const SVCOMPARE_t cmp)
{
I32 sense;
register gptr *b, *p, *q, *t, *p2;
- register gptr c, *last, *r;
- gptr *savep;
+ register gptr *last, *r;
IV runs = 0;
b = list1;
}
}
if (q > b) { /* run of greater than 2 at b */
- savep = p;
+ gptr *savep = p;
+
p = q += 2;
/* pick up singleton, if possible */
if ((p == t) &&
((cmp(aTHX_ *(p-1), *p) > 0) == sense))
savep = r = p = q = last;
p2 = NEXT(p2) = p2 + (p - b); ++runs;
- if (sense) while (b < --p) {
- c = *b;
- *b++ = *p;
- *p = c;
- }
+ if (sense)
+ while (b < --p) {
+ const gptr c = *b;
+ *b++ = *p;
+ *p = c;
+ }
p = savep;
}
while (q < p) { /* simple pairs */
p2 = NEXT(p2) = p2 + 2; ++runs;
if (sense) {
- c = *q++;
+ const gptr c = *q++;
*(q-1) = *q;
*q++ = c;
} else q += 2;
gptr small[SMALLSORT];
gptr *which[3];
off_runs stack[60], *stackp;
- SVCOMPARE_t savecmp = 0;
+ SVCOMPARE_t savecmp = NULL;
if (nmemb <= 1) return; /* sorted trivially */
- if (flags) {
+ if ((flags & SORTf_DESC) != 0) {
savecmp = PL_sort_RealCmp; /* Save current comparison routine, if any */
PL_sort_RealCmp = cmp; /* Put comparison routine where cmp_desc can find it */
cmp = cmp_desc;
PL_sort_RealCmp = cmp; /* Put comparison routine where cmpindir can find it */
/* sort, with indirection */
- S_qsortsvu(aTHX_ (gptr *)indir, nmemb,
- ((flags & SORTf_DESC) != 0 ? cmpindir_desc : cmpindir));
+ if (flags & SORTf_DESC)
+ qsortsvu((gptr *)indir, nmemb, cmpindir_desc);
+ else
+ qsortsvu((gptr *)indir, nmemb, cmpindir);
pp = indir;
q = list1;
/* restore prevailing comparison routine */
PL_sort_RealCmp = savecmp;
} else if ((flags & SORTf_DESC) != 0) {
- SVCOMPARE_t savecmp = PL_sort_RealCmp; /* Save current comparison routine, if any */
+ const SVCOMPARE_t savecmp = PL_sort_RealCmp; /* Save current comparison routine, if any */
PL_sort_RealCmp = cmp; /* Put comparison routine where cmp_desc can find it */
cmp = cmp_desc;
- S_qsortsvu(aTHX_ list1, nmemb, cmp);
+ qsortsvu(list1, nmemb, cmp);
/* restore prevailing comparison routine */
PL_sort_RealCmp = savecmp;
} else {
- S_qsortsvu(aTHX_ list1, nmemb, cmp);
+ qsortsvu(list1, nmemb, cmp);
}
}
void
Perl_sortsv_flags(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp, U32 flags)
{
- void (*sortsvp)(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp, U32 flags)
- = ((flags & SORTf_QSORT) != 0 ? S_qsortsv : S_mergesortsv);
-
- sortsvp(aTHX_ array, nmemb, cmp, flags);
+ if (flags & SORTf_QSORT)
+ S_qsortsv(aTHX_ array, nmemb, cmp, flags);
+ else
+ S_mergesortsv(aTHX_ array, nmemb, cmp, flags);
}
#define SvNSIOK(sv) ((SvFLAGS(sv) & SVf_NOK) || ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) == SVf_IOK))
}
}
if (!(cv && CvROOT(cv))) {
- if (cv && CvXSUB(cv)) {
+ if (cv && CvISXSUB(cv)) {
is_xsub = 1;
}
else if (gv) {
SV *tmpstr = sv_newmortal();
- gv_efullname3(tmpstr, gv, Nullch);
+ gv_efullname3(tmpstr, gv, NULL);
DIE(aTHX_ "Undefined sort subroutine \"%"SVf"\" called",
- tmpstr);
+ SVfARG(tmpstr));
}
else {
DIE(aTHX_ "Undefined subroutine in sort");
}
}
else {
- PL_sortcop = Nullop;
+ PL_sortcop = NULL;
stash = CopSTASH(PL_curcop);
}
p2 = SP;
for (i=0; i < max; i++) {
SV **svp = av_fetch(av, i, FALSE);
- *SP++ = (svp) ? *svp : Nullsv;
+ *SP++ = (svp) ? *svp : NULL;
}
}
else {
SAVESPTR(PL_firstgv);
SAVESPTR(PL_secondgv);
SAVESPTR(PL_sortstash);
- PL_firstgv = gv_fetchpvs("a", TRUE, SVt_PV);
- PL_secondgv = gv_fetchpvs("b", TRUE, SVt_PV);
+ PL_firstgv = gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV);
+ PL_secondgv = gv_fetchpvs("b", GV_ADD|GV_NOTQUAL, SVt_PV);
PL_sortstash = stash;
SAVESPTR(GvSV(PL_firstgv));
SAVESPTR(GvSV(PL_secondgv));
if (hasargs) {
/* This is mostly copied from pp_entersub */
- AV *av = (AV*)PAD_SVl(0);
+ AV * const av = (AV*)PAD_SVl(0);
cx->blk_sub.savearray = GvAV(PL_defgv);
- GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+ GvAV(PL_defgv) = (AV*)SvREFCNT_inc_simple(av);
CX_CURPAD_SAVE(cx->blk_sub);
cx->blk_sub.argarray = av;
}
: ( overloading ? S_amagic_ncmp : S_sv_ncmp ) )
: ( IN_LOCALE_RUNTIME
? ( overloading
- ? S_amagic_cmp_locale
- : sv_cmp_locale_static)
- : ( overloading ? S_amagic_cmp : sv_cmp_static)),
+ ? (SVCOMPARE_t)S_amagic_cmp_locale
+ : (SVCOMPARE_t)sv_cmp_locale_static)
+ : ( overloading ? (SVCOMPARE_t)S_amagic_cmp : (SVCOMPARE_t)sv_cmp_static)),
sort_flags);
}
if ((priv & OPpSORT_REVERSE) != 0) {
SV** ary = AvALLOC(av);
if (AvARRAY(av) != ary) {
AvMAX(av) += AvARRAY(av) - AvALLOC(av);
- SvPV_set(av, (char*)ary);
+ AvARRAY(av) = ary;
}
if (AvMAX(av) < 1) {
AvMAX(av) = 1;
Renew(ary,2,SV*);
- SvPV_set(av, (char*)ary);
+ AvARRAY(av) = ary;
}
}
AvFILLp(av) = 1;
#define tryCALL_AMAGICbin(left,right,meth) \
(PL_amagic_generation && (SvAMAGIC(left)||SvAMAGIC(right))) \
? amagic_call(left, right, CAT2(meth,_amg), 0) \
- : Nullsv;
+ : NULL;
+
+#define SORT_NORMAL_RETURN_VALUE(val) (((val) > 0) ? 1 : ((val) ? -1 : 0))
static I32
S_amagic_ncmp(pTHX_ register SV *a, register SV *b)
if (tmpsv) {
if (SvIOK(tmpsv)) {
const I32 i = SvIVX(tmpsv);
- if (i > 0)
- return 1;
- return i? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(i);
}
else {
const NV d = SvNV(tmpsv);
- if (d > 0)
- return 1;
- return d ? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(d);
}
}
return S_sv_ncmp(aTHX_ a, b);
if (tmpsv) {
if (SvIOK(tmpsv)) {
const I32 i = SvIVX(tmpsv);
- if (i > 0)
- return 1;
- return i? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(i);
}
else {
const NV d = SvNV(tmpsv);
- if (d > 0)
- return 1;
- return d ? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(d);
}
}
return S_sv_i_ncmp(aTHX_ a, b);
if (tmpsv) {
if (SvIOK(tmpsv)) {
const I32 i = SvIVX(tmpsv);
- if (i > 0)
- return 1;
- return i? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(i);
}
else {
const NV d = SvNV(tmpsv);
- if (d > 0)
- return 1;
- return d? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(d);
}
}
return sv_cmp(str1, str2);
if (tmpsv) {
if (SvIOK(tmpsv)) {
const I32 i = SvIVX(tmpsv);
- if (i > 0)
- return 1;
- return i? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(i);
}
else {
const NV d = SvNV(tmpsv);
- if (d > 0)
- return 1;
- return d? -1 : 0;
+ return SORT_NORMAL_RETURN_VALUE(d);
}
}
return sv_cmp_locale(str1, str2);