1 %module(directors="1") xapian 2 %{ 3 /* ruby.i: SWIG interface file for the Ruby bindings 4 * 5 * Original version by Paul Legato (plegato@nks.net), 4/17/06. 6 * Based on the php4 and python util.i files. 7 * 8 * Copyright (C) 2006 Networked Knowledge Systems, Inc. 9 * Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2019 Olly Betts 10 * Copyright (C) 2010 Richard Boulton 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License as 14 * published by the Free Software Foundation; either version 2 of the 15 * License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 25 * USA 26 */ 27 28 %} 29 30 %begin %{ 31 // The Ruby 2.3 headers contain things which cause warnings with more recent 32 // C++ compilers. There's nothing we can really do about them, so just 33 // suppress them. 34 #ifdef __clang__ 35 # pragma clang diagnostic push 36 # pragma clang diagnostic ignored "-Wdeprecated-register" 37 # pragma clang diagnostic ignored "-Wreserved-user-defined-literal" 38 #elif defined __GNUC__ 39 // Warning added in GCC 4.8 and we don't support anything older. 40 # pragma GCC diagnostic push 41 # pragma GCC diagnostic ignored "-Wliteral-suffix" 42 #endif 43 44 #include <ruby.h> 45 46 #ifdef __clang__ 47 # pragma clang diagnostic pop 48 #elif defined __GNUC__ 49 # pragma GCC diagnostic pop 50 #endif 51 %} 52 53 // Use SWIG directors for Ruby wrappers. 54 #define XAPIAN_SWIG_DIRECTORS 55 56 // We don't use the Iterator and ConstIterator wrappers which SWIG now offers, 57 // so disable them to reduce the generated C++ wrapper code. 58 #define SWIG_NO_EXPORT_ITERATOR_METHODS 59 60 %include ../xapian-head.i 61 62 ///////////////////////////////////// 63 // Rename function and method names to match Ruby conventions 64 // e.g. from get_data to data and from set_data to data= 65 66 // Getters 67 %rename("available_languages") get_available_languages; 68 %rename("avlength") get_avlength; 69 %rename("collapse_count") get_collapse_count; 70 %rename("collection_freq") get_collection_freq; 71 %rename("context") get_context; 72 %rename("data") get_data; 73 %rename("default_op") get_default_op; 74 %rename("description") get_description; 75 %rename("docid") get_docid; 76 %rename("document_id") get_document_id; 77 %rename("document_percentage") get_document_percentage; 78 %rename("doccount") get_doccount; 79 %rename("doclength") get_doclength; 80 %rename("document") get_document; 81 %rename("ebound") get_ebound; 82 %rename("eset") get_eset; 83 %rename("firstitem") get_firstitem; 84 %rename("hit") get_hit; 85 %rename("lastdocid") get_lastdocid; 86 %rename("length") get_length; 87 %rename("matches_estimated") get_matches_estimated; 88 %rename("matches_lower_bound") get_matches_lower_bound; 89 %rename("matches_upper_bound") get_matches_upper_bound; 90 %rename("matching_terms") get_matching_terms; 91 %rename("max_attained") get_max_attained; 92 %rename("max_possible") get_max_possible; 93 %rename("maxextra") get_maxextra; 94 %rename("maxpart") get_maxpart; 95 %rename("mset") get_mset; 96 %rename("msg") get_msg; 97 %rename("op_name") get_op_name; 98 %rename("percent") get_percent; 99 %rename("query") get_query; 100 %rename("rank") get_rank; 101 %rename("sumextra") get_sumextra; 102 %rename("sumpart") get_sumpart; 103 %rename("termfreq") get_termfreq; 104 %rename("terms") get_terms; 105 %rename("term") get_term; 106 %rename("termpos") get_termpos; 107 %rename("termweight") get_termweight; 108 %rename("type") get_type; 109 %rename("value") get_value; 110 %rename("valueno") get_valueno; 111 %rename("wdf") get_wdf; 112 %rename("weight") get_weight; 113 114 // These are 'dangerous' methods; i.e. they can cause a segfault if used 115 // improperly. We prefix with _dangerous_ so that Ruby users will not use them 116 // inadvertently. 117 // 118 // There is a safe wrapper for their functionality provided in xapian.rb. 119 120 // in Xapian::Document and Xapian::Database 121 %rename("_dangerous_termlist_begin") termlist_begin; 122 %rename("_dangerous_termlist_end") termlist_end; 123 // in Xapian::Query 124 %rename("_dangerous_terms_begin") get_terms_begin; 125 %rename("_dangerous_terms_end") get_terms_end; 126 // in Xapian::Query 127 %rename("_dangerous_unique_terms_begin") get_unique_terms_begin; 128 %rename("_dangerous_unique_terms_end") get_unique_terms_end; 129 // in Xapian::Enquire 130 %rename("_dangerous_matching_terms_begin") get_matching_terms_begin; 131 %rename("_dangerous_matching_terms_end") get_matching_terms_end; 132 // in Xapian::Database 133 %rename("_dangerous_allterms_begin") allterms_begin; 134 %rename("_dangerous_allterms_end") allterms_end; 135 // in Xapian::Database 136 %rename("_dangerous_metadata_keys_begin") metadata_keys_begin; 137 %rename("_dangerous_metadata_keys_end") metadata_keys_end; 138 // in Xapian::Database 139 %rename("_dangerous_postlist_begin") postlist_begin; 140 %rename("_dangerous_postlist_end") postlist_end; 141 // in Xapian::Database 142 %rename("_dangerous_positionlist_begin") positionlist_begin; 143 %rename("_dangerous_positionlist_end") positionlist_end; 144 // in Xapian::Database 145 %rename("_dangerous_spellings_begin") spellings_begin; 146 %rename("_dangerous_spellings_end") spellings_end; 147 // in Xapian::Database 148 %rename("_dangerous_synonyms_begin") synonyms_begin; 149 %rename("_dangerous_synonyms_end") synonyms_end; 150 // in Xapian::Database 151 %rename("_dangerous_synonym_keys_begin") synonym_keys_begin; 152 %rename("_dangerous_synonym_keys_end") synonym_keys_end; 153 // in Xapian::Database 154 %rename("_dangerous_valuestream_begin") valuestream_begin; 155 %rename("_dangerous_valuestream_end") valuestream_end; 156 // in Xapian::Document and Xapian::ValueCountMatchSpy 157 %rename("_dangerous_values_begin") values_begin; 158 %rename("_dangerous_values_end") values_end; 159 // in Xapian::ValueCountMatchSpy 160 %rename("_dangerous_top_values_begin") top_values_begin; 161 %rename("_dangerous_top_values_end") top_values_end; 162 // in Xapian::QueryParser 163 %rename("_dangerous_stoplist_begin") stoplist_begin; 164 %rename("_dangerous_stoplist_end") stoplist_end; 165 // in Xapian::QueryParser 166 %rename("_dangerous_unstem_begin") unstem_begin; 167 %rename("_dangerous_unstem_end") unstem_end; 168 169 170 // MSetIterators are not dangerous, just inconvenient to use within a Ruby 171 // idiom. 172 %rename ("_begin") begin; 173 %rename ("_end") end; 174 %rename ("_back") back; 175 176 177 178 // Setters 179 %rename("collapse_key=") set_collapse_key; 180 %rename("cutoff!") set_cutoff; 181 %rename("data=") set_data; 182 %rename("database=") set_database; 183 %rename("default_op=") set_default_op; 184 %rename("docid_order=") set_docid_order; 185 %rename("document=") set_document; 186 %rename("query=") set_query(const Xapian::Query &); 187 %rename("query!") set_query(const Xapian::Query &, Xapian::termcount qlen); 188 %rename("sort_by_relevance!") set_sort_by_relevance; 189 %rename("sort_by_relevance_then_value!") set_sort_by_relevance_then_value; 190 %rename("sort_by_value_then_relevance!") set_sort_by_value_then_relevance; 191 %rename("sort_by_value!") set_sort_by_value; 192 %rename("stemmer=") set_stemmer; 193 %rename("stemming_strategy=") set_stemming_strategy; 194 %rename("stopper=") set_stopper; 195 %rename("weighting_scheme=") set_weighting_scheme; 196 197 // Booleans 198 %predicate empty; 199 200 #define XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP 201 202 /* FIXME: 203 * Check to see what is equivalent to a C++ Vector for the purposes of a Query 204 * instantiation. 205 * At the moment, we take Ruby Arrays. 206 */ 207 %typemap(typecheck, precedence=500) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) { 208 $1 = (TYPE($input) == T_ARRAY); 209 /* Currently, the only wrapped method which takes a Ruby array is the 210 * "extra" constructor Query(OP, ARRAY), where ARRAY can contain any mix of 211 * strings and Query objects. 212 * 213 * If we ever had a method (or function) which had two overloaded forms 214 * only differentiated by what type of array can be passed we'd need to 215 * look at the type of the array elements in the typecheck typemaps. 216 */ 217 } 218 219 %{ 220 class XapianSWIGQueryItor { 221 VALUE array; 222 223 int i; 224 225 public: 226 typedef std::random_access_iterator_tag iterator_category; 227 typedef Xapian::Query value_type; 228 typedef Xapian::termcount_diff difference_type; 229 typedef Xapian::Query * pointer; 230 typedef Xapian::Query & reference; 231 XapianSWIGQueryItor()232 XapianSWIGQueryItor() { } 233 begin(VALUE array_)234 void begin(VALUE array_) { 235 array = array_; 236 i = 0; 237 } 238 end(int n)239 void end(int n) { 240 i = n; 241 } 242 243 XapianSWIGQueryItor & operator++() { 244 ++i; 245 return *this; 246 } 247 248 Xapian::Query operator*() const { 249 VALUE entry = rb_ary_entry(array, i); 250 if (TYPE(entry) == T_STRING) { 251 return Xapian::Query(string(RSTRING_PTR(entry), 252 RSTRING_LEN(entry))); 253 } 254 255 // array element may be a Xapian::Query object. Add it if it is, 256 // otherwise error out. 257 Xapian::Query *subq = 0; 258 if (SWIG_ConvertPtr(entry, (void **)&subq, 259 SWIGTYPE_p_Xapian__Query, 0) < 0 || !subq) { 260 SWIG_exception(SWIG_ValueError, "Elements of Arrays passed to Query must be either Strings or other Query objects"); 261 return Xapian::Query(); 262 } 263 return *subq; 264 } 265 266 bool operator==(const XapianSWIGQueryItor & o) { 267 return i == o.i; 268 } 269 270 bool operator!=(const XapianSWIGQueryItor & o) { 271 return !(*this == o); 272 } 273 274 difference_type operator-(const XapianSWIGQueryItor &o) const { 275 return i - o.i; 276 } 277 }; 278 279 %} 280 281 %typemap(in) (XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend) { 282 if (TYPE($input) == T_ARRAY) { 283 // The typecheck typemap should have ensured this is an array. 284 $1.begin($input); 285 $2.end(RARRAY_LEN($input)); 286 } else { 287 $1.end(0); 288 $2.end(0); 289 } 290 } 291 292 %typemap(directorin) (size_t num_tags, const std::string tags[]) { 293 $input = rb_ary_new(); 294 for (size_t i = 0; i != num_tags; ++i) { 295 VALUE str = rb_str_new(tags[i].data(), tags[i].size()); 296 rb_ary_push($input, str); 297 } 298 } 299 300 // For MatchDecider::operator() and ExpandDecider::operator(). 301 %typemap(directorout) int = bool; 302 303 %include ../generic/except.i 304 305 %include ../xapian-headers.i 306 307 %include extra.i 308