1 /* lua
/util.i
: custom lua typemaps for xapian-bindings
3 * Copyright
(C
) 2011 Xiaona Han
4 * Copyright
(C
) 2011,2012,2017 Olly Betts
6 * This program is free software
; you can redistribute it and
/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation
; either version
2 of the
9 * License
, or
(at your option
) any later version.
11 * This program is distributed in the hope that it will be useful
,
12 * but WITHOUT
ANY WARRANTY
; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program
; if not
, write to the Free Software
18 * Foundation
, Inc.
, 51 Franklin St
, Fifth Floor
, Boston
, MA
02110-1301
22 // "end" is a keyword in Lua
, so we rename it to
"_end"
25 %rename
("__tostring") get_description
;
28 #if LUA_VERSION_NUM-0
>= 502
29 // luaL_typerror was removed in Lua
5.2.
30 int luaL_typerror
(lua_State
*L
, int narg
, const char
*tname
) {
31 const char
*msg
= lua_pushfstring
(L
, "%s expected, got %s",
32 tname
, luaL_typename
(L
, narg
));
33 return luaL_argerror
(L
, narg
, msg
);
38 %define SUB_CLASS
(NS
, CLASS
)
40 class lua##CLASS
: public NS
::CLASS
{
45 lua##CLASS
(lua_State
* S
) {
47 if
(!lua_isfunction
(L
, -1)) {
48 luaL_typerror
(L
, -1, "function");
50 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
54 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
57 bool operator
()(const std
::string
&term) const {
58 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
59 if
(!lua_isfunction
(L
, -1)) {
60 luaL_typerror
(L
, -1, "function");
63 lua_pushlstring
(L
, (char
*)term.c_str
(), term.length
());
64 if
(lua_pcall
(L
, 1, 1, 0) != 0) {
65 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
67 if
(!lua_isboolean
(L
, -1)) {
68 luaL_error
(L
, "function must return a boolean");
70 bool result
= lua_toboolean
(L
, -1);
79 SUB_CLASS
(Xapian
, ExpandDecider
)
80 SUB_CLASS
(Xapian
, Stopper
)
83 class luaMatchDecider
: public Xapian
::MatchDecider
{
88 luaMatchDecider
(lua_State
* S
) {
90 if
(!lua_isfunction
(L
, -1)) {
91 luaL_typerror
(L
, -1, "function");
93 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
97 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
100 bool operator
()(const Xapian
::Document
&doc) const {
101 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
102 if
(!lua_isfunction
(L
, -1)) {
103 luaL_typerror
(L
, -1, "function");
106 SWIG_NewPointerObj
(L
, &doc, SWIGTYPE_p_Xapian__Document, 0);
107 if
(lua_pcall
(L
, 1, 1, 0) != 0) {
108 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
110 if
(!lua_isboolean
(L
, -1)) {
111 luaL_error
(L
, "function must return a boolean");
113 bool result
= lua_toboolean
(L
, -1);
121 class luaStemImplementation
: public Xapian
::StemImplementation
{
126 luaStemImplementation
(lua_State
* S
) {
128 if
(!lua_isfunction
(L
, -1)) {
129 luaL_typerror
(L
, -1, "function");
131 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
134 ~luaStemImplementation
() {
135 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
138 std
::string operator
()(const std
::string
&word) {
139 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
140 if
(!lua_isfunction
(L
, -1)) {
141 luaL_typerror
(L
, -1, "function");
144 lua_pushlstring
(L
, (char
*)word.c_str
(), word.length
());
145 if
(lua_pcall
(L
, 1, 1, 0) != 0) {
146 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
148 if
(!lua_isstring
(L
, -1)) {
149 luaL_error
(L
, "function must return a string");
152 const char
* p
= lua_tolstring
(L
, -1, &len);
153 std
::string result
(p
, len
);
158 std
::string get_description
() const
{
159 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
160 if
(!lua_isfunction
(L
, -1)) {
161 luaL_typerror
(L
, -1, "function");
164 if
(lua_pcall
(L
, 0, 1, 0) != 0) {
165 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
167 if
(!lua_isstring
(L
, -1)) {
168 luaL_error
(L
, "function must return a string");
172 const char
* p
= lua_tolstring
(L
, -1, &len);
173 std
::string result
(p
, len
);
181 class luaKeyMaker
: public Xapian
::KeyMaker
{
186 luaKeyMaker
(lua_State
* S
) {
188 if
(!lua_isfunction
(L
, -1)) {
189 luaL_typerror
(L
, -1, "function");
191 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
195 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
198 std
::string operator
()(const Xapian
::Document
&doc) const {
199 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
200 if
(!lua_isfunction
(L
, -1)) {
201 luaL_typerror
(L
, -1, "function");
204 SWIG_NewPointerObj
(L
, &doc, SWIGTYPE_p_Xapian__Document, 0);
205 if
(lua_pcall
(L
, 1, 1, 0) != 0) {
206 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
208 if
(!lua_isstring
(L
, -1)) {
209 luaL_error
(L
, "function must return a string");
212 const char
* p
= lua_tolstring
(L
, -1, &len);
213 std
::string result
(p
, len
);
221 class luaRangeProcessor
: public Xapian
::RangeProcessor
{
226 luaRangeProcessor
(lua_State
* S
) {
228 if
(!lua_isfunction
(L
, -1)) {
229 luaL_typerror
(L
, -1, "function");
231 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
234 ~luaRangeProcessor
() {
235 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
238 Xapian
::Query operator
()(const std
::string
& begin, const std::string& end) {
239 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
240 if
(!lua_isfunction
(L
, -1)) {
241 luaL_typerror
(L
, -1, "function");
244 lua_pushlstring
(L
, (char
*)begin.c_str
(), begin.length
());
245 lua_pushlstring
(L
, (char
*)end.c_str
(), end.length
());
247 if
(lua_pcall
(L
, 2, 1, 0) != 0) {
248 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
251 // Allow the function to return a string or Query object.
252 if
(lua_isstring
(L
, -1)) {
254 const char
* p
= lua_tolstring
(L
, -1, &len);
255 std
::string result
(p
, len
);
257 return Xapian
::Query
(result
);
260 Xapian
::Query
*subq
= 0;
261 if
(!lua_isuserdata
(L
, -1) ||
262 SWIG_ConvertPtr
(L
, -1, (void
**)&subq,
263 SWIGTYPE_p_Xapian__Query
, 0) == -1) {
265 luaL_error
(L
, "function must return a string or Query object");
275 class luaValueRangeProcessor
: public Xapian
::ValueRangeProcessor
{
280 luaValueRangeProcessor
(lua_State
* S
) {
282 if
(!lua_isfunction
(L
, -1)) {
283 luaL_typerror
(L
, -1, "function");
285 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
288 ~luaValueRangeProcessor
() {
289 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
292 Xapian
::valueno operator
()(std
::string
&begin, std::string &end) {
293 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
294 if
(!lua_isfunction
(L
, -1)) {
295 luaL_typerror
(L
, -1, "function");
298 lua_pushlstring
(L
, (char
*)begin.c_str
(), begin.length
());
299 lua_pushlstring
(L
, (char
*)end.c_str
(), end.length
());
301 if
(lua_pcall
(L
, 2, 1, 0) != 0) {
302 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
304 if
(!lua_isnumber
(L
, -1)) {
305 luaL_error
(L
, "function must return a number");
307 Xapian
::valueno result
(lua_tonumber
(L
, -1));
315 class luaFieldProcessor
: public Xapian
::FieldProcessor
{
320 luaFieldProcessor
(lua_State
* S
) {
322 if
(!lua_isfunction
(L
, -1)) {
323 luaL_typerror
(L
, -1, "function");
325 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
328 ~luaFieldProcessor
() {
329 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
332 Xapian
::Query operator
()(const std
::string
&str) {
333 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
334 if
(!lua_isfunction
(L
, -1)) {
335 luaL_typerror
(L
, -1, "function");
338 lua_pushlstring
(L
, (char
*)str.c_str
(), str.length
());
340 if
(lua_pcall
(L
, 1, 1, 0) != 0) {
341 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
344 // Allow the function to return a string or Query object.
345 if
(lua_isstring
(L
, -1)) {
347 const char
* p
= lua_tolstring
(L
, -1, &len);
348 std
::string result
(p
, len
);
350 return Xapian
::Query
(result
);
353 Xapian
::Query
*subq
= 0;
354 if
(!lua_isuserdata
(L
, -1) ||
355 SWIG_ConvertPtr
(L
, -1, (void
**)&subq,
356 SWIGTYPE_p_Xapian__Query
, 0) == -1) {
358 luaL_error
(L
, "function must return a string or Query object");
368 class luaMatchSpy
: public Xapian
::MatchSpy
{
373 luaMatchSpy
(lua_State
* S
) {
375 if
(!lua_isfunction
(L
, -1)) {
376 luaL_typerror
(L
, -1, "function");
378 r
= luaL_ref
(L
, LUA_REGISTRYINDEX
);
382 luaL_unref
(L
, LUA_REGISTRYINDEX
, r
);
385 void operator
()(const Xapian
::Document
&doc, double wt) {
386 lua_rawgeti
(L
, LUA_REGISTRYINDEX
, r
);
387 if
(!lua_isfunction
(L
, -1)) {
388 luaL_typerror
(L
, -1, "function");
391 SWIG_NewPointerObj
(L
, &doc, SWIGTYPE_p_Xapian__Document, 0);
392 SWIG_NewPointerObj
(L
, &wt, SWIGTYPE_p_Xapian__Weight, 0);
393 if
(lua_pcall
(L
, 2, 1, 0) != 0) {
394 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
400 %define SUB_CLASS_TYPEMAPS
(NS
, CLASS
)
402 %typemap
(typecheck
, precedence
=100) NS
::CLASS
* {
404 if
(lua_isfunction
(L
, $input
) ||
(SWIG_isptrtype
(L
, $input
) && !SWIG_ConvertPtr(L, $input, (void **) &ptr, $descriptor(NS::CLASS *), 0))) {
410 %typemap
(in
) NS
::CLASS
* {
411 if
(lua_isfunction
(L
, $input
)) {
412 $
1 = new lua##CLASS
(L
);
414 if
(!SWIG_IsOK
(SWIG_ConvertPtr
(L
, $input
, (void
**)&$1, $descriptor(NS::CLASS *), 0))) {
421 SUB_CLASS_TYPEMAPS
(Xapian
, MatchDecider
)
422 SUB_CLASS_TYPEMAPS
(Xapian
, ExpandDecider
)
423 SUB_CLASS_TYPEMAPS
(Xapian
, Stopper
)
424 SUB_CLASS_TYPEMAPS
(Xapian
, StemImplementation
)
425 SUB_CLASS_TYPEMAPS
(Xapian
, KeyMaker
)
426 SUB_CLASS_TYPEMAPS
(Xapian
, RangeProcessor
)
427 SUB_CLASS_TYPEMAPS
(Xapian
, ValueRangeProcessor
)
428 SUB_CLASS_TYPEMAPS
(Xapian
, FieldProcessor
)
431 function xapian.Iterator
(begin
, _end
)
435 if iter
:equals
(_end
) then
443 if iter
:equals
(_end
) then
453 #define XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP
455 %typemap
(typecheck
, precedence
=500) (XapianSWIGQueryItor qbegin
, XapianSWIGQueryItor qend
) {
456 $
1 = lua_istable
(L
, $input
);
457 /* FIXME
: if we add more array typemaps
, we'll need to check the elements
458 * of the array here to disambiguate.
*/
462 class XapianSWIGQueryItor
{
468 typedef std
::random_access_iterator_tag iterator_category
;
469 typedef Xapian
::Query value_type
;
470 typedef Xapian
::termcount_diff difference_type
;
471 typedef Xapian
::Query
* pointer
;
472 typedef Xapian
::Query
& reference;
474 XapianSWIGQueryItor
() { }
476 void begin
(lua_State
* S
, int index_
) {
482 void end
(lua_State
* S
, int index_
, int n
) {
492 XapianSWIGQueryItor
& operator++() {
497 Xapian
::Query operator
*() const
{
498 lua_rawgeti
(L
, index
, i
+1);
499 if
(lua_isstring
(L
, -1)) {
501 const char
*p
= lua_tolstring
(L
, -1, &len);
503 return Xapian
::Query
(string
(p
, len
));
506 Xapian
::Query
*subq
= 0;
507 if
(!lua_isuserdata
(L
, -1) ||
508 SWIG_ConvertPtr
(L
, -1, (void
**)&subq,
509 SWIGTYPE_p_Xapian__Query
, 0) == -1) {
511 luaL_argerror
(L
, index
,
512 "elements must be Query objects or strings");
519 bool operator
==(const XapianSWIGQueryItor
& o) {
523 bool operator
!=(const XapianSWIGQueryItor
& o) {
524 return
!(*this
== o
);
527 difference_type operator-
(const XapianSWIGQueryItor
&o) const {
534 %typemap
(in
) (XapianSWIGQueryItor qbegin
, XapianSWIGQueryItor qend
) {
535 if
(lua_istable
(L
, $input
)) {
537 $
2.end
(L
, $input
, lua_rawlen
(L
, $input
));
544 %define OUTPUT_ITERATOR_METHODS
(NS
, CLASS
, ITERATOR_CLASS
, ITERATOR_BEGIN
, ITERATOR_END
, DEREF_METHOD
, PARAMETER_NAME
, PARAMETER_VALUE
)
547 std
::pair
<NS
::ITERATOR_CLASS
, NS
::ITERATOR_CLASS
> DEREF_METHOD
(PARAMETER_NAME
) {
548 return std
::make_pair
($self-
>ITERATOR_BEGIN
(PARAMETER_VALUE
), $self-
>ITERATOR_END
(PARAMETER_VALUE
));
552 %typemap
(out
) std
::pair
<NS
::ITERATOR_CLASS
, NS
::ITERATOR_CLASS
> {
553 lua_getglobal
(L
, "xapian");
554 lua_pushstring
(L
, "Iterator");
558 if
(!lua_isfunction
(L
, -1)) {
559 luaL_typerror
(L
, -1, "function");
562 NS
::ITERATOR_CLASS
* begin
= new NS
::ITERATOR_CLASS
((const NS
::ITERATOR_CLASS
&)$1.first);
563 SWIG_NewPointerObj
(L
, (void
*) begin
, $descriptor
(NS
::ITERATOR_CLASS
*), 1);
565 NS
::ITERATOR_CLASS
* end
= new NS
::ITERATOR_CLASS
((const NS
::ITERATOR_CLASS
&)$1.second);
566 SWIG_NewPointerObj
(L
, (void
*) end
, $descriptor
(NS
::ITERATOR_CLASS
*), 1);
568 if
(lua_pcall
(L
, 2, 1, 0) != 0) {
569 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));
577 OUTPUT_ITERATOR_METHODS
(Xapian
, Query
, TermIterator
, get_terms_begin
, get_terms_end
, get_terms
, void
, )
579 OUTPUT_ITERATOR_METHODS
(Xapian
, QueryParser
, TermIterator
, stoplist_begin
, stoplist_end
, stoplist
, void
, )
581 OUTPUT_ITERATOR_METHODS
(Xapian
, ESet
, ESetIterator
, begin
, end
, terms
, void
, )
583 OUTPUT_ITERATOR_METHODS
(Xapian
, MSet
, MSetIterator
, begin
, end
, items
, void
, )
585 OUTPUT_ITERATOR_METHODS
(Xapian
, Document
, TermIterator
, termlist_begin
, termlist_end
, termlist
, void
, )
586 OUTPUT_ITERATOR_METHODS
(Xapian
, Document
, ValueIterator
, values_begin
, values_end
, values
, void
, )
588 OUTPUT_ITERATOR_METHODS
(Xapian
, Enquire
, TermIterator
, get_matching_terms_begin
, get_matching_terms_end
, get_matching_terms
, Xapian
::docid did
, did
)
589 OUTPUT_ITERATOR_METHODS
(Xapian
, Enquire
, TermIterator
, get_matching_terms_begin
, get_matching_terms_end
, get_matching_terms
, const MSetIterator
&it, it)
591 OUTPUT_ITERATOR_METHODS
(Xapian
, ValueCountMatchSpy
, TermIterator
, values_begin
, values_end
, values
, void
, )
592 OUTPUT_ITERATOR_METHODS
(Xapian
, ValueCountMatchSpy
, TermIterator
, top_values_begin
, top_values_end
, top_values
, size_t maxvalues
, maxvalues
)
594 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, allterms_begin
, allterms_end
, allterms
, void
, )
595 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, spellings_begin
, spellings_end
, spellings
, void
, )
596 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, PostingIterator
, postlist_begin
, postlist_end
, postlist
, const std
::string
&tname, tname)
597 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, termlist_begin
, termlist_end
, termlist
, Xapian
::docid did
, did
)
598 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, ValueIterator
, valuestream_begin
, valuestream_end
, valuestream
, Xapian
::valueno slot
, slot
)
599 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, allterms_begin
, allterms_end
, allterms
, const std
::string
&prefix, prefix)
600 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, synonyms_begin
, synonyms_end
, synonyms
, const std
::string
&term, term)
601 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, synonym_keys_begin
, synonym_keys_end
, synonym_keys
, const std
::string
&prefix, prefix)
602 OUTPUT_ITERATOR_METHODS
(Xapian
, Database
, TermIterator
, metadata_keys_begin
, metadata_keys_end
, metadata_keys
, const std
::string
&prefix, prefix)
604 %extend Xapian
::Database
{
605 std
::pair
<Xapian
::PositionIterator
, Xapian
::PositionIterator
> positionlist
(Xapian
::docid did
, const std
::string
&tname) {
606 return std
::make_pair
($self-
>positionlist_begin
(did
, tname
), $self-
>positionlist_end
(did
, tname
));
610 %typemap
(out
) std
::pair
<Xapian
::PositionIterator
, Xapian
::PositionIterator
> {
611 lua_getglobal
(L
, "xapian");
612 lua_pushstring
(L
, "Iterator");
616 if
(!lua_isfunction
(L
, -1)) {
617 luaL_typerror
(L
, -1, "function");
620 Xapian
::PositionIterator
* begin
= new Xapian
::PositionIterator
((const Xapian
::PositionIterator
&)$1.first);
621 SWIG_NewPointerObj
(L
, (void
*) begin
, SWIGTYPE_p_Xapian__PositionIterator
, 1);
623 Xapian
::PositionIterator
* end
= new Xapian
::PositionIterator
((const Xapian
::PositionIterator
&)$1.second);
624 SWIG_NewPointerObj
(L
, (void
*) end
, SWIGTYPE_p_Xapian__PositionIterator
, 1);
626 if
(lua_pcall
(L
, 2, 1, 0) != 0) {
627 luaL_error
(L
, "error running function: %s", lua_tostring
(L
, -1));