dVAR;
register const char *tmps;
STRLEN len;
+ U8 *tmpbuf = NULL;
+ bool happy = TRUE;
/* assuming fp is checked earlier */
if (!sv)
}
/* FALL THROUGH */
default:
+ /* Do this first to trigger any overloading. */
+ tmps = SvPV_const(sv, len);
if (PerlIO_isutf8(fp)) {
- if (!SvUTF8(sv))
- sv_utf8_upgrade_flags(sv = sv_mortalcopy(sv),
- SV_GMAGIC|SV_UTF8_NO_ENCODING);
+ if (!SvUTF8(sv)) {
+ /* We don't modify the original scalar. */
+ tmpbuf = bytes_to_utf8((const U8*) tmps, &len);
+ tmps = (char *) tmpbuf;
+ }
}
else if (DO_UTF8(sv)) {
- if (!sv_utf8_downgrade((sv = sv_mortalcopy(sv)), TRUE)
- && ckWARN_d(WARN_UTF8))
- {
- Perl_warner(aTHX_ packWARN(WARN_UTF8), "Wide character in print");
+ STRLEN tmplen = len;
+ bool utf8 = TRUE;
+ U8 *result = bytes_from_utf8((const U8*) tmps, &tmplen, &utf8);
+ if (!utf8) {
+ tmpbuf = result;
+ tmps = (char *) tmpbuf;
+ len = tmplen;
+ }
+ else {
+ assert((char *)result == tmps);
+ if (ckWARN_d(WARN_UTF8)) {
+ Perl_warner(aTHX_ packWARN(WARN_UTF8),
+ "Wide character in print");
+ }
}
}
- tmps = SvPV_const(sv, len);
break;
}
/* To detect whether the process is about to overstep its
* at which we would get EPERM. Note that when using buffered
* io the write failure can be delayed until the flush/close. --jhi */
if (len && (PerlIO_write(fp,tmps,len) == 0))
- return FALSE;
- return !PerlIO_error(fp);
+ happy = FALSE;
+ if (tmpbuf)
+ Safefree(tmpbuf);
+ return happy ? !PerlIO_error(fp) : FALSE;
}
I32
}
}
-use Test::More tests => 56;
+use Test::More tests => 68;
package UTF8Toggle;
use strict;
sub new {
my $class = shift;
- return bless [shift, 0], $class;
+ my $value = shift;
+ my $state = shift||0;
+ return bless [$value, $state], $class;
}
sub stringify {
is ($uc, "\311", "e accute -> E accute");
}
}
+
+my $tmpfile = 'overload.tmp';
+
+foreach my $operator (qw (print)) {
+ foreach my $layer ('', ':utf8') {
+ open my $fh, "+>$layer", $tmpfile or die $!;
+ my $u = UTF8Toggle->new("\311\n");
+ print $fh $u;
+ print $fh $u;
+ print $fh $u;
+ my $l = UTF8Toggle->new("\351\n", 1);
+ print $fh $l;
+ print $fh $l;
+ print $fh $l;
+
+ seek $fh, 0, 0 or die $!;
+ my $line;
+ chomp ($line = <$fh>);
+ is ($line, "\311", "$operator $layer");
+ chomp ($line = <$fh>);
+ is ($line, "\311", "$operator $layer");
+ chomp ($line = <$fh>);
+ is ($line, "\311", "$operator $layer");
+ chomp ($line = <$fh>);
+ is ($line, "\351", "$operator $layer");
+ chomp ($line = <$fh>);
+ is ($line, "\351", "$operator $layer");
+ chomp ($line = <$fh>);
+ is ($line, "\351", "$operator $layer");
+
+ close $fh or die $!;
+ unlink $tmpfile or die $!;
+ }
+}
+
+
+END {
+ 1 while -f $tmpfile and unlink $tmpfile || die "unlink '$tmpfile': $!";
+}