*
*/
STATIC bool
-S_utf8_mg_pos_init(SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, U8 *s, U8 *start)
+S_utf8_mg_pos_init(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, U8 *s, U8 *start)
{
bool found = FALSE;
*
*/
STATIC bool
-S_utf8_mg_pos(SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, I32 uoff, U8 **sp, U8 *start, U8 *send)
+S_utf8_mg_pos(pTHX_ SV *sv, MAGIC **mgp, STRLEN **cachep, I32 i, I32 *offsetp, I32 uoff, U8 **sp, U8 *start, U8 *send)
{
bool found = FALSE;
*mgp = mg_find(sv, PERL_MAGIC_utf8);
if (*mgp && (*mgp)->mg_ptr) {
*cachep = (STRLEN *) (*mgp)->mg_ptr;
- if ((*cachep)[i] == uoff) /* An exact match. */
+ if ((*cachep)[i] == (STRLEN)uoff) /* An exact match. */
found = TRUE;
else { /* We will skip to the right spot. */
STRLEN forw = 0;
* 2 * backw in the below comes from). (The real
* figure of course depends on the UTF-8 data.) */
- if ((*cachep)[i] > uoff) {
+ if ((*cachep)[i] > (STRLEN)uoff) {
forw = uoff;
- backw = (*cachep)[i] - uoff;
+ backw = (*cachep)[i] - (STRLEN)uoff;
if (forw < 2 * backw)
p = start;
else if (i == 0) { /* (*cachep)[i] < uoff */
STRLEN ulen = sv_len_utf8(sv);
- if (uoff < ulen) {
- forw = uoff - (*cachep)[i];
- backw = ulen - uoff;
+ if ((STRLEN)uoff < ulen) {
+ forw = (STRLEN)uoff - (*cachep)[i];
+ backw = ulen - (STRLEN)uoff;
if (forw < 2 * backw)
p = start + (*cachep)[i+1];
}
/* Update the cache. */
- (*cachep)[i] = uoff;
+ (*cachep)[i] = (STRLEN)uoff;
(*cachep)[i+1] = p - start;
found = TRUE;
MAGIC *mg = 0;
bool found = FALSE;
- if (S_utf8_mg_pos(sv, &mg, &cache, 0, offsetp, *offsetp, &s, start, send))
+ if (utf8_mg_pos(sv, &mg, &cache, 0, offsetp, *offsetp, &s, start, send))
found = TRUE;
if (!found && uoffset > 0) {
while (s < send && uoffset--)
s += UTF8SKIP(s);
if (s >= send)
s = send;
- if (S_utf8_mg_pos_init(sv, &mg, &cache, 0, offsetp, s, start))
+ if (utf8_mg_pos_init(sv, &mg, &cache, 0, offsetp, s, start))
boffset = cache[1];
*offsetp = s - start;
}
if (lenp) {
found = FALSE;
start = s;
- if (S_utf8_mg_pos(sv, &mg, &cache, 2, lenp, *lenp + *offsetp, &s, start, send)) {
+ if (utf8_mg_pos(sv, &mg, &cache, 2, lenp, *lenp + *offsetp, &s, start, send)) {
*lenp -= boffset;
found = TRUE;
}
s += UTF8SKIP(s);
if (s >= send)
s = send;
- if (S_utf8_mg_pos_init(sv, &mg, &cache, 2, lenp, s, start))
+ if (utf8_mg_pos_init(sv, &mg, &cache, 2, lenp, s, start))
cache[2] += *offsetp;
}
*lenp = s - start;
U8 *p = s + cache[1];
STRLEN ubackw = 0;
+ cache[1] -= backw;
+
while (backw--) {
p--;
while (UTF8_IS_CONTINUATION(*p))
}
cache[0] -= ubackw;
- cache[1] -= backw;
return;
}
register I32 cnt;
I32 i = 0;
I32 rspara = 0;
+ I32 recsize;
SV_CHECK_THINKFIRST_COW_DROP(sv);
/* XXX. If you make this PVIV, then copy on write can copy scalars read
(void)SvUPGRADE(sv, SVt_PV);
SvSCREAM_off(sv);
+ SvPOK_only(sv); /* Validate pointer */
if (PL_curcop == &PL_compiling) {
/* we always read code in line mode */
rslen = 1;
}
else if (RsSNARF(PL_rs)) {
+ Stat_t st;
+ if (!PerlLIO_fstat(PerlIO_fileno(fp), &st) && st.st_size
+ && (recsize = st.st_size - PerlIO_tell(fp)))
+ goto read_record;
rsptr = NULL;
rslen = 0;
}
else if (RsRECORD(PL_rs)) {
- I32 recsize, bytesread;
+ I32 bytesread;
char *buffer;
/* Grab the size of the record we're getting */
recsize = SvIV(SvRV(PL_rs));
- (void)SvPOK_only(sv); /* Validate pointer */
- buffer = SvGROW(sv, (STRLEN)(recsize + 1));
+
+ read_record:
+ buffer = SvGROW(sv, (STRLEN)(recsize + append + 1)) + append;
/* Go yank in */
#ifdef VMS
/* VMS wants read instead of fread, because fread doesn't respect */
#else
bytesread = PerlIO_read(fp, buffer, recsize);
#endif
- SvCUR_set(sv, bytesread);
+ SvCUR_set(sv, bytesread += append);
buffer[bytesread] = '\0';
- if (PerlIO_isutf8(fp))
- SvUTF8_on(sv);
- else
- SvUTF8_off(sv);
- return(SvCUR(sv) ? SvPVX(sv) : Nullch);
+ goto check_utf8_and_return;
}
else if (RsPARA(PL_rs)) {
rsptr = "\n\n";
/* Here is some breathtakingly efficient cheating */
cnt = PerlIO_get_cnt(fp); /* get count into register */
- (void)SvPOK_only(sv); /* validate pointer */
if ((I32)(SvLEN(sv) - append) <= cnt + 1) { /* make sure we have the room */
if (cnt > 80 && (I32)SvLEN(sv) > append) {
shortbuffered = cnt - SvLEN(sv) + append + 1;
}
}
+check_utf8_and_return:
if (PerlIO_isutf8(fp))
SvUTF8_on(sv);
else
}
SvRV(sv) = 0;
SvROK_off(sv);
- if (SvREFCNT(rv) != 1 || SvREADONLY(rv) || (flags & SV_IMMEDIATE_UNREF))
+ /* You can't have a || SvREADONLY(rv) here, as $a = $$a, where $a was
+ assigned to as BEGIN {$a = \"Foo"} will fail. */
+ if (SvREFCNT(rv) != 1 || (flags & SV_IMMEDIATE_UNREF))
SvREFCNT_dec(rv);
else /* XXX Hack, but hard to make $a=$a->[1] work otherwise */
sv_2mortal(rv); /* Schedule for freeing later */