Stas Bekman wrote:
> I have attempted to shoe-horn this into mod_perl's print() method (in
> "src/modules/perl/Apache.xs"). Here's the diff against mod_perl 1.28:
> [Unfortunately, I've had to comment-out the first part of that "if"
> block, because I got an unresolved external symbol error relating to the
> PerlIO_isutf8() function otherwise (which may be because that function
> isn't documented in the perlapio manpage).]
mod_perl 1.x doesn't use perlio, hence you have this problem. adding:
#include "perlio.h"
should resolve it I think.
No. The error was "unresolved external symbol", which means that the compiler is happy (it evidently has pulled in perlio.h, or something else that declares PerlIO_isutf8() as "extern ..."), but that the linker couldn't find the definition of that function.
(Check: If I change "PerlIO_isutf8" to "PerlIO_isutf" (deliberate typo) then I get a different error - "undefined; assuming extern returning int" - because now no declaration has been supplied.)
Listing the symbols exported from perl58.lib shows that PerlIO_isutf8 is *not* one of them. So where's the definition supposed to come from?
I'll ask about this on the perlxs mailing list, I think.
Having asked about this, it turns out that the problem was PerlIO_isutf8() not being exported from perl58.lib on Windows (and other platforms where the symbols to export have to be explicitly listed).
I sent a patch off to p5p which fixes this (http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-07/msg01096.html), and it has been integrated as #20203.
So presumably this will not be a problem in the upcoming perl-5.8.1, but how do we cope with the perl-5.8.0 case?
I've attached a new patch (against mod_perl-1.28) which (I believe) fixes the UTF-8 problem, but it won't build on Windows with perl-5.8.0 without #20203.
Steve
--- Apache.xs.orig 2003-06-06 12:31:10.000000000 +0100 +++ Apache.xs 2003-07-18 08:47:59.000000000 +0100 @@ -1119,11 +1119,27 @@ SV *sv = sv_newmortal(); SV *rp = ST(0); SV *sendh = perl_get_sv("Apache::__SendHeader", TRUE); +#if PERL_VERSION >= 8 + PerlIO *fp = IoOFP(GvIOp(defoutgv)); +#endif if(items > 2) do_join(sv, &sv_no, MARK+1, SP); /* $sv = join '', @_[1..$#_] */ else sv_setsv(sv, ST(1)); +#if PERL_VERSION >= 8 + if (PerlIO_isutf8(fp)) { + if (!SvUTF8(sv)) + sv_utf8_upgrade(sv = sv_mortalcopy(sv)); + } + 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"); + } + } +#endif PUSHMARK(sp); XPUSHs(rp); @@ -1176,6 +1192,20 @@ int sent = 0; SV *sv = SvROK(ST(i)) && (SvTYPE(SvRV(ST(i))) == SVt_PV) ? (SV*)SvRV(ST(i)) : ST(i); +#if PERL_VERSION >= 8 + PerlIO *fp = IoOFP(GvIOp(defoutgv)); + if (PerlIO_isutf8(fp)) { + if (!SvUTF8(sv)) + sv_utf8_upgrade(sv = sv_mortalcopy(sv)); + } + 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"); + } + } +#endif buffer = SvPV(sv, len); #ifdef APACHE_SSL while(len > 0) {