File Coverage

Damn.xs
Criterion Covered Total %
statement 29 30 96.6
branch 21 32 65.6
condition n/a
subroutine n/a
pod n/a
total 50 62 80.6


line stmt bran cond sub pod time code
1             /*
2             ** Damn.xs
3             **
4             ** Define the damn() method of Acme::Damn.
5             **
6             */
7              
8             #include "EXTERN.h"
9             #include "perl.h"
10             #include "XSUB.h"
11              
12             /* for Perl > 5.6, additional magic must be handled */
13             #if ( PERL_REVISION == 5 ) && ( PERL_VERSION > 6 )
14             /* if there's magic set - Perl extension magic - then unset it */
15             # define SvUNMAGIC( sv ) if ( SvSMAGICAL( sv ) ) \
16             if ( mg_find( sv , PERL_MAGIC_ext ) \
17             || mg_find( sv , PERL_MAGIC_uvar ) ) \
18             mg_clear( sv )
19              
20             #else
21              
22             /* for Perl <= 5.6 this becomes a no-op */
23             # define SvUNMAGIC( sv )
24              
25             #endif
26              
27             /* ensure SvPV_const is declared */
28             #ifndef SvPV_const
29             # define SvPV_const(s,l) ((const char *)SvPV(s,l))
30             #endif
31              
32              
33             /* handle the evolution of Perl_warner and Perl_ck_warner */
34             #ifdef packWARN
35             # ifdef ckWARN
36             # define WARNER(t,s) if (ckWARN(t)) { Perl_warner( aTHX_ packWARN(t) , s ); }
37             # else
38             # define WARNER(t,s) Perl_ck_warner( aTHX_ packWARN(t) , s )
39             # endif
40             #else
41             # define WARNER(t,s) if (ckWARN(t)) { Perl_warner( aTHX_ t , s ); }
42             #endif
43              
44             static SV *
45 47           __damn( rv )
46             SV * rv;
47             {
48             /* need to dereference the RV to get the SV */
49 47           SV *sv = SvRV( rv );
50              
51             /*
52             ** if this is read-only, then we should do the right thing and slap
53             ** the programmer's wrist; who know's what might happen otherwise
54             */
55 47 50         if ( SvREADONLY( sv ) )
56             /*
57             ** use "%s" rather than just PL_no_modify to satisfy gcc's -Wformat
58             ** see https://rt.cpan.org/Ticket/Display.html?id=45778
59             */
60 0           croak( "%s" , PL_no_modify );
61              
62 47           SvREFCNT_dec( SvSTASH( sv ) ); /* remove the reference to the stash */
63 47           SvSTASH( sv ) = NULL;
64 47           SvOBJECT_off( sv ); /* unset the object flag */
65             #if PERL_VERSION < 18
66             if ( SvTYPE( sv ) != SVt_PVIO ) /* if we don't have an IO stream, we */
67             PL_sv_objcount--; /* should decrement the object count */
68             #endif
69              
70             /* we need to clear the magic flag on the given RV */
71 47           SvAMAGIC_off( rv );
72             /* as of Perl 5.8.0 we need to clear more magic */
73 47 50         SvUNMAGIC( sv );
    0          
    0          
74              
75 47           return rv;
76             } /* __damn() */
77              
78              
79             MODULE = Acme::Damn PACKAGE = Acme::Damn
80              
81             PROTOTYPES: ENABLE
82              
83             SV *
84             damn( rv , ... )
85             SV * rv;
86              
87             PROTOTYPE: $;$$$
88              
89             PREINIT:
90             SV * sv;
91              
92             CODE:
93             /* if we don't have a blessed reference, then raise an error */
94 57 100         if ( ! sv_isobject( rv ) ) {
95             /*
96             ** if we have more than one parameter, then pull the name from
97             ** the stack ... otherwise, use the method[] array
98             */
99 34 100         if ( items > 1 ) {
100 20           char *name = (char *)SvPV_nolen( ST(1) );
101 20           char *file = (char *)SvPV_nolen( ST(2) );
102 20           int line = (int)SvIV( ST(3) );
103              
104 20           croak( "Expected blessed reference; can only %s the programmer "
105             "now at %s line %d.\n" , name , file , line );
106             } else {
107 14           croak( "Expected blessed reference; can only damn the programmer now" );
108             }
109             }
110              
111 23           rv = __damn( rv );
112              
113             OUTPUT:
114             rv
115              
116              
117             SV *
118             bless( rv , ... )
119             SV * rv;
120              
121             PROTOTYPE: $;$
122              
123             CODE:
124             /*
125             ** how many arguments do we have?
126             ** - if we have two arguments, with the second being 'undef'
127             ** then we call damn()
128             ** - otherwise, we default to CORE::bless()
129             */
130 63 100         if ( items == 2 && ! SvOK( ST(1) ) )
    100          
131 24           rv = __damn(rv);
132             else {
133             HV *stash;
134             STRLEN len;
135             const char *ptr;
136             SV *sv;
137              
138             /* have we been called as a two-argument bless? */
139 39 100         if ( items == 2 ) {
140             /*
141             ** here we replicate Perl_pp_bless()
142             ** - see pp.c
143             */
144              
145             /* ensure we have a package name, not a reference as argument #2 */
146 25           sv = ST(1);
147 25 50         if ( ! SvGMAGICAL( sv ) && ! SvAMAGIC( sv ) && SvROK( sv ) )
    100          
    50          
    0          
    100          
148 1           croak( "Attempt to bless into a reference" );
149              
150             /* extract the name of the target package */
151 24           ptr = SvPV_const( sv , len );
152 24 100         if ( len == 0 )
153 6 50         WARNER(WARN_MISC, "Explicit blessing to '' (assuming package main)");
154              
155             /* extract the named stash (creating it if needed) */
156 24           stash = gv_stashpvn( ptr , len , GV_ADD | SvUTF8(sv) );
157             } else {
158              
159             /* if no package name as been given, then use the current package */
160 14           stash = CopSTASH( PL_curcop );
161             }
162              
163             /* bless the target reference */
164 38           (void)sv_bless( rv , stash );
165             }
166              
167             OUTPUT:
168             rv