1 %module
(directors
="1") xapian
3 /* php.i
: SWIG interface file for the PHP bindings
5 * Copyright
(C
) 2004-2022 Olly Betts
7 * This program is free software
; you can redistribute it and
/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation
; either version
2 of the
10 * License
, or
(at your option
) any later version.
12 * This program is distributed in the hope that it will be useful
,
13 * but WITHOUT
ANY WARRANTY
; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program
; if not
, write to the Free Software
19 * Foundation
, Inc.
, 51 Franklin St
, Fifth Floor
, Boston
, MA
02110-1301
23 #include
"../xapian-version.h"
26 // This works around a build failure on Illuminos
:
27 // https
://trac.xapian.org
/ticket
/793
34 // Needed for php_array_merge
().
35 #include
<ext
/standard
/php_array.h
>
39 // Use SWIG directors for PHP wrappers.
40 #define XAPIAN_SWIG_DIRECTORS
42 %include ..
/xapian-head.i
44 /* Add a section to the output from phpinfo
().
*/
45 %pragma
(php
) phpinfo
="\
46 php_info_print_table_start();\n\
47 php_info_print_table_row(2, \"Xapian Support\
", \"enabled\
");\n\
48 php_info_print_table_row(2, \"Xapian Compiled Version\
",\n\
49 XAPIAN_BINDINGS_VERSION);\n\
50 php_info_print_table_row(2, \"Xapian Linked Version\
",\n\
51 Xapian::version_string());\n\
52 php_info_print_table_end();\
55 %pragma
(php
) version
=PACKAGE_VERSION
57 %rename
("is_empty") empty
() const
;
58 %rename
("clone_object") clone
() const
;
60 /* Handle op as an int rather than an enum.
*/
61 %apply int
{ Xapian
::Query
::op
};
63 /* STRING has a lower precedence that numbers
, but the SWIG PHP check for
64 * number
(in
1.3.28 at least
) includes IS_STRING which means that for a
65 * method taking either int or string
, the int version will always be used.
66 * Simplest workaround is to set the precedence here higher that the numeric
67 * precedences
- i.e. SWIG_TYPECHECK_VOIDPTR instead of SWIG_TYPECHECK_STRING.
69 %typemap
(typecheck
, precedence
=SWIG_TYPECHECK_VOIDPTR
) const std
::string
& {
70 $
1 = (Z_TYPE
($input
) == IS_STRING
);
73 /* The SWIG overloading doesn't handle this correctly by default.
*/
74 %typemap
(typecheck
, precedence
=SWIG_TYPECHECK_BOOL
) bool
{
75 $
1 = (Z_TYPE
($input
) == IS_TRUE || Z_TYPE
($input
) == IS_FALSE || Z_TYPE
($input
) == IS_LONG
);
78 #define XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP
80 %typemap
(typecheck
, precedence
=500) (XapianSWIGQueryItor qbegin
, XapianSWIGQueryItor qend
) {
81 $
1 = (Z_TYPE
($input
) == IS_ARRAY
);
82 /* FIXME
: if we add more array typemaps
, we'll need to check the elements
83 * of the array here to disambiguate.
*/
87 /** Merge _ps properties.
89 * We use these to keep references to XapianPostingSource objects used in
90 * XapianQuery objects.
92 static void merge_ps_references
(zval
* target_this
, zval
& input) {
93 zval
* zvq
= zend_read_property
(Z_OBJCE
(input
), Z_OBJ
(input
), "_ps", strlen
("_ps"), false
, NULL);
94 if
(zend_hash_num_elements
(Z_ARR_P
(zvq
)) > 0) {
95 zval
* zv
= zend_read_property
(Z_OBJCE_P
(target_this
), Z_OBJ_P
(target_this
), "_ps", strlen
("_ps"), false
, NULL);
96 if
(zend_hash_num_elements
(Z_ARR_P
(zv
)) == 0) {
100 php_array_merge
(Z_ARR_P
(zv
), Z_ARR_P
(zvq
));
105 class XapianSWIGQueryItor
{
106 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
116 typedef std
::random_access_iterator_tag iterator_category
;
117 typedef Xapian
::Query value_type
;
118 typedef Xapian
::termcount_diff difference_type
;
119 typedef Xapian
::Query
* pointer
;
120 typedef Xapian
::Query
& reference;
122 XapianSWIGQueryItor
()
125 void begin
(zval
* input
, zval
* target_this_
) {
126 HashTable
*ht
= Z_ARRVAL_P
(input
);
127 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
130 elt_size
= ZEND_HASH_ELEMENT_SIZE
(ht
);
131 p
= ZEND_HASH_ELEMENT
(ht
, 0);
133 target_this
= target_this_
;
136 void end
(zval
* input
) {
137 HashTable
*ht
= Z_ARRVAL_P
(input
);
138 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
139 p
= ht-
>arData
+ ht-
>nNumUsed
;
141 elt_size
= ZEND_HASH_ELEMENT_SIZE
(ht
);
142 p
= ZEND_HASH_ELEMENT
(ht
, ht-
>nNumUsed
);
146 XapianSWIGQueryItor
& operator++() {
147 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
150 p
= ZEND_HASH_NEXT_ELEMENT
(p
, elt_size
);
155 Xapian
::Query operator
*() const
{
156 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
157 zval
*item
= &p->val;
162 if
(Z_TYPE_P
(item
) == IS_STRING
) {
163 size_t len
= Z_STRLEN_P
(item
);
164 const char
*str
= Z_STRVAL_P
(item
);
165 return Xapian
::Query
(string
(str
, len
));
168 Xapian
::Query
*subq
= 0;
169 if
(SWIG_ConvertPtr
(item
, (void
**)&subq,
170 SWIGTYPE_p_Xapian__Query
, 0) < 0) {
174 SWIG_PHP_Error
(E_ERROR
, "Expected XapianQuery object or string");
175 fail
: // Label which SWIG_PHP_Error needs.
176 return Xapian
::Query
();
178 merge_ps_references
(target_this
, *item
);
182 bool operator
==(const XapianSWIGQueryItor
& o) {
186 bool operator
!=(const XapianSWIGQueryItor
& o) {
187 return
!(*this
== o
);
190 difference_type operator-
(const XapianSWIGQueryItor
&o) const {
191 #if PHP_MAJOR_VERSION
== 8 && PHP_MINOR_VERSION < 2
194 auto d
= reinterpret_cast
<const char
*>(p
) -
195 reinterpret_cast
<const char
*>(o.p
);
203 %typemap
(in
, phptype
="array") (XapianSWIGQueryItor qbegin
, XapianSWIGQueryItor qend
) {
204 // $
1 and $
2 are default initialised where SWIG declares them.
205 if
(Z_TYPE
($input
) == IS_ARRAY
) {
206 // The typecheck typemap should have ensured this is an array.
207 $
1.begin
(&$input, ZEND_THIS);
212 #define XAPIAN_TERMITERATOR_PAIR_OUTPUT_TYPEMAP
213 %typemap
(out
, phptype
="array") std
::pair
<Xapian
::TermIterator
, Xapian
::TermIterator
> {
216 for
(Xapian
::TermIterator i
= $
1.first
; i
!= $
1.second
; ++i
) {
217 const string
& term = *i;
218 add_next_index_stringl
($result
, term.data
(), term.length
());
222 %typemap
(directorin
) (size_t num_tags
, const std
::string tags
[]) {
223 array_init_size
($input
, num_tags
);
225 for
(size_t i
= 0; i
!= num_tags
; ++i
) {
226 const string
& term = tags[i];
227 add_next_index_stringl
($input
, term.data
(), term.length
());
232 #include
<xapian
/iterator.h
>
235 %define PHP_ITERATOR
(NS
, CLASS
, RET_TYPE
, REWIND_ACTION
)
236 %typemap
("phpinterfaces") NS
::CLASS
"Iterator";
238 const NS
::CLASS
& key() { return *self; }
239 RET_TYPE current
() { return
**self
; }
240 bool valid
() { return Xapian
::iterator_valid
(*self
); }
241 void rewind
() { REWIND_ACTION
}
245 PHP_ITERATOR
(Xapian
, ESetIterator
, std
::string
, Xapian
::iterator_rewind
(*self
);)
246 PHP_ITERATOR
(Xapian
, MSetIterator
, Xapian
::docid
, Xapian
::iterator_rewind
(*self
);)
247 PHP_ITERATOR
(Xapian
, TermIterator
, std
::string
, )
248 PHP_ITERATOR
(Xapian
, PositionIterator
, Xapian
::termpos
, )
249 PHP_ITERATOR
(Xapian
, PostingIterator
, Xapian
::docid
, )
250 PHP_ITERATOR
(Xapian
, ValueIterator
, std
::string
, )
254 %define XAPIAN_FUNCTOR
(CLASS
, PARAM, CODE...
)
255 %typemap
(in
, phptype
="SWIGTYPE") (CLASS
PARAM) %{
261 XAPIAN_FUNCTOR
(Xapian
::FieldProcessor
*, proc
,
262 zval
* zv
= zend_read_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_procs", strlen
("_procs"), false
, NULL);
265 add_next_index_zval
(zv
, &$input);
268 XAPIAN_FUNCTOR
(Xapian
::RangeProcessor
*, range_proc
,
269 zval
* zv
= zend_read_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_procs", strlen
("_procs"), false
, NULL);
272 add_next_index_zval
(zv
, &$input);
275 XAPIAN_FUNCTOR
(Xapian
::Stopper
*, stop
,
276 zend_update_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_stopper", strlen
("_stopper"), &$input);
279 XAPIAN_FUNCTOR
(Xapian
::KeyMaker
*, sorter
,
280 zend_update_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_sorter", strlen
("_sorter"), &$input);
283 // Unset _sorter on any set_sort_by_...
() which sets sorting by a slot.
284 %typemap
(in
, phptype
="int") (Xapian
::valueno sort_key
) %{
285 $typemap
(in
, Xapian
::valueno
)
286 zend_update_property_null
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_sorter", strlen
("_sorter"));
289 %typemap
(out
, phptype
="void") (void Xapian
::Enquire
::set_sort_by_relevance
) %{
290 zend_update_property_null
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_sorter", strlen
("_sorter"));
293 %typemap
(out
, phptype
="void") (void Xapian
::Enquire
::clear_matchspies
) %{
294 { zval z
; ZVAL_EMPTY_ARRAY
(&z); zend_update_property(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), "_spies", strlen("_spies"), &z); }
297 XAPIAN_FUNCTOR
(Xapian
::MatchSpy
*, spy
,
298 zval
* zv
= zend_read_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_spies", strlen
("_spies"), false
, NULL);
301 add_next_index_zval
(zv
, &$input);
304 XAPIAN_FUNCTOR
(Xapian
::PostingSource
*, source
,
305 zval
* zv
= zend_read_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_ps", strlen
("_ps"), false
, NULL);
308 add_next_index_zval
(zv
, &$input);
311 XAPIAN_FUNCTOR
(const Xapian
::Query
&, a, merge_ps_references(ZEND_THIS, $input);)
313 XAPIAN_FUNCTOR
(const Xapian
::Query
&, b, merge_ps_references(ZEND_THIS, $input);)
315 XAPIAN_FUNCTOR
(const Xapian
::Query
&, subquery, merge_ps_references(ZEND_THIS, $input);)
317 // Enquire
::set_query
() stores the PHP query object
, which means we hold on to any
318 // references to PHP XapianPostingSource objects it contains.
319 XAPIAN_FUNCTOR
(const Xapian
::Query
&, query,
320 zend_update_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_query", strlen
("_query"), &$input);
323 // Then Enquire
::get_query
() returns the PHP query object if one is set
, otherwise
324 // it returns the result C
++ gave us
(which will be an empty XapianQuery object.
325 // We could avoid calling C
++ at all here
, but I don't see an easy way to do so.
326 // This isn't a widely used method
, and the C
++ call should be pretty cheap anyway.
327 %typemap
(out
, phptype
="SWIGTYPE") (const Xapian
::Query
& Xapian::Enquire::get_query) %{
329 zval
* zv
= zend_read_property
(Z_OBJCE_P
(ZEND_THIS
), Z_OBJ_P
(ZEND_THIS
), "_query", strlen
("_query"), false
, NULL);
330 if
(Z_TYPE_P
(zv
) == IS_OBJECT
) {
331 RETVAL_OBJ_COPY
(Z_OBJ_P
(zv
));
333 $typemap
(out
, const Query
&)
338 %include ..
/xapian-headers.i
340 // Compatibility wrapping for Xapian
::BAD_VALUENO
(wrapped as a constant since
341 // xapian-bindings
1.4.10).
344 static Xapian
::valueno BAD_VALUENO_get
() { return Xapian
::BAD_VALUENO
; }
347 // Can't throw an exception.
348 %exception Xapian
::BAD_VALUENO_get
"$action"