File Coverage

src/check.c
Criterion Covered Total %
statement 16 41 39.0
branch 9 68 13.2
condition n/a
subroutine n/a
pod n/a
total 25 109 22.9


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #include "EXTERN.h"
4             #include "perl.h"
5              
6             #include "check.h"
7              
8             #define HAVE_PERL_VERSION(R, V, S) \
9             (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S))))))
10              
11             #include "optree-additions.c.inc"
12              
13 9           struct CheckData *Check_make_checkdata(pTHX_ SV *checker)
14             {
15             HV *stash = NULL;
16             CV *checkcv = NULL;
17              
18 9 100         if(SvROK(checker) && SvOBJECT(SvRV(checker)))
    50          
19 3           stash = SvSTASH(SvRV(checker));
20 6 50         else if(SvPOK(checker) && (stash = gv_stashsv(checker, GV_NOADD_NOINIT)))
    50          
21             ; /* checker is package name */
22 0 0         else if(SvROK(checker) && !SvOBJECT(SvRV(checker)) && SvTYPE(SvRV(checker)) == SVt_PVCV) {
    0          
23             checkcv = (CV *)SvREFCNT_inc(SvRV(checker));
24             SvREFCNT_dec(checker);
25             checker = NULL;
26             }
27             else
28 0           croak("Expected the checker expression to yield an object or code reference or package name; got %" SVf " instead",
29             SVfARG(checker));
30              
31 9 50         if(!checkcv) {
32             GV *methgv;
33 9 50         if(!(methgv = gv_fetchmeth_pv(stash, "check", -1, 0)))
34 0           croak("Expected that the checker expression can ->check");
35 9 50         if(!GvCV(methgv))
36 0           croak("Expected that methgv has a GvCV");
37             checkcv = (CV *)SvREFCNT_inc(GvCV(methgv));
38             }
39              
40             struct CheckData *data;
41 9           Newx(data, 1, struct CheckData);
42              
43 9           data->checkobj = checker;
44 9           data->checkcv = checkcv;
45              
46 9           return data;
47             }
48              
49 9           OP *Check_make_assertop(pTHX_ struct CheckData *data, OP *argop)
50             {
51 9           OP *checkop = data->checkobj
52             ? /* checkcv($checker, ARGOP) ... */
53 18           newLISTOPn(OP_ENTERSUB, OPf_WANT_SCALAR|OPf_STACKED,
54             newSVOP(OP_CONST, 0, SvREFCNT_inc(data->checkobj)),
55             argop,
56             newSVOP(OP_CONST, 0, SvREFCNT_inc(data->checkcv)),
57             NULL)
58 18 50         : /* checkcv(ARGOP) ... */
59 0           newLISTOPn(OP_ENTERSUB, OPf_WANT_SCALAR|OPf_STACKED,
60             argop,
61             newSVOP(OP_CONST, 0, SvREFCNT_inc(data->checkcv)),
62             NULL);
63              
64 9           return newLOGOP(OP_OR, 0,
65             checkop,
66             /* ... or die MESSAGE */
67             newLISTOPn(OP_DIE, 0,
68             newSVOP(OP_CONST, 0, SvREFCNT_inc(data->assertmess)),
69             NULL));
70             }
71              
72 0           bool Check_check_value(pTHX_ struct CheckData *data, SV *value)
73             {
74 0           dSP;
75              
76 0           ENTER;
77 0           SAVETMPS;
78              
79 0 0         EXTEND(SP, 2);
80 0 0         PUSHMARK(SP);
81 0 0         if(data->checkobj)
82 0           PUSHs(sv_mortalcopy(data->checkobj));
83 0           PUSHs(value); /* Yes we're pushing the SV itself */
84 0           PUTBACK;
85              
86 0           call_sv((SV *)data->checkcv, G_SCALAR);
87              
88 0           SPAGAIN;
89              
90 0 0         bool ok = SvTRUEx(POPs);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
91              
92 0 0         FREETMPS;
93 0           LEAVE;
94              
95 0           return ok;
96             }
97              
98 0           void Check_assert_value(pTHX_ struct CheckData *data, SV *value)
99             {
100 0 0         if(check_value(data, value))
101 0           return;
102              
103 0           croak_sv(data->assertmess);
104             }