#include #include #include #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif using namespace std; using namespace Xapian; /* PerlStopper class * * Make operator() call Perl $OBJECT->stop_word */ class PerlStopper : public Stopper { public: PerlStopper(SV * obj) { SV_stopper_ref = newRV_inc(obj); } ~PerlStopper() { sv_2mortal(SV_stopper_ref); } bool operator()(const string &term) { dSP ; ENTER ; SAVETMPS ; PUSHMARK(SP); PUSHs(SvRV(SV_stopper_ref)); PUSHs(sv_2mortal(newSVpv(term.data(), term.size()))); PUTBACK ; int count = call_method("stop_word", G_SCALAR); SPAGAIN ; if (count != 1) croak("Perl callback badness in PerlStopper::operator()\n"); // Breaks with SvTRUE(POPs) ?!?!?! bool r = SvTRUE(SP[0]); POPs ; PUTBACK ; FREETMPS ; LEAVE ; return r; } private: SV * SV_stopper_ref; }; MODULE = Search::Xapian PACKAGE = Search::Xapian PROTOTYPES: ENABLE INCLUDE: XS/BM25Weight.xs INCLUDE: XS/BoolWeight.xs INCLUDE: XS/Database.xs INCLUDE: XS/Document.xs INCLUDE: XS/Enquire.xs INCLUDE: XS/MSet.xs INCLUDE: XS/MSetIterator.xs INCLUDE: XS/ESet.xs INCLUDE: XS/ESetIterator.xs INCLUDE: XS/RSet.xs INCLUDE: XS/Query.xs INCLUDE: XS/QueryParser.xs INCLUDE: XS/SimpleStopper.xs INCLUDE: XS/Stem.xs INCLUDE: XS/Stopper.xs INCLUDE: XS/TermIterator.xs INCLUDE: XS/PostingIterator.xs INCLUDE: XS/PositionIterator.xs INCLUDE: XS/ValueIterator.xs INCLUDE: XS/WritableDatabase.xs INCLUDE: XS/Weight.xs BOOT: { HV *mHvStash = gv_stashpv( "Search::Xapian", TRUE ); newCONSTSUB( mHvStash, "OP_AND", newSViv(Query::OP_AND) ); newCONSTSUB( mHvStash, "OP_OR", newSViv(Query::OP_OR) ); newCONSTSUB( mHvStash, "OP_AND_NOT", newSViv(Query::OP_AND_NOT) ); newCONSTSUB( mHvStash, "OP_XOR", newSViv(Query::OP_XOR) ); newCONSTSUB( mHvStash, "OP_AND_MAYBE", newSViv(Query::OP_AND_MAYBE) ); newCONSTSUB( mHvStash, "OP_FILTER", newSViv(Query::OP_FILTER) ); newCONSTSUB( mHvStash, "OP_NEAR", newSViv(Query::OP_NEAR) ); newCONSTSUB( mHvStash, "OP_PHRASE", newSViv(Query::OP_PHRASE) ); newCONSTSUB( mHvStash, "OP_ELITE_SET", newSViv(Query::OP_ELITE_SET) ); newCONSTSUB( mHvStash, "DB_OPEN", newSViv(DB_OPEN) ); newCONSTSUB( mHvStash, "DB_CREATE", newSViv(DB_CREATE) ); newCONSTSUB( mHvStash, "DB_CREATE_OR_OPEN", newSViv(DB_CREATE_OR_OPEN) ); newCONSTSUB( mHvStash, "DB_CREATE_OR_OVERWRITE", newSViv(DB_CREATE_OR_OVERWRITE) ); newCONSTSUB( mHvStash, "ENQ_DESCENDING", newSViv(Enquire::DESCENDING) ); newCONSTSUB( mHvStash, "ENQ_ASCENDING", newSViv(Enquire::ASCENDING) ); newCONSTSUB( mHvStash, "ENQ_DONT_CARE", newSViv(Enquire::DONT_CARE) ); newCONSTSUB( mHvStash, "FLAG_BOOLEAN", newSViv(QueryParser::FLAG_BOOLEAN) ); newCONSTSUB( mHvStash, "FLAG_PHRASE", newSViv(QueryParser::FLAG_PHRASE) ); newCONSTSUB( mHvStash, "FLAG_LOVEHATE", newSViv(QueryParser::FLAG_LOVEHATE) ); newCONSTSUB( mHvStash, "STEM_NONE", newSViv(QueryParser::STEM_NONE) ); newCONSTSUB( mHvStash, "STEM_SOME", newSViv(QueryParser::STEM_SOME) ); newCONSTSUB( mHvStash, "STEM_ALL", newSViv(QueryParser::STEM_ALL) ); }