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()

Reply via email to