[perl-Cairo] Cairo::Surface: fix the exception conversion in callbacks
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Cairo] Cairo::Surface: fix the exception conversion in callbacks
- Date: Sun, 16 May 2010 20:18:18 +0000 (UTC)
commit ca4a5749bf6449347a076f7447912f12dc956c71
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Sun May 16 21:13:43 2010 +0200
Cairo::Surface: fix the exception conversion in callbacks
The recent fix of the off-by-one error in enum handling revealed a bug
in the exception conversion from strings to cairo_status_t in the
read/write callback marshallers. When you do C<die 'no-memory'>, $@ is
actually filled with 'no-memory at foo.pl line 23\n'. The off-by-one
error meant that this was converted successfully as if it was just
'no-memory'. This is not the case anymore, and so we need to strip off
the location suffix before trying to convert to a cairo_status_t.
CairoSurface.xs | 26 ++++++++++++++++++++++++--
1 files changed, 24 insertions(+), 2 deletions(-)
---
diff --git a/CairoSurface.xs b/CairoSurface.xs
index c146d9a..6b21116 100644
--- a/CairoSurface.xs
+++ b/CairoSurface.xs
@@ -166,6 +166,24 @@ cairo_perl_callback_free (CairoPerlCallback *callback)
/* -------------------------------------------------------------------------- */
+/* Caller owns returned SV */
+static SV *
+strip_off_location (SV *error)
+{
+ SV *saved_defsv, *result;
+ saved_defsv = newSVsv (DEFSV);
+ ENTER;
+ SAVETMPS;
+ sv_setsv (DEFSV, error);
+ eval_pv ("s/^([-_\\w]+) .+$/$1/s", FALSE);
+ result = newSVsv (DEFSV);
+ FREETMPS;
+ LEAVE;
+ sv_setsv (DEFSV, saved_defsv);
+ SvREFCNT_dec (saved_defsv);
+ return result;
+}
+
static cairo_status_t
write_func_marshaller (void *closure,
const unsigned char *data,
@@ -192,7 +210,9 @@ write_func_marshaller (void *closure,
SPAGAIN;
if (SvTRUE (ERRSV)) {
- status = SvCairoStatus (ERRSV);
+ SV *sv = strip_off_location (ERRSV);
+ status = SvCairoStatus (sv);
+ SvREFCNT_dec (sv);
}
PUTBACK;
@@ -230,7 +250,9 @@ read_func_marshaller (void *closure,
SPAGAIN;
if (SvTRUE (ERRSV)) {
- status = SvCairoStatus (ERRSV);
+ SV *sv = strip_off_location (ERRSV);
+ status = SvCairoStatus (sv);
+ SvREFCNT_dec (sv);
} else {
SV *retval = POPs;
memcpy (data, SvPV_nolen (retval), sv_len (retval));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]