Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
252 lines
8.3 KiB
C++
252 lines
8.3 KiB
C++
/* enchant
|
|
* Copyright (C) 2003 Dom Lachowicz
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
* In addition, as a special exception, Dom Lachowicz
|
|
* gives permission to link the code of this program with
|
|
* non-LGPL Spelling Provider libraries (eg: a MSFT Office
|
|
* spell checker backend) and distribute linked combinations including
|
|
* the two. You must obey the GNU Lesser General Public License in all
|
|
* respects for all of the code used other than said providers. If you modify
|
|
* this file, you may extend this exception to your version of the
|
|
* file, but you are not obligated to do so. If you do not wish to
|
|
* do so, delete this exception statement from your version.
|
|
*
|
|
* Nicholas Guriev (email: guriev-ns@ya.ru) split the full <enchant++.h> header
|
|
* into two files, linux_enchant.h and linux_enchant.cpp, to use within Desktop
|
|
* App Toolkit. He also implemented explicit linking with dlopen/dlsym to avoid
|
|
* rigid dependency on the Enchant library at runtime.
|
|
*/
|
|
|
|
#include <enchant.h>
|
|
#include "base/platform/linux/base_linux_library.h"
|
|
#include "spellcheck/platform/linux/linux_enchant.h"
|
|
|
|
namespace {
|
|
|
|
struct {
|
|
//decltype (enchant_broker_describe) * broker_describe;
|
|
//decltype (enchant_broker_dict_exists) * broker_dict_exists;
|
|
decltype (enchant_broker_free) * broker_free;
|
|
decltype (enchant_broker_free_dict) * broker_free_dict;
|
|
decltype (enchant_broker_get_error) * broker_get_error;
|
|
decltype (enchant_broker_init) * broker_init;
|
|
decltype (enchant_broker_list_dicts) * broker_list_dicts;
|
|
decltype (enchant_broker_request_dict) * broker_request_dict;
|
|
//decltype (enchant_broker_request_pwl_dict) * broker_request_pwl_dict;
|
|
decltype (enchant_broker_set_ordering) * broker_set_ordering;
|
|
decltype (enchant_dict_add) * dict_add;
|
|
decltype (enchant_dict_add_to_session) * dict_add_to_session;
|
|
decltype (enchant_dict_check) * dict_check;
|
|
decltype (enchant_dict_describe) * dict_describe;
|
|
decltype (enchant_dict_free_string_list) * dict_free_string_list;
|
|
decltype (enchant_dict_get_error) * dict_get_error;
|
|
decltype (enchant_dict_is_added) * dict_is_added;
|
|
//decltype (enchant_dict_is_removed) * dict_is_removed;
|
|
decltype (enchant_dict_remove) * dict_remove;
|
|
decltype (enchant_dict_remove_from_session) * dict_remove_from_session;
|
|
//decltype (enchant_dict_store_replacement) * dict_store_replacement;
|
|
decltype (enchant_dict_suggest) * dict_suggest;
|
|
} f_enchant;
|
|
|
|
} // anonymous namespace
|
|
|
|
enchant::Exception::Exception (const char * ex)
|
|
: std::exception (), m_ex ("") {
|
|
if (ex)
|
|
m_ex = ex;
|
|
}
|
|
|
|
enchant::Exception::~Exception () = default;
|
|
|
|
const char * enchant::Exception::what () const noexcept {
|
|
return m_ex.c_str();
|
|
}
|
|
|
|
enchant::Dict::Dict (EnchantDict * dict, EnchantBroker * broker)
|
|
: m_dict (dict), m_broker (broker) {
|
|
f_enchant.dict_describe (m_dict, s_describe_fn, this);
|
|
}
|
|
|
|
enchant::Dict::~Dict () {
|
|
f_enchant.broker_free_dict (m_broker, m_dict);
|
|
}
|
|
|
|
bool enchant::Dict::check (const std::string & utf8word) {
|
|
int val;
|
|
|
|
val = f_enchant.dict_check (m_dict, utf8word.c_str(), utf8word.size());
|
|
if (val == 0)
|
|
return true;
|
|
else if (val > 0)
|
|
return false;
|
|
else {
|
|
throw enchant::Exception (f_enchant.dict_get_error (m_dict));
|
|
}
|
|
|
|
return false; // never reached
|
|
}
|
|
|
|
void enchant::Dict::suggest (const std::string & utf8word,
|
|
std::vector<std::string> & out_suggestions) {
|
|
size_t n_suggs;
|
|
char ** suggs;
|
|
|
|
out_suggestions.clear ();
|
|
|
|
suggs = f_enchant.dict_suggest (m_dict, utf8word.c_str(),
|
|
utf8word.size(), &n_suggs);
|
|
|
|
if (suggs && n_suggs) {
|
|
out_suggestions.reserve(n_suggs);
|
|
|
|
for (size_t i = 0; i < n_suggs; i++) {
|
|
out_suggestions.push_back (suggs[i]);
|
|
}
|
|
|
|
f_enchant.dict_free_string_list (m_dict, suggs);
|
|
}
|
|
}
|
|
|
|
void enchant::Dict::add (const std::string & utf8word) {
|
|
f_enchant.dict_add (m_dict, utf8word.c_str(), utf8word.size());
|
|
}
|
|
|
|
void enchant::Dict::add_to_session (const std::string & utf8word) {
|
|
f_enchant.dict_add_to_session (m_dict, utf8word.c_str(), utf8word.size());
|
|
}
|
|
|
|
bool enchant::Dict::is_added (const std::string & utf8word) {
|
|
return f_enchant.dict_is_added (m_dict, utf8word.c_str(),
|
|
utf8word.size());
|
|
}
|
|
|
|
void enchant::Dict::remove (const std::string & utf8word) {
|
|
f_enchant.dict_remove (m_dict, utf8word.c_str(), utf8word.size());
|
|
}
|
|
|
|
void enchant::Dict::remove_from_session (const std::string & utf8word) {
|
|
f_enchant.dict_remove_from_session (m_dict, utf8word.c_str(),
|
|
utf8word.size());
|
|
}
|
|
|
|
//bool enchant::Dict::is_removed (const std::string & utf8word) {
|
|
// return f_enchant.dict_is_removed (m_dict, utf8word.c_str(),
|
|
// utf8word.size());
|
|
//}
|
|
|
|
//void enchant::Dict::store_replacement (const std::string & utf8bad,
|
|
// const std::string & utf8good) {
|
|
// f_enchant.dict_store_replacement (m_dict,
|
|
// utf8bad.c_str(), utf8bad.size(),
|
|
// utf8good.c_str(), utf8good.size());
|
|
//}
|
|
|
|
enchant::Broker::Broker ()
|
|
: m_broker (f_enchant.broker_init ())
|
|
{
|
|
}
|
|
|
|
enchant::Broker::~Broker () {
|
|
f_enchant.broker_free (m_broker);
|
|
}
|
|
|
|
enchant::Dict * enchant::Broker::request_dict (const std::string & lang) {
|
|
EnchantDict * dict = f_enchant.broker_request_dict (m_broker, lang.c_str());
|
|
|
|
if (!dict) {
|
|
throw enchant::Exception (f_enchant.broker_get_error (m_broker));
|
|
return 0; // never reached
|
|
}
|
|
|
|
return new Dict (dict, m_broker);
|
|
}
|
|
|
|
//enchant::Dict * enchant::Broker::request_pwl_dict (const std::string & pwl) {
|
|
// EnchantDict * dict = f_enchant.broker_request_pwl_dict (m_broker, pwl.c_str());
|
|
//
|
|
// if (!dict) {
|
|
// throw enchant::Exception (f_enchant.broker_get_error (m_broker));
|
|
// return 0; // never reached
|
|
// }
|
|
//
|
|
// return new Dict (dict, m_broker);
|
|
//}
|
|
|
|
//bool enchant::Broker::dict_exists (const std::string & lang) {
|
|
// if (f_enchant.broker_dict_exists (m_broker, lang.c_str()))
|
|
// return true;
|
|
// return false;
|
|
//}
|
|
|
|
void enchant::Broker::set_ordering (const std::string & tag, const std::string & ordering) {
|
|
f_enchant.broker_set_ordering (m_broker, tag.c_str(), ordering.c_str());
|
|
}
|
|
|
|
//void enchant::Broker::describe (EnchantBrokerDescribeFn fn, void * user_data) {
|
|
// f_enchant.broker_describe (m_broker, fn, user_data);
|
|
//}
|
|
|
|
void enchant::Broker::list_dicts (EnchantDictDescribeFn fn, void * user_data) {
|
|
f_enchant.broker_list_dicts (m_broker, fn, user_data);
|
|
}
|
|
|
|
#define GET_SYMBOL_enchant(func_name) \
|
|
if (!base::Platform::LoadSymbol (handle, "enchant_" # func_name, f_enchant.func_name)) { \
|
|
return false; \
|
|
}
|
|
|
|
bool enchant::loader::do_explicit_linking () {
|
|
static enum { NotLoadedYet, LoadSuccessful, LoadFailed = -1 } load_status;
|
|
if (load_status == NotLoadedYet) {
|
|
load_status = LoadFailed;
|
|
const auto handle = base::Platform::LoadLibrary ("libenchant.so.1", RTLD_NODELETE)
|
|
?: base::Platform::LoadLibrary ("libenchant-2.so.2", RTLD_NODELETE)
|
|
?: base::Platform::LoadLibrary ("libenchant.so.2", RTLD_NODELETE);
|
|
if (!handle) {
|
|
// logs ?
|
|
return false;
|
|
}
|
|
//GET_SYMBOL_enchant (broker_describe);
|
|
//GET_SYMBOL_enchant (broker_dict_exists);
|
|
GET_SYMBOL_enchant (broker_free);
|
|
GET_SYMBOL_enchant (broker_free_dict);
|
|
GET_SYMBOL_enchant (broker_get_error);
|
|
GET_SYMBOL_enchant (broker_init);
|
|
GET_SYMBOL_enchant (broker_list_dicts);
|
|
GET_SYMBOL_enchant (broker_request_dict);
|
|
//GET_SYMBOL_enchant (broker_request_pwl_dict);
|
|
GET_SYMBOL_enchant (broker_set_ordering);
|
|
GET_SYMBOL_enchant (dict_add);
|
|
GET_SYMBOL_enchant (dict_add_to_session);
|
|
GET_SYMBOL_enchant (dict_check);
|
|
GET_SYMBOL_enchant (dict_describe);
|
|
GET_SYMBOL_enchant (dict_free_string_list);
|
|
GET_SYMBOL_enchant (dict_get_error);
|
|
GET_SYMBOL_enchant (dict_is_added);
|
|
//GET_SYMBOL_enchant (dict_is_removed);
|
|
GET_SYMBOL_enchant (dict_remove);
|
|
GET_SYMBOL_enchant (dict_remove_from_session);
|
|
//GET_SYMBOL_enchant (dict_store_replacement);
|
|
GET_SYMBOL_enchant (dict_suggest);
|
|
load_status = LoadSuccessful;
|
|
}
|
|
return load_status == LoadSuccessful;
|
|
}
|
|
|
|
// vi: ts=8 sw=8
|