Aspell: execute the command in pipe mode instead of loading the dll for getting suggestions: simpler and no crashes of the whole UI in case of problem
This commit is contained in:
parent
9abaf84be6
commit
7310709e08
@ -58,7 +58,6 @@ librcldir = $(libdir)/recoll
|
||||
librcl_LTLIBRARIES = librecoll.la
|
||||
|
||||
librecoll_la_SOURCES = \
|
||||
aspell/aspell-local.h \
|
||||
aspell/rclaspell.cpp \
|
||||
aspell/rclaspell.h \
|
||||
bincimapmime/convert.cc \
|
||||
|
||||
@ -1,729 +0,0 @@
|
||||
/* Automatically generated file. Do not edit directly. */
|
||||
|
||||
/* This file is part of The New Aspell
|
||||
* Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
|
||||
* license version 2.0 or 2.1. You should have received a copy of the
|
||||
* LGPL license along with this library if you did not you can find it
|
||||
* at http://www.gnu.org/. */
|
||||
|
||||
#ifndef ASPELL_ASPELL__H
|
||||
#define ASPELL_ASPELL__H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************* type id *******************************/
|
||||
|
||||
|
||||
union AspellTypeId {
|
||||
|
||||
unsigned int num;
|
||||
|
||||
char str[4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef union AspellTypeId AspellTypeId;
|
||||
|
||||
|
||||
/************************** mutable container **************************/
|
||||
|
||||
|
||||
typedef struct AspellMutableContainer AspellMutableContainer;
|
||||
|
||||
|
||||
int aspell_mutable_container_add(struct AspellMutableContainer * ths, const char * to_add);
|
||||
|
||||
int aspell_mutable_container_remove(struct AspellMutableContainer * ths, const char * to_rem);
|
||||
|
||||
void aspell_mutable_container_clear(struct AspellMutableContainer * ths);
|
||||
|
||||
struct AspellMutableContainer * aspell_mutable_container_to_mutable_container(struct AspellMutableContainer * ths);
|
||||
|
||||
|
||||
|
||||
/******************************* key info *******************************/
|
||||
|
||||
|
||||
|
||||
enum AspellKeyInfoType {AspellKeyInfoString, AspellKeyInfoInt, AspellKeyInfoBool, AspellKeyInfoList};
|
||||
typedef enum AspellKeyInfoType AspellKeyInfoType;
|
||||
|
||||
|
||||
struct AspellKeyInfo {
|
||||
|
||||
/* The name of the key. */
|
||||
const char * name;
|
||||
|
||||
/* The key type. */
|
||||
enum AspellKeyInfoType type;
|
||||
|
||||
/* The default value of the key. */
|
||||
const char * def;
|
||||
|
||||
/* A brief description of the key or NULL if internal value. */
|
||||
const char * desc;
|
||||
|
||||
int flags;
|
||||
|
||||
int other_data;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellKeyInfo AspellKeyInfo;
|
||||
|
||||
|
||||
/******************************** config ********************************/
|
||||
|
||||
|
||||
typedef struct AspellKeyInfoEnumeration AspellKeyInfoEnumeration;
|
||||
|
||||
|
||||
int aspell_key_info_enumeration_at_end(const struct AspellKeyInfoEnumeration * ths);
|
||||
|
||||
const struct AspellKeyInfo * aspell_key_info_enumeration_next(struct AspellKeyInfoEnumeration * ths);
|
||||
|
||||
void delete_aspell_key_info_enumeration(struct AspellKeyInfoEnumeration * ths);
|
||||
|
||||
struct AspellKeyInfoEnumeration * aspell_key_info_enumeration_clone(const struct AspellKeyInfoEnumeration * ths);
|
||||
|
||||
void aspell_key_info_enumeration_assign(struct AspellKeyInfoEnumeration * ths, const struct AspellKeyInfoEnumeration * other);
|
||||
|
||||
|
||||
|
||||
typedef struct AspellConfig AspellConfig;
|
||||
|
||||
|
||||
struct AspellConfig * new_aspell_config();
|
||||
|
||||
void delete_aspell_config(struct AspellConfig * ths);
|
||||
|
||||
struct AspellConfig * aspell_config_clone(const struct AspellConfig * ths);
|
||||
|
||||
void aspell_config_assign(struct AspellConfig * ths, const struct AspellConfig * other);
|
||||
|
||||
unsigned int aspell_config_error_number(const struct AspellConfig * ths);
|
||||
|
||||
const char * aspell_config_error_message(const struct AspellConfig * ths);
|
||||
|
||||
const struct AspellError * aspell_config_error(const struct AspellConfig * ths);
|
||||
|
||||
/* Sets extra keys which this config class should
|
||||
* accept. begin and end are expected to point to
|
||||
* the beginning and ending of an array of Aspell
|
||||
* Key Info. */
|
||||
void aspell_config_set_extra(struct AspellConfig * ths, const struct AspellKeyInfo * begin, const struct AspellKeyInfo * end);
|
||||
|
||||
/* Returns the KeyInfo object for the
|
||||
* corresponding key or returns NULL and sets
|
||||
* error_num to PERROR_UNKNOWN_KEY if the key is
|
||||
* not valid. The pointer returned is valid for
|
||||
* the lifetime of the object. */
|
||||
const struct AspellKeyInfo * aspell_config_keyinfo(struct AspellConfig * ths, const char * key);
|
||||
|
||||
/* Returns a newly allocated enumeration of all
|
||||
* the possible objects this config class uses. */
|
||||
struct AspellKeyInfoEnumeration * aspell_config_possible_elements(struct AspellConfig * ths, int include_extra);
|
||||
|
||||
/* Returns the default value for given key which
|
||||
* may involve substituting variables, thus it is
|
||||
* not the same as keyinfo(key)->def returns NULL
|
||||
* and sets error_num to PERROR_UNKNOWN_KEY if
|
||||
* the key is not valid. Uses the temporary
|
||||
* string. */
|
||||
const char * aspell_config_get_default(struct AspellConfig * ths, const char * key);
|
||||
|
||||
/* Returns a newly allocated enumeration of all
|
||||
* the key/value pairs. This DOES not include ones
|
||||
* which are set to their default values. */
|
||||
struct AspellStringPairEnumeration * aspell_config_elements(struct AspellConfig * ths);
|
||||
|
||||
/* Inserts an item, if the item already exists it
|
||||
* will be replaced. Returns TRUE if it succeeded
|
||||
* or FALSE on error. If the key in not valid it
|
||||
* sets error_num to PERROR_UNKNOWN_KEY, if the
|
||||
* value is not valid it will set error_num to
|
||||
* PERROR_BAD_VALUE, if the value can not be
|
||||
* changed it sets error_num to
|
||||
* PERROR_CANT_CHANGE_VALUE, and if the value is
|
||||
* a list and you are trying to set its directory,
|
||||
* it sets error_num to PERROR_LIST_SET */
|
||||
int aspell_config_replace(struct AspellConfig * ths, const char * key, const char * value);
|
||||
|
||||
/* Remove a key and returns TRUE if it exists
|
||||
* otherwise return FALSE. This effectively sets
|
||||
* the key to its default value. Calling replace
|
||||
* with a value of "<default>" will also call
|
||||
* remove. If the key does not exist then it sets
|
||||
* error_num to 0 or PERROR_NOT, if the key is
|
||||
* not valid then it sets error_num to
|
||||
* PERROR_UNKNOWN_KEY, if the value can not be
|
||||
* changed then it sets error_num to
|
||||
* PERROR_CANT_CHANGE_VALUE */
|
||||
int aspell_config_remove(struct AspellConfig * ths, const char * key);
|
||||
|
||||
int aspell_config_have(const struct AspellConfig * ths, const char * key);
|
||||
|
||||
/* Returns NULL on error. */
|
||||
const char * aspell_config_retrieve(struct AspellConfig * ths, const char * key);
|
||||
|
||||
int aspell_config_retrieve_list(struct AspellConfig * ths, const char * key, struct AspellMutableContainer * lst);
|
||||
|
||||
/* Return -1 on error, 0 if false, 1 if true. */
|
||||
int aspell_config_retrieve_bool(struct AspellConfig * ths, const char * key);
|
||||
|
||||
/* Return -1 on error. */
|
||||
int aspell_config_retrieve_int(struct AspellConfig * ths, const char * key);
|
||||
|
||||
|
||||
|
||||
/******************************** error ********************************/
|
||||
|
||||
|
||||
struct AspellError {
|
||||
|
||||
const char * mesg;
|
||||
|
||||
const struct AspellErrorInfo * err;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellError AspellError;
|
||||
|
||||
int aspell_error_is_a(const struct AspellError * ths, const struct AspellErrorInfo * e);
|
||||
|
||||
|
||||
struct AspellErrorInfo {
|
||||
|
||||
const struct AspellErrorInfo * isa;
|
||||
|
||||
const char * mesg;
|
||||
|
||||
unsigned int num_parms;
|
||||
|
||||
const char * parms[3];
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellErrorInfo AspellErrorInfo;
|
||||
|
||||
|
||||
/**************************** can have error ****************************/
|
||||
|
||||
|
||||
typedef struct AspellCanHaveError AspellCanHaveError;
|
||||
|
||||
|
||||
unsigned int aspell_error_number(const struct AspellCanHaveError * ths);
|
||||
|
||||
const char * aspell_error_message(const struct AspellCanHaveError * ths);
|
||||
|
||||
const struct AspellError * aspell_error(const struct AspellCanHaveError * ths);
|
||||
|
||||
void delete_aspell_can_have_error(struct AspellCanHaveError * ths);
|
||||
|
||||
|
||||
|
||||
/******************************** errors ********************************/
|
||||
|
||||
|
||||
extern const struct AspellErrorInfo * const aerror_other;
|
||||
extern const struct AspellErrorInfo * const aerror_operation_not_supported;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_copy;
|
||||
extern const struct AspellErrorInfo * const aerror_unimplemented_method;
|
||||
extern const struct AspellErrorInfo * const aerror_file;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_open_file;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_read_file;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_write_file;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_name;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_file_format;
|
||||
extern const struct AspellErrorInfo * const aerror_dir;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_read_dir;
|
||||
extern const struct AspellErrorInfo * const aerror_config;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_key;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_change_value;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_key;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_value;
|
||||
extern const struct AspellErrorInfo * const aerror_duplicate;
|
||||
extern const struct AspellErrorInfo * const aerror_key_not_string;
|
||||
extern const struct AspellErrorInfo * const aerror_key_not_int;
|
||||
extern const struct AspellErrorInfo * const aerror_key_not_bool;
|
||||
extern const struct AspellErrorInfo * const aerror_key_not_list;
|
||||
extern const struct AspellErrorInfo * const aerror_no_value_reset;
|
||||
extern const struct AspellErrorInfo * const aerror_no_value_enable;
|
||||
extern const struct AspellErrorInfo * const aerror_no_value_disable;
|
||||
extern const struct AspellErrorInfo * const aerror_no_value_clear;
|
||||
extern const struct AspellErrorInfo * const aerror_language_related;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_language;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_soundslike;
|
||||
extern const struct AspellErrorInfo * const aerror_language_not_supported;
|
||||
extern const struct AspellErrorInfo * const aerror_no_wordlist_for_lang;
|
||||
extern const struct AspellErrorInfo * const aerror_mismatched_language;
|
||||
extern const struct AspellErrorInfo * const aerror_affix;
|
||||
extern const struct AspellErrorInfo * const aerror_corrupt_affix;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_cond;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_cond_strip;
|
||||
extern const struct AspellErrorInfo * const aerror_incorrect_encoding;
|
||||
extern const struct AspellErrorInfo * const aerror_encoding;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_encoding;
|
||||
extern const struct AspellErrorInfo * const aerror_encoding_not_supported;
|
||||
extern const struct AspellErrorInfo * const aerror_conversion_not_supported;
|
||||
extern const struct AspellErrorInfo * const aerror_pipe;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_create_pipe;
|
||||
extern const struct AspellErrorInfo * const aerror_process_died;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_input;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_string;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_word;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_affix;
|
||||
extern const struct AspellErrorInfo * const aerror_inapplicable_affix;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_unichar;
|
||||
extern const struct AspellErrorInfo * const aerror_word_list_flags;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_flag;
|
||||
extern const struct AspellErrorInfo * const aerror_conflicting_flags;
|
||||
extern const struct AspellErrorInfo * const aerror_version_control;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_version_string;
|
||||
extern const struct AspellErrorInfo * const aerror_filter;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_dlopen_file;
|
||||
extern const struct AspellErrorInfo * const aerror_empty_filter;
|
||||
extern const struct AspellErrorInfo * const aerror_no_such_filter;
|
||||
extern const struct AspellErrorInfo * const aerror_confusing_version;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_version;
|
||||
extern const struct AspellErrorInfo * const aerror_identical_option;
|
||||
extern const struct AspellErrorInfo * const aerror_options_only;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_option_modifier;
|
||||
extern const struct AspellErrorInfo * const aerror_cant_describe_filter;
|
||||
extern const struct AspellErrorInfo * const aerror_filter_mode_file;
|
||||
extern const struct AspellErrorInfo * const aerror_mode_option_name;
|
||||
extern const struct AspellErrorInfo * const aerror_no_filter_to_option;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_mode_key;
|
||||
extern const struct AspellErrorInfo * const aerror_expect_mode_key;
|
||||
extern const struct AspellErrorInfo * const aerror_mode_version_requirement;
|
||||
extern const struct AspellErrorInfo * const aerror_confusing_mode_version;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_mode_version;
|
||||
extern const struct AspellErrorInfo * const aerror_missing_magic_expression;
|
||||
extern const struct AspellErrorInfo * const aerror_empty_file_ext;
|
||||
extern const struct AspellErrorInfo * const aerror_filter_mode_expand;
|
||||
extern const struct AspellErrorInfo * const aerror_unknown_mode;
|
||||
extern const struct AspellErrorInfo * const aerror_mode_extend_expand;
|
||||
extern const struct AspellErrorInfo * const aerror_filter_mode_magic;
|
||||
extern const struct AspellErrorInfo * const aerror_file_magic_pos;
|
||||
extern const struct AspellErrorInfo * const aerror_file_magic_range;
|
||||
extern const struct AspellErrorInfo * const aerror_missing_magic;
|
||||
extern const struct AspellErrorInfo * const aerror_bad_magic;
|
||||
extern const struct AspellErrorInfo * const aerror_expression;
|
||||
extern const struct AspellErrorInfo * const aerror_invalid_expression;
|
||||
|
||||
|
||||
/******************************* speller *******************************/
|
||||
|
||||
|
||||
typedef struct AspellSpeller AspellSpeller;
|
||||
|
||||
|
||||
struct AspellCanHaveError * new_aspell_speller(struct AspellConfig * config);
|
||||
|
||||
struct AspellSpeller * to_aspell_speller(struct AspellCanHaveError * obj);
|
||||
|
||||
void delete_aspell_speller(struct AspellSpeller * ths);
|
||||
|
||||
unsigned int aspell_speller_error_number(const struct AspellSpeller * ths);
|
||||
|
||||
const char * aspell_speller_error_message(const struct AspellSpeller * ths);
|
||||
|
||||
const struct AspellError * aspell_speller_error(const struct AspellSpeller * ths);
|
||||
|
||||
struct AspellConfig * aspell_speller_config(struct AspellSpeller * ths);
|
||||
|
||||
/* Returns 0 if it is not in the dictionary,
|
||||
* 1 if it is, or -1 on error. */
|
||||
int aspell_speller_check(struct AspellSpeller * ths, const char * word, int word_size);
|
||||
|
||||
/* Add this word to your own personal word list. */
|
||||
int aspell_speller_add_to_personal(struct AspellSpeller * ths, const char * word, int word_size);
|
||||
|
||||
/* Add this word to the current spelling session. */
|
||||
int aspell_speller_add_to_session(struct AspellSpeller * ths, const char * word, int word_size);
|
||||
|
||||
/* This is your own personal word list file plus
|
||||
* any extra words added during this session to
|
||||
* your own personal word list. */
|
||||
const struct AspellWordList * aspell_speller_personal_word_list(struct AspellSpeller * ths);
|
||||
|
||||
/* This is a list of words added to this session
|
||||
* that are not in the main word list or in your
|
||||
* own personal list but are considered valid for
|
||||
* this spelling session. */
|
||||
const struct AspellWordList * aspell_speller_session_word_list(struct AspellSpeller * ths);
|
||||
|
||||
/* This is the main list of words used during this
|
||||
* spelling session. */
|
||||
const struct AspellWordList * aspell_speller_main_word_list(struct AspellSpeller * ths);
|
||||
|
||||
int aspell_speller_save_all_word_lists(struct AspellSpeller * ths);
|
||||
|
||||
int aspell_speller_clear_session(struct AspellSpeller * ths);
|
||||
|
||||
/* Return NULL on error.
|
||||
* The word list returned by suggest is only
|
||||
* valid until the next call to suggest. */
|
||||
const struct AspellWordList * aspell_speller_suggest(struct AspellSpeller * ths, const char * word, int word_size);
|
||||
|
||||
int aspell_speller_store_replacement(struct AspellSpeller * ths, const char * mis, int mis_size, const char * cor, int cor_size);
|
||||
|
||||
|
||||
|
||||
/******************************** filter ********************************/
|
||||
|
||||
|
||||
typedef struct AspellFilter AspellFilter;
|
||||
|
||||
|
||||
void delete_aspell_filter(struct AspellFilter * ths);
|
||||
|
||||
unsigned int aspell_filter_error_number(const struct AspellFilter * ths);
|
||||
|
||||
const char * aspell_filter_error_message(const struct AspellFilter * ths);
|
||||
|
||||
const struct AspellError * aspell_filter_error(const struct AspellFilter * ths);
|
||||
|
||||
struct AspellFilter * to_aspell_filter(struct AspellCanHaveError * obj);
|
||||
|
||||
|
||||
|
||||
/*************************** document checker ***************************/
|
||||
|
||||
|
||||
struct AspellToken {
|
||||
|
||||
unsigned int offset;
|
||||
|
||||
unsigned int len;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellToken AspellToken;
|
||||
|
||||
|
||||
typedef struct AspellDocumentChecker AspellDocumentChecker;
|
||||
|
||||
|
||||
void delete_aspell_document_checker(struct AspellDocumentChecker * ths);
|
||||
|
||||
unsigned int aspell_document_checker_error_number(const struct AspellDocumentChecker * ths);
|
||||
|
||||
const char * aspell_document_checker_error_message(const struct AspellDocumentChecker * ths);
|
||||
|
||||
const struct AspellError * aspell_document_checker_error(const struct AspellDocumentChecker * ths);
|
||||
|
||||
/* Creates a new document checker.
|
||||
* The speller class is expected to last until
|
||||
* this class is destroyed.
|
||||
* If config is given it will be used to override
|
||||
* any relevent options set by this speller class.
|
||||
* The config class is not once this function is done.
|
||||
* If filter is given then it will take ownership of
|
||||
* the filter class and use it to do the filtering.
|
||||
* You are expected to free the checker when done. */
|
||||
struct AspellCanHaveError * new_aspell_document_checker(struct AspellSpeller * speller);
|
||||
|
||||
struct AspellDocumentChecker * to_aspell_document_checker(struct AspellCanHaveError * obj);
|
||||
|
||||
/* Reset the internal state of the filter.
|
||||
* Should be called whenever a new document is
|
||||
* being filtered. */
|
||||
void aspell_document_checker_reset(struct AspellDocumentChecker * ths);
|
||||
|
||||
/* Process a string.
|
||||
* The string passed in should only be split on
|
||||
* white space characters. Furthermore, between
|
||||
* calls to reset, each string should be passed
|
||||
* in exactly once and in the order they appeared
|
||||
* in the document. Passing in strings out of
|
||||
* order, skipping strings or passing them in
|
||||
* more than once may lead to undefined results. */
|
||||
void aspell_document_checker_process(struct AspellDocumentChecker * ths, const char * str, int size);
|
||||
|
||||
/* Returns the next misspelled word in the
|
||||
* processed string. If there are no more
|
||||
* misspelled words, then token.word will be
|
||||
* NULL and token.size will be 0 */
|
||||
struct AspellToken aspell_document_checker_next_misspelling(struct AspellDocumentChecker * ths);
|
||||
|
||||
/* Returns the underlying filter class. */
|
||||
struct AspellFilter * aspell_document_checker_filter(struct AspellDocumentChecker * ths);
|
||||
|
||||
|
||||
|
||||
/****************************** word list ******************************/
|
||||
|
||||
|
||||
typedef struct AspellWordList AspellWordList;
|
||||
|
||||
|
||||
int aspell_word_list_empty(const struct AspellWordList * ths);
|
||||
|
||||
unsigned int aspell_word_list_size(const struct AspellWordList * ths);
|
||||
|
||||
struct AspellStringEnumeration * aspell_word_list_elements(const struct AspellWordList * ths);
|
||||
|
||||
|
||||
|
||||
/************************** string enumeration **************************/
|
||||
|
||||
|
||||
typedef struct AspellStringEnumeration AspellStringEnumeration;
|
||||
|
||||
|
||||
void delete_aspell_string_enumeration(struct AspellStringEnumeration * ths);
|
||||
|
||||
struct AspellStringEnumeration * aspell_string_enumeration_clone(const struct AspellStringEnumeration * ths);
|
||||
|
||||
void aspell_string_enumeration_assign(struct AspellStringEnumeration * ths, const struct AspellStringEnumeration * other);
|
||||
|
||||
int aspell_string_enumeration_at_end(const struct AspellStringEnumeration * ths);
|
||||
|
||||
const char * aspell_string_enumeration_next(struct AspellStringEnumeration * ths);
|
||||
|
||||
|
||||
|
||||
/********************************* info *********************************/
|
||||
|
||||
|
||||
struct AspellModuleInfo {
|
||||
|
||||
const char * name;
|
||||
|
||||
double order_num;
|
||||
|
||||
const char * lib_dir;
|
||||
|
||||
struct AspellStringList * dict_dirs;
|
||||
|
||||
struct AspellStringList * dict_exts;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellModuleInfo AspellModuleInfo;
|
||||
|
||||
|
||||
struct AspellDictInfo {
|
||||
|
||||
/* The Name to identify this dictionary by. */
|
||||
const char * name;
|
||||
|
||||
/* The language code to identify this dictionary.
|
||||
* A two letter UPPER-CASE ISO 639 language code
|
||||
* and an optional two letter ISO 3166 country
|
||||
* code after a dash or underscore. */
|
||||
const char * code;
|
||||
|
||||
/* Any extra information to distinguish this
|
||||
* variety of dictionary from other dictionaries
|
||||
* which may have the same language and size. */
|
||||
const char * jargon;
|
||||
|
||||
int size;
|
||||
|
||||
/* A two char digit code describing the size of
|
||||
* the dictionary: 10=tiny, 20=really small,
|
||||
* 30=small, 40=med-small, 50=med, 60=med-large,
|
||||
* 70=large, 80=huge, 90=insane. Please check
|
||||
* the README in aspell-lang-200?????.tar.bz2 or
|
||||
* see SCOWL (http://wordlist.sourceforge.net)
|
||||
* for an example of how these sizes are used. */
|
||||
const char * size_str;
|
||||
|
||||
struct AspellModuleInfo * module;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellDictInfo AspellDictInfo;
|
||||
|
||||
|
||||
typedef struct AspellModuleInfoList AspellModuleInfoList;
|
||||
|
||||
|
||||
struct AspellModuleInfoList * get_aspell_module_info_list(struct AspellConfig * config);
|
||||
|
||||
int aspell_module_info_list_empty(const struct AspellModuleInfoList * ths);
|
||||
|
||||
unsigned int aspell_module_info_list_size(const struct AspellModuleInfoList * ths);
|
||||
|
||||
struct AspellModuleInfoEnumeration * aspell_module_info_list_elements(const struct AspellModuleInfoList * ths);
|
||||
|
||||
|
||||
|
||||
typedef struct AspellDictInfoList AspellDictInfoList;
|
||||
|
||||
|
||||
struct AspellDictInfoList * get_aspell_dict_info_list(struct AspellConfig * config);
|
||||
|
||||
int aspell_dict_info_list_empty(const struct AspellDictInfoList * ths);
|
||||
|
||||
unsigned int aspell_dict_info_list_size(const struct AspellDictInfoList * ths);
|
||||
|
||||
struct AspellDictInfoEnumeration * aspell_dict_info_list_elements(const struct AspellDictInfoList * ths);
|
||||
|
||||
|
||||
|
||||
typedef struct AspellModuleInfoEnumeration AspellModuleInfoEnumeration;
|
||||
|
||||
|
||||
int aspell_module_info_enumeration_at_end(const struct AspellModuleInfoEnumeration * ths);
|
||||
|
||||
const struct AspellModuleInfo * aspell_module_info_enumeration_next(struct AspellModuleInfoEnumeration * ths);
|
||||
|
||||
void delete_aspell_module_info_enumeration(struct AspellModuleInfoEnumeration * ths);
|
||||
|
||||
struct AspellModuleInfoEnumeration * aspell_module_info_enumeration_clone(const struct AspellModuleInfoEnumeration * ths);
|
||||
|
||||
void aspell_module_info_enumeration_assign(struct AspellModuleInfoEnumeration * ths, const struct AspellModuleInfoEnumeration * other);
|
||||
|
||||
|
||||
|
||||
typedef struct AspellDictInfoEnumeration AspellDictInfoEnumeration;
|
||||
|
||||
|
||||
int aspell_dict_info_enumeration_at_end(const struct AspellDictInfoEnumeration * ths);
|
||||
|
||||
const struct AspellDictInfo * aspell_dict_info_enumeration_next(struct AspellDictInfoEnumeration * ths);
|
||||
|
||||
void delete_aspell_dict_info_enumeration(struct AspellDictInfoEnumeration * ths);
|
||||
|
||||
struct AspellDictInfoEnumeration * aspell_dict_info_enumeration_clone(const struct AspellDictInfoEnumeration * ths);
|
||||
|
||||
void aspell_dict_info_enumeration_assign(struct AspellDictInfoEnumeration * ths, const struct AspellDictInfoEnumeration * other);
|
||||
|
||||
|
||||
|
||||
/***************************** string list *****************************/
|
||||
|
||||
|
||||
typedef struct AspellStringList AspellStringList;
|
||||
|
||||
|
||||
struct AspellStringList * new_aspell_string_list();
|
||||
|
||||
int aspell_string_list_empty(const struct AspellStringList * ths);
|
||||
|
||||
unsigned int aspell_string_list_size(const struct AspellStringList * ths);
|
||||
|
||||
struct AspellStringEnumeration * aspell_string_list_elements(const struct AspellStringList * ths);
|
||||
|
||||
int aspell_string_list_add(struct AspellStringList * ths, const char * to_add);
|
||||
|
||||
int aspell_string_list_remove(struct AspellStringList * ths, const char * to_rem);
|
||||
|
||||
void aspell_string_list_clear(struct AspellStringList * ths);
|
||||
|
||||
struct AspellMutableContainer * aspell_string_list_to_mutable_container(struct AspellStringList * ths);
|
||||
|
||||
void delete_aspell_string_list(struct AspellStringList * ths);
|
||||
|
||||
struct AspellStringList * aspell_string_list_clone(const struct AspellStringList * ths);
|
||||
|
||||
void aspell_string_list_assign(struct AspellStringList * ths, const struct AspellStringList * other);
|
||||
|
||||
|
||||
|
||||
/****************************** string map ******************************/
|
||||
|
||||
|
||||
typedef struct AspellStringMap AspellStringMap;
|
||||
|
||||
|
||||
struct AspellStringMap * new_aspell_string_map();
|
||||
|
||||
int aspell_string_map_add(struct AspellStringMap * ths, const char * to_add);
|
||||
|
||||
int aspell_string_map_remove(struct AspellStringMap * ths, const char * to_rem);
|
||||
|
||||
void aspell_string_map_clear(struct AspellStringMap * ths);
|
||||
|
||||
struct AspellMutableContainer * aspell_string_map_to_mutable_container(struct AspellStringMap * ths);
|
||||
|
||||
void delete_aspell_string_map(struct AspellStringMap * ths);
|
||||
|
||||
struct AspellStringMap * aspell_string_map_clone(const struct AspellStringMap * ths);
|
||||
|
||||
void aspell_string_map_assign(struct AspellStringMap * ths, const struct AspellStringMap * other);
|
||||
|
||||
int aspell_string_map_empty(const struct AspellStringMap * ths);
|
||||
|
||||
unsigned int aspell_string_map_size(const struct AspellStringMap * ths);
|
||||
|
||||
struct AspellStringPairEnumeration * aspell_string_map_elements(const struct AspellStringMap * ths);
|
||||
|
||||
/* Insert a new element.
|
||||
* Will NOT overwrite an existing entry.
|
||||
* Returns FALSE if the element already exists. */
|
||||
int aspell_string_map_insert(struct AspellStringMap * ths, const char * key, const char * value);
|
||||
|
||||
/* Insert a new element.
|
||||
* Will overwrite an existing entry.
|
||||
* Always returns TRUE. */
|
||||
int aspell_string_map_replace(struct AspellStringMap * ths, const char * key, const char * value);
|
||||
|
||||
/* Looks up an element and returns the value.
|
||||
* Returns NULL if the element does not exist.
|
||||
* Returns an empty string if the element exists
|
||||
* but has a NULL value. */
|
||||
const char * aspell_string_map_lookup(const struct AspellStringMap * ths, const char * key);
|
||||
|
||||
|
||||
|
||||
/***************************** string pair *****************************/
|
||||
|
||||
|
||||
struct AspellStringPair {
|
||||
|
||||
const char * first;
|
||||
|
||||
const char * second;
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct AspellStringPair AspellStringPair;
|
||||
|
||||
|
||||
/*********************** string pair enumeration ***********************/
|
||||
|
||||
|
||||
typedef struct AspellStringPairEnumeration AspellStringPairEnumeration;
|
||||
|
||||
|
||||
int aspell_string_pair_enumeration_at_end(const struct AspellStringPairEnumeration * ths);
|
||||
|
||||
struct AspellStringPair aspell_string_pair_enumeration_next(struct AspellStringPairEnumeration * ths);
|
||||
|
||||
void delete_aspell_string_pair_enumeration(struct AspellStringPairEnumeration * ths);
|
||||
|
||||
struct AspellStringPairEnumeration * aspell_string_pair_enumeration_clone(const struct AspellStringPairEnumeration * ths);
|
||||
|
||||
void aspell_string_pair_enumeration_assign(struct AspellStringPairEnumeration * ths, const struct AspellStringPairEnumeration * other);
|
||||
|
||||
|
||||
|
||||
/******************************** cache ********************************/
|
||||
|
||||
|
||||
/* Reset the global cache(s) so that cache queries will
|
||||
* create a new object. If existing objects are still in
|
||||
* use they are not deleted. If which is NULL then all
|
||||
* caches will be reset. Current caches are "encode",
|
||||
* "decode", "dictionary", "language", and "keyboard". */
|
||||
int aspell_reset_cache(const char * which);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* ASPELL_ASPELL__H */
|
||||
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2006-2019 J.F.Dockes
|
||||
/* Copyright (C) 2006-2021 J.F.Dockes
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@ -18,8 +18,6 @@
|
||||
|
||||
#ifdef RCL_USE_ASPELL
|
||||
|
||||
#include ASPELL_INCLUDE
|
||||
|
||||
#include <mutex>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -34,72 +32,11 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Aspell library entry points
|
||||
class AspellApi {
|
||||
public:
|
||||
struct AspellConfig *(*new_aspell_config)();
|
||||
int (*aspell_config_replace)(struct AspellConfig *, const char * key,
|
||||
const char * value);
|
||||
struct AspellCanHaveError *(*new_aspell_speller)(struct AspellConfig *);
|
||||
void (*delete_aspell_config)(struct AspellConfig *);
|
||||
void (*delete_aspell_can_have_error)(struct AspellCanHaveError *);
|
||||
struct AspellSpeller * (*to_aspell_speller)(struct AspellCanHaveError *);
|
||||
struct AspellConfig * (*aspell_speller_config)(struct AspellSpeller *);
|
||||
const struct AspellWordList * (*aspell_speller_suggest)
|
||||
(struct AspellSpeller *, const char *, int);
|
||||
int (*aspell_speller_check)(struct AspellSpeller *, const char *, int);
|
||||
struct AspellStringEnumeration * (*aspell_word_list_elements)
|
||||
(const struct AspellWordList * ths);
|
||||
const char * (*aspell_string_enumeration_next)
|
||||
(struct AspellStringEnumeration * ths);
|
||||
void (*delete_aspell_string_enumeration)(struct AspellStringEnumeration *);
|
||||
const struct AspellError *(*aspell_error)
|
||||
(const struct AspellCanHaveError *);
|
||||
const char *(*aspell_error_message)(const struct AspellCanHaveError *);
|
||||
const char *(*aspell_speller_error_message)(const struct AspellSpeller *);
|
||||
void (*delete_aspell_speller)(struct AspellSpeller *);
|
||||
|
||||
};
|
||||
static AspellApi aapi;
|
||||
static std::mutex o_aapi_mutex;
|
||||
|
||||
#define NMTOPTR(NM, TP) \
|
||||
if ((aapi.NM = TP dlib_sym(m_data->m_handle, #NM)) == 0) { \
|
||||
badnames += #NM + string(" "); \
|
||||
}
|
||||
|
||||
static const vector<string> aspell_lib_suffixes {
|
||||
#if defined(__APPLE__)
|
||||
".15.dylib",
|
||||
".dylib",
|
||||
#elif defined(_WIN32)
|
||||
"-15.dll",
|
||||
#else
|
||||
".so",
|
||||
".so.15",
|
||||
#endif
|
||||
};
|
||||
|
||||
// Private rclaspell data
|
||||
class AspellData {
|
||||
public:
|
||||
~AspellData() {
|
||||
LOGDEB2("~AspellData\n" );
|
||||
if (m_handle) {
|
||||
dlib_close(m_handle);
|
||||
m_handle = nullptr;
|
||||
}
|
||||
if (m_speller) {
|
||||
// Dumps core if I do this??
|
||||
//aapi.delete_aspell_speller(m_speller);
|
||||
m_speller = nullptr;
|
||||
LOGDEB2("~AspellData: speller done\n" );
|
||||
}
|
||||
}
|
||||
|
||||
void *m_handle{nullptr};
|
||||
string m_exec;
|
||||
AspellSpeller *m_speller{nullptr};
|
||||
ExecCmd m_speller;
|
||||
#ifdef _WIN32
|
||||
string m_datadir;
|
||||
#endif
|
||||
@ -118,7 +55,6 @@ Aspell::~Aspell()
|
||||
|
||||
bool Aspell::init(string &reason)
|
||||
{
|
||||
std::unique_lock<std::mutex> locker(o_aapi_mutex);
|
||||
deleteZ(m_data);
|
||||
|
||||
// Language: we get this from the configuration, else from the NLS
|
||||
@ -149,11 +85,10 @@ bool Aspell::init(string &reason)
|
||||
m_config->getConfParam("aspellAddCreateParam", m_data->m_addCreateParam);
|
||||
#ifdef _WIN32
|
||||
m_data->m_datadir = path_cat(
|
||||
path_pkgdatadir(),
|
||||
"filters/aspell-installed/mingw32/lib/aspell-0.60");
|
||||
path_pkgdatadir(), "filters/aspell-installed/mingw32/lib/aspell-0.60");
|
||||
if (m_data->m_addCreateParam.empty()) {
|
||||
m_data->m_addCreateParam = string("--local-data-dir=") +
|
||||
path_cat(m_config->getConfDir(), "aspell");
|
||||
m_data->m_addCreateParam =
|
||||
string("--local-data-dir=") + path_cat(m_config->getConfDir(), "aspell");
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
@ -179,110 +114,16 @@ bool Aspell::init(string &reason)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't know what with Apple and (DY)LD_LIBRARY_PATH. Does not work
|
||||
// So we look in all ../lib in the PATH...
|
||||
#if defined(__APPLE__)
|
||||
vector<string> path;
|
||||
const char *pp = getenv("PATH");
|
||||
if (pp) {
|
||||
stringToTokens(pp, path, ":");
|
||||
}
|
||||
#endif
|
||||
|
||||
reason = "Could not open shared library ";
|
||||
string libbase("libaspell");
|
||||
string lib;
|
||||
for (const auto& suff : aspell_lib_suffixes) {
|
||||
lib = libbase + suff;
|
||||
reason += string("[") + lib + "] ";
|
||||
if ((m_data->m_handle = dlib_open(lib)) != 0) {
|
||||
reason.erase();
|
||||
goto found;
|
||||
}
|
||||
// Above was the normal lookup: let dlopen search the directories.
|
||||
// Also look in other places for Apple and Windows.
|
||||
#if defined(__APPLE__)
|
||||
for (const auto& dir : path) {
|
||||
string lib1 = path_canon(dir + "/../lib/" + lib);
|
||||
if ((m_data->m_handle = dlib_open(lib1)) != 0) {
|
||||
reason.erase();
|
||||
lib=lib1;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(_MSC_VER)
|
||||
// Look in the directory of the aspell binary. When building
|
||||
// with msvc, the aspell .exe is still the mingw one, but we
|
||||
// copy the msvc dll in the recoll top directory, so no need
|
||||
// to look in the aspell one.
|
||||
{
|
||||
string bindir = path_getfather(m_data->m_exec);
|
||||
string lib1 = path_cat(bindir, lib);
|
||||
if ((m_data->m_handle = dlib_open(lib1)) != 0) {
|
||||
reason.erase();
|
||||
lib=lib1;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
found:
|
||||
if (m_data->m_handle == 0) {
|
||||
reason += string(" : ") + dlib_error();
|
||||
deleteZ(m_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
string badnames;
|
||||
NMTOPTR(new_aspell_config, (struct AspellConfig *(*)()));
|
||||
NMTOPTR(aspell_config_replace, (int (*)(struct AspellConfig *,
|
||||
const char *, const char *)));
|
||||
NMTOPTR(new_aspell_speller,
|
||||
(struct AspellCanHaveError *(*)(struct AspellConfig *)));
|
||||
NMTOPTR(delete_aspell_config,
|
||||
(void (*)(struct AspellConfig *)));
|
||||
NMTOPTR(delete_aspell_can_have_error,
|
||||
(void (*)(struct AspellCanHaveError *)));
|
||||
NMTOPTR(to_aspell_speller,
|
||||
(struct AspellSpeller *(*)(struct AspellCanHaveError *)));
|
||||
NMTOPTR(aspell_speller_config,
|
||||
(struct AspellConfig *(*)(struct AspellSpeller *)));
|
||||
NMTOPTR(aspell_speller_suggest,
|
||||
(const struct AspellWordList *(*)(struct AspellSpeller *,
|
||||
const char *, int)));
|
||||
NMTOPTR(aspell_speller_check,
|
||||
(int (*)(struct AspellSpeller *, const char *, int)));
|
||||
NMTOPTR(aspell_word_list_elements,
|
||||
(struct AspellStringEnumeration *(*)
|
||||
(const struct AspellWordList *)));
|
||||
NMTOPTR(aspell_string_enumeration_next,
|
||||
(const char * (*)(struct AspellStringEnumeration *)));
|
||||
NMTOPTR(delete_aspell_string_enumeration,
|
||||
(void (*)(struct AspellStringEnumeration *)));
|
||||
NMTOPTR(aspell_error,
|
||||
(const struct AspellError*(*)(const struct AspellCanHaveError *)));
|
||||
NMTOPTR(aspell_error_message,
|
||||
(const char *(*)(const struct AspellCanHaveError *)));
|
||||
NMTOPTR(aspell_speller_error_message,
|
||||
(const char *(*)(const struct AspellSpeller *)));
|
||||
NMTOPTR(delete_aspell_speller, (void (*)(struct AspellSpeller *)));
|
||||
|
||||
if (!badnames.empty()) {
|
||||
reason = string("Aspell::init: symbols not found:") + badnames;
|
||||
deleteZ(m_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Aspell::ok() const
|
||||
{
|
||||
return m_data != 0 && m_data->m_handle != 0;
|
||||
return nullptr != m_data;
|
||||
}
|
||||
|
||||
|
||||
string Aspell::dicPath()
|
||||
{
|
||||
string ccdir = m_config->getAspellcacheDir();
|
||||
@ -409,84 +250,76 @@ bool Aspell::buildDict(Rcl::Db &db, string &reason)
|
||||
return true;
|
||||
}
|
||||
|
||||
static const unsigned int ldatadiroptsz =
|
||||
string("--local-data-dir=").size();
|
||||
static const unsigned int ldatadiroptsz = strlen("--local-data-dir=");
|
||||
|
||||
bool Aspell::make_speller(string& reason)
|
||||
{
|
||||
if (!ok())
|
||||
return false;
|
||||
if (m_data->m_speller != 0)
|
||||
if (m_data->m_speller.getChildPid() > 0)
|
||||
return true;
|
||||
|
||||
AspellCanHaveError *ret;
|
||||
// aspell --lang=[lang] --encoding=utf-8 --master=[dicPath()] --sug-mode=fast pipe
|
||||
|
||||
string cmdstring(m_data->m_exec);
|
||||
|
||||
ExecCmd aspell;
|
||||
vector<string> args;
|
||||
|
||||
args.push_back(string("--lang=")+ m_lang);
|
||||
cmdstring += string(" ") + args.back();
|
||||
|
||||
args.push_back("--encoding=utf-8");
|
||||
cmdstring += string(" ") + args.back();
|
||||
|
||||
AspellConfig *config = aapi.new_aspell_config();
|
||||
aapi.aspell_config_replace(config, "lang", m_lang.c_str());
|
||||
aapi.aspell_config_replace(config, "encoding", "utf-8");
|
||||
aapi.aspell_config_replace(config, "master", dicPath().c_str());
|
||||
aapi.aspell_config_replace(config, "sug-mode", "fast");
|
||||
#ifdef _WIN32
|
||||
aapi.aspell_config_replace(config, "data-dir", m_data->m_datadir.c_str());
|
||||
args.push_back(string("--data-dir=") + m_data->m_datadir);
|
||||
cmdstring += string(" ") + args.back();
|
||||
#endif
|
||||
if (m_data->m_addCreateParam.size() > ldatadiroptsz) {
|
||||
aapi.aspell_config_replace(
|
||||
config, "local-data-dir",
|
||||
m_data->m_addCreateParam.substr(ldatadiroptsz).c_str());
|
||||
args.push_back(
|
||||
string("--local-data-dir=") + m_data->m_addCreateParam.substr(ldatadiroptsz));
|
||||
cmdstring += string(" ") + args.back();
|
||||
}
|
||||
// aapi.aspell_config_replace(config, "sug-edit-dist", "2");
|
||||
ret = aapi.new_aspell_speller(config);
|
||||
aapi.delete_aspell_config(config);
|
||||
|
||||
if (aapi.aspell_error(ret) != 0) {
|
||||
reason = aapi.aspell_error_message(ret);
|
||||
aapi.delete_aspell_can_have_error(ret);
|
||||
if (!m_data->m_addCreateParam.empty()) {
|
||||
args.push_back(m_data->m_addCreateParam);
|
||||
cmdstring += string(" ") + args.back();
|
||||
}
|
||||
|
||||
args.push_back(string("--master=") + dicPath());
|
||||
cmdstring += string(" ") + args.back();
|
||||
|
||||
args.push_back(string("--sug-mode=fast"));
|
||||
cmdstring += string(" ") + args.back();
|
||||
|
||||
args.push_back("pipe");
|
||||
cmdstring += string(" ") + args.back();
|
||||
|
||||
// Keep stderr by default when querying?
|
||||
bool keepStderr = true;
|
||||
m_config->getConfParam("aspellKeepStderr", &keepStderr);
|
||||
if (!keepStderr)
|
||||
m_data->m_speller.setStderr("/dev/null");
|
||||
|
||||
LOGDEB("Starting aspell command [" << cmdstring << "]\n");
|
||||
if (m_data->m_speller.startExec(m_data->m_exec, args, true, true) != 0) {
|
||||
LOGERR("Can't start aspell\n");
|
||||
return false;
|
||||
}
|
||||
m_data->m_speller = aapi.to_aspell_speller(ret);
|
||||
// Read initial line from aspell: version etc.
|
||||
string line;
|
||||
if (m_data->m_speller.getline(line, 2) <= 0) {
|
||||
LOGERR("rclaspell: failed reading initial aspell line. Command was " << cmdstring << "\n");
|
||||
m_data->m_speller.zapChild();
|
||||
return false;
|
||||
}
|
||||
LOGDEB("rclaspell: aspell initial answer: [" << line << "]\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Aspell::check(const string &iterm, string& reason)
|
||||
{
|
||||
LOGDEB("Aspell::check [" << iterm << "]\n");
|
||||
string mterm(iterm);
|
||||
|
||||
if (!Rcl::Db::isSpellingCandidate(mterm)) {
|
||||
LOGDEB0("Aspell::check: [" << mterm <<
|
||||
" not spelling candidate, return true\n");
|
||||
return true;
|
||||
}
|
||||
if (!ok() || !make_speller(reason))
|
||||
return false;
|
||||
if (iterm.empty())
|
||||
return true; //??
|
||||
|
||||
if (!o_index_stripchars) {
|
||||
string lower;
|
||||
if (!unacmaybefold(mterm, lower, "UTF-8", UNACOP_FOLD)) {
|
||||
LOGERR("Aspell::check: cant lowercase input\n");
|
||||
return false;
|
||||
}
|
||||
mterm.swap(lower);
|
||||
}
|
||||
|
||||
int ret = aapi.aspell_speller_check(m_data->m_speller,
|
||||
mterm.c_str(), mterm.length());
|
||||
reason.clear();
|
||||
switch (ret) {
|
||||
case 0: return false;
|
||||
case 1: return true;
|
||||
default:
|
||||
case -1:
|
||||
reason.append("Aspell error: ");
|
||||
reason.append(aapi.aspell_speller_error_message(m_data->m_speller));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Aspell::suggest(Rcl::Db &db, const string &_term,
|
||||
list<string>& suggestions, string& reason)
|
||||
bool Aspell::suggest(
|
||||
Rcl::Db &db, const string &_term, vector<string>& suggestions, string& reason)
|
||||
{
|
||||
LOGDEB("Aspell::suggest: term [" << _term << "]\n");
|
||||
if (!ok() || !make_speller(reason))
|
||||
@ -496,8 +329,7 @@ bool Aspell::suggest(Rcl::Db &db, const string &_term,
|
||||
return true; //??
|
||||
|
||||
if (!Rcl::Db::isSpellingCandidate(mterm)) {
|
||||
LOGDEB0("Aspell::suggest: [" << mterm <<
|
||||
" not spelling candidate, return empty/true\n");
|
||||
LOGDEB0("Aspell::suggest: [" << mterm << " not spelling candidate, return empty/true\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -510,27 +342,37 @@ bool Aspell::suggest(Rcl::Db &db, const string &_term,
|
||||
mterm.swap(lower);
|
||||
}
|
||||
|
||||
const AspellWordList *wl =
|
||||
aapi.aspell_speller_suggest(m_data->m_speller,
|
||||
mterm.c_str(), mterm.length());
|
||||
if (wl == 0) {
|
||||
reason = aapi.aspell_speller_error_message(m_data->m_speller);
|
||||
m_data->m_speller.send(mterm + "\n");
|
||||
std::string line;
|
||||
if (m_data->m_speller.getline(line, 3) <= 0) {
|
||||
reason.append("Aspell error: ");
|
||||
return false;
|
||||
}
|
||||
AspellStringEnumeration *els = aapi.aspell_word_list_elements(wl);
|
||||
const char *word;
|
||||
while ((word = aapi.aspell_string_enumeration_next(els)) != 0) {
|
||||
LOGDEB0("Aspell::suggest: got [" << word << "]\n");
|
||||
// Check that the word exists in the index (we don't want
|
||||
// aspell computed stuff, only exact terms from the
|
||||
// dictionary). We used to also check that it stems
|
||||
// differently from the base word but this is complicated
|
||||
// (stemming on/off + language), so we now leave this to the
|
||||
// caller.
|
||||
LOGDEB1("ASPELL: got answer: " << line << "\n");
|
||||
string empty;
|
||||
if (m_data->m_speller.getline(empty, 1) <= 0) {
|
||||
reason.append("Aspell: failed reading final empty line\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (line[0] == '*' || line[0] == '#') {
|
||||
// Word is in dictionary, or there are no suggestions
|
||||
return true;
|
||||
}
|
||||
string::size_type colon;
|
||||
// Aspell suggestions line: & original count offset: miss, miss, …
|
||||
if (line[0] != '&' || (colon = line.find(':')) == string::npos || colon == line.size()-1) {
|
||||
// ??
|
||||
reason.append("Aspell: bad answer line: ");
|
||||
reason.append(line);
|
||||
return false;
|
||||
}
|
||||
std::vector<std::string> words;
|
||||
stringSplitString(line.substr(colon + 2), words, ", ");
|
||||
for (const auto& word : words) {
|
||||
if (db.termExists(word))
|
||||
suggestions.push_back(word);
|
||||
}
|
||||
aapi.delete_aspell_string_enumeration(els);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2006 J.F.Dockes
|
||||
/* Copyright (C) 2006-2021 J.F.Dockes
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@ -27,12 +27,10 @@
|
||||
* exist in the document set for a given word.
|
||||
* A specific aspell dictionary is created out of all the terms in the
|
||||
* xapian index, and we then use it to expand a term to spelling neighbours.
|
||||
* We use the aspell C api for term expansion, but have
|
||||
* to execute the program to create dictionaries.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "rclconfig.h"
|
||||
#include "rcldb.h"
|
||||
@ -40,7 +38,7 @@
|
||||
class AspellData;
|
||||
|
||||
class Aspell {
|
||||
public:
|
||||
public:
|
||||
Aspell(const RclConfig *cnf);
|
||||
~Aspell();
|
||||
|
||||
@ -54,19 +52,11 @@ class Aspell {
|
||||
* of an indexing pass. */
|
||||
bool buildDict(Rcl::Db &db, std::string &reason);
|
||||
|
||||
/** Check that word is in dictionary. Note that this would mean
|
||||
* that the EXACT word is: aspell just does a lookup, no
|
||||
* grammatical, case or diacritics magic of any kind
|
||||
*
|
||||
* @return true if word in dic, false if not. reason.size() -> error
|
||||
*/
|
||||
bool check(const std::string& term, std::string& reason);
|
||||
|
||||
/** Return a list of possible expansions for a given word */
|
||||
bool suggest(Rcl::Db &db, const std::string& term,
|
||||
std::list<std::string> &suggestions, std::string &reason);
|
||||
std::vector<std::string> &suggestions, std::string &reason);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string dicPath();
|
||||
const RclConfig *m_config;
|
||||
std::string m_lang;
|
||||
|
||||
@ -10,9 +10,6 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Path to the aspell api include file */
|
||||
#define ASPELL_INCLUDE "../aspell/aspell-local.h"
|
||||
|
||||
/* Path to the aspell program */
|
||||
#define ASPELL_PROG "/opt/local/bin/aspell"
|
||||
|
||||
|
||||
@ -4,9 +4,6 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* Path to the aspell api include file */
|
||||
#define ASPELL_INCLUDE "aspell-local.h"
|
||||
|
||||
/* Aspell program parameter to findFilter(). */
|
||||
#define ASPELL_PROG "aspell-installed/mingw32/bin/aspell"
|
||||
|
||||
|
||||
@ -3,9 +3,6 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Path to the aspell api include file */
|
||||
#undef ASPELL_INCLUDE
|
||||
|
||||
/* Path to the aspell program */
|
||||
#undef ASPELL_PROG
|
||||
|
||||
|
||||
@ -114,19 +114,7 @@ if test X$withAspell != Xno ; then
|
||||
if test X$aspellProg != X ; then
|
||||
aspellBase=`dirname $aspellProg`
|
||||
aspellBase=`dirname $aspellBase`
|
||||
AC_DEFINE_UNQUOTED(ASPELL_PROG, "$aspellProg",
|
||||
[Path to the aspell program])
|
||||
if test -f $aspellBase/include/aspell.h ; then
|
||||
AC_DEFINE_UNQUOTED(ASPELL_INCLUDE, "$aspellBase/include/aspell.h",
|
||||
[Path to the aspell api include file])
|
||||
else
|
||||
AC_MSG_NOTICE([aspell support enabled but aspell package not found. Compiling with internal aspell interface file])
|
||||
AC_DEFINE(ASPELL_INCLUDE, ["aspell-local.h"])
|
||||
fi
|
||||
else
|
||||
# aspell support enabled but no aspell install yet
|
||||
AC_MSG_NOTICE([aspell support enabled but aspell package not found. Compiling with internal aspell interface file])
|
||||
AC_DEFINE(ASPELL_INCLUDE, ["aspell-local.h"])
|
||||
AC_DEFINE_UNQUOTED(ASPELL_PROG, "$aspellProg", [Path to the aspell program])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@ -1453,14 +1453,11 @@ bool Db::getSpellingSuggestions(const string& word, vector<string>& suggs)
|
||||
return false;
|
||||
}
|
||||
|
||||
list<string> asuggs;
|
||||
string reason;
|
||||
if (!m_aspell->suggest(*this, term, asuggs, reason)) {
|
||||
LOGERR("Db::getSpellingSuggestions: aspell failed: " << reason <<
|
||||
"\n");
|
||||
if (!m_aspell->suggest(*this, term, suggs, reason)) {
|
||||
LOGERR("Db::getSpellingSuggestions: aspell failed: " << reason << "\n");
|
||||
return false;
|
||||
}
|
||||
suggs = vector<string>(asuggs.begin(), asuggs.end());
|
||||
#endif
|
||||
} else {
|
||||
#ifdef TESTING_XAPIAN_SPELL
|
||||
|
||||
@ -37,11 +37,10 @@ static char *thisprog;
|
||||
RclConfig *rclconfig;
|
||||
|
||||
static char usage [] =
|
||||
" -b : build dictionary\n"
|
||||
" -s <term>: suggestions for term\n"
|
||||
" -c <term>: check term\n"
|
||||
"\n"
|
||||
;
|
||||
" -b : build dictionary\n"
|
||||
" -s <term>: suggestions for term\n"
|
||||
"\n"
|
||||
;
|
||||
static void
|
||||
Usage(void)
|
||||
{
|
||||
@ -63,83 +62,71 @@ int main(int argc, char **argv)
|
||||
argc--; argv++;
|
||||
|
||||
while (argc > 0 && **argv == '-') {
|
||||
(*argv)++;
|
||||
if (!(**argv))
|
||||
/* Cas du "adb - core" */
|
||||
Usage();
|
||||
while (**argv)
|
||||
switch (*(*argv)++) {
|
||||
case 'b': op_flags |= OPT_b; break;
|
||||
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
|
||||
word = *(++argv);
|
||||
argc--;
|
||||
goto b1;
|
||||
case 's': op_flags |= OPT_s; if (argc < 2) Usage();
|
||||
word = *(++argv);
|
||||
argc--;
|
||||
goto b1;
|
||||
default: Usage(); break;
|
||||
}
|
||||
(*argv)++;
|
||||
if (!(**argv))
|
||||
/* Cas du "adb - core" */
|
||||
Usage();
|
||||
while (**argv)
|
||||
switch (*(*argv)++) {
|
||||
case 'b': op_flags |= OPT_b; break;
|
||||
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
|
||||
word = *(++argv);
|
||||
argc--;
|
||||
goto b1;
|
||||
case 's': op_flags |= OPT_s; if (argc < 2) Usage();
|
||||
word = *(++argv);
|
||||
argc--;
|
||||
goto b1;
|
||||
default: Usage(); break;
|
||||
}
|
||||
b1: argc--; argv++;
|
||||
}
|
||||
|
||||
if (argc != 0 || op_flags == 0)
|
||||
Usage();
|
||||
Usage();
|
||||
|
||||
string reason;
|
||||
rclconfig = recollinit(0, 0, 0, reason);
|
||||
if (!rclconfig || !rclconfig->ok()) {
|
||||
fprintf(stderr, "Configuration problem: %s\n", reason.c_str());
|
||||
exit(1);
|
||||
fprintf(stderr, "Configuration problem: %s\n", reason.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
string dbdir = rclconfig->getDbDir();
|
||||
if (dbdir.empty()) {
|
||||
fprintf(stderr, "No db directory in configuration");
|
||||
exit(1);
|
||||
fprintf(stderr, "No db directory in configuration");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Rcl::Db rcldb(rclconfig);
|
||||
|
||||
if (!rcldb.open(Rcl::Db::DbRO, 0)) {
|
||||
fprintf(stderr, "Could not open database in %s\n", dbdir.c_str());
|
||||
exit(1);
|
||||
fprintf(stderr, "Could not open database in %s\n", dbdir.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Aspell aspell(rclconfig);
|
||||
|
||||
if (!aspell.init(reason)) {
|
||||
cerr << "Init failed: " << reason << endl;
|
||||
exit(1);
|
||||
cerr << "Init failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (op_flags & OPT_b) {
|
||||
if (!aspell.buildDict(rcldb, reason)) {
|
||||
cerr << "buildDict failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
} else if (op_flags & OPT_c) {
|
||||
bool ret = aspell.check(word, reason);
|
||||
if (!ret && reason.size()) {
|
||||
cerr << "Aspell error: " << reason << endl;
|
||||
return 1;
|
||||
}
|
||||
cout << word;
|
||||
if (ret) {
|
||||
cout << " is in dictionary" << endl;
|
||||
if (!aspell.buildDict(rcldb, reason)) {
|
||||
cerr << "buildDict failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
cout << " not in dictionary" << endl;
|
||||
}
|
||||
} else {
|
||||
list<string> suggs;
|
||||
if (!aspell.suggest(rcldb, word, suggs, reason)) {
|
||||
cerr << "suggest failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
cout << "Suggestions for " << word << ":" << endl;
|
||||
for (list<string>::iterator it = suggs.begin();
|
||||
it != suggs.end(); it++) {
|
||||
cout << *it << endl;
|
||||
}
|
||||
list<string> suggs;
|
||||
if (!aspell.suggest(rcldb, word, suggs, reason)) {
|
||||
cerr << "suggest failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
cout << "Suggestions for " << word << ":" << endl;
|
||||
for (list<string>::iterator it = suggs.begin();
|
||||
it != suggs.end(); it++) {
|
||||
cout << *it << endl;
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user