* floating-point type to use for NV that has adequate bits to fully
* hold an IV/UV. (In other words, sizeof(long) == sizeof(double).)
*
- * It just so happens that "int" is the right size everywhere, at
- * least today.
+ * It just so happens that "int" is the right size almost everywhere.
*/
typedef int IBW;
typedef unsigned UBW;
+/*
+ * Mask used after bitwise operations.
+ *
+ * There is at least one realm (Cray word machines) that doesn't
+ * have an integral type (except char) small enough to be represented
+ * in a double without loss; that is, it has no 32-bit type.
+ */
+#if BYTEORDER > 0xFFFF && defined(_CRAY) && !defined(_CRAYMPP)
+# define BW_BITS 32
+# define BW_MASK ((1 << BW_BITS) - 1)
+# define BW_SIGN (1 << (BW_BITS - 1))
+# define BWi(i) (((i) & BW_SIGN) ? ((i) | ~BW_MASK) : ((i) & BW_MASK))
+# define BWu(u) ((u) & BW_MASK)
+#else
+# define BWi(i) (i)
+# define BWu(u) (u)
+#endif
+
+/*
+ * Offset for integer pack/unpack.
+ *
+ * On architectures where I16 and I32 aren't really 16 and 32 bits,
+ * which for now are all Crays, pack and unpack have to play games.
+ */
+
+/*
+ * These values are required for portability of pack() output.
+ * If they're not right on your machine, then pack() and unpack()
+ * wouldn't work right anyway; you'll need to apply the Cray hack.
+ * (I'd like to check them with #if, but you can't use sizeof() in
+ * the preprocessor.)
+ */
+#define SIZE16 2
+#define SIZE32 4
+
+#if BYTEORDER > 0xFFFF && defined(_CRAY) && !defined(_CRAYMPP)
+# if BYTEORDER == 0x12345678
+# define OFF16(p) (char*)(p)
+# define OFF32(p) (char*)(p)
+# else
+# if BYTEORDER == 0x87654321
+# define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16))
+# define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32))
+# else
+ }}}} bad cray byte order
+# endif
+# endif
+# define COPY16(s,p) (*(p) = 0, Copy(s, OFF16(p), SIZE16, char))
+# define COPY32(s,p) (*(p) = 0, Copy(s, OFF32(p), SIZE32, char))
+# define CAT16(sv,p) sv_catpvn(sv, OFF16(p), SIZE16)
+# define CAT32(sv,p) sv_catpvn(sv, OFF32(p), SIZE32)
+#else
+# define COPY16(s,p) Copy(s, p, SIZE16, char)
+# define COPY32(s,p) Copy(s, p, SIZE32, char)
+# define CAT16(sv,p) sv_catpvn(sv, (char*)(p), SIZE16)
+# define CAT32(sv,p) sv_catpvn(sv, (char*)(p), SIZE32)
+#endif
+
static void doencodes _((SV* sv, char* s, I32 len));
static SV* refto _((SV* sv));
static U32 seed _((void));
PP(pp_stub)
{
dSP;
- if (GIMME != G_ARRAY) {
+ if (GIMME_V == G_SCALAR)
XPUSHs(&sv_undef);
- }
RETURN;
}
PP(pp_padhv)
{
dSP; dTARGET;
+ I32 gimme;
+
XPUSHs(TARG);
if (op->op_private & OPpLVAL_INTRO)
SAVECLEARSV(curpad[op->op_targ]);
if (op->op_flags & OPf_REF)
RETURN;
- if (GIMME == G_ARRAY) { /* array wanted */
+ gimme = GIMME_V;
+ if (gimme == G_ARRAY) {
RETURNOP(do_kv(ARGS));
}
- else {
+ else if (gimme == G_SCALAR) {
SV* sv = sv_newmortal();
- if (HvFILL((HV*)TARG)) {
- sprintf(buf, "%ld/%ld",
- (long)HvFILL((HV*)TARG), (long)HvMAX((HV*)TARG)+1);
- sv_setpv(sv, buf);
- }
+ if (HvFILL((HV*)TARG))
+ sv_setpvf(sv, "%ld/%ld",
+ (long)HvFILL((HV*)TARG), (long)HvMAX((HV*)TARG) + 1);
else
sv_setiv(sv, 0);
SETs(sv);
- RETURN;
}
+ RETURN;
}
PP(pp_padany)
if (op->op_private & OPpLVAL_INTRO)
sv = save_scalar((GV*)TOPs);
else if (op->op_private & OPpDEREF)
- provide_ref(op, sv);
+ vivify_ref(sv, op->op_private & OPpDEREF);
}
SETs(sv);
RETURN;
if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
if (LvTARGLEN(sv))
- vivify_itervar(sv);
- if (LvTARG(sv))
- sv = LvTARG(sv);
+ vivify_defelem(sv);
+ if (!(sv = LvTARG(sv)))
+ sv = &sv_undef;
}
else if (SvPADTMP(sv))
sv = newSVsv(sv);
hv_undef((HV*)sv);
break;
case SVt_PVCV:
- if (!CvANON((CV*)sv) && cv_const_sv((CV*)sv))
+ if (cv_const_sv((CV*)sv))
warn("Constant subroutine %s undefined",
- GvENAME(CvGV((CV*)sv)));
+ CvANON((CV*)sv) ? "(anonymous)" : GvENAME(CvGV((CV*)sv)));
/* FALL THROUGH */
case SVt_PVFM:
- cv_undef((CV*)sv);
+ { GV* gv = (GV*)SvREFCNT_inc(CvGV((CV*)sv));
+ cv_undef((CV*)sv);
+ CvGV((CV*)sv) = gv; } /* let user-undef'd sub keep its identity */
break;
case SVt_PVGV:
if (SvFAKE(sv))
PP(pp_predec)
{
dSP;
- if (SvREADONLY(TOPs))
+ if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
croak(no_modify);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MIN)
PP(pp_postinc)
{
dSP; dTARGET;
- if (SvREADONLY(TOPs))
+ if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
PP(pp_postdec)
{
dSP; dTARGET;
- if(SvREADONLY(TOPs))
+ if(SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
{
dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
{
- register UV right;
+ UV left;
+ UV right;
+ bool left_neg;
+ bool right_neg;
+ UV ans;
- right = POPu;
- if (!right)
- DIE("Illegal modulus zero");
+ if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
+ IV i = SvIVX(POPs);
+ right = (right_neg = (i < 0)) ? -i : i;
+ }
+ else {
+ double n = POPn;
+ right = U_V((right_neg = (n < 0)) ? -n : n);
+ }
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
- register IV left = SvIVX(TOPs);
- if (left < 0)
- SETu( (right - ((UV)(-left) - 1) % right) - 1 );
- else
- SETi( left % right );
+ IV i = SvIVX(POPs);
+ left = (left_neg = (i < 0)) ? -i : i;
}
else {
- register double left = TOPn;
- if (left < 0.0)
- SETu( (right - (U_V(-left) - 1) % right) - 1 );
+ double n = POPn;
+ left = U_V((left_neg = (n < 0)) ? -n : n);
+ }
+
+ if (!right)
+ DIE("Illegal modulus zero");
+
+ ans = left % right;
+ if ((left_neg != right_neg) && ans)
+ ans = right - ans;
+ if (right_neg) {
+ if (ans <= -(UV)IV_MAX)
+ sv_setiv(TARG, (IV) -ans);
else
- SETu( U_V(left) % right );
+ sv_setnv(TARG, -(double)ans);
}
+ else
+ sv_setuv(TARG, ans);
+ PUSHTARG;
RETURN;
}
}
IBW shift = POPi;
if (op->op_private & HINT_INTEGER) {
IBW i = TOPi;
- SETi( i << shift );
+ i = BWi(i) << shift;
+ SETi(BWi(i));
}
else {
UBW u = TOPu;
- SETu( u << shift );
+ u <<= shift;
+ SETu(BWu(u));
}
RETURN;
}
IBW shift = POPi;
if (op->op_private & HINT_INTEGER) {
IBW i = TOPi;
- SETi( i >> shift );
+ i = BWi(i) >> shift;
+ SETi(BWi(i));
}
else {
UBW u = TOPu;
- SETu( u >> shift );
+ u >>= shift;
+ SETu(BWu(u));
}
RETURN;
}
dSP; tryAMAGICbinSET(lt,0);
{
dPOPnv;
- SETs((TOPn < value) ? &sv_yes : &sv_no);
+ SETs(boolSV(TOPn < value));
RETURN;
}
}
dSP; tryAMAGICbinSET(gt,0);
{
dPOPnv;
- SETs((TOPn > value) ? &sv_yes : &sv_no);
+ SETs(boolSV(TOPn > value));
RETURN;
}
}
dSP; tryAMAGICbinSET(le,0);
{
dPOPnv;
- SETs((TOPn <= value) ? &sv_yes : &sv_no);
+ SETs(boolSV(TOPn <= value));
RETURN;
}
}
dSP; tryAMAGICbinSET(ge,0);
{
dPOPnv;
- SETs((TOPn >= value) ? &sv_yes : &sv_no);
+ SETs(boolSV(TOPn >= value));
RETURN;
}
}
dSP; tryAMAGICbinSET(ne,0);
{
dPOPnv;
- SETs((TOPn != value) ? &sv_yes : &sv_no);
+ SETs(boolSV(TOPn != value));
RETURN;
}
}
int cmp = ((op->op_private & OPpLOCALE)
? sv_cmp_locale(left, right)
: sv_cmp(left, right));
- SETs( cmp < 0 ? &sv_yes : &sv_no );
+ SETs(boolSV(cmp < 0));
RETURN;
}
}
int cmp = ((op->op_private & OPpLOCALE)
? sv_cmp_locale(left, right)
: sv_cmp(left, right));
- SETs( cmp > 0 ? &sv_yes : &sv_no );
+ SETs(boolSV(cmp > 0));
RETURN;
}
}
int cmp = ((op->op_private & OPpLOCALE)
? sv_cmp_locale(left, right)
: sv_cmp(left, right));
- SETs( cmp <= 0 ? &sv_yes : &sv_no );
+ SETs(boolSV(cmp <= 0));
RETURN;
}
}
int cmp = ((op->op_private & OPpLOCALE)
? sv_cmp_locale(left, right)
: sv_cmp(left, right));
- SETs( cmp >= 0 ? &sv_yes : &sv_no );
+ SETs(boolSV(cmp >= 0));
RETURN;
}
}
dSP; tryAMAGICbinSET(seq,0);
{
dPOPTOPssrl;
- SETs( sv_eq(left, right) ? &sv_yes : &sv_no );
+ SETs(boolSV(sv_eq(left, right)));
RETURN;
}
}
dSP; tryAMAGICbinSET(sne,0);
{
dPOPTOPssrl;
- SETs( !sv_eq(left, right) ? &sv_yes : &sv_no );
+ SETs(boolSV(!sv_eq(left, right)));
RETURN;
}
}
if (SvNIOKp(left) || SvNIOKp(right)) {
if (op->op_private & HINT_INTEGER) {
IBW value = SvIV(left) & SvIV(right);
- SETi( value );
+ SETi(BWi(value));
}
else {
UBW value = SvUV(left) & SvUV(right);
- SETu( value );
+ SETu(BWu(value));
}
}
else {
if (SvNIOKp(left) || SvNIOKp(right)) {
if (op->op_private & HINT_INTEGER) {
IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right);
- SETi( value );
+ SETi(BWi(value));
}
else {
UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right);
- SETu( value );
+ SETu(BWu(value));
}
}
else {
if (SvNIOKp(left) || SvNIOKp(right)) {
if (op->op_private & HINT_INTEGER) {
IBW value = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right);
- SETi( value );
+ SETi(BWi(value));
}
else {
UBW value = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right);
- SETu( value );
+ SETu(BWu(value));
}
}
else {
#ifdef OVERLOAD
dSP; tryAMAGICunSET(not);
#endif /* OVERLOAD */
- *stack_sp = SvTRUE(*stack_sp) ? &sv_no : &sv_yes;
+ *stack_sp = boolSV(!SvTRUE(*stack_sp));
return NORMAL;
}
if (SvNIOKp(sv)) {
if (op->op_private & HINT_INTEGER) {
IBW value = ~SvIV(sv);
- SETi( value );
+ SETi(BWi(value));
}
else {
UBW value = ~SvUV(sv);
- SETu( value );
+ SETu(BWu(value));
}
}
else {
dSP; tryAMAGICbinSET(lt,0);
{
dPOPTOPiirl;
- SETs((left < right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left < right));
RETURN;
}
}
dSP; tryAMAGICbinSET(gt,0);
{
dPOPTOPiirl;
- SETs((left > right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left > right));
RETURN;
}
}
dSP; tryAMAGICbinSET(le,0);
{
dPOPTOPiirl;
- SETs((left <= right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left <= right));
RETURN;
}
}
dSP; tryAMAGICbinSET(ge,0);
{
dPOPTOPiirl;
- SETs((left >= right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left >= right));
RETURN;
}
}
dSP; tryAMAGICbinSET(eq,0);
{
dPOPTOPiirl;
- SETs((left == right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left == right));
RETURN;
}
}
dSP; tryAMAGICbinSET(ne,0);
{
dPOPTOPiirl;
- SETs((left != right) ? &sv_yes : &sv_no);
+ SETs(boolSV(left != right));
RETURN;
}
}
static U32
seed()
{
+ /*
+ * This is really just a quick hack which grabs various garbage
+ * values. It really should be a real hash algorithm which
+ * spreads the effect of every input bit onto every output bit,
+ * if someone who knows about such tings would bother to write it.
+ * Might be a good idea to add that function to CORE as well.
+ * No numbers below come from careful analysis or anyting here,
+ * except they are primes and SEED_C1 > 1E6 to get a full-width
+ * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should
+ * probably be bigger too.
+ */
+#if RANDBITS > 16
+# define SEED_C1 1000003
+#define SEED_C4 73819
+#else
+# define SEED_C1 25747
+#define SEED_C4 20639
+#endif
+#define SEED_C2 3
+#define SEED_C3 269
+#define SEED_C5 26107
+
U32 u;
#ifdef VMS
# include <starlet.h>
+ /* when[] = (low 32 bits, high 32 bits) of time since epoch
+ * in 100-ns units, typically incremented ever 10 ms. */
unsigned int when[2];
_ckvmssts(sys$gettim(when));
- u = when[0] ^ when[1];
+ u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1];
#else
# ifdef HAS_GETTIMEOFDAY
struct timeval when;
gettimeofday(&when,(struct timezone *) 0);
- u = when.tv_sec ^ when.tv_usec;
+ u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec;
# else
Time_t when;
(void)time(&when);
- u = when;
+ u = (U32)SEED_C1 * when;
# endif
#endif
-#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));
+ u += SEED_C3 * (U32)getpid();
+ u += SEED_C4 * (U32)(UV)stack_sp;
+#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
+ u += SEED_C5 * (U32)(UV)&when;
#endif
return u;
}
pos = POPi - arybase;
sv = POPs;
tmps = SvPV(sv, curlen);
- if (pos < 0)
+ if (pos < 0) {
pos += curlen + arybase;
+ if (pos < 0 && MAXARG < 3)
+ pos = 0;
+ }
if (pos < 0 || pos > curlen) {
if (dowarn || lvalue)
warn("substr outside of string");
dSP; dTARGET;
HV *hash = (HV*)POPs;
HE *entry;
+ I32 gimme = GIMME_V;
PUTBACK;
- entry = hv_iternext(hash); /* might clobber stack_sp */
+ entry = hv_iternext(hash); /* might clobber stack_sp */
SPAGAIN;
EXTEND(SP, 2);
if (entry) {
- PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
- if (GIMME == G_ARRAY) {
+ PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */
+ if (gimme == G_ARRAY) {
PUTBACK;
- sv_setsv(TARG, hv_iterval(hash, entry)); /* might clobber stack_sp */
+ sv_setsv(TARG, hv_iterval(hash, entry)); /* might hit stack_sp */
SPAGAIN;
PUSHs(TARG);
}
}
- else if (GIMME == G_SCALAR)
+ else if (gimme == G_SCALAR)
RETPUSHUNDEF;
RETURN;
PP(pp_delete)
{
dSP;
+ I32 gimme = GIMME_V;
+ I32 discard = (gimme == G_VOID) ? G_DISCARD : 0;
SV *sv;
HV *hv;
if (SvTYPE(hv) != SVt_PVHV)
DIE("Not a HASH reference");
while (++MARK <= SP) {
- sv = hv_delete_ent(hv, *MARK,
- (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+ sv = hv_delete_ent(hv, *MARK, discard, 0);
*MARK = sv ? sv : &sv_undef;
}
- if (GIMME != G_ARRAY) {
+ if (discard)
+ SP = ORIGMARK;
+ else if (gimme == G_SCALAR) {
MARK = ORIGMARK;
*++MARK = *SP;
SP = MARK;
hv = (HV*)POPs;
if (SvTYPE(hv) != SVt_PVHV)
DIE("Not a HASH reference");
- sv = hv_delete_ent(hv, keysv,
- (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+ sv = hv_delete_ent(hv, keysv, discard, 0);
if (!sv)
sv = &sv_undef;
- PUSHs(sv);
+ if (!discard)
+ PUSHs(sv);
}
RETURN;
}
if (SP - MARK > 1)
do_join(TARG, &sv_no, MARK, SP);
else
- sv_setsv(TARG, *SP);
+ sv_setsv(TARG, (SP > MARK) ? *SP : GvSV(defgv));
up = SvPV_force(TARG, len);
if (len > 1) {
down = SvPVX(TARG) + len - 1;
dSP;
dPOPPOPssrl;
SV **oldsp = sp;
+ I32 gimme = GIMME_V;
SV *sv;
STRLEN llen;
STRLEN rlen;
double cdouble;
static char* bitcount = 0;
- if (GIMME != G_ARRAY) { /* arrange to do first one only */
+ if (gimme != G_ARRAY) { /* arrange to do first one only */
/*SUPPRESS 530*/
for (patend = pat; !isALPHA(*patend) || *patend == 'x'; patend++) ;
if (strchr("aAbBhHP", *patend) || *pat == '%') {
}
while (pat < patend) {
reparse:
- datumtype = *pat++;
+ datumtype = *pat++ & 0xFF;
+ if (isSPACE(datumtype))
+ continue;
if (pat >= patend)
len = 1;
else if (*pat == '*') {
len = (datumtype != '@');
switch(datumtype) {
default:
- break;
+ croak("Invalid type in unpack: '%c'", (int)datumtype);
case '%':
if (len == 1 && pat[-1] != '1')
len = 16;
}
break;
case 's':
- along = (strend - s) / sizeof(I16);
+ along = (strend - s) / SIZE16;
if (len > along)
len = along;
if (checksum) {
while (len-- > 0) {
- Copy(s, &ashort, 1, I16);
- s += sizeof(I16);
+ COPY16(s, &ashort);
+ s += SIZE16;
culong += ashort;
}
}
EXTEND(SP, len);
EXTEND_MORTAL(len);
while (len-- > 0) {
- Copy(s, &ashort, 1, I16);
- s += sizeof(I16);
+ COPY16(s, &ashort);
+ s += SIZE16;
sv = NEWSV(38, 0);
sv_setiv(sv, (IV)ashort);
PUSHs(sv_2mortal(sv));
case 'v':
case 'n':
case 'S':
- along = (strend - s) / sizeof(U16);
+ along = (strend - s) / SIZE16;
if (len > along)
len = along;
if (checksum) {
while (len-- > 0) {
- Copy(s, &aushort, 1, U16);
- s += sizeof(U16);
+ COPY16(s, &aushort);
+ s += SIZE16;
#ifdef HAS_NTOHS
if (datumtype == 'n')
aushort = ntohs(aushort);
EXTEND(SP, len);
EXTEND_MORTAL(len);
while (len-- > 0) {
- Copy(s, &aushort, 1, U16);
- s += sizeof(U16);
+ COPY16(s, &aushort);
+ s += SIZE16;
sv = NEWSV(39, 0);
#ifdef HAS_NTOHS
if (datumtype == 'n')
}
break;
case 'l':
- along = (strend - s) / sizeof(I32);
+ along = (strend - s) / SIZE32;
if (len > along)
len = along;
if (checksum) {
while (len-- > 0) {
- Copy(s, &along, 1, I32);
- s += sizeof(I32);
+ COPY32(s, &along);
+ s += SIZE32;
if (checksum > 32)
cdouble += (double)along;
else
EXTEND(SP, len);
EXTEND_MORTAL(len);
while (len-- > 0) {
- Copy(s, &along, 1, I32);
- s += sizeof(I32);
+ COPY32(s, &along);
+ s += SIZE32;
sv = NEWSV(42, 0);
sv_setiv(sv, (IV)along);
PUSHs(sv_2mortal(sv));
case 'V':
case 'N':
case 'L':
- along = (strend - s) / sizeof(U32);
+ along = (strend - s) / SIZE32;
if (len > along)
len = along;
if (checksum) {
while (len-- > 0) {
- Copy(s, &aulong, 1, U32);
- s += sizeof(U32);
+ COPY32(s, &aulong);
+ s += SIZE32;
#ifdef HAS_NTOHL
if (datumtype == 'N')
aulong = ntohl(aulong);
EXTEND(SP, len);
EXTEND_MORTAL(len);
while (len-- > 0) {
- Copy(s, &aulong, 1, U32);
- s += sizeof(U32);
+ COPY32(s, &aulong);
+ s += SIZE32;
#ifdef HAS_NTOHL
if (datumtype == 'N')
aulong = ntohl(aulong);
auv = 0;
}
else if (++bytes >= sizeof(UV)) { /* promote to string */
- char decn[sizeof(UV) * 3 + 1];
char *t;
- (void) sprintf(decn, "%0*ld",
- (int)sizeof(decn) - 1, auv);
- sv = newSVpv(decn, 0);
+ sv = newSVpvf("%.*Vu", (int)TYPE_DIGITS(UV), auv);
while (s < strend) {
sv = mul128(sv, *s & 0x7f);
if (!(*s++ & 0x80)) {
s += sizeof(Quad_t);
}
sv = NEWSV(42, 0);
- sv_setiv(sv, (IV)aquad);
+ if (aquad >= IV_MIN && aquad <= IV_MAX)
+ sv_setiv(sv, (IV)aquad);
+ else
+ sv_setnv(sv, (double)aquad);
PUSHs(sv_2mortal(sv));
}
break;
s += sizeof(unsigned Quad_t);
}
sv = NEWSV(43, 0);
- sv_setuv(sv, (UV)auquad);
+ if (aquad <= UV_MAX)
+ sv_setuv(sv, (UV)auquad);
+ else
+ sv_setnv(sv, (double)auquad);
PUSHs(sv_2mortal(sv));
}
break;
}
else {
if (checksum < 32) {
- along = (1 << checksum) - 1;
- culong &= (U32)along;
+ aulong = (1 << checksum) - 1;
+ culong &= aulong;
}
- sv_setnv(sv, (double)culong);
+ sv_setuv(sv, (UV)culong);
}
XPUSHs(sv_2mortal(sv));
checksum = 0;
}
}
- if (sp == oldsp && GIMME != G_ARRAY)
+ if (sp == oldsp && gimme == G_SCALAR)
PUSHs(&sv_undef);
RETURN;
}
sv_setpvn(cat, "", 0);
while (pat < patend) {
#define NEXTFROM (items-- > 0 ? *MARK++ : &sv_no)
- datumtype = *pat++;
+ datumtype = *pat++ & 0xFF;
+ if (isSPACE(datumtype))
+ continue;
if (*pat == '*') {
len = strchr("@Xxu", datumtype) ? 0 : items;
pat++;
len = 1;
switch(datumtype) {
default:
- break;
+ croak("Invalid type in pack: '%c'", (int)datumtype);
case '%':
DIE("%% may only be used in unpack");
case '@':
#ifdef HAS_HTONS
ashort = htons(ashort);
#endif
- sv_catpvn(cat, (char*)&ashort, sizeof(I16));
+ CAT16(cat, &ashort);
}
break;
case 'v':
#ifdef HAS_HTOVS
ashort = htovs(ashort);
#endif
- sv_catpvn(cat, (char*)&ashort, sizeof(I16));
+ CAT16(cat, &ashort);
}
break;
case 'S':
while (len-- > 0) {
fromstr = NEXTFROM;
ashort = (I16)SvIV(fromstr);
- sv_catpvn(cat, (char*)&ashort, sizeof(I16));
+ CAT16(cat, &ashort);
}
break;
case 'I':
while (len-- > 0) {
fromstr = NEXTFROM;
- auint = U_I(SvNV(fromstr));
+ auint = SvUV(fromstr);
sv_catpvn(cat, (char*)&auint, sizeof(unsigned int));
}
break;
if (adouble < 0)
croak("Cannot compress negative numbers");
- if (adouble <= UV_MAX) {
+ if (
+#ifdef BW_BITS
+ adouble <= BW_MASK
+#else
+ adouble <= UV_MAX
+#endif
+ )
+ {
char buf[1 + sizeof(UV)];
char *in = buf + sizeof(buf);
UV auv = U_V(adouble);;
case 'N':
while (len-- > 0) {
fromstr = NEXTFROM;
- aulong = U_L(SvNV(fromstr));
+ aulong = SvUV(fromstr);
#ifdef HAS_HTONL
aulong = htonl(aulong);
#endif
- sv_catpvn(cat, (char*)&aulong, sizeof(U32));
+ CAT32(cat, &aulong);
}
break;
case 'V':
while (len-- > 0) {
fromstr = NEXTFROM;
- aulong = U_L(SvNV(fromstr));
+ aulong = SvUV(fromstr);
#ifdef HAS_HTOVL
aulong = htovl(aulong);
#endif
- sv_catpvn(cat, (char*)&aulong, sizeof(U32));
+ CAT32(cat, &aulong);
}
break;
case 'L':
while (len-- > 0) {
fromstr = NEXTFROM;
- aulong = U_L(SvNV(fromstr));
- sv_catpvn(cat, (char*)&aulong, sizeof(U32));
+ aulong = SvUV(fromstr);
+ CAT32(cat, &aulong);
}
break;
case 'l':
while (len-- > 0) {
fromstr = NEXTFROM;
along = SvIV(fromstr);
- sv_catpvn(cat, (char*)&along, sizeof(I32));
+ CAT32(cat, &along);
}
break;
#ifdef HAS_QUAD
I32 realarray = 0;
I32 base;
AV *oldstack = curstack;
- I32 gimme = GIMME;
+ I32 gimme = GIMME_V;
I32 oldsave = savestack_ix;
#ifdef DEBUGGING