typedef int IBW;
typedef unsigned UBW;
-static SV* refto _((SV* sv));
static void doencodes _((SV* sv, char* s, I32 len));
+static SV* refto _((SV* sv));
+static U32 seed _((void));
+
+static bool srand_called = FALSE;
/* variations on pp_null */
/* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
/* (But not in defined().) */
CV *cv = sv_2cv(TOPs, &stash, &gv, !(op->op_flags & OPf_SPECIAL));
-
- if (!cv)
+ if (cv) {
+ if (CvCLONE(cv))
+ cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
+ }
+ else
cv = (CV*)&sv_undef;
SETs((SV*)cv);
RETURN;
dSP;
SV *sv;
- if (!op->op_private)
+ if (!op->op_private) {
+ EXTEND(SP, 1);
RETPUSHUNDEF;
+ }
sv = POPs;
if (!sv)
break;
case SVt_PVCV:
cv_undef((CV*)sv);
- sub_generation++;
break;
case SVt_PVGV:
- if (SvFAKE(sv)) {
- sv_setsv(sv, &sv_undef);
- break;
- }
+ if (SvFAKE(sv))
+ sv_setsv(sv, &sv_undef);
+ break;
default:
- if (SvPOK(sv) && SvLEN(sv)) {
+ if (SvTYPE(sv) >= SVt_PV && SvPVX(sv) && SvLEN(sv)) {
(void)SvOOK_off(sv);
Safefree(SvPVX(sv));
SvPV_set(sv, Nullch);
PP(pp_predec)
{
dSP;
+ if (SvREADONLY(TOPs))
+ croak(no_modify);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MIN)
{
PP(pp_postinc)
{
dSP; dTARGET;
+ if (SvREADONLY(TOPs))
+ croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MAX)
PP(pp_postdec)
{
dSP; dTARGET;
+ if(SvREADONLY(TOPs))
+ croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MIN)
{
dSP; dATARGET; tryAMAGICbin(pow,opASSIGN);
{
- dPOPTOPnnrl_ul;
+ dPOPTOPnnrl;
SETn( pow( left, right) );
RETURN;
}
{
dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
{
- dPOPTOPnnrl_ul;
+ dPOPTOPnnrl;
SETn( left * right );
RETURN;
}
{
dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
{
- dPOPPOPnnrl_ul;
+ dPOPPOPnnrl;
double value;
if (right == 0.0)
DIE("Illegal division by zero");
SETi( left % right );
}
else {
- register double left = USE_LEFT(TOPs) ? SvNV(TOPs) : 0.0;
+ register double left = TOPn;
if (left < 0.0)
SETu( (right - (U_V(-left) - 1) % right) - 1 );
else
if (SvROK(tmpstr))
sv_unref(tmpstr);
}
- if (USE_LEFT(tmpstr) || SvTYPE(tmpstr) > SVt_PVMG) {
- SvSetSV(TARG, tmpstr);
- SvPV_force(TARG, len);
- if (count != 1) {
- if (count < 1)
- SvCUR_set(TARG, 0);
- else {
- SvGROW(TARG, (count * len) + 1);
- repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
- SvCUR(TARG) *= count;
- }
- *SvEND(TARG) = '\0';
+ SvSetSV(TARG, tmpstr);
+ SvPV_force(TARG, len);
+ if (count != 1) {
+ if (count < 1)
+ SvCUR_set(TARG, 0);
+ else {
+ SvGROW(TARG, (count * len) + 1);
+ repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
+ SvCUR(TARG) *= count;
}
- (void)SvPOK_only(TARG);
+ *SvEND(TARG) = '\0';
}
- else
- sv_setsv(TARG, &sv_no);
+ (void)SvPOK_only(TARG);
PUSHTARG;
}
RETURN;
dPOPTOPnnrl;
I32 value;
- if (left > right)
- value = 1;
+ if (left == right)
+ value = 0;
else if (left < right)
value = -1;
- else
- value = 0;
+ else if (left > right)
+ value = 1;
+ else {
+ SETs(&sv_undef);
+ RETURN;
+ }
SETi(value);
RETURN;
}
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
if (op->op_private & HINT_INTEGER) {
- IBW value = SvIV(left) ^ SvIV(right);
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right);
SETi( value );
}
else {
- UBW value = SvUV(left) ^ SvUV(right);
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right);
SETu( value );
}
}
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
if (op->op_private & HINT_INTEGER) {
- IBW value = SvIV(left) | SvIV(right);
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right);
SETi( value );
}
else {
- UBW value = SvUV(left) | SvUV(right);
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right);
SETu( value );
}
}
dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
{
dPOPTOPiirl;
+ if (!right)
+ DIE("Illegal modulus zero");
SETi( left % right );
RETURN;
}
value = POPn;
if (value == 0.0)
value = 1.0;
+ if (!srand_called) {
+ (void)srand((unsigned)seed());
+ srand_called = TRUE;
+ }
#if RANDBITS == 31
value = rand() * value / 2147483648.0;
#else
PP(pp_srand)
{
dSP;
- I32 anum;
+ UV anum;
+ if (MAXARG < 1)
+ anum = seed();
+ else
+ anum = POPu;
+ (void)srand((unsigned)anum);
+ srand_called = TRUE;
+ EXTEND(SP, 1);
+ RETPUSHYES;
+}
- if (MAXARG < 1) {
+static U32
+seed()
+{
+ U32 u;
#ifdef VMS
# include <starlet.h>
- unsigned int when[2];
- _ckvmssts(sys$gettim(when));
- anum = when[0] ^ when[1];
+ unsigned int when[2];
+ _ckvmssts(sys$gettim(when));
+ u = when[0] ^ when[1];
#else
# ifdef HAS_GETTIMEOFDAY
- struct timeval when;
- gettimeofday(&when,(struct timezone *) 0);
- anum = when.tv_sec ^ when.tv_usec;
+ struct timeval when;
+ gettimeofday(&when,(struct timezone *) 0);
+ u = when.tv_sec ^ when.tv_usec;
# else
- Time_t when;
- (void)time(&when);
- anum = when;
+ Time_t when;
+ (void)time(&when);
+ u = when;
# endif
#endif
-#if !defined(PLAN9) /* XXX Plan9 assembler chokes on this; fix coming soon */
- /* 17-Jul-1996 bailey@genetics.upenn.edu */
- /* What is a good hashing algorithm here? */
- anum ^= ( ( 269 * (U32)getpid())
- ^ (26107 * (U32)&when)
- ^ (73819 * (U32)stack_sp));
+#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
+ /* What is a good hashing algorithm here? */
+ u ^= ( ( 269 * (U32)getpid())
+ ^ (26107 * (U32)&when)
+ ^ (73819 * (U32)stack_sp));
#endif
- }
- else
- anum = POPi;
- (void)srand(anum);
- EXTEND(SP, 1);
- RETPUSHYES;
+ return u;
}
PP(pp_exp)
PP(pp_int)
{
dSP; dTARGET;
- double value;
- value = POPn;
- if (value >= 0.0)
- (void)modf(value, &value);
- else {
- (void)modf(-value, &value);
- value = -value;
+ {
+ double value = TOPn;
+ IV iv;
+
+ if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs)) {
+ iv = SvIVX(TOPs);
+ SETi(iv);
+ }
+ else {
+ if (value >= 0.0)
+ (void)modf(value, &value);
+ else {
+ (void)modf(-value, &value);
+ value = -value;
+ }
+ iv = I_V(value);
+ if (iv == value)
+ SETi(iv);
+ else
+ SETn(value);
+ }
}
- XPUSHn(value);
RETURN;
}
{
dSP; dTARGET; tryAMAGICun(abs);
{
- double value;
- value = POPn;
-
- if (value < 0.0)
- value = -value;
-
- XPUSHn(value);
- RETURN;
+ double value = TOPn;
+ IV iv;
+
+ if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs) &&
+ (iv = SvIVX(TOPs)) != IV_MIN) {
+ if (iv < 0)
+ iv = -iv;
+ SETi(iv);
+ }
+ else {
+ if (value < 0.0)
+ value = -value;
+ SETn(value);
+ }
}
+ RETURN;
}
PP(pp_hex)
if (ix >= max || !(*lelem = firstrelem[ix]))
*lelem = &sv_undef;
}
- if (!is_something_there && (SvOKp(*lelem) || SvGMAGICAL(*lelem)))
+ if (!is_something_there && (SvOK(*lelem) || SvGMAGICAL(*lelem)))
is_something_there = TRUE;
}
if (is_something_there)
PP(pp_anonlist)
{
- dSP; dMARK;
+ dSP; dMARK; dORIGMARK;
I32 items = SP - MARK;
- SP = MARK;
- XPUSHs((SV*)sv_2mortal((SV*)av_make(items, MARK+1)));
+ SV *av = sv_2mortal((SV*)av_make(items, MARK+1));
+ SP = ORIGMARK; /* av_make() might realloc stack_sp */
+ XPUSHs(av);
RETURN;
}
STRLEN len;
register char *s = SvPV(sv, len);
char *strend = s + len;
- register PMOP *pm = (PMOP*)POPs;
+ register PMOP *pm;
+ register REGEXP *rx;
register SV *dstr;
register char *m;
I32 iters = 0;
I32 realarray = 0;
I32 base;
AV *oldstack = curstack;
- register REGEXP *rx = pm->op_pmregexp;
I32 gimme = GIMME;
I32 oldsave = savestack_ix;
+#ifdef DEBUGGING
+ Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
+#else
+ pm = (PMOP*)POPs;
+#endif
if (!pm || !s)
DIE("panic: do_split");
+ rx = pm->op_pmregexp;
TAINT_IF((pm->op_pmflags & PMf_LOCALE) &&
(pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE)));
s = m;
}
}
- else if (pm->op_pmshort) {
+ else if (pm->op_pmshort && !rx->nparens) {
i = SvCUR(pm->op_pmshort);
if (i == 1) {
i = *SvPVX(pm->op_pmshort);