File: Equ.xs

package info (click to toggle)
libsyntax-operator-equ-perl 0.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 172 kB
  • sloc: perl: 352; pascal: 34; makefile: 3
file content (105 lines) | stat: -rw-r--r-- 2,418 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*  You may distribute under the terms of either the GNU General Public License
 *  or the Artistic License (the same terms as Perl itself)
 *
 *  (C) Paul Evans, 2016-2023 -- leonerd@leonerd.org.uk
 */
#define PERL_NO_GET_CONTEXT

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "XSParseInfix.h"

#include "sv_regexp_match.c.inc"
#include "sv_numeq.c.inc"
#include "sv_streq.c.inc"

static OP *pp_equ_numeric(pTHX)
{
  dSP;
  dTARG;
  SV *lhs = TOPs, *rhs = TOPm1s;

  SvGETMAGIC(lhs);
  SvGETMAGIC(rhs);

  bool lundef = !SvOK(lhs), rundef = !SvOK(rhs);

  if(lundef || rundef) {
    POPs;
    SETs(lundef && rundef ? &PL_sv_yes : &PL_sv_no);
    RETURN;
  }

  POPs;
  SETs(sv_numeq_flags(lhs, rhs, 0) ? &PL_sv_yes : &PL_sv_no);
  RETURN;
}

static bool test_stringy_equ(pTHX_ SV *lhs, SV *rhs, bool test_rhs_regexp)
{
  SvGETMAGIC(lhs);
  SvGETMAGIC(rhs);

  bool lundef = !SvOK(lhs), rundef = !SvOK(rhs);

  if(lundef || rundef) {
    return lundef && rundef;
  }

  if(test_rhs_regexp && SvRXOK(rhs))
    return sv_regexp_match(lhs, (REGEXP *)SvRV(rhs));
  else
    return sv_streq_flags(lhs, rhs, 0);
}

static OP *pp_equ_stringy(pTHX)
{
  dSP;
  dTARG;
  SV *lhs = TOPm1s, *rhs = TOPs;

  POPs;
  SETs(test_stringy_equ(aTHX_ lhs, rhs, FALSE) ? &PL_sv_yes : &PL_sv_no);
  RETURN;
}

static OP *pp_eqr(pTHX)
{
  dSP;
  dTARG;
  SV *lhs = TOPm1s, *rhs = TOPs;

  POPs;
  SETs(test_stringy_equ(aTHX_ lhs, rhs, TRUE) ? &PL_sv_yes : &PL_sv_no);
  RETURN;
}

static const struct XSParseInfixHooks hooks_equ_numeric = {
  .cls               = XPI_CLS_EQUALITY,
  .wrapper_func_name = "Syntax::Operator::Equ::is_numequ",
  .ppaddr            = &pp_equ_numeric,
};

static const struct XSParseInfixHooks hooks_equ_stringy = {
  .cls               = XPI_CLS_EQUALITY,
  .wrapper_func_name = "Syntax::Operator::Equ::is_strequ",
  .ppaddr            = &pp_equ_stringy,
};

static const struct XSParseInfixHooks hooks_eqr = {
  .cls               = XPI_CLS_MATCH_MISC,
  .wrapper_func_name = "Syntax::Operator::Eqr::is_eqr",
  .ppaddr            = &pp_eqr,
};

MODULE = Syntax::Operator::Equ    PACKAGE = Syntax::Operator::Equ

BOOT:
  boot_xs_parse_infix(0.44);

  register_xs_parse_infix("Syntax::Operator::Equ::===", &hooks_equ_numeric, NULL);
  register_xs_parse_infix("Syntax::Operator::Equ::equ", &hooks_equ_stringy, NULL);

  register_xs_parse_infix("Syntax::Operator::Eqr::eqr", &hooks_eqr, NULL);