File Coverage

lib/Syntax/Operator/Equ.xs
Criterion Covered Total %
statement 38 38 100.0
branch 16 16 100.0
condition n/a
subroutine n/a
pod n/a
total 54 54 100.0


line stmt bran cond sub pod time code
1             /* You may distribute under the terms of either the GNU General Public License
2             * or the Artistic License (the same terms as Perl itself)
3             *
4             * (C) Paul Evans, 2016-2023 -- leonerd@leonerd.org.uk
5             */
6             #define PERL_NO_GET_CONTEXT
7              
8             #include "EXTERN.h"
9             #include "perl.h"
10             #include "XSUB.h"
11              
12             #include "XSParseInfix.h"
13              
14             #include "sv_regexp_match.c.inc"
15             #include "sv_numeq.c.inc"
16             #include "sv_streq.c.inc"
17              
18 13           static OP *pp_equ_numeric(pTHX)
19             {
20 13           dSP;
21             dTARG;
22 13           SV *lhs = TOPs, *rhs = TOPm1s;
23              
24 13           SvGETMAGIC(lhs);
25 13           SvGETMAGIC(rhs);
26              
27 13           bool lundef = !SvOK(lhs), rundef = !SvOK(rhs);
28              
29 13 100         if(lundef || rundef) {
30 6           POPs;
31 6 100         SETs(lundef && rundef ? &PL_sv_yes : &PL_sv_no);
32 6           RETURN;
33             }
34              
35 7           POPs;
36 7 100         SETs(sv_numeq_flags(lhs, rhs, 0) ? &PL_sv_yes : &PL_sv_no);
37 7           RETURN;
38             }
39              
40 28           static bool test_stringy_equ(pTHX_ SV *lhs, SV *rhs, bool test_rhs_regexp)
41             {
42 28           SvGETMAGIC(lhs);
43 28           SvGETMAGIC(rhs);
44              
45 28           bool lundef = !SvOK(lhs), rundef = !SvOK(rhs);
46              
47 28 100         if(lundef || rundef) {
48 9           return lundef && rundef;
49             }
50              
51 19 100         if(test_rhs_regexp && SvRXOK(rhs))
    100          
52 6           return sv_regexp_match(lhs, (REGEXP *)SvRV(rhs));
53             else
54 13           return sv_streq_flags(lhs, rhs, 0);
55             }
56              
57 13           static OP *pp_equ_stringy(pTHX)
58             {
59 13           dSP;
60             dTARG;
61 13           SV *lhs = TOPm1s, *rhs = TOPs;
62              
63 13           POPs;
64 13 100         SETs(test_stringy_equ(aTHX_ lhs, rhs, FALSE) ? &PL_sv_yes : &PL_sv_no);
65 13           RETURN;
66             }
67              
68 15           static OP *pp_eqr(pTHX)
69             {
70 15           dSP;
71             dTARG;
72 15           SV *lhs = TOPm1s, *rhs = TOPs;
73              
74 15           POPs;
75 15 100         SETs(test_stringy_equ(aTHX_ lhs, rhs, TRUE) ? &PL_sv_yes : &PL_sv_no);
76 15           RETURN;
77             }
78              
79             static const struct XSParseInfixHooks hooks_equ_numeric = {
80             .cls = XPI_CLS_EQUALITY,
81             .wrapper_func_name = "Syntax::Operator::Equ::is_numequ",
82             .ppaddr = &pp_equ_numeric,
83             };
84              
85             static const struct XSParseInfixHooks hooks_equ_stringy = {
86             .cls = XPI_CLS_EQUALITY,
87             .wrapper_func_name = "Syntax::Operator::Equ::is_strequ",
88             .ppaddr = &pp_equ_stringy,
89             };
90              
91             static const struct XSParseInfixHooks hooks_eqr = {
92             .cls = XPI_CLS_MATCH_MISC,
93             .wrapper_func_name = "Syntax::Operator::Eqr::is_eqr",
94             .ppaddr = &pp_eqr,
95             };
96              
97             MODULE = Syntax::Operator::Equ PACKAGE = Syntax::Operator::Equ
98              
99             BOOT:
100 7           boot_xs_parse_infix(0.44);
101              
102 7           register_xs_parse_infix("Syntax::Operator::Equ::===", &hooks_equ_numeric, NULL);
103 7           register_xs_parse_infix("Syntax::Operator::Equ::equ", &hooks_equ_stringy, NULL);
104              
105 7           register_xs_parse_infix("Syntax::Operator::Eqr::eqr", &hooks_eqr, NULL);