X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_ctl.c;h=ab6466be783c8e0f878796dc00826860b9339852;hb=a682de96b5260e75b40bb25b8d2eb16f338518c6;hp=64e695bc2e83f722aabf3e785fee47072240c664;hpb=f6b3007c38a92f48d086a19ea8682dd935b6d4ee;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_ctl.c b/pp_ctl.c index 64e695b..ab6466b 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -32,6 +32,21 @@ #define CALLOP *PL_op #endif +static I32 sortcv(pTHXo_ SV *a, SV *b); +static I32 sv_ncmp(pTHXo_ SV *a, SV *b); +static I32 sv_i_ncmp(pTHXo_ SV *a, SV *b); +static I32 amagic_ncmp(pTHXo_ SV *a, SV *b); +static I32 amagic_i_ncmp(pTHXo_ SV *a, SV *b); +static I32 amagic_cmp(pTHXo_ SV *a, SV *b); +static I32 amagic_cmp_locale(pTHXo_ SV *a, SV *b); +#ifdef PERL_OBJECT +static I32 sv_cmp_static(pTHXo_ SV *a, SV *b); +static I32 sv_cmp_locale_static(pTHXo_ SV *a, SV *b); +#else +#define sv_cmp_static Perl_sv_cmp +#define sv_cmp_locale_static Perl_sv_cmp_locale +#endif + PP(pp_wantarray) { djSP; @@ -276,7 +291,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 +584,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 +599,7 @@ PP(pp_formline) sprintf(t, "%*.0f", (int) fieldsize, value); } +#endif RESTORE_NUMERIC_STANDARD(); } t += fieldsize; @@ -746,120 +770,6 @@ PP(pp_mapwhile) } } -STATIC I32 -S_sv_ncmp(pTHX_ SV *a, SV *b) -{ - double nv1 = SvNV(a); - double nv2 = SvNV(b); - return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0; -} - -STATIC I32 -S_sv_i_ncmp(pTHX_ SV *a, SV *b) -{ - IV iv1 = SvIV(a); - IV iv2 = SvIV(b); - return iv1 < iv2 ? -1 : iv1 > iv2 ? 1 : 0; -} -#define tryCALL_AMAGICbin(left,right,meth,svp) STMT_START { \ - *svp = Nullsv; \ - if (PL_amagic_generation) { \ - if (SvAMAGIC(left)||SvAMAGIC(right))\ - *svp = amagic_call(left, \ - right, \ - CAT2(meth,_amg), \ - 0); \ - } \ - } STMT_END - -STATIC I32 -S_amagic_ncmp(pTHX_ register SV *a, register SV *b) -{ - SV *tmpsv; - tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); - if (tmpsv) { - double d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_ncmp(a, b); -} - -STATIC I32 -S_amagic_i_ncmp(pTHX_ register SV *a, register SV *b) -{ - SV *tmpsv; - tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); - if (tmpsv) { - double d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_i_ncmp(a, b); -} - -STATIC I32 -S_amagic_cmp(pTHX_ register SV *str1, register SV *str2) -{ - SV *tmpsv; - tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); - if (tmpsv) { - double d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_cmp(str1, str2); -} - -STATIC I32 -S_amagic_cmp_locale(pTHX_ register SV *str1, register SV *str2) -{ - SV *tmpsv; - tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); - if (tmpsv) { - double d; - - if (SvIOK(tmpsv)) { - I32 i = SvIVX(tmpsv); - if (i > 0) - return 1; - return i? -1 : 0; - } - d = SvNV(tmpsv); - if (d > 0) - return 1; - return d? -1 : 0; - } - return sv_cmp_locale(str1, str2); -} - PP(pp_sort) { djSP; dMARK; dORIGMARK; @@ -965,7 +875,7 @@ PP(pp_sort) (void)SvREFCNT_inc(cv); /* in preparation for POPSUB */ } PL_sortcxix = cxstack_ix; - qsortsv((myorigmark+1), max, FUNC_NAME_TO_PTR(S_sortcv)); + qsortsv((myorigmark+1), max, sortcv); POPBLOCK(cx,PL_curpm); PL_stack_sp = newsp; @@ -979,19 +889,13 @@ PP(pp_sort) qsortsv(ORIGMARK+1, max, (PL_op->op_private & OPpSORT_NUMERIC) ? ( (PL_op->op_private & OPpSORT_INTEGER) - ? ( overloading - ? FUNC_NAME_TO_PTR(S_amagic_i_ncmp) - : FUNC_NAME_TO_PTR(S_sv_i_ncmp)) - : ( overloading - ? FUNC_NAME_TO_PTR(S_amagic_ncmp) - : FUNC_NAME_TO_PTR(S_sv_ncmp))) + ? ( overloading ? amagic_i_ncmp : sv_i_ncmp) + : ( overloading ? amagic_ncmp : sv_ncmp)) : ( (PL_op->op_private & OPpLOCALE) ? ( overloading - ? FUNC_NAME_TO_PTR(S_amagic_cmp_locale) - : FUNC_NAME_TO_PTR(Perl_sv_cmp_locale)) - : ( overloading - ? FUNC_NAME_TO_PTR(S_amagic_cmp) - : FUNC_NAME_TO_PTR(Perl_sv_cmp) ))); + ? amagic_cmp_locale + : sv_cmp_locale_static) + : ( overloading ? amagic_cmp : sv_cmp_static))); if (PL_op->op_private & OPpSORT_REVERSE) { SV **p = ORIGMARK+1; SV **q = ORIGMARK+max; @@ -1013,11 +917,11 @@ PP(pp_sort) PP(pp_range) { if (GIMME == G_ARRAY) - return cCONDOP->op_true; + return NORMAL; if (SvTRUEx(PAD_SV(PL_op->op_targ))) - return cCONDOP->op_false; + return cLOGOP->op_other; else - return cCONDOP->op_true; + return NORMAL; } PP(pp_flip) @@ -1025,7 +929,7 @@ PP(pp_flip) djSP; if (GIMME == G_ARRAY) { - RETURNOP(((CONDOP*)cUNOP->op_first)->op_false); + RETURNOP(((LOGOP*)cUNOP->op_first)->op_other); } else { dTOPss; @@ -1043,7 +947,7 @@ PP(pp_flip) else { sv_setiv(targ, 0); SP--; - RETURNOP(((CONDOP*)cUNOP->op_first)->op_false); + RETURNOP(((LOGOP*)cUNOP->op_first)->op_other); } } sv_setpv(TARG, ""); @@ -1558,9 +1462,12 @@ PP(pp_caller) PUSHs(&PL_sv_yes); } } - else if (CxTYPE(cx) == CXt_SUB && - cx->blk_sub.hasargs && - PL_curcop->cop_stash == PL_debstash) + else { + PUSHs(&PL_sv_undef); + PUSHs(&PL_sv_undef); + } + if (CxTYPE(cx) == CXt_SUB && cx->blk_sub.hasargs + && PL_curcop->cop_stash == PL_debstash) { AV *ary = cx->blk_sub.argarray; int off = AvARRAY(ary) - AvALLOC(ary); @@ -1586,30 +1493,6 @@ PP(pp_caller) RETURN; } -STATIC I32 -S_sortcv(pTHX_ SV *a, SV *b) -{ - dTHR; - I32 oldsaveix = PL_savestack_ix; - I32 oldscopeix = PL_scopestack_ix; - I32 result; - GvSV(PL_firstgv) = a; - GvSV(PL_secondgv) = b; - PL_stack_sp = PL_stack_base; - PL_op = PL_sortcop; - CALLRUNOPS(aTHX); - if (PL_stack_sp != PL_stack_base + 1) - Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); - result = SvIV(*PL_stack_sp); - while (PL_scopestack_ix > oldscopeix) { - LEAVE; - } - leave_scope(oldsaveix); - return result; -} - PP(pp_reset) { djSP; @@ -2036,29 +1919,32 @@ S_dofindlabel(pTHX_ OP *o, char *label, OP **opstack, OP **oplimit) *ops++ = cUNOPo->op_first; if (ops >= oplimit) Perl_croak(aTHX_ too_deep); + *ops = 0; } - *ops = 0; if (o->op_flags & OPf_KIDS) { dTHR; /* First try all the kids at this level, since that's likeliest. */ for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { - if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && - kCOP->cop_label && strEQ(kCOP->cop_label, label)) + if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) + && kCOP->cop_label && strEQ(kCOP->cop_label, label)) + { return kid; + } } for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) { if (kid == PL_lastgotoprobe) continue; - if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && - (ops == opstack || - (ops[-1]->op_type != OP_NEXTSTATE && - ops[-1]->op_type != OP_DBSTATE))) + if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) + && (ops == opstack || (ops[-1]->op_type != OP_NEXTSTATE + && ops[-1]->op_type != OP_DBSTATE))) + { *ops++ = kid; + *ops = 0; + } if (o = dofindlabel(kid, label, ops, oplimit)) return o; } } - *ops = 0; return 0; } @@ -2464,11 +2350,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; @@ -2546,7 +2432,7 @@ S_docatch(pTHX_ OP *o) #endif PL_op = o; redo_body: - CALLPROTECT(aTHX_ &ret, FUNC_NAME_TO_PTR(S_docatch_body)); + CALLPROTECT(aTHX_ &ret, MEMBER_TO_FPTR(S_docatch_body)); switch (ret) { case 0: break; @@ -2975,9 +2861,13 @@ PP(pp_require) SAVEHINTS(); PL_hints = 0; SAVEPPTR(PL_compiling.cop_warnings); - PL_compiling.cop_warnings = ((PL_dowarn & G_WARN_ALL_ON) ? WARN_ALL - : WARN_NONE); - + if (PL_dowarn & G_WARN_ALL_ON) + PL_compiling.cop_warnings = WARN_ALL ; + else if (PL_dowarn & G_WARN_ALL_OFF) + PL_compiling.cop_warnings = WARN_NONE ; + else + PL_compiling.cop_warnings = WARN_STD ; + /* switch to eval mode */ push_return(PL_op->op_next); @@ -3039,8 +2929,7 @@ PP(pp_entereval) SAVEHINTS(); PL_hints = PL_op->op_targ; SAVEPPTR(PL_compiling.cop_warnings); - if (PL_compiling.cop_warnings != WARN_ALL - && PL_compiling.cop_warnings != WARN_NONE){ + if (!specialWARN(PL_compiling.cop_warnings)) { PL_compiling.cop_warnings = newSVsv(PL_compiling.cop_warnings) ; SAVEFREESV(PL_compiling.cop_warnings) ; } @@ -3491,13 +3380,8 @@ struct partition_stack_entry { /* Return < 0 == 0 or > 0 as the value of elt1 is < elt2, == elt2, > elt2 */ -#ifdef PERL_OBJECT #define qsort_cmp(elt1, elt2) \ - ((this->*compare)(array[elt1], array[elt2])) -#else -#define qsort_cmp(elt1, elt2) \ - ((*compare)(aTHX_ array[elt1], array[elt2])) -#endif + ((*compare)(aTHXo_ array[elt1], array[elt2])) #ifdef QSORT_ORDER_GUESS #define QSORT_NOTICE_SWAP swapped++; @@ -4068,3 +3952,167 @@ S_qsortsv(pTHX_ SV ** array, size_t num_elts, SVCOMPARE_t compare) /* Believe it or not, the array is sorted at this point! */ } + + +#ifdef PERL_OBJECT +#define NO_XSLOCKS +#undef this +#define this pPerl +#include "XSUB.h" +#endif + + +static I32 +sortcv(pTHXo_ SV *a, SV *b) +{ + dTHR; + I32 oldsaveix = PL_savestack_ix; + I32 oldscopeix = PL_scopestack_ix; + I32 result; + GvSV(PL_firstgv) = a; + GvSV(PL_secondgv) = b; + PL_stack_sp = PL_stack_base; + PL_op = PL_sortcop; + CALLRUNOPS(aTHX); + if (PL_stack_sp != PL_stack_base + 1) + Perl_croak(aTHX_ "Sort subroutine didn't return single value"); + if (!SvNIOKp(*PL_stack_sp)) + Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); + result = SvIV(*PL_stack_sp); + while (PL_scopestack_ix > oldscopeix) { + LEAVE; + } + leave_scope(oldsaveix); + return result; +} + + +static I32 +sv_ncmp(pTHXo_ SV *a, SV *b) +{ + NV nv1 = SvNV(a); + NV nv2 = SvNV(b); + return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0; +} + +static I32 +sv_i_ncmp(pTHXo_ SV *a, SV *b) +{ + IV iv1 = SvIV(a); + IV iv2 = SvIV(b); + return iv1 < iv2 ? -1 : iv1 > iv2 ? 1 : 0; +} +#define tryCALL_AMAGICbin(left,right,meth,svp) STMT_START { \ + *svp = Nullsv; \ + if (PL_amagic_generation) { \ + if (SvAMAGIC(left)||SvAMAGIC(right))\ + *svp = amagic_call(left, \ + right, \ + CAT2(meth,_amg), \ + 0); \ + } \ + } STMT_END + +static I32 +amagic_ncmp(pTHXo_ register SV *a, register SV *b) +{ + SV *tmpsv; + tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); + if (tmpsv) { + NV d; + + if (SvIOK(tmpsv)) { + I32 i = SvIVX(tmpsv); + if (i > 0) + return 1; + return i? -1 : 0; + } + d = SvNV(tmpsv); + if (d > 0) + return 1; + return d? -1 : 0; + } + return sv_ncmp(aTHXo_ a, b); +} + +static I32 +amagic_i_ncmp(pTHXo_ register SV *a, register SV *b) +{ + SV *tmpsv; + tryCALL_AMAGICbin(a,b,ncmp,&tmpsv); + if (tmpsv) { + NV d; + + if (SvIOK(tmpsv)) { + I32 i = SvIVX(tmpsv); + if (i > 0) + return 1; + return i? -1 : 0; + } + d = SvNV(tmpsv); + if (d > 0) + return 1; + return d? -1 : 0; + } + return sv_i_ncmp(aTHXo_ a, b); +} + +static I32 +amagic_cmp(pTHXo_ register SV *str1, register SV *str2) +{ + SV *tmpsv; + tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); + if (tmpsv) { + NV d; + + if (SvIOK(tmpsv)) { + I32 i = SvIVX(tmpsv); + if (i > 0) + return 1; + return i? -1 : 0; + } + d = SvNV(tmpsv); + if (d > 0) + return 1; + return d? -1 : 0; + } + return sv_cmp(str1, str2); +} + +static I32 +amagic_cmp_locale(pTHXo_ register SV *str1, register SV *str2) +{ + SV *tmpsv; + tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv); + if (tmpsv) { + NV d; + + if (SvIOK(tmpsv)) { + I32 i = SvIVX(tmpsv); + if (i > 0) + return 1; + return i? -1 : 0; + } + d = SvNV(tmpsv); + if (d > 0) + return 1; + return d? -1 : 0; + } + return sv_cmp_locale(str1, str2); +} + +#ifdef PERL_OBJECT + +static I32 +sv_cmp_locale_static(pTHXo_ register SV *str1, register SV *str2) +{ + return sv_cmp_locale(str1, str2); +} + +static I32 +sv_cmp_static(pTHXo_ register SV *str1, register SV *str2) +{ + return sv_cmp(str1, str2); +} + +#endif /* PERL_OBJECT */