Enchant Generic spell checking library

enchant++.h
1 /* enchant
2 * Copyright (C) 2003 Dom Lachowicz
3 * Copyright (C) 2017-2022 Reuben Thomas
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along along with this program; if not, see
17 * <https://www.gnu.org/licenses/>.
18 *
19 * In addition, as a special exception, the copyright holders
20 * give permission to link the code of this program with
21 * non-LGPL Spelling Provider libraries (eg: a MSFT Office
22 * spell checker backend) and distribute linked combinations including
23 * the two. You must obey the GNU Lesser General Public License in all
24 * respects for all of the code used other than said providers. If you modify
25 * this file, you may extend this exception to your version of the
26 * file, but you are not obligated to do so. If you do not wish to
27 * do so, delete this exception statement from your version.
28 */
29
30 #ifndef ENCHANT_PLUS_PLUS_H
31 #define ENCHANT_PLUS_PLUS_H
32
33 #include <enchant.h>
34 #include <string>
35 #include <vector>
36 #include <exception>
37
38 namespace enchant
39 {
40 void set_prefix_dir (const std::string prefix) {
41 enchant_set_prefix_dir (prefix.c_str ());
42 }
43
44 class Broker;
45
46 class Exception : public std::exception
47 {
48 public:
49 explicit Exception (const char * ex)
50 : std::exception (), m_ex ("") {
51 if (ex)
52 m_ex = ex;
53 }
54
55 virtual ~Exception () noexcept {
56 }
57
58 virtual const char * what () const noexcept {
59 return m_ex.c_str();
60 }
61
62 private:
63 std::string m_ex;
64 };
65
66 class Dict
67 {
68 friend class enchant::Broker;
69
70 public:
71
72 ~Dict () {
73 enchant_broker_free_dict (m_broker, m_dict);
74 }
75
76 bool check (const std::string & utf8word) {
77 int val;
78
79 val = enchant_dict_check (m_dict, utf8word.c_str(),
80 utf8word.size());
81 if (val == 0)
82 return true;
83 else if (val > 0)
84 return false;
85 else {
86 throw enchant::Exception (enchant_dict_get_error (m_dict));
87 }
88
89 return false; // never reached
90 }
91
92 void suggest (const std::string & utf8word,
93 std::vector<std::string> & out_suggestions) {
94 size_t n_suggs;
95 char ** suggs;
96
97 out_suggestions.clear ();
98
99 suggs = enchant_dict_suggest (m_dict, utf8word.c_str(),
100 utf8word.size(), &n_suggs);
101
102 if (suggs && n_suggs) {
103 out_suggestions.reserve(n_suggs);
104
105 for (size_t i = 0; i < n_suggs; i++) {
106 out_suggestions.push_back (suggs[i]);
107 }
108
109 enchant_dict_free_string_list (m_dict, suggs);
110 }
111 }
112
113 std::vector<std::string> suggest (const std::string & utf8word) {
114 std::vector<std::string> result;
115 suggest (utf8word, result);
116 return result;
117 }
118
119 void add (const std::string & utf8word) {
120 enchant_dict_add (m_dict, utf8word.c_str(),
121 utf8word.size());
122 }
123
124 void add_to_session (const std::string & utf8word) {
125 enchant_dict_add_to_session (m_dict, utf8word.c_str(),
126 utf8word.size());
127 }
128
129 bool is_added (const std::string & utf8word) {
130 return enchant_dict_is_added (m_dict, utf8word.c_str(),
131 utf8word.size());
132 }
133
134 void remove (const std::string & utf8word) {
135 enchant_dict_remove (m_dict, utf8word.c_str(),
136 utf8word.size());
137 }
138
139 void remove_from_session (const std::string & utf8word) {
140 enchant_dict_remove_from_session (m_dict, utf8word.c_str(),
141 utf8word.size());
142 }
143
144 void is_removed (const std::string & utf8word) {
145 enchant_dict_is_removed (m_dict, utf8word.c_str(),
146 utf8word.size());
147 }
148
149 void store_replacement (const std::string & utf8bad,
150 const std::string & utf8good) {
151 enchant_dict_store_replacement (m_dict,
152 utf8bad.c_str(), utf8bad.size(),
153 utf8good.c_str(), utf8good.size());
154 }
155
156 const std::string & get_lang () const {
157 return m_lang;
158 }
159
160 const std::string & get_provider_name () const {
161 return m_provider_name;
162 }
163
164 const std::string & get_provider_desc () const {
165 return m_provider_desc;
166 }
167
168 const std::string & get_provider_file () const {
169 return m_provider_file;
170 }
171
172 private:
173
174 // space reserved for API/ABI expansion
175 void * _private[5];
176
177 static void s_describe_fn (const char * const lang,
178 const char * const provider_name,
179 const char * const provider_desc,
180 const char * const provider_file,
181 void * user_data) {
182 enchant::Dict * dict = static_cast<enchant::Dict *> (user_data);
183
184 dict->m_lang = lang;
185 dict->m_provider_name = provider_name;
186 dict->m_provider_desc = provider_desc;
187 dict->m_provider_file = provider_file;
188 }
189
190 Dict (EnchantDict * dict, EnchantBroker * broker)
191 : m_dict (dict), m_broker (broker) {
192 enchant_dict_describe (m_dict, s_describe_fn, this);
193 }
194
195 // private, unimplemented
196 Dict ();
197 Dict (const Dict & rhs);
198 Dict& operator=(const Dict & rhs);
199
200 EnchantDict * m_dict;
201 EnchantBroker * m_broker;
202
203 std::string m_lang;
204 std::string m_provider_name;
205 std::string m_provider_desc;
206 std::string m_provider_file;
207 }; // class enchant::Dict
208
209 class Broker
210 {
211
212 public:
213
214 Broker ()
215 : m_broker (enchant_broker_init ())
216 {
217 }
218
219 ~Broker () {
220 enchant_broker_free (m_broker);
221 }
222
223 Dict * request_dict (const std::string & lang) {
224 EnchantDict * dict = enchant_broker_request_dict (m_broker, lang.c_str());
225
226 if (!dict) {
227 throw enchant::Exception (enchant_broker_get_error (m_broker));
228 return 0; // never reached
229 }
230
231 return new Dict (dict, m_broker);
232 }
233
234 Dict * request_pwl_dict (const std::string & pwl) {
235 EnchantDict * dict = enchant_broker_request_pwl_dict (m_broker, pwl.c_str());
236
237 if (!dict) {
238 throw enchant::Exception (enchant_broker_get_error (m_broker));
239 return 0; // never reached
240 }
241
242 return new Dict (dict, m_broker);
243 }
244
245 bool dict_exists (const std::string & lang) {
246 if (enchant_broker_dict_exists (m_broker, lang.c_str()))
247 return true;
248 return false;
249 }
250
251 void set_ordering (const std::string & tag, const std::string & ordering) {
252 enchant_broker_set_ordering (m_broker, tag.c_str(), ordering.c_str());
253 }
254
255 void describe (EnchantBrokerDescribeFn fn, void * user_data = NULL) {
256 enchant_broker_describe (m_broker, fn, user_data);
257 }
258
259 void list_dicts (EnchantDictDescribeFn fn, void * user_data = NULL) {
260 enchant_broker_list_dicts (m_broker, fn, user_data);
261 }
262
263 private:
264
265 // not implemented
266 Broker (const Broker & rhs);
267 Broker& operator=(const Broker & rhs);
268
269 EnchantBroker * m_broker;
270 }; // class enchant::Broker
271 } // enchant namespace
272
273 #endif /* ENCHANT_PLUS_PLUS_H */
enchant::Broker
Definition: enchant++.h:210
enchant::Dict
Definition: enchant++.h:67
enchant::Exception
Definition: enchant++.h:47
str_enchant_broker
Definition: lib.c:55
str_enchant_dict
Definition: enchant-provider.h:125