#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);
+static I32 run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen);
+
+#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;
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;
gotsome = TRUE;
value = SvNV(sv);
/* Formats aren't yet marked for locales, so assume "yes". */
- SET_NUMERIC_LOCAL();
- if (arg & 256) {
- sprintf(t, "%#*.*f", (int) fieldsize, (int) arg & 255, value);
- } else {
- sprintf(t, "%*.0f", (int) fieldsize, value);
+ {
+ 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);
+ } else {
+ sprintf(t, "%*.0f",
+ (int) fieldsize, value);
+ }
+#endif
+ RESTORE_NUMERIC_STANDARD();
}
t += fieldsize;
break;
}
}
-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;
(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;
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;
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)
djSP;
if (GIMME == G_ARRAY) {
- RETURNOP(((CONDOP*)cUNOP->op_first)->op_false);
+ RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
}
else {
dTOPss;
else {
sv_setiv(targ, 0);
SP--;
- RETURNOP(((CONDOP*)cUNOP->op_first)->op_false);
+ RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
}
}
sv_setpv(TARG, "");
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);
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;
*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;
}
PL_stack_sp--; /* There is no cv arg. */
/* Push a mark for the start of arglist */
PUSHMARK(mark);
- (void)(*CvXSUB(cv))(aTHX_ cv);
+ (void)(*CvXSUB(cv))(aTHXo_ cv);
/* Pop the current context like a decent sub should */
POPBLOCK(cx, PL_curpm);
/* Do _not_ use PUTBACK, keep the XSUB's return stack! */
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;
#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;
PERL_CONTEXT *cx;
I32 optype = 0; /* Might be reset by POPEVAL. */
STRLEN n_a;
-
+
PL_op = saveop;
if (PL_eval_root) {
op_free(PL_eval_root);
STRLEN namelen = strlen(name);
PerlIO *fp;
- if (namelen > 3 && strcmp(name + namelen - 3, ".pm") == 0) {
+ if (namelen > 3 && strEQ(name + namelen - 3, ".pm")) {
SV *pmcsv = Perl_newSVpvf(aTHX_ "%s%c", name, 'c');
char *pmc = SvPV_nolen(pmcsv);
Stat_t pmstat;
I32 gimme = G_SCALAR;
PerlIO *tryrsfp = 0;
STRLEN n_a;
+ int filter_has_file = 0;
+ GV *filter_child_proc = 0;
+ SV *filter_state = 0;
+ SV *filter_sub = 0;
sv = POPs;
if (SvNIOKp(sv) && !SvPOKp(sv)) {
- SET_NUMERIC_STANDARD();
- if (atof(PL_patchlevel) + 0.00000999 < SvNV(sv))
+ if (Atof(PL_patchlevel) + 0.00000999 < SvNV(sv))
DIE(aTHX_ "Perl %s required--this is only version %s, stopped",
SvPV(sv,n_a),PL_patchlevel);
RETPUSHYES;
{
namesv = NEWSV(806, 0);
for (i = 0; i <= AvFILL(ar); i++) {
- char *dir = SvPVx(*av_fetch(ar, i, TRUE), n_a);
+ SV *dirsv = *av_fetch(ar, i, TRUE);
+
+ if (SvROK(dirsv)) {
+ int count;
+ SV *loader = dirsv;
+
+ if (SvTYPE(SvRV(loader)) == SVt_PVAV) {
+ loader = *av_fetch((AV *)SvRV(loader), 0, TRUE);
+ }
+
+ Perl_sv_setpvf(aTHX_ namesv, "/loader/0x%lx/%s",
+ SvANY(loader), name);
+ tryname = SvPVX(namesv);
+ tryrsfp = 0;
+
+ ENTER;
+ SAVETMPS;
+ EXTEND(SP, 2);
+
+ PUSHMARK(SP);
+ PUSHs(dirsv);
+ PUSHs(sv);
+ PUTBACK;
+ count = call_sv(loader, G_ARRAY);
+ SPAGAIN;
+
+ if (count > 0) {
+ int i = 0;
+ SV *arg;
+
+ SP -= count - 1;
+ arg = SP[i++];
+
+ if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVGV) {
+ arg = SvRV(arg);
+ }
+
+ if (SvTYPE(arg) == SVt_PVGV) {
+ IO *io = GvIO((GV *)arg);
+
+ ++filter_has_file;
+
+ if (io) {
+ tryrsfp = IoIFP(io);
+ if (IoTYPE(io) == '|') {
+ /* reading from a child process doesn't
+ nest -- when returning from reading
+ the inner module, the outer one is
+ unreadable (closed?) I've tried to
+ save the gv to manage the lifespan of
+ the pipe, but this didn't help. XXX */
+ filter_child_proc = (GV *)arg;
+ (void)SvREFCNT_inc(filter_child_proc);
+ }
+ else {
+ if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
+ PerlIO_close(IoOFP(io));
+ }
+ IoIFP(io) = Nullfp;
+ IoOFP(io) = Nullfp;
+ }
+ }
+
+ if (i < count) {
+ arg = SP[i++];
+ }
+ }
+
+ if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) {
+ filter_sub = arg;
+ (void)SvREFCNT_inc(filter_sub);
+
+ if (i < count) {
+ filter_state = SP[i];
+ (void)SvREFCNT_inc(filter_state);
+ }
+
+ if (tryrsfp == 0) {
+ tryrsfp = PerlIO_open("/dev/null",
+ PERL_SCRIPT_MODE);
+ }
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ if (tryrsfp) {
+ break;
+ }
+
+ filter_has_file = 0;
+ if (filter_child_proc) {
+ SvREFCNT_dec(filter_child_proc);
+ filter_child_proc = 0;
+ }
+ if (filter_state) {
+ SvREFCNT_dec(filter_state);
+ filter_state = 0;
+ }
+ if (filter_sub) {
+ SvREFCNT_dec(filter_sub);
+ filter_sub = 0;
+ }
+ }
+ else {
+ char *dir = SvPVx(dirsv, n_a);
#ifdef VMS
- char *unixdir;
- if ((unixdir = tounixpath(dir, Nullch)) == Nullch)
- continue;
- sv_setpv(namesv, unixdir);
- sv_catpv(namesv, unixname);
+ char *unixdir;
+ if ((unixdir = tounixpath(dir, Nullch)) == Nullch)
+ continue;
+ sv_setpv(namesv, unixdir);
+ sv_catpv(namesv, unixname);
#else
- Perl_sv_setpvf(aTHX_ namesv, "%s/%s", dir, name);
+ Perl_sv_setpvf(aTHX_ namesv, "%s/%s", dir, name);
#endif
- TAINT_PROPER("require");
- tryname = SvPVX(namesv);
- tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
- if (tryrsfp) {
- if (tryname[0] == '.' && tryname[1] == '/')
- tryname += 2;
- break;
+ TAINT_PROPER("require");
+ tryname = SvPVX(namesv);
+ tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
+ if (tryrsfp) {
+ if (tryname[0] == '.' && tryname[1] == '/')
+ tryname += 2;
+ break;
+ }
}
}
}
SAVEHINTS();
PL_hints = 0;
SAVEPPTR(PL_compiling.cop_warnings);
- PL_compiling.cop_warnings = ((PL_dowarn & G_WARN_ALL_ON) ? WARN_ALL
- : WARN_NONE);
-
- /* switch to eval mode */
+ 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 ;
+
+ if (filter_sub || filter_child_proc) {
+ SV *datasv = filter_add(run_user_filter, Nullsv);
+ IoLINES(datasv) = filter_has_file;
+ IoFMT_GV(datasv) = (GV *)filter_child_proc;
+ IoTOP_GV(datasv) = (GV *)filter_state;
+ IoBOTTOM_GV(datasv) = (GV *)filter_sub;
+ }
+ /* switch to eval mode */
push_return(PL_op->op_next);
PUSHBLOCK(cx, CXt_EVAL, SP);
PUSHEVAL(cx, name, PL_compiling.cop_filegv);
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) ;
}
/* 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++;
/* 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);
+}
+
+static I32
+run_user_filter(pTHXo_ int idx, SV *buf_sv, int maxlen)
+{
+ SV *datasv = FILTER_DATA(idx);
+ int filter_has_file = IoLINES(datasv);
+ GV *filter_child_proc = (GV *)IoFMT_GV(datasv);
+ SV *filter_state = (SV *)IoTOP_GV(datasv);
+ SV *filter_sub = (SV *)IoBOTTOM_GV(datasv);
+ int len = 0;
+
+ /* I was having segfault trouble under Linux 2.2.5 after a
+ parse error occured. (Had to hack around it with a test
+ for PL_error_count == 0.) Solaris doesn't segfault --
+ not sure where the trouble is yet. XXX */
+
+ if (filter_has_file) {
+ len = FILTER_READ(idx+1, buf_sv, maxlen);
+ }
+
+ if (filter_sub && len >= 0) {
+ djSP;
+ int count;
+
+ ENTER;
+ SAVE_DEFSV;
+ SAVETMPS;
+ EXTEND(SP, 2);
+
+ DEFSV = buf_sv;
+ PUSHMARK(SP);
+ PUSHs(sv_2mortal(newSViv(maxlen)));
+ if (filter_state) {
+ PUSHs(filter_state);
+ }
+ PUTBACK;
+ count = call_sv(filter_sub, G_SCALAR);
+ SPAGAIN;
+
+ if (count > 0) {
+ SV *out = POPs;
+ if (SvOK(out)) {
+ len = SvIV(out);
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ if (len <= 0) {
+ IoLINES(datasv) = 0;
+ if (filter_child_proc) {
+ SvREFCNT_dec(filter_child_proc);
+ IoFMT_GV(datasv) = Nullgv;
+ }
+ if (filter_state) {
+ SvREFCNT_dec(filter_state);
+ IoTOP_GV(datasv) = Nullgv;
+ }
+ if (filter_sub) {
+ SvREFCNT_dec(filter_sub);
+ IoBOTTOM_GV(datasv) = Nullgv;
+ }
+ filter_del(run_user_filter);
+ }
+
+ return len;
+}
+
+#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 */