aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Isaac2020-02-15 19:25:30 +0530
committerArun Isaac2020-02-15 19:34:29 +0530
commit9a1bfc6980fb492149ad795330f0d5b17a3b59cf (patch)
tree54a017fb98582e2c5f1160c08411df58aaa60e98
downloadguile-xapian-9a1bfc6980fb492149ad795330f0d5b17a3b59cf.tar.gz
guile-xapian-9a1bfc6980fb492149ad795330f0d5b17a3b59cf.tar.lz
guile-xapian-9a1bfc6980fb492149ad795330f0d5b17a3b59cf.zip
First commit.
-rw-r--r--COPYING339
-rw-r--r--Makefile.am50
-rw-r--r--README.org64
-rw-r--r--configure.ac34
-rw-r--r--examples/100-objects.sexp100
-rw-r--r--examples/index.scm48
-rw-r--r--examples/search.scm50
-rw-r--r--guix.scm65
-rw-r--r--pre-inst-env.in29
-rw-r--r--xapian-head.i113
-rw-r--r--xapian-headers.i471
-rw-r--r--xapian.i31
-rw-r--r--xapian/wrap.scm902
-rw-r--r--xapian/xapian.scm124
14 files changed, 2420 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program 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.
+
+ This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..bb1b74f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,50 @@
+# guile-xapian --- Guile bindings for Xapian
+# Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+#
+# 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/>.
+
+# Xapian wrapper
+
+lib_LTLIBRARIES = libguilexapian.la
+
+BUILT_SOURCES = xapian_wrap.cc
+libguilexapian_la_SOURCES = xapian_wrap.cc
+libguilexapian_la_CXXFLAGS = $(GUILE_CFLAGS) $(XAPIAN_CFLAGS)
+libguilexapian_la_LDFLAGS = $(GUILE_LIBS) $(XAPIAN_LIBS)
+
+xapian_wrap.cc: xapian.i xapian-head.i xapian-headers.i
+ $(SWIG) $(XAPIAN_CFLAGS) -scmstub -o $@ -guile -package xapian -c++ $<
+
+xapian_wrap.scm: xapian_wrap.cc
+
+# Guile code
+
+moddir = $(prefix)/share/guile/site/$(GUILE_EFFECTIVE_VERSION)
+godir = $(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache
+
+SOURCES = xapian/wrap.scm xapian/xapian.scm
+GOBJECTS = $(SOURCES:%.scm=%.go)
+
+nobase_mod_DATA = $(SOURCES)
+nobase_go_DATA = $(GOBJECTS)
+
+CLEANFILES = $(GOBJECTS)
+EXTRA_DIST = $(SOURCES)
+GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
+SUFFIXES = .scm .go
+.scm.go:
+ $(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILD) compile $(GUILE_WARNINGS) -o "$@" "$<"
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..ca961d2
--- /dev/null
+++ b/README.org
@@ -0,0 +1,64 @@
+#+TITLE: guile-xapian
+#+OPTIONS: *:nil
+
+guile-xapian provides Guile bindings for [[https://xapian.org][Xapian]], a search engine
+library. Xapian is a highly adaptable toolkit which allows developers
+to easily add advanced indexing and search facilities to their own
+applications. It has built-in support for several families of
+weighting models and also supports a rich set of boolean query
+operators.
+
+Once these bindings are sufficiently mature, they will be merged with
+[[https://github.com/xapian/xapian/tree/master/xapian-bindings][xapian-bindings]]. This will involve creating more complete
+Scheme-friendly wrapping of the Xapian library, writing test cases and
+documentation.
+
+There is no proper documentation yet. See the examples in the source
+tree. Also see [[https://getting-started-with-xapian.readthedocs.io/en/latest/index.html][Getting Started with Xapian]] which describes the Python
+bindings.
+
+* Usage
+
+Drop into a development environment.
+
+#+BEGIN_SRC sh
+guix environment -l guix.scm
+#+END_SRC
+
+Bootstrap autotools, then configure and make.
+
+#+BEGIN_SRC sh
+./bootstrap.sh
+./configure
+make
+#+END_SRC
+
+Try out the examples.
+
+First, let's index data in examples/100-objects.sexp creating a
+Xapian database at /tmp/db.
+
+#+BEGIN_SRC sh
+./pre-inst-env guile -s examples/index.scm examples/100-objects.sexp /tmp/db
+#+END_SRC
+
+Then, we may run searches on the database. Shown below are a few
+example searches.
+
+#+BEGIN_SRC sh
+./pre-inst-env guile -s examples/search.scm /tmp/db watch
+./pre-inst-env guile -s examples/search.scm /tmp/db Dent watch
+./pre-inst-env guile -s examples/search.scm /tmp/db title:sunwatch
+./pre-inst-env guile -s examples/search.scm /tmp/db description:\"leather case\" AND title:sundial
+#+END_SRC
+
+* Contributing
+
+Feedback, suggestions, feature requests and bug reports are all
+welcome. Please write to me at [[mailto:arunisaac@systemreboot.net][arunisaac@systemreboot.net]].
+
+* License
+
+guile-xapian is free software released under the terms of the [[https://www.gnu.org/licenses/gpl-3.0.html][GNU
+General Public License]], either version 2 of the License, or (at your
+option) any later version.
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..6814e48
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,34 @@
+dnl guile-xapian --- Guile bindings for Xapian
+dnl Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+dnl
+dnl This file is part of guile-xapian.
+dnl
+dnl guile-xapian is free software: you can redistribute it and/or
+dnl modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation, either version 2 of the
+dnl License, or (at your option) any later version.
+dnl
+dnl guile-xapian is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with guile-xapian. If not, see
+dnl <https://www.gnu.org/licenses/>.
+
+AC_INIT([guile-xapian], [0.1.0])
+AM_INIT_AUTOMAKE([color-tests -Wall -Wno-portability foreign check-news no-dist-gzip dist-lzip])
+AM_SILENT_RULES([yes])
+LT_INIT
+
+AC_PROG_CXX
+AX_PKG_SWIG
+PKG_CHECK_MODULES([GUILE], [guile-2.2])
+GUILE_PROGS
+PKG_CHECK_MODULES([XAPIAN], [xapian-core])
+PKG_CHECK_MODULES([ZLIB], [zlib])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([pre-inst-env], [chmod +x pre-inst-env])
+AC_OUTPUT
diff --git a/examples/100-objects.sexp b/examples/100-objects.sexp
new file mode 100644
index 0000000..addfd38
--- /dev/null
+++ b/examples/100-objects.sexp
@@ -0,0 +1,100 @@
+(("Ansonia Sunwatch (pocket compass dial)" "Ansonia Sunwatch (pocket compas dial)" "1974-100")
+ ("Model of train of wheels used in a clock (full size) with pair of vanes and base" "Model of train of wheels used in a clock (full size) with pa" "1883-74")
+ ("Ship's log-glass in wooden mount. 14 secs. Abbot Horne No.22. Type B" "Ship's log-glass in wooden mount. 14 secs. Abbot Horne No.22" "1953-404")
+ ("Watch with Chinese duplex escapement" "Watch with Chinese duplex escapement" "1970-377")
+ ("\"Ever Ready\" ceiling clock" "\"Ever Ready\" ceiling clock" "1979-5")
+ ("Ivory diptych dial by Jasper Milner" "Ivory diptych dial by Jasper Milner" "1938-371")
+ ("Dead-beat escapement model (full size) with wooden stand." "Dead-beat escapement model (full size) with wooden stand." "1883-64")
+ ("Large single sand-glass in wooden mount, 21 1/2\" long x 11\" diameter. Abbot Horne No.111. Type A" "Large single sand-glass in wooden mount, 21 1/2\" long x 11\"" "1953-448")
+ ("Copy of a Dwerrihouse skeleton clock with coup-perdu escapement. Made by Thwaites and Reed, London, England, 1973. No. 88 of a limited edition of 100." "Copy of a Dwerrihouse skeleton clock with coup-perdu escape" "1985-438")
+ ("Synchronome free pendulum clock, patented by F. Hope-Jones in 1935, in oak case, lacks both pendulums, with weight (probably not original)" "Synchronome free pendulum clock, patented by F. Hope-Jones i" "1985-475")
+ ("\"Timetrunk\" by Hines and Co., Glasgow (a sandglass for timing telephone calls)" "\"Timetrunk\" by Hines and Co., Glasgow (a sandglass for timin" "1985-770")
+ ("Electric clock kit in original box and a similar clock which has been assembled, by EXA, Belgium, 1931-1939. Support stand broken on finished dock. Lid of box containing finished clock missing." "Assembled and unassembled EXA electric clock kit" "1985-1202")
+ ("Watch timer by P.L. Instruments Ltd., Welwyn Garden City; with tuning fork standard and spark printer" "Watch timer by P" "1985-1538")
+ ("Horizontal sundial in bronze dated, 1551 with initials W.B. (? William Buckley). Possibly by Thomas Gemini" "Horizontal sundial in bronze dated, 1551 with initials W.B." "1985-1389")
+ ("Ingersoll \"Dan Dare\" automaton pocket watch with pin-pallet lever escapement. The dial shows a helmeted Dan Dare holding a ray gun, with a monster approaching. The emblem of the \" Eagle\" children's comic is impressed in the back of case." "Ingersoll \"Dan Dare\" automaton pocket watch with pin-pallet" "1985-1914")
+ ("Copy of the gearing of the Byzantine sundial-calendar (1983-1393) three times true size, conjecturally completed, in perspex and brass" "Copy of the gearing of the Byzantine sundial-calendar (1983-" "1985-172")
+ ("Column dial by Henry Robert, Horloger, au Palais Royal, paper on wood, early 19th century" "Column dial by Henry Robert, Horloger, au Palais Royal, pape" "1955-303")
+ ("Solar/Sidereal verge watch with epicyclic maintaining power by James Green, London, no. 5969, in silver pair case hallmarked 1776, believed to be the earliest English watch to indicate solar and sidereal time with seconds." "Solar/Sidereal verge watch with epicyclic maintaining power" "1987-1145")
+ ("Photograph (portrait) of Dent's chronometer with glass balance spring, taken by the School of Military Engineering, Chatham, Kent, England, 1870-1876" "Photograph of Dent's chronometer with glass balance spring" "1876-19")
+ ("Copy of the drawing representing Galileo's idea of the application of the pendulum to the clock, 1659." "Drawing Representing Galileo's Proposal for the Application of the Pendulum to the Clock, 1659, copy" "1876-70")
+ ("Ancient stone sundial - plaster cast" "Ancient stone sundial - plaster cast" "1876-322")
+ ("Bashforth's Chronograph with screens, frame and weights, invented c. 1865." "Bashforth's Chronograph with screens, frame and weights, inv" "1876-377")
+ ("Description of the Chronograph, given by Mr. Bashforth (Note:- may be accepted as presented with the chronograph)" "Description of the Chronograph, given by Mr" "1876-950")
+ ("Clock with gravity escapement constructed by Mr. J. M. Bloxam, 1845-1855." "Regulator Clock with Gravity Escapement" "1879-32")
+ ("Universal ringdial brass (part silvered), diameter 8 1/2\", brassplate 3 3/8 In. square, French, 18th century" "Universal ringdial brass (part silvered), diameter 8 1/2\", b" "1880-29")
+ ("Sundial and compass with perpetual calendar and lunar circles. Brass, part silvered, 6 1/8 x 5 3/8-inches. By Christopher Kohler, Dresden, Germany, 1677. Glass of compass box cracked, compass needle missing." "Sundial and compass with perpetual calendar and lunar circles" "1880-30")
+ ("Sundial, Brass, gromon and heads of levelling screws gilt. Plate 8 in. by 6 7/8 in. Invented by Julien le Roy. Made by Langlois, French. 1730-1751" "Sundial" "1880-31")
+ ("Sundial with separate compass. Brass gilt 8 5/8\" by 7 1/2\". Compass plate 3in. square. By Godfried Weiss, German, late 17th or early 18th century" "Sundial with separate compass. Brass gilt 8 5/8\" by 7 1/2\"." "1880-34")
+ ("Sundial and compass, brass gilt, dial plate 10 3/4in. by 8 3/4in. Engraved \"Franz Antoni Knitl Linz, fecit\". Austrian, late 17th or early 18th century" "Sundial and compass, brass gilt, dial plate 10 3/4in. by 8 3" "1880-35")
+ ("A universal equinoctial sundial signed \"Carl Von Mandern fecit Hafnia\" (Copenhagen), 18th century" "A universal equinoctial sundial signed \"Carl Von Mandern fec" "1985-2001")
+ ("Portable universal equinoctial sundial, in brass, signed \"A Ryther * Fecit * 1588\" with inscription \"WILLIAM PAWLEY OWETH THIS SAME IN ANNO DOMINI 1588\". Diameter 50mm. With compass needle (not original)." "Portable universal equinoctial sundial, in brass, signed \"A" "1985-2021")
+ ("Glass bowl in the shape of an ancient Egyptian water-clock, 1940-1965" "Glass Bowl Replicating an Egyptian Water Clock, 1940-1965" "1969-479")
+ ("A device by Favag of Neuchatel which enables a stop watch to be operated by an electric signal, 1961" "A device by Favag of Neuchatel which enables a stop watch to" "1986-516")
+ ("\"Ticket\" clock by Ever-Ready in mahogany case with reeded brass pillars, c.1915" "\"Ticket\" clock by Ever-Ready in mahogany case with reeded br" "1986-279")
+ ("Synchronome master clock (No.6133), fitted with a seconds switch and a centre seconds slave dial. With a battery charger" "Synchronome master clock (No" "1986-1153")
+ ("'Tri-Compax' calendar chronograph wristwatch in gold case, by Universal, Geneva, Switzerland, 1960-1986." "Universal 'Tri-Compax' chronographic wrist watch" "1986-91")
+ ("\"Silent Triangle\" 1/2 minute impulse dial movement by Gents of Leicester, patented 1925" "\"Silent Triangle\" 1/2 minute impulse dial movement by Gents" "1986-1553")
+ ("Dipleidoscope, signed Plossl In Wien" "Dipleidoscope, signed Plossl In Wien" "1986-1695")
+ ("Electric clock of the Bain type" "Electric clock of the Bain type" "1987-213")
+ ("Millisecond Stopclock type TSA3314 by Venner Electronics Limited, 1963" "Millisecond Stopclock type TSA3314 by Venner Electronics Lim" "1987-238")
+ ("Frequency and time measuring instrument type TSA3436 by Venner Electronics Limited, 1965 with cover" "Frequency and time measuring instrument type TSA3436 by Venn" "1987-239")
+ ("MKV11b quartz timer by Hurd-Brown Limited, Bolton c.1955" "MKV11b quartz timer by Hurd-Brown Limited, Bolton c.1955" "1987-241")
+ ("Loughborough-Hayes automatic timing apparatus. Used by the RAC to time motor sporting events from 1936 to 1962. Comprising; 1) Rythmic starter motor and lights. 2) Start and finish photocells. 3) 2 `hockey stick' switches. 4) Tuning fork. 5) Amplifier for maintaining the tuning fork and driving the chronography. 6) Chronograph. 7) Control box. 8) Connecting wires and loudspeaker" "Loughborough-Hayes automatic timing apparatus. Used by the R" "1987-240")
+ ("Two-dial clock by the Self-Winding Clock Co; as used on the London underground" "Two-dial clock by the Self-Winding Clock Co; as used on the" "1987-294")
+ ("Master clock of the \"Silent Electric\" type made by the Magneto Time division of the British Vacuum Cleaner and Engineering Co. Ltd." "Master clock of the \"Silent Electric\" type made by the Magne" "1987-295")
+ ("Model by Dent of mechanism for setting hands and winding up a keyless watch" "Model by Dent of mechanism for setting hands and winding up" "1883-68")
+ ("Model of Swiss lever escapement, and clockwork winding key" "Model of Swiss lever escapement, and clockwork winding key" "1984-633")
+ ("Synchronous mains electric clock of the non self-starting type by Ferranti with 24 hour alarm and illuminated dial c.1936" "Synchronous mains electric clock of the non self-starting ty" "1984-1143")
+ ("Digital wristwatch with \"jumping hour\", lever escapement, Swiss, c.1932" "Digital wristwatch with \"jumping hour\", lever escapement, Sw" "1984-1275")
+ ("Quartz Analogue \"no battery\" wristwatch by Pulsar Quartz (CAL. V103), 1984, in presentation box, powered by an amorphous silicon photocell with reserve power provided by a capacitor." "Quartz Analogue \"no battery\" wristwatch by Pulsar Quartz (CA" "1984-1415")
+ ("Analogue quartz clock with voice controlled alarm by Braun, 1984, type 47763/AB30vs with original packing and instructional manual, supplied by Selfridges" "Analogue quartz clock with voice controlled alarm by Braun," "1984-1611")
+ ("Reconstruction of Dondi clock, which represents a working model of the universe. Its movements, dials and calender are kept in motion by the weight driven clock, 1974" "Reconstruction of Dondi's Astronomical Clock, 1974" "1974-386")
+ ("Electric clock of the bulle type probably made by The British Horo Electric Company, 1930' s" "Electric clock of the bulle type probably made by The Britis" "1984-1688")
+ ("Sol-horometer, by Pilkington and Gibbs, Preston, design patented in 1911" "Sol-horometer, by Pilkington and Gibbs, Preston, design pate" "1985-73")
+ ("Altitude sundial, in silver, for latitude 51°30 secs. (London), signed Humfray Colle, in original tooled leather case, by Humfrey Cole, London, England, 1568-1590 (see note)." "Silver altitude sundial in leather case" "1985-100")
+ ("Single sandglass in 4 pillared wood mount, running time 15 1/2 minutes, Horne Type B, height 138mm." "Single sandglass in 4 pillared wood mount, running time 15 1" "1907-153")
+ ("Electric clock by Alexander Bain, in case" "Electric clock by Alexander Bain, in case" "1909-135")
+ ("The \"Empire\" clock, to show the time at various longitudes, with parts" "The \"Empire\" clock, to show the time at various longitudes," "1909-199")
+ ("Electrically operated clock controller by J. Lund, United Kingdom, 1876-1905." "Electrically operated clock controller" "1909-474")
+ ("Sand glass (old sermon glass)" "Sand glass (old sermon glass)" "1911-209")
+ ("Van der Plancke master clock" "Van der Plancke master clock" "1912-224")
+ ("Van der Plancke impulse dial mechanism" "Van der Plancke impulse dial mechanism" "1912-225")
+ ("Peyer Favarger, Hipp dial movement" "Peyer Favarger, Hipp dial movement" "1912-228")
+ ("Morse electrical clock, dial mechanism" "Morse electrical clock, dial mechanism" "1912-230")
+ ("Electric time piece with hands but without dial (no pendulum)" "Electric time piece with hands but without dial (no pendulum" "1913-564")
+ ("Sundial, brass, baseplate 7 1/4in. by 6in., late 17th century. Engraved (M. Kolwein fecit Vienna 48 Gral 14 min)" "Sundial, brass, baseplate 7 1/4in. by 6in., late 17th centur" "1880-40")
+ ("Nocturnal, brass gilt, diameter 2 3/4in. Italian, early 17th century" "Nocturnal, brass gilt, diameter 2 3/4in. Italian, early 17th" "1880-42")
+ ("Perpetual Calendar, brass scroll-work chased. Revolving plates silvered. Length 5 3/8-inches. Made in France, 1801-1830." "Ornate brass Perpetual Calendar" "1880-44")
+ ("Sundial, brass, originally silvered, base plate 9in. by 6 7/8in. Engraved Joseph Modestin in Chindin (Bohemia), German, 18th century. Sights of alidate and one small brass screen missing" "Sundial, brass, originally silvered, base plate 9in. by 6 7/" "1880-45")
+ ("Sundial with compass, brass gilt, silvered circles. Diameter 6in. Engraved No.116 Se 61812, Toda M. Uda Rymoe. German, late 17th century (cover glass of compass box cracked)" "Sundial with compass, brass gilt, silvered circles. Diameter" "1880-46")
+ ("Clock with pendulum showing action of snail plate and repeater." "Clock with pendulum showing action of snail plate and repeat" "1883-95")
+ ("Perpetual calendar, gilt metal, 2½ x 9/16-inches, Germany, 1701-1800." "German Perpetual Calendar in gilt metal" "1883-120")
+ ("Universal pocket sundial, silver with gilt hour ring and pin gnomon, diameter 1¾-inches, by Johann Martin, Augsburg, Germany, 1701-1721 (see note)." "Universal pocket sundial" "1883-121")
+ ("Sundial, made as a locket, gilt metal, part silver, 1¾-inches square, by Juan Cocart, madrid, Spain, 1596 (see note)." "Sundial, made as a locket, gilt metal, part silver" "1883-122")
+ ("Column sun-dial, gilt bronze (639-65). 9in. high, diam. of pillar = 2in. V and A. Museum Reg. Imperfect, no compass or cover glass, 1531-1570" "Column Sundial in Gilt Bronze, Unsigned, 1531-1570" "1883-124")
+ ("Cubical sun-dial (30-81 V. and A. M. Reg), in wood, painted in distemper, Italian, 1550-1570." "Italian Cubical Sundial, Unsigned, 1550-1570" "1883-128")
+ ("Column sun-dial (21-1879 V and A. M. Reg), height 9 1/8inches, 1601-1700, gilt metal, on square base, surmounted by figure of dragon" "Column Sundial with Dragon Design, Unsigned, 1601-1700" "1883-132")
+ ("Pocket sun-dial, brass, by Nicolas Bion, Paris, France, 1680-1733." "Brass sundial" "1883-137")
+ ("Sun-dial Brass, French (23-79 V. and A. M. Reg), late 17th or early 18th century with four levelling screws (compass needle and gloves missing)" "Sun-dial Brass, French (23-79 V. and A. M. Reg), late 17th o" "1883-139")
+ ("Tablet sun-dial, gilt metal, string gnomon, 3 3/8 x 2 3/8-inches, Germany, 1597. For use at latitude 50°. Engraved on base with circular tables of Julian and Gregorian epacts 1597-1615, and lunar circle. Bead threaded onto gnomon allows determination of planetary or Jewish hours (see note)." "Tablet sun-dial in gilt metal" "1883-140")
+ ("Bistoury, curved and probe-ended, steel and ebony, by Eggington of Manchester, 19th century" "" "A616989")
+ ("Clock made by Benjamin Vulliamy for His Majesty George III, and used in his Observatory at Kew. In polished mahogany case, with a side plate and glass top for case" "Movement of regulator clock by Vulliamy, about 1760" "1884-79")
+ ("Original eight day clock by Harrison, date 1715, wheel work mostly of wood. With correspondence concerning Harrison clocks" "Harrison's eight-day wooden clock movement, 1715." "1884-80")
+ ("Horizontal, magnetic sundial, silvered, in brass case, diameter 3.75-inches, dial made in England, 1801-1900 (see note)." "Magnetic sundial in brass case" "1887-13")
+ ("Boulenges chronograph for the determination of the velocity of projectiles, with zinc tubes for records, includes additional zinc tubes and an illustration" "Boulenges chronograph for the determination of the velocity" "1887-27")
+ ("Model of chronometer escapement, for use with a projecting latern, made by Dent, 1950-1883. Represents the detent chronometer escapement, invented by Thomas Earnshaw 1777-1787. This escapement was typically used in marine chronometers." "Model representing Earnshaw's detent chronometer escapement, 1950-1883" "1883-67")
+ ("Sundial, Gnomon fixed on a cannon over touch hole of which a lens is fixed. French, 1782, of cast bronze. Base 8 1/2\" square" "Sundial, Gnomon fixed on a cannon over touch hole of which a" "1880-52")
+ ("Tablet azimuth sundial, with compass, engraved. Ivory, 3¼ x 2½-inches, by Charles (Carolus) Bloud, Dieppe, France, 1650-1686. With equatorial dial in the upper leaf (see note)." "Bloud sundial" "1880-53")
+ ("Tablet sundial with compass, ivory with coloured engraving, 4¼ x 2½-inches, Germany, 1648 (see note)." "Diptych dials" "1880-54")
+ ("Tablet sundial with compass, engraved ivory, highly decorative with religious images, 3 x 2¾-inches, Germany, 1601-1700. With subsidiary dial (see note)." "Tablet sundial of ivory" "1880-55")
+ ("Model showing the first idea of the application of the pendulum to the clock designed by Galileo in 1642, made his son Vincenzo in 1649 and illustrated by Vincenzo Viviani, Italy. This model is by Eustachio Porcellotti, Florence, Italy, 1883." "Pendulum clock designed by Galileo in 1642 and made by his son in 1649, model." "1883-29")
+ ("Model of recoil escapement of clock, with pendulum and wooden stand, having a hollow cylindrical bob, marked \"Mech Lab 100\"" "Model of recoil escapement of clock, with pendulum and woode" "1883-54")
+ ("Model by Dent of Graham's cylinder escapement for use with lantern, 1850-1883" "Model of Graham's Cylinder Escapement, 1850-1883" "1883-65")
+ ("Model by Dent of lever escapement for use with lantern, 1850-1883" "Model of a Lever Escapement , 1850-1883" "1883-66")
+ ("1/4-repeater verge by Lieutand a Aix, in silver case, London, hall mark 1803, donated by Evan Roberts in 1916" "1/4-repeater in case" "1916-229")
+ ("Clock with Hipp pendulum (an electric driven clock with Hipp butterfly escapement) with a door of back of case" "Clock with Hipp pendulum (an electric driven clock with Hipp" "1913-567")
+ ("Subsidiary electric clock (no weight, hands, pulley and suspension spring) by Alexander Bain, United Kingdom, 1875-1885." "Bain's subsidiary electric clock" "1913-580")
+ ("'Pond' electric clock (movement only, no dial), by Self Winding Clock Company, New York, United States, 1905-1913." "'Pond' electric clock movement (no dial)" "1913-581")
+ ("15th Century Iron striking clock with 17th century escapement and other later modifications (on stand). (Arrangement for driving hands incomplete, no driving weights) Including count wheel" "15th Century Iron striking clock with 17th century escapemen" "1914-453")
+ ("Wooden pocket sundial. Horizontal and vertical dials for use at various latitudes on moving style, Germany, 1776-1800 (see note)." "Wooden pocket sundial for use at various latitudes" "1914-887"))
diff --git a/examples/index.scm b/examples/index.scm
new file mode 100644
index 0000000..396df7c
--- /dev/null
+++ b/examples/index.scm
@@ -0,0 +1,48 @@
+;;; guile-xapian --- Guile bindings for Xapian
+;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; 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/>.
+
+(use-modules (ice-9 match)
+ (srfi srfi-26)
+ (xapian xapian))
+
+(define (index datapath dbpath)
+ (call-with-writable-database dbpath
+ (lambda (db)
+ (for-each
+ (lambda (record)
+ (match record
+ ((description title identifier)
+ (let* ((idterm (string-append "Q" identifier))
+ (doc (make-document #:data (call-with-output-string (cut write record <>))
+ #:terms `((,idterm . 0))))
+ (term-generator (make-term-generator #:stem (make-stem "en")
+ #:document doc)))
+ (index-text! term-generator title #:prefix "S")
+ (index-text! term-generator description #:prefix "XD")
+ (index-text! term-generator title)
+ (increase-termpos! term-generator)
+ (index-text! term-generator description)
+ (replace-document! db idterm doc)))))
+ (call-with-input-file datapath read)))))
+
+(match (command-line)
+ ((_ datapath dbpath)
+ (index datapath dbpath))
+ ((program . _)
+ (format (current-error-port) "Usage: ~a DATAPATH DBPATH~%" program)))
diff --git a/examples/search.scm b/examples/search.scm
new file mode 100644
index 0000000..4b58313
--- /dev/null
+++ b/examples/search.scm
@@ -0,0 +1,50 @@
+;;; guile-xapian --- Guile bindings for Xapian
+;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; 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/>.
+
+(use-modules (ice-9 format)
+ (ice-9 match)
+ (xapian xapian))
+
+(define (get-title record)
+ (match record
+ ((description title identifier) title)))
+
+(define* (search dbpath querystring #:key (offset 0) (pagesize 10))
+ (call-with-database dbpath
+ (lambda (db)
+ (let ((query (parse-query querystring
+ #:stemmer (make-stem "en")
+ #:prefixes '(("title" ."S")
+ ("description" . "XD")))))
+ (mset-fold (lambda (item _)
+ (format #t "~a: #~3,'0d ~a~%"
+ (mset-item-rank item)
+ (mset-item-docid item)
+ (get-title
+ (call-with-input-string
+ (document-data (mset-item-document item))
+ read))))
+ #f
+ (enquire-mset (enquire db query) offset pagesize))))))
+
+(match (command-line)
+ ((_ dbpath . query-terms)
+ (search dbpath (string-join query-terms)))
+ ((program . _)
+ (format (current-error-port) "Usage: ~a DBPATH QUERYTERM...~%" program)))
diff --git a/guix.scm b/guix.scm
new file mode 100644
index 0000000..aad3616
--- /dev/null
+++ b/guix.scm
@@ -0,0 +1,65 @@
+;;; guile-xapian --- Guile bindings for Xapian
+;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; 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/>.
+
+;;; Run the following command to enter a development environment for
+;;; guile-xapian:
+;;;
+;;; $ guix environment -l guix.scm
+
+(use-modules (guix build-system gnu)
+ (guix git-download)
+ ((guix licenses) #:prefix license:)
+ (guix packages)
+ (gnu packages autotools)
+ (gnu packages commencement)
+ (gnu packages compression)
+ (gnu packages guile)
+ (gnu packages pkg-config)
+ (gnu packages search)
+ (gnu packages swig))
+
+(package
+ (name "guile-xapian")
+ (version "0.1.0")
+ (home-page "https://git.systemreboot.net/guile-xapian")
+ (source
+ (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url home-page)
+ (commit "a14ea81b71803ee93de6edff9065b4bebcb2cf2e")))
+ (file-name (git-file-name name version))
+ (sha256
+ (base32
+ "1ac7g0gd8ndwv3ybqn5vjgqxa7090bby4db164a7mn9ssp8b803s"))))
+ (inputs
+ `(("guile" ,guile-2.2)
+ ("xapian" ,xapian)
+ ("zlib" ,zlib)))
+ (native-inputs
+ `(("autoconf" ,autoconf)
+ ("autoconf-archive" ,autoconf-archive)
+ ("automake" ,automake)
+ ("libtool" ,libtool)
+ ("pkg-config" ,pkg-config)
+ ("swig" ,swig)))
+ (build-system gnu-build-system)
+ (synopsis "Guile bindings for Xapian")
+ (description "Guile bindings for Xapian")
+ (license license:gpl2+))
diff --git a/pre-inst-env.in b/pre-inst-env.in
new file mode 100644
index 0000000..c0c694f
--- /dev/null
+++ b/pre-inst-env.in
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+# guile-xapian --- Guile bindings for Xapian
+# Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+#
+# 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/>.
+
+abs_top_srcdir="`cd "@abs_top_srcdir@" > /dev/null; pwd -P`"
+abs_top_builddir="`cd "@abs_top_builddir@" > /dev/null; pwd -P`"
+
+GUILE_LOAD_COMPILED_PATH="$abs_top_builddir${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH"
+GUILE_LOAD_PATH="$abs_top_builddir:$abs_top_srcdir${GUILE_LOAD_PATH:+:}$GUILE_LOAD_PATH"
+export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH
+
+exec "$@"
diff --git a/xapian-head.i b/xapian-head.i
new file mode 100644
index 0000000..c079f93
--- /dev/null
+++ b/xapian-head.i
@@ -0,0 +1,113 @@
+%{
+/** @file xapian-head.i
+ * @brief Header for SWIG interface file for Xapian.
+ */
+/* Copyright (C) 2005,2006,2007,2008,2009,2011,2012,2013,2014,2015,2016 Olly Betts
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+// Disable any deprecation warnings for Xapian methods/functions/classes.
+#define XAPIAN_DEPRECATED(D) D
+
+#include <xapian.h>
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+// If a backend has been disabled in xapian-core (manually or automatically) we
+// include a stub definition here so the bindings can still be built.
+namespace Xapian {
+%}
+#ifndef XAPIAN_BINDINGS_SKIP_DEPRECATED_DB_FACTORIES
+%{
+
+#ifndef XAPIAN_HAS_CHERT_BACKEND
+ namespace Chert {
+ static Database open(const string &) {
+ throw FeatureUnavailableError("Chert backend not supported");
+ }
+ static WritableDatabase open(const string &, int, int = 0) {
+ throw FeatureUnavailableError("Chert backend not supported");
+ }
+ }
+#endif
+
+#ifndef XAPIAN_HAS_INMEMORY_BACKEND
+ namespace InMemory {
+ static WritableDatabase open() {
+ throw FeatureUnavailableError("InMemory backend not supported");
+ }
+ }
+#endif
+
+%}
+#endif
+%{
+
+#ifndef XAPIAN_HAS_REMOTE_BACKEND
+ namespace Remote {
+ static Database open(const string &, unsigned int, useconds_t = 0, useconds_t = 0) {
+ throw FeatureUnavailableError("Remote backend not supported");
+ }
+
+ static WritableDatabase open_writable(const string &, unsigned int, useconds_t = 0, useconds_t = 0, int = 0) {
+ throw FeatureUnavailableError("Remote backend not supported");
+ }
+
+ static Database open(const string &, const string &, useconds_t = 0) {
+ throw FeatureUnavailableError("Remote backend not supported");
+ }
+
+ static WritableDatabase open_writable(const string &, const string &, useconds_t = 0, int = 0) {
+ throw FeatureUnavailableError("Remote backend not supported");
+ }
+ }
+#endif
+
+}
+%}
+
+using namespace std;
+
+%include exception.i
+%include stl.i
+
+// Disable errors about not including headers individually.
+#define XAPIAN_IN_XAPIAN_H
+
+// Define these away for SWIG's parser.
+#define XAPIAN_DEPRECATED(D) D
+#define XAPIAN_DEPRECATED_EX(D) D
+#define XAPIAN_DEPRECATED_CLASS
+#define XAPIAN_DEPRECATED_CLASS_EX
+#define XAPIAN_VISIBILITY_DEFAULT
+#define XAPIAN_CONST_FUNCTION
+#define XAPIAN_PURE_FUNCTION
+#define XAPIAN_NOEXCEPT
+#define XAPIAN_NOTHROW(D) D
+
+// Ignore these which SWIG seems to add pointless type entries for due them
+// being used in the SWIG typemap for std::pair.
+%ignore first_type;
+%ignore second_type;
+
+// Treat POSIX useconds_t as unsigned.
+%apply unsigned { useconds_t };
diff --git a/xapian-headers.i b/xapian-headers.i
new file mode 100644
index 0000000..4b393a1
--- /dev/null
+++ b/xapian-headers.i
@@ -0,0 +1,471 @@
+%{
+/* xapian-headers.i: Getting SWIG to parse Xapian's C++ headers.
+ *
+ * Copyright 2004,2006,2011,2012,2013,2014,2015,2016,2019 Olly Betts
+ * Copyright 2014 Assem Chelli
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+%}
+
+/* Ignore these functions: */
+%ignore Xapian::iterator_rewind;
+%ignore Xapian::iterator_valid;
+
+/* Ignore anything ending in an underscore, which is for internal use only: */
+%rename("$ignore", regexmatch$name="_$") "";
+
+/* A class which can usefully be subclassed in the target language. */
+%define SUBCLASSABLE(NS, CLASS)
+ %ignore NS::CLASS::clone;
+ %ignore NS::CLASS::serialise;
+ %ignore NS::CLASS::unserialise;
+ %#ifdef XAPIAN_SWIG_DIRECTORS
+ %feature(director) NS::CLASS;
+ %#endif
+%enddef
+
+/* A class which is only useful to wrap if the target language allows
+ * subclassing of wrapped classes (what SWIG calls "director support").
+ */
+#ifdef XAPIAN_SWIG_DIRECTORS
+#define SUBCLASSABLE_ONLY(NS, CLASS) SUBCLASSABLE(NS, CLASS)
+#else
+#define SUBCLASSABLE_ONLY(NS, CLASS) %ignore NS::CLASS;
+#endif
+
+#ifdef SWIGTCL
+/* Tcl needs copy constructors it seems. */
+%define STANDARD_IGNORES(NS, CLASS)
+ %ignore NS::CLASS::internal;
+ %ignore NS::CLASS::CLASS(Internal*);
+ %ignore NS::CLASS::CLASS(Internal&);
+ %ignore NS::CLASS::operator=;
+%enddef
+#else
+%define STANDARD_IGNORES(NS, CLASS)
+ %ignore NS::CLASS::internal;
+ %ignore NS::CLASS::CLASS(Internal*);
+ %ignore NS::CLASS::CLASS(Internal&);
+ %ignore NS::CLASS::operator=;
+ %ignore NS::CLASS::CLASS(const CLASS &);
+%enddef
+#endif
+
+#ifdef SWIGCSHARP
+/* In C#, next and prev return the iterator object. */
+#define INC_OR_DEC(METHOD, OP, NS, CLASS, RET_TYPE) NS::CLASS METHOD() { return OP(*self); }
+#elif defined SWIGJAVA
+/* In Java, next and prev return the result of dereferencing the iterator. */
+#define INC_OR_DEC(METHOD, OP, NS, CLASS, RET_TYPE) RET_TYPE METHOD() { return *(OP(*self)); }
+#else
+/* Otherwise, next and prev return void. */
+#define INC_OR_DEC(METHOD, OP, NS, CLASS, RET_TYPE) void METHOD() { OP(*self); }
+#endif
+
+/* For other languages, SWIG already renames operator() suitably. */
+#if defined SWIGGUILE || defined SWIGJAVA || defined SWIGPHP || defined SWIGTCL
+%rename(apply) *::operator();
+#elif defined SWIGCSHARP
+%rename(Apply) *::operator();
+#endif
+
+/* We use %ignore and %extend rather than %rename on operator* so that any
+ * pattern rename used to match local naming conventions applies to
+ * DEREF_METHOD.
+ */
+%define INPUT_ITERATOR_METHODS(NS, CLASS, RET_TYPE, DEREF_METHOD)
+ STANDARD_IGNORES(NS, CLASS)
+ %ignore NS::CLASS::operator++;
+ %ignore NS::CLASS::operator*;
+ %extend NS::CLASS {
+ bool equals(const NS::CLASS & o) const { return *self == o; }
+ RET_TYPE DEREF_METHOD() const { return **self; }
+ INC_OR_DEC(next, ++, NS, CLASS, RET_TYPE)
+ }
+%enddef
+
+%define RANDOM_ACCESS_ITERATOR_METHODS(NS, CLASS, RET_TYPE, DEREF_METHOD)
+ INPUT_ITERATOR_METHODS(NS, CLASS, RET_TYPE, DEREF_METHOD)
+ %ignore NS::CLASS::operator--;
+ %ignore NS::CLASS::operator+=;
+ %ignore NS::CLASS::operator-=;
+ %ignore NS::CLASS::operator+;
+ %ignore NS::CLASS::operator-;
+ %extend NS::CLASS {
+ INC_OR_DEC(prev, --, NS, CLASS, RET_TYPE)
+ }
+%enddef
+
+%define CONSTANT(TYPE, NS, NAME)
+ %ignore NS::NAME;
+ %constant TYPE NAME = NS::NAME;
+%enddef
+
+/* Ignore these for all classes: */
+%ignore operator==;
+%ignore operator!=;
+%ignore operator<;
+%ignore operator>;
+%ignore operator<=;
+%ignore operator>=;
+%ignore operator+;
+%ignore difference_type;
+%ignore iterator_category;
+%ignore value_type;
+%ignore max_size;
+%ignore swap;
+%ignore iterator;
+%ignore const_iterator;
+%ignore size_type;
+%ignore unserialise(const char **, const char *);
+%ignore release();
+
+/* These methods won't throw exceptions. */
+%exception Xapian::major_version "$action"
+%exception Xapian::minor_version "$action"
+%exception Xapian::revision "$action"
+%exception Xapian::version_string "$action"
+// For XAPIAN_DOCID_BASE_TYPE and XAPIAN_TERMCOUNT_BASE_TYPE:
+%import <xapian/version.h>
+%include <xapian.h>
+
+// Disable errors about not including headers individually.
+#define XAPIAN_IN_XAPIAN_H
+
+/* We don't wrap the version macros - they're useful for compile time checks
+ * in C++ code, but for a scripting language, the version functions tell us
+ * the version of Xapian we're actually using, which is more interesting than
+ * the one the bindings were built against.
+ */
+/* %include <xapian/version.h> */
+
+CONSTANT(Xapian::valueno, Xapian, BAD_VALUENO);
+
+/* Types are needed by most of the other headers. */
+%include <xapian/types.h>
+
+CONSTANT(int, Xapian, DB_CREATE);
+CONSTANT(int, Xapian, DB_CREATE_OR_OPEN);
+CONSTANT(int, Xapian, DB_CREATE_OR_OVERWRITE);
+CONSTANT(int, Xapian, DB_OPEN);
+CONSTANT(int, Xapian, DB_NO_SYNC);
+CONSTANT(int, Xapian, DB_FULL_SYNC);
+CONSTANT(int, Xapian, DB_DANGEROUS);
+CONSTANT(int, Xapian, DB_NO_TERMLIST);
+CONSTANT(int, Xapian, DB_BACKEND_CHERT);
+CONSTANT(int, Xapian, DB_BACKEND_GLASS);
+CONSTANT(int, Xapian, DB_BACKEND_INMEMORY);
+CONSTANT(int, Xapian, DB_BACKEND_STUB);
+CONSTANT(int, Xapian, DB_RETRY_LOCK);
+CONSTANT(int, Xapian, DBCHECK_SHORT_TREE);
+CONSTANT(int, Xapian, DBCHECK_FULL_TREE);
+CONSTANT(int, Xapian, DBCHECK_SHOW_FREELIST);
+CONSTANT(int, Xapian, DBCHECK_SHOW_STATS);
+CONSTANT(int, Xapian, DBCHECK_FIX);
+CONSTANT(int, Xapian, DBCOMPACT_MULTIPASS);
+CONSTANT(int, Xapian, DBCOMPACT_NO_RENUMBER);
+CONSTANT(int, Xapian, DBCOMPACT_SINGLE_FILE);
+CONSTANT(int, Xapian, DOC_ASSUME_VALID);
+%include <xapian/constants.h>
+
+/* The Error subclasses are handled separately for languages where we wrap
+ * them. */
+/* %include <xapian/error.h> */
+
+/* ErrorHandler isn't currently wrapped. */
+/* %include <xapian/errorhandler.h> */
+
+INPUT_ITERATOR_METHODS(Xapian, PositionIterator, Xapian::termpos, get_termpos)
+%include <xapian/positioniterator.h>
+
+%ignore Xapian::DocIDWrapper;
+INPUT_ITERATOR_METHODS(Xapian, PostingIterator, Xapian::docid, get_docid)
+%include <xapian/postingiterator.h>
+
+INPUT_ITERATOR_METHODS(Xapian, TermIterator, std::string, get_term)
+%include <xapian/termiterator.h>
+
+INPUT_ITERATOR_METHODS(Xapian, ValueIterator, std::string, get_value)
+%include <xapian/valueiterator.h>
+
+STANDARD_IGNORES(Xapian, Document)
+%include <xapian/document.h>
+
+STANDARD_IGNORES(Xapian, Registry)
+%include <xapian/registry.h>
+
+STANDARD_IGNORES(Xapian, Query)
+%ignore Xapian::Query::Internal;
+%ignore operator Query;
+%ignore *::operator&(const Xapian::Query &, const Xapian::InvertedQuery_ &);
+%ignore *::operator~;
+%ignore *::operator&=;
+%ignore ::operator&=;
+%ignore *::operator|=;
+%ignore *::operator^=;
+%ignore *::operator*=;
+%ignore *::operator/=;
+#if defined SWIGCSHARP || defined SWIGGUILE || defined SWIGJAVA || defined SWIGLUA || defined SWIGPHP
+%ignore *::operator&;
+%ignore *::operator|;
+%ignore *::operator^;
+%ignore *::operator*;
+%ignore *::operator/;
+#endif
+%ignore Xapian::Query::LEAF_TERM;
+%ignore Xapian::Query::LEAF_POSTING_SOURCE;
+%ignore Xapian::Query::LEAF_MATCH_ALL;
+%ignore Xapian::Query::LEAF_MATCH_NOTHING;
+
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::Query::Internal;
+#if defined SWIGCSHARP || defined SWIGJAVA || defined SWIGPERL || \
+ defined SWIGPYTHON || defined SWIGRUBY
+// C#, Java, Perl, Python and Ruby wrap these "by hand" to give a nicer API
+// than SWIG gives by default.
+%ignore Xapian::Query::MatchAll;
+%ignore Xapian::Query::MatchNothing;
+#endif
+#ifndef XAPIAN_MIXED_SUBQUERIES_BY_ITERATOR_TYPEMAP
+%ignore Query(op op_, XapianSWIGQueryItor qbegin, XapianSWIGQueryItor qend,
+ Xapian::termcount parameter = 0);
+#endif
+%include <xapian/query.h>
+
+// Suppress warning that Xapian::Internal::intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::StemImplementation;
+SUBCLASSABLE_ONLY(Xapian, StemImplementation)
+#ifndef XAPIAN_SWIG_DIRECTORS
+%ignore Xapian::Stem::Stem(Xapian::StemImplementation *);
+#endif
+STANDARD_IGNORES(Xapian, Stem)
+%ignore Xapian::Stem::Stem();
+%include <xapian/stem.h>
+
+STANDARD_IGNORES(Xapian, TermGenerator)
+%ignore Xapian::TermGenerator::operator=;
+/* Ignore forms which use Utf8Iterator, as we don't wrap that class. */
+%ignore Xapian::TermGenerator::index_text(const Xapian::Utf8Iterator &);
+%ignore Xapian::TermGenerator::index_text(const Xapian::Utf8Iterator &, Xapian::termcount);
+%ignore Xapian::TermGenerator::index_text(const Xapian::Utf8Iterator &, Xapian::termcount, const std::string &);
+%ignore Xapian::TermGenerator::index_text_without_positions(const Xapian::Utf8Iterator &);
+%ignore Xapian::TermGenerator::index_text_without_positions(const Xapian::Utf8Iterator &, Xapian::termcount);
+%ignore Xapian::TermGenerator::index_text_without_positions(const Xapian::Utf8Iterator &, Xapian::termcount, const std::string &);
+%ignore Xapian::TermGenerator::TermGenerator(const TermGenerator &);
+%include <xapian/termgenerator.h>
+
+STANDARD_IGNORES(Xapian, MSet)
+#ifdef SWIGJAVA
+// For compatibility with the original JNI wrappers.
+%rename("getElement") Xapian::MSet::operator[];
+#else
+%ignore Xapian::MSet::operator[];
+#endif
+%extend Xapian::MSet {
+ Xapian::docid get_docid(Xapian::doccount i) const {
+ return *(*self)[i];
+ }
+
+ Xapian::Document get_document(Xapian::doccount i) const {
+ return (*self)[i].get_document();
+ }
+
+ Xapian::MSetIterator get_hit(Xapian::doccount i) const {
+ return (*self)[i];
+ }
+
+ int get_document_percentage(Xapian::doccount i) const {
+ return self->convert_to_percent((*self)[i]);
+ }
+}
+
+RANDOM_ACCESS_ITERATOR_METHODS(Xapian, MSetIterator, Xapian::docid, get_docid)
+
+%include <xapian/mset.h>
+
+STANDARD_IGNORES(Xapian, ESet)
+%ignore Xapian::ESet::operator[];
+
+RANDOM_ACCESS_ITERATOR_METHODS(Xapian, ESetIterator, std::string, get_term)
+
+%include <xapian/eset.h>
+
+STANDARD_IGNORES(Xapian, RSet)
+
+STANDARD_IGNORES(Xapian, Enquire)
+
+SUBCLASSABLE(Xapian, MatchDecider)
+
+#ifdef XAPIAN_TERMITERATOR_PAIR_OUTPUT_TYPEMAP
+/* Instantiating the template we're going to use avoids SWIG wrapping uses
+ * of it in SwigValueWrapper.
+ */
+%template() std::pair<Xapian::TermIterator, Xapian::TermIterator>;
+
+%extend Xapian::Enquire {
+ /* This returns start and end iterators, then a typemap iterates between
+ * those and returns an array of strings in the target language.
+ */
+ std::pair<Xapian::TermIterator, Xapian::TermIterator>
+ get_matching_terms(const Xapian::MSetIterator & item) const {
+ return std::make_pair($self->get_matching_terms_begin(item),
+ $self->get_matching_terms_end(item));
+ }
+}
+#endif
+
+/* We don't wrap ErrorHandler, so ignore the optional ErrorHandler parameter.
+ */
+%ignore Enquire(const Database &, ErrorHandler *);
+
+%include <xapian/enquire.h>
+
+SUBCLASSABLE(Xapian, ExpandDecider)
+// Suppress warning that Xapian::Internal::opt_intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::ExpandDecider;
+%ignore Xapian::ExpandDeciderAnd::ExpandDeciderAnd(const ExpandDecider *, const ExpandDecider *);
+/* FIXME: %extend ExpandDeciderFilterTerms so it can be constructed from an
+ * array of strings (or whatever the equivalent is in the target language).
+ */
+%ignore Xapian::ExpandDeciderFilterTerms;
+%include <xapian/expanddecider.h>
+
+SUBCLASSABLE(Xapian, KeyMaker)
+// Suppress warning that Xapian::Internal::opt_intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::KeyMaker;
+%include <xapian/keymaker.h>
+
+%extend Xapian::SimpleStopper {
+ /** Load stop words from a text file (one word per line). */
+ SimpleStopper(const std::string &file) {
+ ifstream in_file(file.c_str());
+ if (!in_file.is_open())
+ throw Xapian::InvalidArgumentError("Stopword file not found: " + file);
+ istream_iterator<std::string> in_iter(in_file);
+ istream_iterator<std::string> eof;
+ return new Xapian::SimpleStopper(in_iter, eof);
+ }
+}
+
+SUBCLASSABLE(Xapian, FieldProcessor)
+// Suppress warning that Xapian::Internal::opt_intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::Stopper;
+SUBCLASSABLE(Xapian, RangeProcessor)
+SUBCLASSABLE(Xapian, Stopper)
+SUBCLASSABLE(Xapian, ValueRangeProcessor)
+// Suppress warning that Xapian::Internal::opt_intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::RangeProcessor;
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::ValueRangeProcessor;
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::FieldProcessor;
+STANDARD_IGNORES(Xapian, QueryParser)
+%ignore Xapian::QueryParser::QueryParser(const QueryParser &);
+CONSTANT(int, Xapian, RP_SUFFIX);
+CONSTANT(int, Xapian, RP_REPEATED);
+CONSTANT(int, Xapian, RP_DATE_PREFER_MDY);
+%include <xapian/queryparser.h>
+
+%include <xapian/valuesetmatchdecider.h>
+
+/* Xapian::Weight isn't usefully subclassable via the bindings, as clone()
+ * needs to be implemented for it to be usable for weighting a search. But
+ * there are several supplied weighting schemes implemented in C++ which can
+ * usefully be used via the bindings so we wrap those.
+ */
+STANDARD_IGNORES(Xapian, Weight)
+/* The copy constructor isn't implemented, but is protected rather than
+ * private to work around a compiler bug, so we ignore it explicitly.
+ */
+%ignore Xapian::Weight::Weight(const Weight &);
+%ignore Xapian::Weight::clone;
+%ignore Xapian::Weight::serialise;
+%ignore Xapian::Weight::unserialise;
+%include <xapian/weight.h>
+
+/* We don't wrap Xapian's Unicode support as other languages usually already
+ * have their own Unicode support. */
+/* %include <xapian/unicode.h> */
+
+SUBCLASSABLE(Xapian, Compactor)
+%include <xapian/compactor.h>
+
+SUBCLASSABLE(Xapian, PostingSource)
+// Suppress warning that Xapian::Internal::opt_intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::PostingSource;
+SUBCLASSABLE(Xapian, ValuePostingSource)
+SUBCLASSABLE(Xapian, ValueWeightPostingSource)
+%ignore Xapian::PostingSource::unserialise_with_registry;
+%include <xapian/postingsource.h>
+
+// Suppress warning that Xapian::Internal::intrusive_base is unknown.
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Xapian::MatchSpy;
+SUBCLASSABLE(Xapian, MatchSpy)
+%ignore Xapian::MatchSpy::serialise_results;
+%include <xapian/matchspy.h>
+
+SUBCLASSABLE(Xapian, LatLongMetric)
+INPUT_ITERATOR_METHODS(Xapian, LatLongCoordsIterator, LatLongCoord, get_coord)
+%ignore Xapian::LatLongCoord::operator<;
+%include <xapian/geospatial.h>
+
+STANDARD_IGNORES(Xapian, Database)
+STANDARD_IGNORES(Xapian, WritableDatabase)
+%ignore Xapian::WritableDatabase::WritableDatabase(Database::Internal *);
+%ignore Xapian::Database::check(const std::string &, int, std::ostream *);
+%ignore Xapian::Database::check(int fd, int, std::ostream *);
+%include <xapian/database.h>
+%extend Xapian::Database {
+ static size_t check(const std::string &path, int opts = 0) {
+ return Xapian::Database::check(path, opts, opts ? &std::cout : NULL);
+ }
+}
+
+#if defined SWIGCSHARP || defined SWIGJAVA
+
+/* xapian/dbfactory.h is currently wrapped via fake class declarations in
+ * fake_dbfactory.i for C# and Java. */
+
+#else
+
+#ifdef XAPIAN_BINDINGS_SKIP_DEPRECATED_DB_FACTORIES
+%ignore Xapian::InMemory::open;
+%ignore Xapian::Chert::open;
+%ignore Xapian::Auto::open_stub;
+#else
+
+%rename("inmemory_open") Xapian::InMemory::open;
+
+/* SWIG Tcl wrappers don't call destructors for classes returned by factory
+ * functions, so we don't wrap them so users are forced to use the
+ * WritableDatabase ctor instead. */
+#ifdef SWIGTCL
+%ignore Xapian::Chert::open(const std::string &dir, int action, int block_size = 8192);
+#endif
+
+%rename("chert_open") Xapian::Chert::open;
+
+#ifndef SWIGPHP
+/* PHP renames this to auto_open_stub() in php/php.i. */
+%rename("open_stub") Xapian::Auto::open_stub;
+#endif
+
+#endif
+
+%rename("remote_open") Xapian::Remote::open;
+%rename("remote_open_writable") Xapian::Remote::open_writable;
+
+%include <xapian/dbfactory.h>
+
+#endif
diff --git a/xapian.i b/xapian.i
new file mode 100644
index 0000000..54f8c0e
--- /dev/null
+++ b/xapian.i
@@ -0,0 +1,31 @@
+/* guile-xapian --- Guile bindings for Xapian
+ * Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+ *
+ * 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
+%{
+(load-extension "./libguilexapian" "SWIG_init")
+%}
+
+%include xapian-head.i
+%include xapian-headers.i
diff --git a/xapian/wrap.scm b/xapian/wrap.scm
new file mode 100644
index 0000000..be4039c
--- /dev/null
+++ b/xapian/wrap.scm
@@ -0,0 +1,902 @@
+;;; This file was automatically generated by SWIG (http://www.swig.org).
+;;; Version 3.0.12
+;;;
+;;; Do not make changes to this file unless you know what you are doing--modify
+;;; the SWIG interface file instead.
+
+(define-module (xapian wrap))
+
+
+(load-extension "./libguilexapian" "SWIG_init")
+
+
+(export version-string
+ major-version
+ minor-version
+ revision
+ BAD-VALUENO
+ DB-CREATE
+ DB-CREATE-OR-OPEN
+ DB-CREATE-OR-OVERWRITE
+ DB-OPEN
+ DB-NO-SYNC
+ DB-FULL-SYNC
+ DB-DANGEROUS
+ DB-NO-TERMLIST
+ DB-BACKEND-CHERT
+ DB-BACKEND-GLASS
+ DB-BACKEND-INMEMORY
+ DB-BACKEND-STUB
+ DB-RETRY-LOCK
+ DBCHECK-SHORT-TREE
+ DBCHECK-FULL-TREE
+ DBCHECK-SHOW-FREELIST
+ DBCHECK-SHOW-STATS
+ DBCHECK-FIX
+ DBCOMPACT-MULTIPASS
+ DBCOMPACT-NO-RENUMBER
+ DBCOMPACT-SINGLE-FILE
+ DOC-ASSUME-VALID
+ new-PositionIterator
+ delete-PositionIterator
+ PositionIterator-skip-to
+ PositionIterator-get-description
+ PositionIterator-equals
+ PositionIterator-get-termpos
+ PositionIterator-next
+ new-PostingIterator
+ delete-PostingIterator
+ PostingIterator-get-wdf
+ PostingIterator-get-doclength
+ PostingIterator-get-unique-terms
+ PostingIterator-positionlist-begin
+ PostingIterator-positionlist-end
+ PostingIterator-skip-to
+ PostingIterator-get-description
+ PostingIterator-equals
+ PostingIterator-get-docid
+ PostingIterator-next
+ new-TermIterator
+ delete-TermIterator
+ TermIterator-get-wdf
+ TermIterator-get-termfreq
+ TermIterator-positionlist-count
+ TermIterator-positionlist-begin
+ TermIterator-positionlist-end
+ TermIterator-skip-to
+ TermIterator-get-description
+ TermIterator-equals
+ TermIterator-get-term
+ TermIterator-next
+ new-ValueIterator
+ delete-ValueIterator
+ ValueIterator-get-docid
+ ValueIterator-get-valueno
+ ValueIterator-skip-to
+ ValueIterator-check
+ ValueIterator-get-description
+ ValueIterator-equals
+ ValueIterator-get-value
+ ValueIterator-next
+ new-Document
+ delete-Document
+ Document-get-value
+ Document-add-value
+ Document-remove-value
+ Document-clear-values
+ Document-get-data
+ Document-set-data
+ Document-add-posting
+ Document-add-posting
+ Document-add-term
+ Document-add-term
+ Document-add-boolean-term
+ Document-remove-posting
+ Document-remove-posting
+ Document-remove-postings
+ Document-remove-postings
+ Document-remove-term
+ Document-clear-terms
+ Document-termlist-count
+ Document-termlist-begin
+ Document-termlist-end
+ Document-values-count
+ Document-values-begin
+ Document-values-end
+ Document-get-docid
+ Document-serialise
+ Document-unserialise
+ Document-get-description
+ new-Registry
+ delete-Registry
+ Registry-register-weighting-scheme
+ Registry-get-weighting-scheme
+ Registry-register-posting-source
+ Registry-get-posting-source
+ Registry-register-match-spy
+ Registry-get-match-spy
+ Registry-register-lat-long-metric
+ Registry-get-lat-long-metric
+ Query-MatchNothing
+ Query-MatchAll
+ Query-OP-AND
+ Query-OP-OR
+ Query-OP-AND-NOT
+ Query-OP-XOR
+ Query-OP-AND-MAYBE
+ Query-OP-FILTER
+ Query-OP-NEAR
+ Query-OP-PHRASE
+ Query-OP-VALUE-RANGE
+ Query-OP-SCALE-WEIGHT
+ Query-OP-ELITE-SET
+ Query-OP-VALUE-GE
+ Query-OP-VALUE-LE
+ Query-OP-SYNONYM
+ Query-OP-MAX
+ Query-OP-WILDCARD
+ Query-OP-INVALID
+ Query-WILDCARD-LIMIT-ERROR
+ Query-WILDCARD-LIMIT-FIRST
+ Query-WILDCARD-LIMIT-MOST-FREQUENT
+ new-Query
+ delete-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ new-Query
+ Query-get-terms-begin
+ Query-get-terms-end
+ Query-get-unique-terms-begin
+ Query-get-unique-terms-end
+ Query-get-length
+ Query-empty
+ Query-serialise
+ Query-unserialise
+ Query-unserialise
+ Query-get-type
+ Query-get-num-subqueries
+ Query-get-subquery
+ Query-get-description
+ new-Query
+ new-Stem
+ new-Stem
+ new-Stem
+ delete-Stem
+ Stem-apply
+ Stem-is-none
+ Stem-get-description
+ Stem-get-available-languages
+ new-TermGenerator
+ delete-TermGenerator
+ TermGenerator-set-stemmer
+ TermGenerator-set-stopper
+ TermGenerator-set-stopper
+ TermGenerator-set-document
+ TermGenerator-get-document
+ TermGenerator-set-database
+ TermGenerator-FLAG-SPELLING
+ TermGenerator-FLAG-CJK-NGRAM
+ TermGenerator-STEM-NONE
+ TermGenerator-STEM-SOME
+ TermGenerator-STEM-ALL
+ TermGenerator-STEM-ALL-Z
+ TermGenerator-STEM-SOME-FULL-POS
+ TermGenerator-STOP-NONE
+ TermGenerator-STOP-ALL
+ TermGenerator-STOP-STEMMED
+ TermGenerator-set-flags
+ TermGenerator-set-flags
+ TermGenerator-set-stemming-strategy
+ TermGenerator-set-stopper-strategy
+ TermGenerator-set-max-word-length
+ TermGenerator-index-text
+ TermGenerator-index-text
+ TermGenerator-index-text
+ TermGenerator-index-text-without-positions
+ TermGenerator-index-text-without-positions
+ TermGenerator-index-text-without-positions
+ TermGenerator-increase-termpos
+ TermGenerator-increase-termpos
+ TermGenerator-get-termpos
+ TermGenerator-set-termpos
+ TermGenerator-get-description
+ new-MSet
+ delete-MSet
+ MSet-convert-to-percent
+ MSet-convert-to-percent
+ MSet-get-termfreq
+ MSet-get-termweight
+ MSet-get-firstitem
+ MSet-get-matches-lower-bound
+ MSet-get-matches-estimated
+ MSet-get-matches-upper-bound
+ MSet-get-uncollapsed-matches-lower-bound
+ MSet-get-uncollapsed-matches-estimated
+ MSet-get-uncollapsed-matches-upper-bound
+ MSet-get-max-attained
+ MSet-get-max-possible
+ MSet-SNIPPET-BACKGROUND-MODEL
+ MSet-SNIPPET-EXHAUSTIVE
+ MSet-SNIPPET-EMPTY-WITHOUT-MATCH
+ MSet-SNIPPET-CJK-NGRAM
+ MSet-snippet
+ MSet-snippet
+ MSet-snippet
+ MSet-snippet
+ MSet-snippet
+ MSet-snippet
+ MSet-snippet
+ MSet-fetch
+ MSet-fetch
+ MSet-fetch
+ MSet-size
+ MSet-empty
+ MSet-begin
+ MSet-end
+ MSet-back
+ MSet-get-description
+ MSet-get-docid
+ MSet-get-document
+ MSet-get-hit
+ MSet-get-document-percentage
+ MSetIterator-mset-set
+ MSetIterator-mset-get
+ MSetIterator-off-from-end-set
+ MSetIterator-off-from-end-get
+ new-MSetIterator
+ MSetIterator-get-rank
+ MSetIterator-get-document
+ MSetIterator-get-weight
+ MSetIterator-get-collapse-key
+ MSetIterator-get-collapse-count
+ MSetIterator-get-sort-key
+ MSetIterator-get-percent
+ MSetIterator-get-description
+ MSetIterator-equals
+ MSetIterator-get-docid
+ MSetIterator-next
+ MSetIterator-prev
+ delete-MSetIterator
+ new-ESet
+ delete-ESet
+ ESet-size
+ ESet-empty
+ ESet-get-ebound
+ ESet-begin
+ ESet-end
+ ESet-back
+ ESet-get-description
+ ESetIterator-eset-set
+ ESetIterator-eset-get
+ ESetIterator-off-from-end-set
+ ESetIterator-off-from-end-get
+ new-ESetIterator
+ ESetIterator-get-weight
+ ESetIterator-get-description
+ ESetIterator-equals
+ ESetIterator-get-term
+ ESetIterator-next
+ ESetIterator-prev
+ delete-ESetIterator
+ new-RSet
+ delete-RSet
+ RSet-size
+ RSet-empty
+ RSet-add-document
+ RSet-add-document
+ RSet-remove-document
+ RSet-remove-document
+ RSet-contains
+ RSet-contains
+ RSet-get-description
+ MatchDecider-apply
+ delete-MatchDecider
+ new-Enquire
+ delete-Enquire
+ Enquire-set-query
+ Enquire-set-query
+ Enquire-get-query
+ Enquire-add-matchspy
+ Enquire-clear-matchspies
+ Enquire-set-weighting-scheme
+ Enquire-set-expansion-scheme
+ Enquire-set-expansion-scheme
+ Enquire-set-collapse-key
+ Enquire-set-collapse-key
+ Enquire-ASCENDING
+ Enquire-DESCENDING
+ Enquire-DONT-CARE
+ Enquire-set-docid-order
+ Enquire-set-cutoff
+ Enquire-set-cutoff
+ Enquire-set-sort-by-relevance
+ Enquire-set-sort-by-value
+ Enquire-set-sort-by-key
+ Enquire-set-sort-by-value-then-relevance
+ Enquire-set-sort-by-key-then-relevance
+ Enquire-set-sort-by-relevance-then-value
+ Enquire-set-sort-by-relevance-then-key
+ Enquire-set-time-limit
+ Enquire-get-mset
+ Enquire-get-mset
+ Enquire-get-mset
+ Enquire-get-mset
+ Enquire-get-mset
+ Enquire-get-mset
+ Enquire-INCLUDE-QUERY-TERMS
+ Enquire-USE-EXACT-TERMFREQ
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-eset
+ Enquire-get-matching-terms-begin
+ Enquire-get-matching-terms-end
+ Enquire-get-matching-terms-begin
+ Enquire-get-matching-terms-end
+ Enquire-get-description
+ ExpandDecider-apply
+ delete-ExpandDecider
+ ExpandDecider-release
+ new-ExpandDeciderAnd
+ ExpandDeciderAnd-apply
+ delete-ExpandDeciderAnd
+ new-ExpandDeciderFilterPrefix
+ ExpandDeciderFilterPrefix-apply
+ delete-ExpandDeciderFilterPrefix
+ KeyMaker-apply
+ delete-KeyMaker
+ KeyMaker-release
+ new-MultiValueKeyMaker
+ MultiValueKeyMaker-apply
+ MultiValueKeyMaker-add-value
+ MultiValueKeyMaker-add-value
+ MultiValueKeyMaker-add-value
+ delete-MultiValueKeyMaker
+ RP-SUFFIX
+ RP-REPEATED
+ RP-DATE-PREFER-MDY
+ Stopper-apply
+ delete-Stopper
+ Stopper-get-description
+ Stopper-release
+ new-SimpleStopper
+ SimpleStopper-add
+ SimpleStopper-apply
+ SimpleStopper-get-description
+ new-SimpleStopper
+ delete-SimpleStopper
+ new-RangeProcessor
+ new-RangeProcessor
+ new-RangeProcessor
+ new-RangeProcessor
+ delete-RangeProcessor
+ RangeProcessor-check-range
+ RangeProcessor-apply
+ RangeProcessor-release
+ new-DateRangeProcessor
+ new-DateRangeProcessor
+ new-DateRangeProcessor
+ new-DateRangeProcessor
+ new-DateRangeProcessor
+ new-DateRangeProcessor
+ DateRangeProcessor-apply
+ delete-DateRangeProcessor
+ new-NumberRangeProcessor
+ new-NumberRangeProcessor
+ new-NumberRangeProcessor
+ NumberRangeProcessor-apply
+ delete-NumberRangeProcessor
+ delete-ValueRangeProcessor
+ ValueRangeProcessor-apply
+ ValueRangeProcessor-release
+ new-StringValueRangeProcessor
+ new-StringValueRangeProcessor
+ new-StringValueRangeProcessor
+ StringValueRangeProcessor-apply
+ delete-StringValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ new-DateValueRangeProcessor
+ DateValueRangeProcessor-apply
+ delete-DateValueRangeProcessor
+ new-NumberValueRangeProcessor
+ new-NumberValueRangeProcessor
+ new-NumberValueRangeProcessor
+ NumberValueRangeProcessor-apply
+ delete-NumberValueRangeProcessor
+ delete-FieldProcessor
+ FieldProcessor-apply
+ FieldProcessor-release
+ QueryParser-FLAG-BOOLEAN
+ QueryParser-FLAG-PHRASE
+ QueryParser-FLAG-LOVEHATE
+ QueryParser-FLAG-BOOLEAN-ANY-CASE
+ QueryParser-FLAG-WILDCARD
+ QueryParser-FLAG-PURE-NOT
+ QueryParser-FLAG-PARTIAL
+ QueryParser-FLAG-SPELLING-CORRECTION
+ QueryParser-FLAG-SYNONYM
+ QueryParser-FLAG-AUTO-SYNONYMS
+ QueryParser-FLAG-AUTO-MULTIWORD-SYNONYMS
+ QueryParser-FLAG-CJK-NGRAM
+ QueryParser-FLAG-DEFAULT
+ QueryParser-STEM-NONE
+ QueryParser-STEM-SOME
+ QueryParser-STEM-ALL
+ QueryParser-STEM-ALL-Z
+ QueryParser-STEM-SOME-FULL-POS
+ new-QueryParser
+ delete-QueryParser
+ QueryParser-set-stemmer
+ QueryParser-set-stemming-strategy
+ QueryParser-set-stopper
+ QueryParser-set-stopper
+ QueryParser-set-default-op
+ QueryParser-get-default-op
+ QueryParser-set-database
+ QueryParser-set-max-expansion
+ QueryParser-set-max-expansion
+ QueryParser-set-max-expansion
+ QueryParser-set-max-wildcard-expansion
+ QueryParser-parse-query
+ QueryParser-parse-query
+ QueryParser-parse-query
+ QueryParser-add-prefix
+ QueryParser-add-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-add-boolean-prefix
+ QueryParser-stoplist-begin
+ QueryParser-stoplist-end
+ QueryParser-unstem-begin
+ QueryParser-unstem-end
+ QueryParser-add-rangeprocessor
+ QueryParser-add-rangeprocessor
+ QueryParser-add-valuerangeprocessor
+ QueryParser-get-corrected-query-string
+ QueryParser-get-description
+ sortable-serialise
+ sortable-unserialise
+ new-ValueSetMatchDecider
+ ValueSetMatchDecider-add-value
+ ValueSetMatchDecider-remove-value
+ ValueSetMatchDecider-apply
+ delete-ValueSetMatchDecider
+ Weight-TWO-STAGE-SMOOTHING
+ Weight-DIRICHLET-SMOOTHING
+ Weight-ABSOLUTE-DISCOUNT-SMOOTHING
+ Weight-JELINEK-MERCER-SMOOTHING
+ Weight-DIRICHLET-PLUS-SMOOTHING
+ delete-Weight
+ Weight-name
+ Weight-get-sumpart
+ Weight-get-maxpart
+ Weight-get-sumextra
+ Weight-get-maxextra
+ new-BoolWeight
+ BoolWeight-name
+ BoolWeight-get-sumpart
+ BoolWeight-get-maxpart
+ BoolWeight-get-sumextra
+ BoolWeight-get-maxextra
+ delete-BoolWeight
+ new-TfIdfWeight
+ new-TfIdfWeight
+ TfIdfWeight-name
+ TfIdfWeight-get-sumpart
+ TfIdfWeight-get-maxpart
+ TfIdfWeight-get-sumextra
+ TfIdfWeight-get-maxextra
+ delete-TfIdfWeight
+ new-BM25Weight
+ new-BM25Weight
+ BM25Weight-name
+ BM25Weight-get-sumpart
+ BM25Weight-get-maxpart
+ BM25Weight-get-sumextra
+ BM25Weight-get-maxextra
+ delete-BM25Weight
+ new-BM25PlusWeight
+ new-BM25PlusWeight
+ BM25PlusWeight-name
+ BM25PlusWeight-get-sumpart
+ BM25PlusWeight-get-maxpart
+ BM25PlusWeight-get-sumextra
+ BM25PlusWeight-get-maxextra
+ delete-BM25PlusWeight
+ new-TradWeight
+ new-TradWeight
+ TradWeight-name
+ TradWeight-get-sumpart
+ TradWeight-get-maxpart
+ TradWeight-get-sumextra
+ TradWeight-get-maxextra
+ delete-TradWeight
+ new-InL2Weight
+ new-InL2Weight
+ InL2Weight-name
+ InL2Weight-get-sumpart
+ InL2Weight-get-maxpart
+ InL2Weight-get-sumextra
+ InL2Weight-get-maxextra
+ delete-InL2Weight
+ new-IfB2Weight
+ new-IfB2Weight
+ IfB2Weight-name
+ IfB2Weight-get-sumpart
+ IfB2Weight-get-maxpart
+ IfB2Weight-get-sumextra
+ IfB2Weight-get-maxextra
+ delete-IfB2Weight
+ new-IneB2Weight
+ new-IneB2Weight
+ IneB2Weight-name
+ IneB2Weight-get-sumpart
+ IneB2Weight-get-maxpart
+ IneB2Weight-get-sumextra
+ IneB2Weight-get-maxextra
+ delete-IneB2Weight
+ new-BB2Weight
+ new-BB2Weight
+ BB2Weight-name
+ BB2Weight-get-sumpart
+ BB2Weight-get-maxpart
+ BB2Weight-get-sumextra
+ BB2Weight-get-maxextra
+ delete-BB2Weight
+ new-DLHWeight
+ DLHWeight-name
+ DLHWeight-get-sumpart
+ DLHWeight-get-maxpart
+ DLHWeight-get-sumextra
+ DLHWeight-get-maxextra
+ delete-DLHWeight
+ new-PL2Weight
+ new-PL2Weight
+ PL2Weight-name
+ PL2Weight-get-sumpart
+ PL2Weight-get-maxpart
+ PL2Weight-get-sumextra
+ PL2Weight-get-maxextra
+ delete-PL2Weight
+ new-PL2PlusWeight
+ new-PL2PlusWeight
+ PL2PlusWeight-name
+ PL2PlusWeight-get-sumpart
+ PL2PlusWeight-get-maxpart
+ PL2PlusWeight-get-sumextra
+ PL2PlusWeight-get-maxextra
+ delete-PL2PlusWeight
+ new-DPHWeight
+ DPHWeight-name
+ DPHWeight-get-sumpart
+ DPHWeight-get-maxpart
+ DPHWeight-get-sumextra
+ DPHWeight-get-maxextra
+ delete-DPHWeight
+ new-LMWeight
+ new-LMWeight
+ new-LMWeight
+ new-LMWeight
+ new-LMWeight
+ LMWeight-name
+ LMWeight-get-sumpart
+ LMWeight-get-maxpart
+ LMWeight-get-sumextra
+ LMWeight-get-maxextra
+ delete-LMWeight
+ CoordWeight-init
+ new-CoordWeight
+ CoordWeight-name
+ CoordWeight-get-sumpart
+ CoordWeight-get-maxpart
+ CoordWeight-get-sumextra
+ CoordWeight-get-maxextra
+ delete-CoordWeight
+ Compactor-STANDARD
+ Compactor-FULL
+ Compactor-FULLER
+ new-Compactor
+ delete-Compactor
+ Compactor-set-block-size
+ Compactor-set-renumber
+ Compactor-set-multipass
+ Compactor-set-compaction-level
+ Compactor-set-destdir
+ Compactor-add-source
+ Compactor-compact
+ Compactor-set-status
+ Compactor-resolve-duplicate-metadata
+ delete-PostingSource
+ PostingSource-get-termfreq-min
+ PostingSource-get-termfreq-est
+ PostingSource-get-termfreq-max
+ PostingSource-set-maxweight
+ PostingSource-get-maxweight
+ PostingSource-get-weight
+ PostingSource-get-docid
+ PostingSource-next
+ PostingSource-skip-to
+ PostingSource-check
+ PostingSource-at-end
+ PostingSource-name
+ PostingSource-init
+ PostingSource-get-description
+ PostingSource-release
+ new-ValuePostingSource
+ ValuePostingSource-get-termfreq-min
+ ValuePostingSource-get-termfreq-est
+ ValuePostingSource-get-termfreq-max
+ ValuePostingSource-next
+ ValuePostingSource-skip-to
+ ValuePostingSource-check
+ ValuePostingSource-at-end
+ ValuePostingSource-get-docid
+ ValuePostingSource-init
+ ValuePostingSource-get-database
+ ValuePostingSource-get-slot
+ ValuePostingSource-get-value
+ ValuePostingSource-done
+ ValuePostingSource-get-started
+ ValuePostingSource-set-termfreq-min
+ ValuePostingSource-set-termfreq-est
+ ValuePostingSource-set-termfreq-max
+ delete-ValuePostingSource
+ new-ValueWeightPostingSource
+ ValueWeightPostingSource-get-weight
+ ValueWeightPostingSource-name
+ ValueWeightPostingSource-init
+ ValueWeightPostingSource-get-description
+ delete-ValueWeightPostingSource
+ new-DecreasingValueWeightPostingSource
+ new-DecreasingValueWeightPostingSource
+ new-DecreasingValueWeightPostingSource
+ DecreasingValueWeightPostingSource-get-weight
+ DecreasingValueWeightPostingSource-name
+ DecreasingValueWeightPostingSource-init
+ DecreasingValueWeightPostingSource-next
+ DecreasingValueWeightPostingSource-skip-to
+ DecreasingValueWeightPostingSource-check
+ DecreasingValueWeightPostingSource-get-description
+ delete-DecreasingValueWeightPostingSource
+ new-ValueMapPostingSource
+ ValueMapPostingSource-add-mapping
+ ValueMapPostingSource-clear-mappings
+ ValueMapPostingSource-set-default-weight
+ ValueMapPostingSource-get-weight
+ ValueMapPostingSource-name
+ ValueMapPostingSource-init
+ ValueMapPostingSource-get-description
+ delete-ValueMapPostingSource
+ new-FixedWeightPostingSource
+ FixedWeightPostingSource-get-termfreq-min
+ FixedWeightPostingSource-get-termfreq-est
+ FixedWeightPostingSource-get-termfreq-max
+ FixedWeightPostingSource-get-weight
+ FixedWeightPostingSource-next
+ FixedWeightPostingSource-skip-to
+ FixedWeightPostingSource-check
+ FixedWeightPostingSource-at-end
+ FixedWeightPostingSource-get-docid
+ FixedWeightPostingSource-name
+ FixedWeightPostingSource-init
+ FixedWeightPostingSource-get-description
+ delete-FixedWeightPostingSource
+ delete-MatchSpy
+ MatchSpy-apply
+ MatchSpy-name
+ MatchSpy-merge-results
+ MatchSpy-get-description
+ MatchSpy-release
+ new-ValueCountMatchSpy
+ new-ValueCountMatchSpy
+ ValueCountMatchSpy-get-total
+ ValueCountMatchSpy-values-begin
+ ValueCountMatchSpy-values-end
+ ValueCountMatchSpy-top-values-begin
+ ValueCountMatchSpy-top-values-end
+ ValueCountMatchSpy-apply
+ ValueCountMatchSpy-name
+ ValueCountMatchSpy-merge-results
+ ValueCountMatchSpy-get-description
+ delete-ValueCountMatchSpy
+ miles-to-metres
+ metres-to-miles
+ LatLongCoord-latitude-set
+ LatLongCoord-latitude-get
+ LatLongCoord-longitude-set
+ LatLongCoord-longitude-get
+ new-LatLongCoord
+ new-LatLongCoord
+ LatLongCoord-unserialise
+ LatLongCoord-serialise
+ LatLongCoord-get-description
+ delete-LatLongCoord
+ new-LatLongCoordsIterator
+ LatLongCoordsIterator-equals
+ LatLongCoordsIterator-get-coord
+ LatLongCoordsIterator-next
+ delete-LatLongCoordsIterator
+ LatLongCoords-begin
+ LatLongCoords-end
+ LatLongCoords-size
+ LatLongCoords-empty
+ LatLongCoords-append
+ new-LatLongCoords
+ new-LatLongCoords
+ LatLongCoords-unserialise
+ LatLongCoords-serialise
+ LatLongCoords-get-description
+ delete-LatLongCoords
+ delete-LatLongMetric
+ LatLongMetric-pointwise-distance
+ LatLongMetric-apply
+ LatLongMetric-apply
+ LatLongMetric-apply
+ LatLongMetric-name
+ new-GreatCircleMetric
+ new-GreatCircleMetric
+ GreatCircleMetric-pointwise-distance
+ GreatCircleMetric-name
+ delete-GreatCircleMetric
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ new-LatLongDistancePostingSource
+ delete-LatLongDistancePostingSource
+ LatLongDistancePostingSource-next
+ LatLongDistancePostingSource-skip-to
+ LatLongDistancePostingSource-check
+ LatLongDistancePostingSource-get-weight
+ LatLongDistancePostingSource-name
+ LatLongDistancePostingSource-init
+ LatLongDistancePostingSource-get-description
+ new-LatLongDistanceKeyMaker
+ new-LatLongDistanceKeyMaker
+ new-LatLongDistanceKeyMaker
+ new-LatLongDistanceKeyMaker
+ new-LatLongDistanceKeyMaker
+ new-LatLongDistanceKeyMaker
+ delete-LatLongDistanceKeyMaker
+ LatLongDistanceKeyMaker-apply
+ Database-add-database
+ Database-size
+ new-Database
+ new-Database
+ new-Database
+ new-Database
+ new-Database
+ delete-Database
+ Database-reopen
+ Database-close
+ Database-get-description
+ Database-postlist-begin
+ Database-postlist-end
+ Database-termlist-begin
+ Database-termlist-end
+ Database-has-positions
+ Database-positionlist-begin
+ Database-positionlist-end
+ Database-allterms-begin
+ Database-allterms-begin
+ Database-allterms-end
+ Database-allterms-end
+ Database-get-doccount
+ Database-get-lastdocid
+ Database-get-avlength
+ Database-get-total-length
+ Database-get-termfreq
+ Database-term-exists
+ Database-get-collection-freq
+ Database-get-value-freq
+ Database-get-value-lower-bound
+ Database-get-value-upper-bound
+ Database-get-doclength-lower-bound
+ Database-get-doclength-upper-bound
+ Database-get-wdf-upper-bound
+ Database-valuestream-begin
+ Database-valuestream-end
+ Database-get-doclength
+ Database-get-unique-terms
+ Database-keep-alive
+ Database-get-document
+ Database-get-document
+ Database-get-spelling-suggestion
+ Database-get-spelling-suggestion
+ Database-spellings-begin
+ Database-spellings-end
+ Database-synonyms-begin
+ Database-synonyms-end
+ Database-synonym-keys-begin
+ Database-synonym-keys-begin
+ Database-synonym-keys-end
+ Database-synonym-keys-end
+ Database-get-metadata
+ Database-metadata-keys-begin
+ Database-metadata-keys-begin
+ Database-metadata-keys-end
+ Database-metadata-keys-end
+ Database-get-uuid
+ Database-locked
+ Database-get-revision
+ Database-check
+ Database-check
+ Database-check
+ Database-check
+ Database-compact
+ Database-compact
+ Database-compact
+ Database-compact
+ Database-compact
+ Database-compact
+ Database-compact
+ Database-compact
+ delete-WritableDatabase
+ new-WritableDatabase
+ new-WritableDatabase
+ new-WritableDatabase
+ new-WritableDatabase
+ WritableDatabase-commit
+ WritableDatabase-flush
+ WritableDatabase-begin-transaction
+ WritableDatabase-begin-transaction
+ WritableDatabase-commit-transaction
+ WritableDatabase-cancel-transaction
+ WritableDatabase-add-document
+ WritableDatabase-delete-document
+ WritableDatabase-delete-document
+ WritableDatabase-replace-document
+ WritableDatabase-replace-document
+ WritableDatabase-add-spelling
+ WritableDatabase-add-spelling
+ WritableDatabase-remove-spelling
+ WritableDatabase-remove-spelling
+ WritableDatabase-add-synonym
+ WritableDatabase-remove-synonym
+ WritableDatabase-clear-synonyms
+ WritableDatabase-set-metadata
+ WritableDatabase-get-description
+ open-stub
+ open-stub
+ inmemory-open
+ chert-open
+ chert-open
+ chert-open
+ remote-open
+ remote-open
+ remote-open
+ remote-open-writable
+ remote-open-writable
+ remote-open-writable
+ remote-open-writable
+ remote-open
+ remote-open
+ remote-open-writable
+ remote-open-writable
+ remote-open-writable)
diff --git a/xapian/xapian.scm b/xapian/xapian.scm
new file mode 100644
index 0000000..8801838
--- /dev/null
+++ b/xapian/xapian.scm
@@ -0,0 +1,124 @@
+;;; guile-xapian --- Guile bindings for Xapian
+;;; Copyright © 2020 Arun Isaac <arunisaac@systemreboot.net>
+;;;
+;;; 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/>.
+
+(define-module (xapian xapian)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-26)
+ #:use-module (xapian wrap)
+ #:export (xapian-open
+ xapian-close
+ call-with-database
+ xapian-open-writable
+ xapian-close-writable
+ call-with-writable-database
+ add-document!
+ replace-document!
+ make-document
+ document-data
+ make-stem
+ make-term-generator
+ index-text!
+ increase-termpos!
+ parse-query
+ enquire
+ enquire-mset
+ mset-item-docid
+ mset-item-document
+ mset-item-rank
+ mset-item-weight
+ mset-fold))
+
+(define xapian-open new-Database)
+(define xapian-close delete-Database)
+
+(define (call-with-database dbpath proc)
+ (let ((db (xapian-open dbpath)))
+ (dynamic-wind noop (cut proc db) (cut xapian-close db))))
+
+(define xapian-open-writable new-WritableDatabase)
+(define xapian-close-writable delete-WritableDatabase)
+
+(define (call-with-writable-database dbpath proc)
+ (let ((db (xapian-open-writable dbpath)))
+ (dynamic-wind noop (cut proc db) (cut xapian-close-writable db))))
+
+(define add-document! WritableDatabase-add-document)
+(define replace-document! WritableDatabase-replace-document)
+
+(define* (make-document #:key data (terms '()))
+ (let ((doc (new-Document)))
+ (when data
+ (Document-set-data doc data))
+ (for-each (match-lambda
+ ((term . wdf-increment)
+ (Document-add-term doc term wdf-increment)))
+ terms)
+ doc))
+
+(define document-data Document-get-data)
+
+(define make-stem new-Stem)
+
+(define* (make-term-generator #:key stem document)
+ (let ((term-generator (new-TermGenerator)))
+ (TermGenerator-set-stemmer term-generator stem)
+ (TermGenerator-set-document term-generator document)
+ term-generator))
+
+(define* (index-text! term-generator text #:key (wdf-increment 1) prefix)
+ (apply TermGenerator-index-text term-generator text wdf-increment
+ (if prefix (list prefix) '())))
+
+(define increase-termpos! TermGenerator-increase-termpos)
+
+(define* (parse-query querystring #:key stemmer stemming-strategy (prefixes '()))
+ (let ((queryparser (new-QueryParser)))
+ (QueryParser-set-stemmer queryparser stemmer)
+ (when stemming-strategy
+ (QueryParser-set-stemming-strategy queryparser stemming-strategy))
+ (for-each (match-lambda
+ ((field . prefix)
+ (QueryParser-add-prefix queryparser field prefix)))
+ prefixes)
+ (let ((query (QueryParser-parse-query queryparser querystring)))
+ (delete-QueryParser queryparser)
+ query)))
+
+(define* (enquire db query #:key weighting-scheme)
+ (let ((enquire (new-Enquire db)))
+ (Enquire-set-query enquire query)
+ (when weighting-scheme
+ (Enquire-set-weighting-scheme enquire weighting-scheme))
+ enquire))
+
+(define enquire-mset Enquire-get-mset)
+
+(define mset-item-docid MSetIterator-get-docid)
+(define mset-item-document MSetIterator-get-document)
+(define mset-item-rank MSetIterator-get-rank)
+(define mset-item-weight MSetIterator-get-weight)
+
+(define (mset-fold proc init mset)
+ (let loop ((head (MSet-begin mset))
+ (result init))
+ (cond
+ ((MSetIterator-equals head (MSet-end mset)) result)
+ (else (let ((result (proc head result)))
+ (MSetIterator-next head)
+ (loop head result))))))