char tmpbuf[64];
char *d = tmpbuf;
char *s;
- int i;
+ char *limit = tmpbuf + sizeof(tmpbuf) - 8;
+ /* each *s can expand to 4 chars + "...\0",
+ i.e. need room for 8 chars */
- for (s = SvPVX(sv), i = 50; *s && i; s++,i--) {
+ for (s = SvPVX(sv); *s && d < limit; s++) {
int ch = *s & 0xFF;
if (ch & 128 && !isPRINT_LC(ch)) {
*d++ = 'M';
register char *s;
register char *send;
register char *sbegin;
- I32 numtype = 1;
+ I32 numtype;
STRLEN len;
if (SvPOK(sv)) {
s = sbegin;
while (isSPACE(*s))
s++;
- if (s >= send)
- return 0;
if (*s == '+' || *s == '-')
s++;
- while (isDIGIT(*s))
- s++;
- if (s == send)
- return numtype;
- if (*s == '.') {
- numtype = 1;
- s++;
+
+ /* next must be digit or '.' */
+ if (isDIGIT(*s)) {
+ do {
+ s++;
+ } while (isDIGIT(*s));
+ if (*s == '.') {
+ s++;
+ while (isDIGIT(*s)) /* optional digits after "." */
+ s++;
+ }
}
- else if (s == SvPVX(sv))
- return 0;
- while (isDIGIT(*s))
- s++;
- if (s == send)
- return numtype;
+ else if (*s == '.') {
+ s++;
+ /* no digits before '.' means we need digits after it */
+ if (isDIGIT(*s)) {
+ do {
+ s++;
+ } while (isDIGIT(*s));
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+
+ /*
+ * we return 1 if the number can be converted to _integer_ with atol()
+ * and 2 if you need (int)atof().
+ */
+ numtype = 1;
+
+ /* we can have an optional exponent part */
if (*s == 'e' || *s == 'E') {
numtype = 2;
s++;
if (*s == '+' || *s == '-')
s++;
- while (isDIGIT(*s))
- s++;
+ if (isDIGIT(*s)) {
+ do {
+ s++;
+ } while (isDIGIT(*s));
+ }
+ else
+ return 0;
}
while (isSPACE(*s))
s++;
sv_upgrade(&ref, SVt_RV);
SvRV(&ref) = SvREFCNT_inc(sv);
SvROK_on(&ref);
+ SvREFCNT(&ref) = 1; /* Fake, but otherwise
+ creating+destructing a ref
+ leads to disaster. */
EXTEND(SP, 2);
PUSHMARK(SP);
Safefree(mg->mg_ptr);
s = SvPV(sv, len);
if ((xf = mem_collxfrm(s, len, &xlen))) {
+ if (SvREADONLY(sv)) {
+ SAVEFREEPV(xf);
+ *nxp = xlen;
+ return xf;
+ }
if (! mg) {
sv_magic(sv, 0, 'o', 0, 0);
mg = mg_find(sv, 'o');
mg->mg_len = xlen;
}
else {
- mg->mg_ptr = NULL;
- mg->mg_len = -1;
+ if (mg) {
+ mg->mg_ptr = NULL;
+ mg->mg_len = -1;
+ }
}
}
if (mg && mg->mg_ptr) {
if (SvFLAGS(ref) & (SVs_OBJECT|SVf_READONLY)) {
if (SvREADONLY(ref))
croak(no_modify);
- if (SvOBJECT(ref) && SvTYPE(ref) != SVt_PVIO)
- --sv_objcount;
+ if (SvOBJECT(ref)) {
+ if (SvTYPE(ref) != SVt_PVIO)
+ --sv_objcount;
+ SvREFCNT_dec(SvSTASH(ref));
+ }
}
SvOBJECT_on(ref);
- ++sv_objcount;
+ if (SvTYPE(ref) != SVt_PVIO)
+ ++sv_objcount;
(void)SvUPGRADE(ref, SVt_PVMG);
SvSTASH(ref) = (HV*)SvREFCNT_inc(stash);
#ifdef OVERLOAD
- SvAMAGIC_off(sv);
- if (Gv_AMG(stash)) {
- SvAMAGIC_on(sv);
- }
+ if (Gv_AMG(stash))
+ SvAMAGIC_on(sv);
+ else
+ SvAMAGIC_off(sv);
#endif /* OVERLOAD */
return sv;