diff options
author | Jesse Luehrs <doy@tozt.net> | 2011-07-06 19:21:56 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2011-07-06 23:48:55 -0500 |
commit | 4a1aaf32fde2658905f84ffb76708d7ffe53480f (patch) | |
tree | a80e79bc568be9b8cafeefde4b48cbca005ca983 /smartmatch.xs | |
parent | 934895217ebd317f2506e6853d3875d7970ea6aa (diff) | |
download | smartmatch-engine-rjbs-4a1aaf32fde2658905f84ffb76708d7ffe53480f.tar.gz smartmatch-engine-rjbs-4a1aaf32fde2658905f84ffb76708d7ffe53480f.zip |
initial implementation
Diffstat (limited to 'smartmatch.xs')
-rw-r--r-- | smartmatch.xs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/smartmatch.xs b/smartmatch.xs new file mode 100644 index 0000000..b3e12c5 --- /dev/null +++ b/smartmatch.xs @@ -0,0 +1,60 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include "ppport.h" + +#include "hook_op_check_smartmatch.h" + +STATIC OP* +smartmatch_cb(pTHX_ OP *o, void *user_data) +{ + OP *left, *right, *cb_op, *list, *new; + + left = cBINOPo->op_first; + right = left->op_sibling; + + o->op_flags &= ~OPf_KIDS; + op_free(o); + + cb_op = newSVOP(OP_CONST, 0, (SV*)user_data); + list = newLISTOP(OP_LIST, 0, left, right); + new = newUNOP(OP_ENTERSUB, OPf_STACKED, + op_append_elem(OP_LIST, list, cb_op)); + + return new; +} + +UV +hook_op_check_smartmatch(void *user_data) +{ + return hook_op_check(OP_SMARTMATCH, smartmatch_cb, user_data); +} + +void * +hook_op_check_smartmatch_remove(UV id) +{ + return hook_op_check_remove(OP_SMARTMATCH, id); +} + +MODULE = smartmatch PACKAGE = smartmatch + +PROTOTYPES: DISABLE + +UV +register (cb) + SV *cb; + CODE: + if (!SvROK(cb) || SvTYPE(SvRV(cb)) != SVt_PVCV) { + croak("not a coderef"); + } + + RETVAL = hook_op_check_smartmatch(newSVsv(cb)); + OUTPUT: + RETVAL + +void +unregister (id) + UV id; + CODE: + hook_op_check_smartmatch_remove(id); |