/* guile-xapian --- Guile bindings for Xapian
* Copyright © 2020, 2023–2024 Arun Isaac <arunisaac@systemreboot.net>
* Copyright © 2021, 2022 Bob131 <bob@bob131.so>
*
* This file is part of guile-xapian.
*
* guile-xapian is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* guile-xapian is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with guile-xapian. If not, see
* <https://www.gnu.org/licenses/>.
*/
%module wrap
%{
%}
%scheme
%{
;; Try loading the shared library by absolute path. If that fails, try
;; searching for it using LD_LIBRARY_PATH and other mechanisms. We do this
;; so that guile-xapian finds libguilexapian both before and after installation.
(catch #t
(lambda ()
(load-extension "@libdir@/libguilexapian-@GUILE_EFFECTIVE_VERSION@" "SWIG_init"))
(lambda _
(load-extension "libguilexapian-@GUILE_EFFECTIVE_VERSION@" "SWIG_init")))
%}
%{
#include <string>
// We introduce a dummy typedef for std::string without declaring it
// to SWIG so we can establish a new SWIG typemap applying only to
// certain redeclarations of existing C++ functions taking or
// returning strings.
typedef std::string SWIG_bytevector;
static inline void typemap_in_SWIG_bytevector (SWIG_bytevector& out, SCM in) {
out.assign ((char*) SCM_BYTEVECTOR_CONTENTS (in),
SCM_BYTEVECTOR_LENGTH (in));
}
static inline SCM typemap_out_SWIG_bytevector (const SWIG_bytevector& in) {
SCM result = scm_c_make_bytevector (in.size ());
memcpy (SCM_BYTEVECTOR_CONTENTS (result), in.data (), in.size ());
return result;
}
%}
%typemap(in) SWIG_bytevector {
if (scm_is_bytevector ($input)) {
$1 = std::string ();
typemap_in_SWIG_bytevector ($1, $input);
} else {
%argument_fail (SWIG_TypeError, "$type", $symname, $argnum);
}
}
%typemap(in) SWIG_bytevector&, SWIG_bytevector* {
if (scm_is_bytevector ($input)) {
$1 = new std::string ();
typemap_in_SWIG_bytevector (*$1, $input);
} else {
%argument_fail (SWIG_TypeError, "$type", $symname, $argnum);
}
}
%typemap(out) SWIG_bytevector {
$result = typemap_out_SWIG_bytevector ($1);
}
%typemap(out) SWIG_bytevector&, SWIG_bytevector* {
$result = typemap_out_SWIG_bytevector (*$1);
}
%typecheck(SWIG_TYPECHECK_SWIGOBJECT)
SWIG_bytevector, SWIG_bytevector&, SWIG_bytevector*
{
$1 = scm_is_bytevector ($input);
}
%include xapian-head.i
%include except.i
%include xapian-headers.i
%extend Xapian::ValueIterator {
SWIG_bytevector get_value_bytes () {
return **$self;
}
}
%extend Xapian::Document {
SWIG_bytevector get_value_bytes (Xapian::valueno valueno) {
return $self->get_value (valueno);
}
void add_value_bytes (Xapian::valueno valueno, const SWIG_bytevector& bytes) {
$self->add_value (valueno, bytes);
}
SWIG_bytevector get_data_bytes () {
return $self->get_data ();
}
void set_data_bytes (const SWIG_bytevector& bytes) {
$self->set_data (bytes);
}
}
%extend Xapian::Database {
SWIG_bytevector get_metadata_bytes (const std::string& key) {
return $self->get_metadata (key);
}
}
%extend Xapian::WritableDatabase {
void set_metadata_bytes (const std::string& key,
const SWIG_bytevector& bytes)
{
$self->set_metadata (key, bytes);
}
}
%extend Xapian::Query {
Query (op op_, Xapian::valueno slot, const SWIG_bytevector& range_limit) {
return new Xapian::Query (op_, slot, range_limit);
}
Query (op op_, Xapian::valueno slot,
const SWIG_bytevector& range_lower, const SWIG_bytevector& range_upper)
{
return new Xapian::Query (op_, slot, range_lower, range_upper);
}
}
// Child class of Xapian::RangeProcessor that calls back to a
// user-specified Scheme procedure to process fields.
%{
class GuileXapianRangeProcessorWrapper
: public Xapian::RangeProcessor {
private:
SCM proc;
public:
GuileXapianRangeProcessorWrapper(Xapian::valueno slot, const std::string &str, unsigned flags, SCM _proc)
: Xapian::RangeProcessor(slot, str, flags) {
proc = _proc;
}
Xapian::Query operator()(const std::string &begin, const std::string &end) {
void *ptr;
int res = SWIG_ConvertPtr(scm_call_2(proc,
begin.empty() ? SCM_BOOL_F : scm_from_utf8_string(begin.c_str()),
end.empty() ? SCM_BOOL_F : scm_from_utf8_string(end.c_str())),
&ptr,
SWIGTYPE_p_Xapian__Query,
0);
return *((Xapian::Query*)ptr);
}
};
%}
class GuileXapianRangeProcessorWrapper
: public Xapian::RangeProcessor
{
public:
GuileXapianRangeProcessorWrapper(Xapian::valueno, std::string const&, unsigned, SCM);
~GuileXapianRangeProcessorWrapper();
Xapian::Query operator()(std::string const&, std::string const&);
};
// Child class of Xapian::FieldProcessor that calls back to a
// user-specified Scheme procedure to process fields.
%{
class GuileXapianFieldProcessorWrapper
: public Xapian::FieldProcessor {
private:
SCM proc;
public:
GuileXapianFieldProcessorWrapper(SCM _proc) {
proc = _proc;
}
Xapian::Query operator()(const std::string &str) {
void *ptr;
int res = SWIG_ConvertPtr(scm_call_1(proc, scm_from_utf8_string(str.c_str())),
&ptr,
SWIGTYPE_p_Xapian__Query,
0);
return *((Xapian::Query*)ptr);
}
};
%}
class GuileXapianFieldProcessorWrapper
: public Xapian::FieldProcessor
{
public:
GuileXapianFieldProcessorWrapper(SCM);
~GuileXapianFieldProcessorWrapper();
Xapian::Query operator()(std::string const&);
};