const char * const end = s + SvCUR(sv);
for ( ; s < end && d < limit; s++ ) {
int ch = *s & 0xFF;
- if (ch & 128 && !isPRINT_LC(ch)) {
+ if (! isASCII(ch) && !isPRINT_LC(ch)) {
*d++ = 'M';
*d++ = '-';
- ch &= 127;
+
+ /* Map to ASCII "equivalent" of Latin1 */
+ ch = LATIN1_TO_NATIVE(NATIVE_TO_LATIN1(ch) & 127);
}
if (ch == '\n') {
*d++ = '\\';
while (t < e) {
const U8 ch = *t++;
- if (NATIVE_IS_INVARIANT(ch)) continue;
+ if (NATIVE_BYTE_IS_INVARIANT(ch)) continue;
t--; /* t already incremented; re-point to first variant */
two_byte_count = 1;
}
while (t < e) {
- const UV uv = NATIVE8_TO_UNI(*t++);
- if (UNI_IS_INVARIANT(uv))
- *d++ = (U8)UNI_TO_NATIVE(uv);
- else {
- *d++ = (U8)UTF8_EIGHT_BIT_HI(uv);
- *d++ = (U8)UTF8_EIGHT_BIT_LO(uv);
- }
+ append_utf8_from_native_byte(*t, &d);
+ t++;
}
*d = '\0';
SvPV_free(sv); /* No longer using pre-existing string */
while (d < e) {
const U8 chr = *d++;
- if (! NATIVE_IS_INVARIANT(chr)) two_byte_count++;
+ if (! NATIVE_BYTE_IS_INVARIANT(chr)) two_byte_count++;
}
/* The string will expand by just the number of bytes that
e--;
while (e >= t) {
- const U8 ch = NATIVE8_TO_UNI(*e--);
- if (UNI_IS_INVARIANT(ch)) {
- *d-- = UNI_TO_NATIVE(ch);
+ if (NATIVE_BYTE_IS_INVARIANT(*e)) {
+ *d-- = *e;
} else {
- *d-- = (U8)UTF8_EIGHT_BIT_LO(ch);
- *d-- = (U8)UTF8_EIGHT_BIT_HI(ch);
+ *d-- = UTF8_EIGHT_BIT_LO(*e);
+ *d-- = UTF8_EIGHT_BIT_HI(*e);
}
+ e--;
}
}
if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
/* Update pos. We do it at the end rather than during
* the upgrade, to avoid slowing down the common case
- * (upgrade without pos) */
+ * (upgrade without pos).
+ * pos can be stored as either bytes or characters. Since
+ * this was previously a byte string we can just turn off
+ * the bytes flag. */
MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
if (mg) {
- I32 pos = mg->mg_len;
- if (pos > 0 && (U32)pos > invariant_head) {
- U8 *d = (U8*) SvPVX(sv) + invariant_head;
- STRLEN n = (U32)pos - invariant_head;
- while (n > 0) {
- if (UTF8_IS_START(*d))
- d++;
- d++;
- n--;
- }
- mg->mg_len = d - (U8*)SvPVX(sv);
- }
+ mg->mg_flags &= ~MGf_BYTES;
}
if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
magic_setutf8(sv,mg); /* clear UTF8 cache */
if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
/* update pos */
MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
- if (mg) {
- I32 pos = mg->mg_len;
- if (pos > 0) {
- sv_pos_b2u(sv, &pos);
+ if (mg && mg->mg_len > 0 && mg->mg_flags & MGf_BYTES) {
+ mg->mg_len = sv_pos_b2u_flags(sv, mg->mg_len,
+ SV_GMAGIC|SV_CONST_RETURN);
mg_flags = 0; /* sv_pos_b2u does get magic */
- mg->mg_len = pos;
- }
}
if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
magic_setutf8(sv,mg); /* clear UTF8 cache */
}
}
if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+ /* XXX Is this dead code? XS_utf8_decode calls SvSETMAGIC
+ after this, clearing pos. Does anything on CPAN
+ need this? */
/* adjust pos to the start of a UTF8 char sequence */
MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
if (mg) {
d = (U8 *)SvPVX(dsv) + dlen;
while (sstr < send) {
- const UV uv = NATIVE_TO_ASCII((U8)*sstr++);
- if (UNI_IS_INVARIANT(uv))
- *d++ = (U8)UTF_TO_NATIVE(uv);
- else {
- *d++ = (U8)UTF8_EIGHT_BIT_HI(uv);
- *d++ = (U8)UTF8_EIGHT_BIT_LO(uv);
- }
+ append_utf8_from_native_byte(*sstr, &d);
+ sstr++;
}
SvCUR_set(dsv, d-(const U8 *)SvPVX(dsv));
}
}
}
+ /* Force pos to be stored as characters, not bytes. */
+ if (SvMAGICAL(sv) && DO_UTF8(sv)
+ && (mg = mg_find(sv, PERL_MAGIC_regex_global))
+ && mg->mg_len != -1
+ && mg->mg_flags & MGf_BYTES) {
+ mg->mg_len = (SSize_t)sv_pos_b2u_flags(sv, (STRLEN)mg->mg_len,
+ SV_CONST_RETURN);
+ mg->mg_flags &= ~MGf_BYTES;
+ }
+
/* Rest of work is done else where */
mg = sv_magicext(sv,obj,how,vtable,name,namlen);
STRLEN rslen;
STDCHAR rslast;
STDCHAR *bp;
- I32 cnt;
- I32 i = 0;
- I32 rspara = 0;
+ SSize_t cnt;
+ int i = 0;
+ int rspara = 0;
PERL_ARGS_ASSERT_SV_GETS;
DEBUG_P(PerlIO_printf(Perl_debug_log,
"Screamer: entering, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
DEBUG_P(PerlIO_printf(Perl_debug_log,
- "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
- PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+ "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%zd, base=%"
+ UVuf"\n",
+ PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0)));
for (;;) {
screamer:
cannot_be_shortbuffered:
DEBUG_P(PerlIO_printf(Perl_debug_log,
- "Screamer: going to getc, ptr=%"UVuf", cnt=%ld\n",
- PTR2UV(ptr),(long)cnt));
+ "Screamer: going to getc, ptr=%"UVuf", cnt=%zd\n",
+ PTR2UV(ptr),cnt));
PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* deregisterize cnt and ptr */
DEBUG_Pv(PerlIO_printf(Perl_debug_log,
- "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
- PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+ "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n",
+ PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
/* This used to call 'filbuf' in stdio form, but as that behaves like
i = PerlIO_getc(fp); /* get more characters */
DEBUG_Pv(PerlIO_printf(Perl_debug_log,
- "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
- PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+ "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n",
+ PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
cnt = PerlIO_get_cnt(fp);
ptr = (STDCHAR*)PerlIO_get_ptr(fp); /* reregisterize cnt and ptr */
DEBUG_P(PerlIO_printf(Perl_debug_log,
- "Screamer: after getc, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
+ "Screamer: after getc, ptr=%"UVuf", cnt=%zd\n",
+ PTR2UV(ptr),cnt));
if (i == EOF) /* all done for ever? */
goto thats_really_all_folks;
if (shortbuffered)
cnt += shortbuffered;
DEBUG_P(PerlIO_printf(Perl_debug_log,
- "Screamer: quitting, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
+ "Screamer: quitting, ptr=%"UVuf", cnt=%zd\n",PTR2UV(ptr),cnt));
PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* put these back or we're in trouble */
DEBUG_P(PerlIO_printf(Perl_debug_log,
- "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
- PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+ "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf
+ "\n",
+ PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
*bp = '\0';
SvCUR_set(sv, bp - (STDCHAR*)SvPVX_const(sv)); /* set length */
return sv;
}
+SV *
+Perl_newSVavdefelem(pTHX_ AV *av, SSize_t ix, bool extendible)
+{
+ SV * const lv = newSV_type(SVt_PVLV);
+ PERL_ARGS_ASSERT_NEWSVAVDEFELEM;
+ LvTYPE(lv) = 'y';
+ sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
+ LvTARG(lv) = SvREFCNT_inc_simple_NN(av);
+ LvSTARGOFF(lv) = ix;
+ LvTARGLEN(lv) = extendible ? 1 : (STRLEN)UV_MAX;
+ return lv;
+}
+
/*
=for apidoc sv_setref_pv
{
dVAR;
SV *tmpRef;
+ HV *oldstash = NULL;
PERL_ARGS_ASSERT_SV_BLESS;
if (SvREADONLY(tmpRef))
Perl_croak_no_modify();
if (SvOBJECT(tmpRef)) {
- SvREFCNT_dec(SvSTASH(tmpRef));
+ oldstash = SvSTASH(tmpRef);
}
}
SvOBJECT_on(tmpRef);
SvUPGRADE(tmpRef, SVt_PVMG);
SvSTASH_set(tmpRef, MUTABLE_HV(SvREFCNT_inc_simple(stash)));
+ SvREFCNT_dec(oldstash);
if(SvSMAGICAL(tmpRef))
if(mg_find(tmpRef, PERL_MAGIC_ext) || mg_find(tmpRef, PERL_MAGIC_uvar))
char ebuf[IV_DIG * 4 + NV_DIG + 32];
/* large enough for "%#.#f" --chip */
/* what about long double NVs? --jhi */
+#ifdef USE_LOCALE_NUMERIC
+ SV* oldlocale = NULL;
+#endif
PERL_ARGS_ASSERT_SV_VCATPVFN_FLAGS;
PERL_UNUSED_ARG(maybe_tainted);
q++;
break;
#endif
-#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
+#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE)
case 'L': /* Ld */
/*FALLTHROUGH*/
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
case 'q': /* qd */
#endif
intsize = 'q';
#endif
case 'l':
++q;
-#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
+#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE)
if (*q == 'l') { /* lld, llf */
intsize = 'q';
++q;
goto unknown;
uv = (args) ? va_arg(*args, int) : SvIV(argsv);
if ((uv > 255 ||
- (!UNI_IS_INVARIANT(uv) && SvUTF8(sv)))
+ (!UVCHR_IS_INVARIANT(uv) && SvUTF8(sv)))
&& !IN_BYTES) {
eptr = (char*)utf8buf;
elen = uvchr_to_utf8((U8*)eptr, uv) - utf8buf;
case 'j': iv = va_arg(*args, intmax_t); break;
#endif
case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
iv = va_arg(*args, Quad_t); break;
#else
goto unknown;
case 'V':
default: iv = tiv; break;
case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
iv = (Quad_t)tiv; break;
#else
goto unknown;
#endif
default: uv = va_arg(*args, unsigned); break;
case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
uv = va_arg(*args, Uquad_t); break;
#else
goto unknown;
case 'V':
default: uv = tuv; break;
case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
uv = (Uquad_t)tuv; break;
#else
goto unknown;
/* No taint. Otherwise we are in the strange situation
* where printf() taints but print($float) doesn't.
* --jhi */
+
+#ifdef USE_LOCALE_NUMERIC
+ if (! PL_numeric_standard && ! IN_SOME_LOCALE_FORM) {
+
+ /* We use a mortal SV, so that any failures (such as if
+ * warnings are made fatal) won't leak */
+ char *oldlocale_string = setlocale(LC_NUMERIC, NULL);
+ oldlocale = newSVpvn_flags(oldlocale_string,
+ strlen(oldlocale_string),
+ SVs_TEMP);
+ PL_numeric_standard = TRUE;
+ setlocale(LC_NUMERIC, "C");
+ }
+#endif
+
#if defined(HAS_LONG_DOUBLE)
elen = ((intsize == 'q')
? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
case 'j': *(va_arg(*args, intmax_t*)) = i; break;
#endif
case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
*(va_arg(*args, Quad_t*)) = i; break;
#else
goto unknown;
}
}
SvTAINT(sv);
+
+#ifdef USE_LOCALE_NUMERIC /* Done outside loop, so don't have to save/restore
+ each iteration. */
+ if (oldlocale) {
+ setlocale(LC_NUMERIC, SvPVX(oldlocale));
+ PL_numeric_standard = FALSE;
+ }
+#endif
}
/* =========================================================================
PL_last_swash_slen = 0;
PL_srand_called = proto_perl->Isrand_called;
+ Copy(&(proto_perl->Irandom_state), &PL_random_state, 1, PL_RANDOM_STATE_TYPE);
if (flags & CLONEf_COPY_STACKS) {
/* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */