* Implement a different way to delete a password from the cache.
[alpine.git] / pico / osdep / mswin_aspell.c
blob26e998dabec11bf7ace18d32e41cc38af7ff1a3a
1 /*
2 * ========================================================================
3 * FILE: MSWIN_ASPELL.C
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
13 #include <system.h>
14 #include "mswin_aspell.h"
17 * Aspell typedefs
19 typedef struct AspellConfig AspellConfig;
20 typedef struct AspellSpeller AspellSpeller;
21 typedef struct AspellCanHaveError AspellCanHaveError;
22 typedef struct AspellStringEnumeration AspellStringEnumeration;
23 typedef struct AspellWordList AspellWordList;
24 typedef struct AspellError AspellError;
27 * Aspell function prototypes
29 typedef AspellCanHaveError * (__cdecl NEW_ASPELL_SPELLER)(AspellConfig * config);
30 typedef AspellConfig * (__cdecl NEW_ASPELL_CONFIG)();
31 typedef AspellSpeller * (__cdecl TO_ASPELL_SPELLER)(AspellCanHaveError * obj);
32 typedef int (__cdecl ASPELL_CONFIG_REPLACE)(AspellConfig * ths, const char * key, const char * value);
33 typedef void (__cdecl DELETE_ASPELL_CONFIG)(AspellConfig * ths);
34 typedef const char * (__cdecl ASPELL_CONFIG_RETRIEVE)(AspellConfig * ths, const char * key);
35 typedef int (__cdecl ASPELL_SPELLER_ADD_TO_PERSONAL)(AspellSpeller * ths, const char * word, int word_size);
36 typedef int (__cdecl ASPELL_SPELLER_ADD_TO_SESSION)(AspellSpeller * ths, const char * word, int word_size);
37 typedef int (__cdecl ASPELL_SPELLER_CHECK)(AspellSpeller * ths, const char * word, int word_size);
38 typedef const AspellWordList * (__cdecl ASPELL_SPELLER_SUGGEST)(AspellSpeller * ths, const char * word, int word_size);
39 typedef int (__cdecl ASPELL_SPELLER_SAVE_ALL_WORD_LISTS)(AspellSpeller * ths);
40 typedef int (__cdecl ASPELL_SPELLER_STORE_REPLACEMENT)(AspellSpeller * ths, const char * mis, int mis_size, const char * cor, int cor_size);
41 typedef const char * (__cdecl ASPELL_STRING_ENUMERATION_NEXT)(AspellStringEnumeration * ths);
42 typedef AspellStringEnumeration *(__cdecl ASPELL_WORD_LIST_ELEMENTS)(const AspellWordList * ths);
43 typedef void (__cdecl DELETE_ASPELL_SPELLER)(AspellSpeller * ths);
44 typedef void (__cdecl DELETE_ASPELL_STRING_ENUMERATION)(AspellStringEnumeration * ths);
45 typedef void (__cdecl DELETE_ASPELL_CAN_HAVE_ERROR)(AspellCanHaveError * ths);
46 typedef const char * (__cdecl ASPELL_ERROR_MESSAGE)(const AspellCanHaveError * ths);
47 typedef unsigned int (__cdecl ASPELL_ERROR_NUMBER)(const AspellCanHaveError * ths);
48 typedef const AspellError * (__cdecl ASPELL_SPELLER_ERROR)(const AspellSpeller * ths);
49 typedef const char * (__cdecl ASPELL_SPELLER_ERROR_MESSAGE)(const struct AspellSpeller * ths);
50 typedef AspellConfig * (__cdecl ASPELL_SPELLER_CONFIG)(AspellSpeller * ths);
53 * MsWin speller information structure
55 typedef struct ASPELLINFO
57 AspellSpeller *speller;
58 AspellStringEnumeration *suggestion_elements;
59 const char *error_message;
61 AspellCanHaveError *err;
63 HMODULE mod_aspell;
65 NEW_ASPELL_SPELLER *new_aspell_speller;
66 NEW_ASPELL_CONFIG *new_aspell_config;
67 TO_ASPELL_SPELLER *to_aspell_speller;
68 ASPELL_CONFIG_REPLACE *aspell_config_replace;
69 DELETE_ASPELL_CONFIG *delete_aspell_config;
70 ASPELL_CONFIG_RETRIEVE *aspell_config_retrieve;
71 ASPELL_SPELLER_ADD_TO_PERSONAL *aspell_speller_add_to_personal;
72 ASPELL_SPELLER_ADD_TO_SESSION *aspell_speller_add_to_session;
73 ASPELL_SPELLER_CHECK *aspell_speller_check;
74 ASPELL_SPELLER_SUGGEST *aspell_speller_suggest;
75 ASPELL_SPELLER_SAVE_ALL_WORD_LISTS *aspell_speller_save_all_word_lists;
76 ASPELL_SPELLER_STORE_REPLACEMENT *aspell_speller_store_replacement;
77 ASPELL_STRING_ENUMERATION_NEXT *aspell_string_enumeration_next;
78 ASPELL_WORD_LIST_ELEMENTS *aspell_word_list_elements;
79 DELETE_ASPELL_SPELLER *delete_aspell_speller;
80 DELETE_ASPELL_STRING_ENUMERATION *delete_aspell_string_enumeration;
81 DELETE_ASPELL_CAN_HAVE_ERROR *delete_aspell_can_have_error;
82 ASPELL_ERROR_MESSAGE *aspell_error_message;
83 ASPELL_ERROR_NUMBER *aspell_error_number;
84 ASPELL_SPELLER_ERROR *aspell_speller_error;
85 ASPELL_SPELLER_ERROR_MESSAGE *aspell_speller_error_message;
86 ASPELL_SPELLER_CONFIG *aspell_speller_config;
87 } ASPELLINFO;
90 * Find, aspell-15.dll, load it, and attempt to initialize our func pointers.
91 * 1:success, 0:failed
93 static int
94 speller_load_aspell_library(ASPELLINFO *aspellinfo)
96 HKEY hKey;
97 int success = 1;
98 HMODULE mod_aspell = NULL;
99 TCHAR aspell_fullname[MAX_PATH + 1];
100 static const TCHAR aspell_name[] = TEXT("aspell-15.dll");
102 aspell_fullname[0] = '\0';
104 // Try to open the Aspell Registry key.
105 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Aspell"),
106 0, KEY_READ, &hKey) == ERROR_SUCCESS)
108 DWORD dtype;
109 TCHAR aspell_path[MAX_PATH + 1];
110 DWORD aspell_path_len = sizeof(aspell_path);
112 // Query the path.
113 if(RegQueryValueEx(hKey, TEXT("Path"), NULL, &dtype,
114 (LPBYTE)aspell_path, &aspell_path_len) == ERROR_SUCCESS)
116 _sntprintf(aspell_fullname, ARRAYSIZE(aspell_fullname),
117 TEXT("%s\\%s"), aspell_path, aspell_name);
118 aspell_fullname[ARRAYSIZE(aspell_fullname) - 1] = 0;
121 RegCloseKey(hKey);
124 // If the registry thing didn't work, then just try doing a Loadlibrary
125 // using the standard Windows LoadLibrary search gunk.
126 if(!aspell_fullname[0])
128 _tcsncpy(aspell_fullname, aspell_name, ARRAYSIZE(aspell_fullname));
129 aspell_fullname[ARRAYSIZE(aspell_fullname) - 1] = 0;
132 // Load the library.
133 mod_aspell = LoadLibrary(aspell_fullname);
134 if(!mod_aspell)
136 // Failed.
137 success = 0;
139 else
141 // Found the library - now try to initialize our function pointers.
143 #define GET_ASPELL_PROC_ADDR(_functype, _func) \
144 aspellinfo->_func = (_functype *)GetProcAddress(mod_aspell, #_func); \
145 if(!aspellinfo->_func) \
146 success = 0
148 GET_ASPELL_PROC_ADDR(NEW_ASPELL_SPELLER, new_aspell_speller);
149 GET_ASPELL_PROC_ADDR(NEW_ASPELL_CONFIG, new_aspell_config);
150 GET_ASPELL_PROC_ADDR(TO_ASPELL_SPELLER, to_aspell_speller);
151 GET_ASPELL_PROC_ADDR(ASPELL_CONFIG_REPLACE, aspell_config_replace);
152 GET_ASPELL_PROC_ADDR(DELETE_ASPELL_CONFIG, delete_aspell_config);
153 GET_ASPELL_PROC_ADDR(ASPELL_CONFIG_RETRIEVE, aspell_config_retrieve);
154 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ADD_TO_PERSONAL, aspell_speller_add_to_personal);
155 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ADD_TO_SESSION, aspell_speller_add_to_session);
156 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_CHECK, aspell_speller_check);
157 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_SUGGEST, aspell_speller_suggest);
158 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_SAVE_ALL_WORD_LISTS, aspell_speller_save_all_word_lists);
159 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_STORE_REPLACEMENT, aspell_speller_store_replacement);
160 GET_ASPELL_PROC_ADDR(ASPELL_STRING_ENUMERATION_NEXT, aspell_string_enumeration_next);
161 GET_ASPELL_PROC_ADDR(ASPELL_WORD_LIST_ELEMENTS, aspell_word_list_elements);
162 GET_ASPELL_PROC_ADDR(DELETE_ASPELL_SPELLER, delete_aspell_speller);
163 GET_ASPELL_PROC_ADDR(DELETE_ASPELL_STRING_ENUMERATION, delete_aspell_string_enumeration);
164 GET_ASPELL_PROC_ADDR(DELETE_ASPELL_CAN_HAVE_ERROR, delete_aspell_can_have_error);
165 GET_ASPELL_PROC_ADDR(ASPELL_ERROR_MESSAGE, aspell_error_message);
166 GET_ASPELL_PROC_ADDR(ASPELL_ERROR_NUMBER, aspell_error_number);
167 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ERROR, aspell_speller_error);
168 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ERROR_MESSAGE, aspell_speller_error_message);
169 GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_CONFIG, aspell_speller_config);
171 #undef GET_ASPELL_PROC_ADDR
173 if(!success)
175 FreeLibrary(mod_aspell);
176 mod_aspell = NULL;
180 aspellinfo->mod_aspell = mod_aspell;
181 return success;
185 * Find, load, and initialize the aspell library.
186 * NULL on failure, otherwise an ASPELLINFO pointer.
188 ASPELLINFO *
189 speller_init(char *lang)
191 ASPELLINFO *aspellinfo;
193 aspellinfo = (ASPELLINFO *)malloc(sizeof(ASPELLINFO));
194 if(aspellinfo)
196 AspellConfig *config;
197 AspellSpeller *speller;
199 memset(aspellinfo, 0, sizeof(ASPELLINFO));
201 // Load the aspell library and set up our function pointers, etc.
202 if(!speller_load_aspell_library(aspellinfo))
204 speller_close(aspellinfo);
205 return NULL;
208 config = aspellinfo->new_aspell_config();
210 if(lang)
212 aspellinfo->aspell_config_replace(config, "lang", lang);
215 aspellinfo->aspell_config_replace(config, "encoding", "utf-8");
217 aspellinfo->err = aspellinfo->new_aspell_speller(config);
218 aspellinfo->delete_aspell_config(config);
220 if(aspellinfo->aspell_error_number(aspellinfo->err))
222 aspellinfo->error_message =
223 aspellinfo->aspell_error_message(aspellinfo->err);
225 else
227 aspellinfo->speller = aspellinfo->to_aspell_speller(aspellinfo->err);
228 aspellinfo->err = NULL;
231 TODO: Log the current speller config somewhere?
233 config = aspell_speller_config(speller);
235 fputs("Using: ", stdout);
236 fputs(aspell_config_retrieve(config, "lang"), stdout);
237 fputs("-", stdout);
238 fputs(aspell_config_retrieve(config, "jargon"), stdout);
239 fputs("-", stdout);
240 fputs(aspell_config_retrieve(config, "size"), stdout);
241 fputs("-", stdout);
242 fputs(aspell_config_retrieve(config, "module"), stdout);
243 fputs("\n\n", stdout);
248 return aspellinfo;
252 * Get the last aspell error message.
254 const char *
255 speller_get_error_message(ASPELLINFO *aspellinfo)
257 return aspellinfo ? aspellinfo->error_message : NULL;
261 * Close up shop.
263 void
264 speller_close(ASPELLINFO *aspellinfo)
266 if(aspellinfo)
268 // Make sure someone hasn't missed a speller_suggestion_close
269 assert(!aspellinfo->suggestion_elements);
271 if(aspellinfo->err)
273 aspellinfo->delete_aspell_can_have_error(aspellinfo->err);
274 aspellinfo->err = NULL;
277 if(aspellinfo->speller)
279 aspellinfo->delete_aspell_speller(aspellinfo->speller);
280 aspellinfo->speller = NULL;
283 if(aspellinfo->mod_aspell)
285 FreeLibrary(aspellinfo->mod_aspell);
286 aspellinfo->mod_aspell = NULL;
289 free(aspellinfo);
294 * Check the dictionary for a word.
295 * 1:found, 0:not found, -1:error
298 speller_check_word(ASPELLINFO *aspellinfo, const char *word, int word_size)
300 int have = 1;
302 if(!isdigit(*word))
304 have = aspellinfo->aspell_speller_check(aspellinfo->speller, word, word_size);
305 if(have == -1)
307 aspellinfo->error_message =
308 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
313 return have;
317 * Add word to dictionary.
318 * 1:success, 0:failed
321 speller_add_to_dictionary(ASPELLINFO *aspellinfo, const char *word, int word_size)
323 aspellinfo->aspell_speller_add_to_personal(aspellinfo->speller,
324 word, word_size);
325 if(aspellinfo->aspell_speller_error(aspellinfo->speller))
327 aspellinfo->error_message =
328 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
329 return 0;
332 aspellinfo->aspell_speller_save_all_word_lists(aspellinfo->speller);
333 if(aspellinfo->aspell_speller_error(aspellinfo->speller))
335 aspellinfo->error_message =
336 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
337 return 0;
340 return 1;
344 * Add this word to the current spelling session.
345 * 1:success, 0:failed
348 speller_ignore_all(ASPELLINFO *aspellinfo, const char *word, int word_size)
350 aspellinfo->aspell_speller_add_to_session(aspellinfo->speller, word, word_size);
351 if(aspellinfo->aspell_speller_error(aspellinfo->speller))
353 aspellinfo->error_message =
354 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
355 return 0;
358 return 1;
362 * Replace a word.
363 * 1:success, 0:failed
366 speller_replace_word(ASPELLINFO *aspellinfo,
367 const char * mis, int mis_size, const char * cor, int cor_size)
369 int ret;
371 ret = aspellinfo->aspell_speller_store_replacement(aspellinfo->speller,
372 mis, mis_size, cor, cor_size);
373 if(ret == -1)
375 aspellinfo->error_message =
376 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
377 return 0;
380 return 1;
384 * Init the suggestions element array for a specific word.
385 * 1:success, 0:failed
388 speller_suggestion_init(ASPELLINFO *aspellinfo, const char *word, int word_size)
390 const AspellWordList *suggestions;
392 // Make sure someone hasn't missed a speller_suggestion_close
393 assert(!aspellinfo->suggestion_elements);
395 suggestions = aspellinfo->aspell_speller_suggest(aspellinfo->speller,
396 word, word_size);
397 if(!suggestions)
399 aspellinfo->error_message =
400 aspellinfo->aspell_speller_error_message(aspellinfo->speller);
401 return 0;
404 aspellinfo->suggestion_elements =
405 aspellinfo->aspell_word_list_elements(suggestions);
406 return 1;
410 * Find next suggestion. Returns NULL when no more are left.
412 const char *
413 speller_suggestion_getnext(ASPELLINFO *aspellinfo)
415 return aspellinfo->aspell_string_enumeration_next(
416 aspellinfo->suggestion_elements);
420 * Close the suggestion element array.
422 void
423 speller_suggestion_close(ASPELLINFO *aspellinfo)
425 aspellinfo->delete_aspell_string_enumeration(aspellinfo->suggestion_elements);
426 aspellinfo->suggestion_elements = NULL;