summaryrefslogtreecommitdiff
path: root/pico/osdep/mswin_aspell.c
diff options
context:
space:
mode:
authorEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
committerEduardo Chappa <echappa@gmx.com>2013-02-03 00:59:38 -0700
commit094ca96844842928810f14844413109fc6cdd890 (patch)
treee60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /pico/osdep/mswin_aspell.c
downloadalpine-094ca96844842928810f14844413109fc6cdd890.tar.xz
Initial Alpine Version
Diffstat (limited to 'pico/osdep/mswin_aspell.c')
-rw-r--r--pico/osdep/mswin_aspell.c427
1 files changed, 427 insertions, 0 deletions
diff --git a/pico/osdep/mswin_aspell.c b/pico/osdep/mswin_aspell.c
new file mode 100644
index 00000000..26e998da
--- /dev/null
+++ b/pico/osdep/mswin_aspell.c
@@ -0,0 +1,427 @@
+/*
+ * ========================================================================
+ * FILE: MSWIN_ASPELL.C
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ========================================================================
+ */
+#include <system.h>
+#include "mswin_aspell.h"
+
+/*
+ * Aspell typedefs
+ */
+typedef struct AspellConfig AspellConfig;
+typedef struct AspellSpeller AspellSpeller;
+typedef struct AspellCanHaveError AspellCanHaveError;
+typedef struct AspellStringEnumeration AspellStringEnumeration;
+typedef struct AspellWordList AspellWordList;
+typedef struct AspellError AspellError;
+
+/*
+ * Aspell function prototypes
+ */
+typedef AspellCanHaveError * (__cdecl NEW_ASPELL_SPELLER)(AspellConfig * config);
+typedef AspellConfig * (__cdecl NEW_ASPELL_CONFIG)();
+typedef AspellSpeller * (__cdecl TO_ASPELL_SPELLER)(AspellCanHaveError * obj);
+typedef int (__cdecl ASPELL_CONFIG_REPLACE)(AspellConfig * ths, const char * key, const char * value);
+typedef void (__cdecl DELETE_ASPELL_CONFIG)(AspellConfig * ths);
+typedef const char * (__cdecl ASPELL_CONFIG_RETRIEVE)(AspellConfig * ths, const char * key);
+typedef int (__cdecl ASPELL_SPELLER_ADD_TO_PERSONAL)(AspellSpeller * ths, const char * word, int word_size);
+typedef int (__cdecl ASPELL_SPELLER_ADD_TO_SESSION)(AspellSpeller * ths, const char * word, int word_size);
+typedef int (__cdecl ASPELL_SPELLER_CHECK)(AspellSpeller * ths, const char * word, int word_size);
+typedef const AspellWordList * (__cdecl ASPELL_SPELLER_SUGGEST)(AspellSpeller * ths, const char * word, int word_size);
+typedef int (__cdecl ASPELL_SPELLER_SAVE_ALL_WORD_LISTS)(AspellSpeller * ths);
+typedef int (__cdecl ASPELL_SPELLER_STORE_REPLACEMENT)(AspellSpeller * ths, const char * mis, int mis_size, const char * cor, int cor_size);
+typedef const char * (__cdecl ASPELL_STRING_ENUMERATION_NEXT)(AspellStringEnumeration * ths);
+typedef AspellStringEnumeration *(__cdecl ASPELL_WORD_LIST_ELEMENTS)(const AspellWordList * ths);
+typedef void (__cdecl DELETE_ASPELL_SPELLER)(AspellSpeller * ths);
+typedef void (__cdecl DELETE_ASPELL_STRING_ENUMERATION)(AspellStringEnumeration * ths);
+typedef void (__cdecl DELETE_ASPELL_CAN_HAVE_ERROR)(AspellCanHaveError * ths);
+typedef const char * (__cdecl ASPELL_ERROR_MESSAGE)(const AspellCanHaveError * ths);
+typedef unsigned int (__cdecl ASPELL_ERROR_NUMBER)(const AspellCanHaveError * ths);
+typedef const AspellError * (__cdecl ASPELL_SPELLER_ERROR)(const AspellSpeller * ths);
+typedef const char * (__cdecl ASPELL_SPELLER_ERROR_MESSAGE)(const struct AspellSpeller * ths);
+typedef AspellConfig * (__cdecl ASPELL_SPELLER_CONFIG)(AspellSpeller * ths);
+
+/*
+ * MsWin speller information structure
+ */
+typedef struct ASPELLINFO
+{
+ AspellSpeller *speller;
+ AspellStringEnumeration *suggestion_elements;
+ const char *error_message;
+
+ AspellCanHaveError *err;
+
+ HMODULE mod_aspell;
+
+ NEW_ASPELL_SPELLER *new_aspell_speller;
+ NEW_ASPELL_CONFIG *new_aspell_config;
+ TO_ASPELL_SPELLER *to_aspell_speller;
+ ASPELL_CONFIG_REPLACE *aspell_config_replace;
+ DELETE_ASPELL_CONFIG *delete_aspell_config;
+ ASPELL_CONFIG_RETRIEVE *aspell_config_retrieve;
+ ASPELL_SPELLER_ADD_TO_PERSONAL *aspell_speller_add_to_personal;
+ ASPELL_SPELLER_ADD_TO_SESSION *aspell_speller_add_to_session;
+ ASPELL_SPELLER_CHECK *aspell_speller_check;
+ ASPELL_SPELLER_SUGGEST *aspell_speller_suggest;
+ ASPELL_SPELLER_SAVE_ALL_WORD_LISTS *aspell_speller_save_all_word_lists;
+ ASPELL_SPELLER_STORE_REPLACEMENT *aspell_speller_store_replacement;
+ ASPELL_STRING_ENUMERATION_NEXT *aspell_string_enumeration_next;
+ ASPELL_WORD_LIST_ELEMENTS *aspell_word_list_elements;
+ DELETE_ASPELL_SPELLER *delete_aspell_speller;
+ DELETE_ASPELL_STRING_ENUMERATION *delete_aspell_string_enumeration;
+ DELETE_ASPELL_CAN_HAVE_ERROR *delete_aspell_can_have_error;
+ ASPELL_ERROR_MESSAGE *aspell_error_message;
+ ASPELL_ERROR_NUMBER *aspell_error_number;
+ ASPELL_SPELLER_ERROR *aspell_speller_error;
+ ASPELL_SPELLER_ERROR_MESSAGE *aspell_speller_error_message;
+ ASPELL_SPELLER_CONFIG *aspell_speller_config;
+} ASPELLINFO;
+
+/*
+ * Find, aspell-15.dll, load it, and attempt to initialize our func pointers.
+ * 1:success, 0:failed
+ */
+static int
+speller_load_aspell_library(ASPELLINFO *aspellinfo)
+{
+ HKEY hKey;
+ int success = 1;
+ HMODULE mod_aspell = NULL;
+ TCHAR aspell_fullname[MAX_PATH + 1];
+ static const TCHAR aspell_name[] = TEXT("aspell-15.dll");
+
+ aspell_fullname[0] = '\0';
+
+ // Try to open the Aspell Registry key.
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Aspell"),
+ 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD dtype;
+ TCHAR aspell_path[MAX_PATH + 1];
+ DWORD aspell_path_len = sizeof(aspell_path);
+
+ // Query the path.
+ if(RegQueryValueEx(hKey, TEXT("Path"), NULL, &dtype,
+ (LPBYTE)aspell_path, &aspell_path_len) == ERROR_SUCCESS)
+ {
+ _sntprintf(aspell_fullname, ARRAYSIZE(aspell_fullname),
+ TEXT("%s\\%s"), aspell_path, aspell_name);
+ aspell_fullname[ARRAYSIZE(aspell_fullname) - 1] = 0;
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ // If the registry thing didn't work, then just try doing a Loadlibrary
+ // using the standard Windows LoadLibrary search gunk.
+ if(!aspell_fullname[0])
+ {
+ _tcsncpy(aspell_fullname, aspell_name, ARRAYSIZE(aspell_fullname));
+ aspell_fullname[ARRAYSIZE(aspell_fullname) - 1] = 0;
+ }
+
+ // Load the library.
+ mod_aspell = LoadLibrary(aspell_fullname);
+ if(!mod_aspell)
+ {
+ // Failed.
+ success = 0;
+ }
+ else
+ {
+ // Found the library - now try to initialize our function pointers.
+ //
+#define GET_ASPELL_PROC_ADDR(_functype, _func) \
+ aspellinfo->_func = (_functype *)GetProcAddress(mod_aspell, #_func); \
+ if(!aspellinfo->_func) \
+ success = 0
+
+ GET_ASPELL_PROC_ADDR(NEW_ASPELL_SPELLER, new_aspell_speller);
+ GET_ASPELL_PROC_ADDR(NEW_ASPELL_CONFIG, new_aspell_config);
+ GET_ASPELL_PROC_ADDR(TO_ASPELL_SPELLER, to_aspell_speller);
+ GET_ASPELL_PROC_ADDR(ASPELL_CONFIG_REPLACE, aspell_config_replace);
+ GET_ASPELL_PROC_ADDR(DELETE_ASPELL_CONFIG, delete_aspell_config);
+ GET_ASPELL_PROC_ADDR(ASPELL_CONFIG_RETRIEVE, aspell_config_retrieve);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ADD_TO_PERSONAL, aspell_speller_add_to_personal);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ADD_TO_SESSION, aspell_speller_add_to_session);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_CHECK, aspell_speller_check);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_SUGGEST, aspell_speller_suggest);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_SAVE_ALL_WORD_LISTS, aspell_speller_save_all_word_lists);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_STORE_REPLACEMENT, aspell_speller_store_replacement);
+ GET_ASPELL_PROC_ADDR(ASPELL_STRING_ENUMERATION_NEXT, aspell_string_enumeration_next);
+ GET_ASPELL_PROC_ADDR(ASPELL_WORD_LIST_ELEMENTS, aspell_word_list_elements);
+ GET_ASPELL_PROC_ADDR(DELETE_ASPELL_SPELLER, delete_aspell_speller);
+ GET_ASPELL_PROC_ADDR(DELETE_ASPELL_STRING_ENUMERATION, delete_aspell_string_enumeration);
+ GET_ASPELL_PROC_ADDR(DELETE_ASPELL_CAN_HAVE_ERROR, delete_aspell_can_have_error);
+ GET_ASPELL_PROC_ADDR(ASPELL_ERROR_MESSAGE, aspell_error_message);
+ GET_ASPELL_PROC_ADDR(ASPELL_ERROR_NUMBER, aspell_error_number);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ERROR, aspell_speller_error);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_ERROR_MESSAGE, aspell_speller_error_message);
+ GET_ASPELL_PROC_ADDR(ASPELL_SPELLER_CONFIG, aspell_speller_config);
+
+#undef GET_ASPELL_PROC_ADDR
+
+ if(!success)
+ {
+ FreeLibrary(mod_aspell);
+ mod_aspell = NULL;
+ }
+ }
+
+ aspellinfo->mod_aspell = mod_aspell;
+ return success;
+}
+
+/*
+ * Find, load, and initialize the aspell library.
+ * NULL on failure, otherwise an ASPELLINFO pointer.
+ */
+ASPELLINFO *
+speller_init(char *lang)
+{
+ ASPELLINFO *aspellinfo;
+
+ aspellinfo = (ASPELLINFO *)malloc(sizeof(ASPELLINFO));
+ if(aspellinfo)
+ {
+ AspellConfig *config;
+ AspellSpeller *speller;
+
+ memset(aspellinfo, 0, sizeof(ASPELLINFO));
+
+ // Load the aspell library and set up our function pointers, etc.
+ if(!speller_load_aspell_library(aspellinfo))
+ {
+ speller_close(aspellinfo);
+ return NULL;
+ }
+
+ config = aspellinfo->new_aspell_config();
+
+ if(lang)
+ {
+ aspellinfo->aspell_config_replace(config, "lang", lang);
+ }
+
+ aspellinfo->aspell_config_replace(config, "encoding", "utf-8");
+
+ aspellinfo->err = aspellinfo->new_aspell_speller(config);
+ aspellinfo->delete_aspell_config(config);
+
+ if(aspellinfo->aspell_error_number(aspellinfo->err))
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_error_message(aspellinfo->err);
+ }
+ else
+ {
+ aspellinfo->speller = aspellinfo->to_aspell_speller(aspellinfo->err);
+ aspellinfo->err = NULL;
+
+ /*
+ TODO: Log the current speller config somewhere?
+
+ config = aspell_speller_config(speller);
+
+ fputs("Using: ", stdout);
+ fputs(aspell_config_retrieve(config, "lang"), stdout);
+ fputs("-", stdout);
+ fputs(aspell_config_retrieve(config, "jargon"), stdout);
+ fputs("-", stdout);
+ fputs(aspell_config_retrieve(config, "size"), stdout);
+ fputs("-", stdout);
+ fputs(aspell_config_retrieve(config, "module"), stdout);
+ fputs("\n\n", stdout);
+ */
+ }
+ }
+
+ return aspellinfo;
+}
+
+/*
+ * Get the last aspell error message.
+ */
+const char *
+speller_get_error_message(ASPELLINFO *aspellinfo)
+{
+ return aspellinfo ? aspellinfo->error_message : NULL;
+}
+
+/*
+ * Close up shop.
+ */
+void
+speller_close(ASPELLINFO *aspellinfo)
+{
+ if(aspellinfo)
+ {
+ // Make sure someone hasn't missed a speller_suggestion_close
+ assert(!aspellinfo->suggestion_elements);
+
+ if(aspellinfo->err)
+ {
+ aspellinfo->delete_aspell_can_have_error(aspellinfo->err);
+ aspellinfo->err = NULL;
+ }
+
+ if(aspellinfo->speller)
+ {
+ aspellinfo->delete_aspell_speller(aspellinfo->speller);
+ aspellinfo->speller = NULL;
+ }
+
+ if(aspellinfo->mod_aspell)
+ {
+ FreeLibrary(aspellinfo->mod_aspell);
+ aspellinfo->mod_aspell = NULL;
+ }
+
+ free(aspellinfo);
+ }
+}
+
+/*
+ * Check the dictionary for a word.
+ * 1:found, 0:not found, -1:error
+ */
+int
+speller_check_word(ASPELLINFO *aspellinfo, const char *word, int word_size)
+{
+ int have = 1;
+
+ if(!isdigit(*word))
+ {
+ have = aspellinfo->aspell_speller_check(aspellinfo->speller, word, word_size);
+ if(have == -1)
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ }
+
+ }
+
+ return have;
+}
+
+/*
+ * Add word to dictionary.
+ * 1:success, 0:failed
+ */
+int
+speller_add_to_dictionary(ASPELLINFO *aspellinfo, const char *word, int word_size)
+{
+ aspellinfo->aspell_speller_add_to_personal(aspellinfo->speller,
+ word, word_size);
+ if(aspellinfo->aspell_speller_error(aspellinfo->speller))
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ return 0;
+ }
+
+ aspellinfo->aspell_speller_save_all_word_lists(aspellinfo->speller);
+ if(aspellinfo->aspell_speller_error(aspellinfo->speller))
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Add this word to the current spelling session.
+ * 1:success, 0:failed
+ */
+int
+speller_ignore_all(ASPELLINFO *aspellinfo, const char *word, int word_size)
+{
+ aspellinfo->aspell_speller_add_to_session(aspellinfo->speller, word, word_size);
+ if(aspellinfo->aspell_speller_error(aspellinfo->speller))
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Replace a word.
+ * 1:success, 0:failed
+ */
+int
+speller_replace_word(ASPELLINFO *aspellinfo,
+ const char * mis, int mis_size, const char * cor, int cor_size)
+{
+ int ret;
+
+ ret = aspellinfo->aspell_speller_store_replacement(aspellinfo->speller,
+ mis, mis_size, cor, cor_size);
+ if(ret == -1)
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Init the suggestions element array for a specific word.
+ * 1:success, 0:failed
+ */
+int
+speller_suggestion_init(ASPELLINFO *aspellinfo, const char *word, int word_size)
+{
+ const AspellWordList *suggestions;
+
+ // Make sure someone hasn't missed a speller_suggestion_close
+ assert(!aspellinfo->suggestion_elements);
+
+ suggestions = aspellinfo->aspell_speller_suggest(aspellinfo->speller,
+ word, word_size);
+ if(!suggestions)
+ {
+ aspellinfo->error_message =
+ aspellinfo->aspell_speller_error_message(aspellinfo->speller);
+ return 0;
+ }
+
+ aspellinfo->suggestion_elements =
+ aspellinfo->aspell_word_list_elements(suggestions);
+ return 1;
+}
+
+/*
+ * Find next suggestion. Returns NULL when no more are left.
+ */
+const char *
+speller_suggestion_getnext(ASPELLINFO *aspellinfo)
+{
+ return aspellinfo->aspell_string_enumeration_next(
+ aspellinfo->suggestion_elements);
+}
+
+/*
+ * Close the suggestion element array.
+ */
+void
+speller_suggestion_close(ASPELLINFO *aspellinfo)
+{
+ aspellinfo->delete_aspell_string_enumeration(aspellinfo->suggestion_elements);
+ aspellinfo->suggestion_elements = NULL;
+}