Dan Kogai <[EMAIL PROTECTED]> writes: >On Oct 24, 2004, at 18:34, Rafael Garcia-Suarez wrote: >> Welcome to backward compatibility hell :) > >Hell it was but seems like I came up with a way out (yay). > >>> I just want Encode::utf8->decode() to make sure Encode:RETURN_ON_ERR >>> is >>> on when the callar is PerlIO::encoding... >> >> Or, one could backport PerlIO::encoding (with your patch) to CPAN and >> require this latest version for Encode 2.08. > >That was what came across my mind first but I found it was not good >enough to coerce Encode:RETURN_ON_ERR since $PerlIO::encoding:fallback >is open to the public (even documented!). > >So far ->renew() is only used by PerlIO (and is meaningful only when >the object is Encode::Unicode).
And certain other bits of code writen by its original author ;-) >In other words, you can tell it's >PerlIO that is calling you if the object is renewed. > >The following patch does that. The new Encode::utf8->decode() checks >$self->renewed and if so it sets Encode:RETURN_ON_ERR. Here is the >patch or you can wait for Encode-2.08. Will try and find time to do a proper patch to the utf-8 decoder. > >Thankfully Encode::XS needs no "real" ->renew so it is left as is >(dummy ->renewed() was introduced just to be safe). > >Dan the Encode Maintainer > >diff -ruN ext/Encode-2.07/Encode.xs ext/Encode/Encode.xs >--- ext/Encode-2.07/Encode.xs Sat Oct 23 04:37:13 2004 >+++ ext/Encode/Encode.xs Sun Oct 24 20:31:06 2004 >@@ -252,14 +252,6 @@ > PROTOTYPES: DISABLE > > void >-Method_renew(obj) >-SV * obj >-CODE: >-{ >- XSRETURN(1); >-} >- >-void > Method_decode_xs(obj,src,check = 0) > SV * obj > SV * src >@@ -270,6 +262,28 @@ > U8 *s = (U8 *) SvPV(src, slen); > U8 *e = (U8 *) SvEND(src); > SV *dst = newSV(slen>0?slen:1); /* newSV() abhors 0 -- inaba */ >+ >+ /* >+ * PerlO check -- we assume the object is of PerlIO if renewed >+ * and if so, we set RETURN_ON_ERR for partial character >+ */ >+ int renewed = 0; >+ dSP; ENTER; SAVETMPS; >+ PUSHMARK(sp); >+ XPUSHs(obj); >+ PUTBACK; >+ if (call_method("renewed",G_SCALAR) == 1) { >+ SPAGAIN; >+ renewed = POPi; >+ PUTBACK; >+#if 0 >+ fprintf(stderr, "renewed == %d\n", renewed); >+#endif >+ if (renewed){ check |= ENCODE_RETURN_ON_ERR; } >+ } >+ FREETMPS; LEAVE; >+ /* end PerlIO check */ >+ > SvPOK_only(dst); > SvCUR_set(dst,0); > if (SvUTF8(src)) { >@@ -397,6 +411,14 @@ > { > XSRETURN(1); > } >+ >+int >+Method_renewed(obj) >+SV * obj >+CODE: >+ RETVAL = 0; >+OUTPUT: >+ RETVAL > > void > Method_name(obj) >diff -ruN ext/Encode-2.07/Unicode/Unicode.pm >ext/Encode/Unicode/Unicode.pm >--- ext/Encode-2.07/Unicode/Unicode.pm Sat Oct 23 04:37:17 2004 >+++ ext/Encode/Unicode/Unicode.pm Sun Oct 24 20:38:16 2004 >@@ -46,7 +46,7 @@ > my $self = shift; > $BOM_Unknown{$self->name} or return $self; > my $clone = bless { %$self } => ref($self); >- $clone->{clone} = 1; # so the caller knows it is renewed. >+ $clone->{clone}++ # so the caller knows it is renewed. > return $clone; > } > >diff -ruN ext/Encode-2.07/lib/Encode/Encoding.pm >ext/Encode/lib/Encode/Encoding.pm >--- ext/Encode-2.07/lib/Encode/Encoding.pm Sat Oct 23 04:37:13 2004 >+++ ext/Encode/lib/Encode/Encoding.pm Sun Oct 24 20:25:13 2004 >@@ -5,6 +5,7 @@ > > require Encode; > >+sub DEBUG { 0 } > sub Define > { > my $obj = shift; >@@ -16,7 +17,18 @@ > > sub name { return shift->{'Name'} } > >-sub renew { return $_[0] } >+# sub renew { return $_[0] } >+ >+sub renew { >+ my $self = shift; >+ my $clone = bless { %$self } => ref($self); >+ $clone->{renewed}++; # so the caller can see it >+ DEBUG and warn $clone->{renewed}; >+ return $clone; >+} >+ >+sub renewed{ return $_[0]->{renewed} || 0 } >+ > *new_sequence = \&renew; > > sub needs_lines { 0 }; >@@ -167,24 +179,28 @@ > > Predefined As: > >- sub renew { return $_[0] } >+ sub renew { >+ my $self = shift; >+ my $clone = bless { %$self } => ref($self); >+ $clone->{renewed}++; >+ return $clone; >+ } > > This method reconstructs the encoding object if necessary. If you need > to store the state during encoding, this is where you clone your >object. >-Here is an example: >- >- sub renew { >- my $self = shift; >- my $clone = bless { %$self } => ref($self); >- $clone->{clone} = 1; # so the caller can see it >- return $clone; >- } >- >-Since most encodings are stateless the default behavior is just return >-itself as shown above. > > PerlIO ALWAYS calls this method to make sure it has its own private > encoding object. >+ >+=item -E<gt>renewed >+ >+Predefined As: >+ >+ sub renewed { $_[0]->{renewed} || 0 } >+ >+Tells whether the object is renewed (and how many times). Some >+modules emit C<Use of uninitialized value in null operation> warning >+unless the value is numeric so return 0 for false. > > =item -E<gt>perlio_ok()