if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */
mg_magical(sv); /* else fix the flags now */
}
- else {
+ else
SvMAGICAL_off(sv);
- SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
- }
+
return 0;
}
return;
}
+ /* treat AV/HV/CV/FM/IO and non-fake GVs as immutable */
+ if (SvTYPE(sv) >= SVt_PVAV || (isGV_with_GP(sv) && !SvFAKE(sv)))
+ Perl_croak_no_modify();
+
if (!(flags & SVp_POK) || !*SvPVX_const(sv)) {
if ((flags & SVTYPEMASK) < SVt_PVIV)
sv_upgrade(sv, ((flags & SVTYPEMASK) > SVt_IV ? SVt_PVIV : SVt_IV));
return;
}
}
+
+ /* treat AV/HV/CV/FM/IO and non-fake GVs as immutable */
+ if (SvTYPE(sv) >= SVt_PVAV || (isGV_with_GP(sv) && !SvFAKE(sv)))
+ Perl_croak_no_modify();
+
if (!(flags & SVp_POK)) {
if ((flags & SVTYPEMASK) < SVt_PVIV)
sv_upgrade(sv, ((flags & SVTYPEMASK) > SVt_IV) ? SVt_PVIV : SVt_IV);
U8* v = vhex; /* working pointer to vhex */
U8* vend; /* pointer to one beyond last digit of vhex */
U8* vfnz = NULL; /* first non-zero */
+ U8* vlnz = NULL; /* last non-zero */
const bool lower = (c == 'a');
/* At output the values of vhex (up to vend) will
* be mapped through the xdig to get the actual
const char* xdig = PL_hexdigit;
int zerotail = 0; /* how many extra zeros to append */
int exponent = 0; /* exponent of the floating point input */
+ bool hexradix = FALSE; /* should we output the radix */
/* XXX: denormals, NaN, Inf.
*
# endif
#endif
- if (fv < 0)
+ if (fv < 0
+ || Perl_signbit(nv)
+ )
*p++ = '-';
else if (plus)
*p++ = plus;
}
if (vfnz) {
- U8* vlnz = NULL; /* The last non-zero. */
-
/* Find the last non-zero xdigit. */
for (v = vend - 1; v >= vhex; v--) {
if (*v) {
v = vhex;
*p++ = xdig[*v++];
- /* The radix is always output after the first
- * non-zero xdigit, or if alt. */
- if (vfnz < vlnz || alt) {
+ /* If there are non-zero xdigits, the radix
+ * is output after the first one. */
+ if (vfnz < vlnz) {
+ hexradix = TRUE;
+ }
+ }
+ else {
+ *p++ = '0';
+ exponent = 0;
+ zerotail = precis;
+ }
+
+ /* The radix is always output if precis, or if alt. */
+ if (precis > 0 || alt) {
+ hexradix = TRUE;
+ }
+
+ if (hexradix) {
#ifndef USE_LOCALE_NUMERIC
*p++ = '.';
#else
}
RESTORE_LC_NUMERIC();
#endif
- }
+ }
+ if (vlnz) {
while (v <= vlnz)
*p++ = xdig[*v++];
-
- while (zerotail--)
- *p++ = '0';
}
- else {
+
+ if (zerotail > 0) {
+ while (zerotail--) {
*p++ = '0';
- exponent = 0;
+ }
}
elen = p - PL_efloatbuf;
If C<sv> already is UTF-8 (or if it is not C<POK>), or if C<encoding>
is not a reference, nothing is done to C<sv>. If C<encoding> is not
an C<Encode::XS> Encoding object, bad things will happen.
-(See F<lib/encoding.pm> and L<Encode>.)
+(See F<cpan/Encode/encoding.pm> and L<Encode>.)
The PV of C<sv> is returned.