branch: externals/xeft
commit 76b13ca6547092edb06d60584e8896f432c4dea0
Author: Yuan Fu <[email protected]>
Commit: Yuan Fu <[email protected]>
Upgrade xapian-lite
* xapian-lite.cc: Upgrade to latest.
---
xapian-lite.cc | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 100 insertions(+), 3 deletions(-)
diff --git a/xapian-lite.cc b/xapian-lite.cc
index 539c15046c..e1c9499560 100644
--- a/xapian-lite.cc
+++ b/xapian-lite.cc
@@ -42,6 +42,10 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include "emacs-module.h"
#include "emacs-module-prelude.h"
+#if defined _WIN32
+#include <Windows.h>
+#endif
+
using namespace std;
int plugin_is_GPL_compatible;
@@ -113,6 +117,37 @@ hash_path (string path)
}
}
+#ifdef _WIN32
+static std::wstring ConvertUtf8ToWide(const std::string& str)
+{
+ int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(),
nullptr, 0);
+ std::wstring wstr(count, 0);
+ MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0],
count);
+ return wstr;
+}
+
+static std::string ConvertWideToANSI(const std::wstring& wstr)
+{
+ int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(),
nullptr, 0, nullptr, nullptr);
+ std::string str(count, 0);
+ WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, nullptr,
nullptr);
+ return str;
+}
+
+static std::string GetConvertedWindowsPath(const std::string &path)
+{
+ std::string cvtPath = path;
+ // Code pages for reference
https://learn.microsoft.com/zh-tw/windows/win32/intl/code-page-identifiers
+ if (65001 != GetACP())
+ {
+ auto wsPath = ConvertUtf8ToWide(path);
+ cvtPath = ConvertWideToANSI(wsPath);
+ }
+
+ return cvtPath;
+}
+#endif
+
// Reindex the file at PATH, using database at DBPATH. Throws
// cannot_open_file. Both path must be absolute. Normally only reindex
// if file has change since last index, if FORCE is true, always
@@ -128,7 +163,13 @@ reindex_file
struct stat st;
time_t file_mtime;
off_t file_size;
+
+#if defined _WIN32
+ auto cvtPath = GetConvertedWindowsPath(path);
+ if (stat (cvtPath.c_str(), &st) == 0)
+#else
if (stat (path.c_str(), &st) == 0)
+#endif
{
file_mtime = st.st_mtime;
file_size = st.st_size;
@@ -145,6 +186,10 @@ reindex_file
// modified.
if (dbpath != cached_dbpath)
{
+ if (cached_dbpath != "")
+ {
+ database.close();
+ }
database = Xapian::WritableDatabase
(dbpath, Xapian::DB_CREATE_OR_OPEN);
cached_dbpath = dbpath;
@@ -212,6 +257,10 @@ query_term
// See reindex_file for the reason for caching the database object.
if (dbpath != cached_dbpath)
{
+ if (cached_dbpath != "")
+ {
+ database.close();
+ }
database = Xapian::WritableDatabase
(dbpath, Xapian::DB_CREATE_OR_OPEN);
cached_dbpath = dbpath;
@@ -244,7 +293,7 @@ query_term
(term, Xapian::QueryParser::FLAG_CJK_NGRAM
| Xapian::QueryParser::FLAG_PARTIAL);
}
-
+
Xapian::Enquire enquire (database);
enquire.set_query (query);
@@ -341,7 +390,7 @@ Fxapian_lite_reindex_file
emacs_value lisp_lang = nargs < 3 ? emp_intern (env, "nil") : args[2];
emacs_value lisp_force = nargs < 4 ? emp_intern (env, "nil") : args[3];
-
+
string path = copy_string (env, lisp_path);
string dbpath = copy_string (env, lisp_dbpath);
bool force = !NILP (env, lisp_force);
@@ -349,7 +398,7 @@ Fxapian_lite_reindex_file
string lang = NILP (env, lisp_lang) ?
"en" : copy_string (env, lisp_lang);
CHECK_EXIT (env);
-
+
// Do the work.
bool indexed;
try
@@ -475,6 +524,51 @@ Fxapian_lite_query_term
return emp_funcall (env, "reverse", 1, ret);
}
+static const char *xapian_lite_close_database_doc =
+ "By closing the databse, you allow other xapian-lite instances to\n"
+ "access the database. In addition, closing the database commits all the\n"
+ "pending modifications to the database done by\n"
+ "`xapian-lite-reindex-file'. (For performance reasons, modifications to\n"
+ "the database is only committed to the disk after 10000 changes or when\n"
+ "closing the database.) It’s a good idea to close the database\n"
+ "periodically so database modifications aren’t lost due to unexpected\n"
+ "Emacs crash.\n"
+ "\n"
+ "There’s no need to explicitly reconnect to the database, since any\n"
+ "subsequent access will automatically reconnect to it.\n"
+ "\n"
+ "(fn DBPATH)";
+
+static emacs_value
+Fxapian_lite_close_database
+(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
+ EMACS_NOEXCEPT
+{
+ emacs_value lisp_dbpath = args[0];
+
+ if (NILP (env,
+ emp_funcall (env, "file-name-absolute-p", 1, lisp_dbpath)))
+ {
+ emp_signal_message1 (env, "xapian-lite-file-error",
+ "DBPATH is not a absolute path");
+ return NULL;
+ }
+
+ lisp_dbpath = emp_funcall (env, "expand-file-name", 1, lisp_dbpath);
+ string dbpath = copy_string (env, lisp_dbpath);
+
+ /* If cached_dbpath == "", there's no database to close. If dbpath
+ != cached_dbpath, the database that the user wants to close is
+ already closed. */
+ if (cached_dbpath != "" && dbpath == cached_dbpath)
+ {
+ database.close();
+ cached_dbpath = "";
+ }
+
+ return emp_intern (env, "nil");
+}
+
int
emacs_module_init (struct emacs_runtime *ert) EMACS_NOEXCEPT
{
@@ -497,6 +591,9 @@ emacs_module_init (struct emacs_runtime *ert) EMACS_NOEXCEPT
emp_define_function(env, "xapian-lite-query-term", 4, 4,
&Fxapian_lite_query_term,
xapian_lite_query_term_doc);
+ emp_define_function(env, "xapian-lite-close-database", 1, 1,
+ &Fxapian_lite_close_database,
+ xapian_lite_close_database_doc);
emp_provide (env, "xapian-lite");