diff options
author | Reuben Thomas <rrt@sc3d.org> | 2021-06-14 22:04:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-14 22:04:17 +0100 |
commit | e5ae20ffca11ef73c6564dc0f71c798eca208f99 (patch) | |
tree | e30384860394ac50c0404e3abbf8bdc8dd95870c | |
parent | 32fc9f475f0c45b3532ed186cc312508c9049840 (diff) | |
parent | 6ed01f461c8d3599df1e7270630cd67ca786b03e (diff) | |
download | enchant-e5ae20ffca11ef73c6564dc0f71c798eca208f99.tar.gz |
Merge pull request #275 from rrthomas/masterv2.3.0
Add -p option to enchant
-rw-r--r-- | NEWS | 17 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/enchant.1.in | 3 | ||||
-rw-r--r-- | src/enchant.c | 58 | ||||
-rw-r--r-- | src/pwl.c | 22 | ||||
-rw-r--r-- | src/pwl.h | 8 |
6 files changed, 88 insertions, 22 deletions
@@ -1,3 +1,20 @@ +2.3.0 (June 14, 2021) +--------------------- + +Add -p flag to enchant. + +Allow personal wordlist APIs (enchant_pwl_*) to take -1 as the length of the +word, as the enchant_dict_* APIs already allowed. + +Add documentation to enchant_provider.h. + +Make Aspell the default backend for English locales it supports, as it is +much quicker than Hunspell in this case and achieves slightly better +results. + +Require nuspell version 4.1.0 or later. + + 2.2.15 (December 22, 2020) -------------------------- diff --git a/configure.ac b/configure.ac index 4877edc..e67163e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([enchant],[2.2.15]) +AC_INIT([enchant],[2.3.0]) AC_CONFIG_SRCDIR(src/enchant.h) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([subdir-objects]) diff --git a/src/enchant.1.in b/src/enchant.1.in index 3b76c3a..4ee07f6 100644 --- a/src/enchant.1.in +++ b/src/enchant.1.in @@ -14,6 +14,9 @@ is an ispell-compatible spellchecker. \fB\-d \fIDICTIONARY\fR use the given dictionary .TP +\fB\-p \fIWORDLIST\fR +use the given personal wordlist +.TP .B "\-a" list suggestions in ispell pipe mode format .TP diff --git a/src/enchant.c b/src/enchant.c index 06f72ce..2e520c0 100644 --- a/src/enchant.c +++ b/src/enchant.c @@ -1,7 +1,7 @@ /* enchant * Copyright (C) 2003 Dom Lachowicz * 2007 Hannu Väisänen - * 2016-2020 Reuben Thomas + * 2016-2021 Reuben Thomas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -47,6 +47,7 @@ #endif #include "enchant.h" +#include "pwl.h" #include "enchant-provider.h" @@ -75,6 +76,7 @@ print_help (const char * prog) fprintf (stderr, "Usage: %s -a|-l|-h|-v [-L] [-d DICTIONARY] [FILE]\n\ -d DICTIONARY use the given dictionary\n\ + -p FILE use the given personal word list\n\ -a list suggestions in ispell pipe mode format\n\ -l list only the misspellings\n\ -L display line numbers\n\ @@ -132,10 +134,20 @@ print_utf (const char * str) } } +static int +check_word (EnchantDict * dict, EnchantPWL * pwl, GString * word) +{ + int ok = word->len <= MIN_WORD_LENGTH || + enchant_dict_check (dict, word->str, word->len) == 0; + if (!ok && pwl) + ok = enchant_pwl_check (pwl, word->str, word->len) == 0; + return ok; +} + static void -do_mode_a (EnchantDict * dict, GString * word, size_t start_pos, size_t lineCount, gboolean terse_mode) +do_mode_a (EnchantDict * dict, EnchantPWL * pwl, GString * word, size_t start_pos, size_t lineCount, gboolean terse_mode) { - if (word->len <= MIN_WORD_LENGTH || enchant_dict_check (dict, word->str, word->len) == 0) { + if (check_word (dict, pwl, word)) { if (!terse_mode) { if (lineCount) printf ("* %u\n", (unsigned int)lineCount); @@ -145,6 +157,8 @@ do_mode_a (EnchantDict * dict, GString * word, size_t start_pos, size_t lineCoun } else { size_t n_suggs; char ** suggs = enchant_dict_suggest (dict, word->str, word->len, &n_suggs); + if (pwl) + suggs = enchant_pwl_suggest (pwl, word->str, word->len, suggs, &n_suggs); if (!n_suggs || !suggs) { printf ("# "); if (lineCount) @@ -174,9 +188,9 @@ do_mode_a (EnchantDict * dict, GString * word, size_t start_pos, size_t lineCoun } static void -do_mode_l (EnchantDict * dict, GString * word, size_t lineCount) +do_mode_l (EnchantDict * dict, EnchantPWL * pwl, GString * word, size_t lineCount) { - if (enchant_dict_check (dict, word->str, word->len) != 0) { + if (!check_word (dict, pwl, word)) { if (lineCount) printf ("%u ", (unsigned int)lineCount); print_utf (word->str); @@ -238,7 +252,7 @@ tokenize_line (EnchantDict * dict, GString * line) } static int -parse_file (FILE * in, IspellMode_t mode, gboolean countLines, gchar *dictionary) +parse_file (FILE * in, IspellMode_t mode, gboolean countLines, gchar *dictionary, EnchantPWL *pwl) { EnchantBroker * broker; EnchantDict * dict; @@ -301,7 +315,10 @@ parse_file (FILE * in, IspellMode_t mode, gboolean countLines, gchar *dictionary case '*': /* Insert in personal word list */ if (str->len == 1) goto empty_word; - enchant_dict_add(dict, str->str + 1, -1); + if (pwl) + enchant_pwl_add (pwl, str->str + 1, -1); + else + enchant_dict_add (dict, str->str + 1, -1); break; case '@': /* Accept for this session */ if (str->len == 1) @@ -311,7 +328,10 @@ parse_file (FILE * in, IspellMode_t mode, gboolean countLines, gchar *dictionary case '/': /* Remove from personal word list */ if (str->len == 1) goto empty_word; - enchant_dict_remove (dict, str->str + 1, -1); + if (pwl) + enchant_pwl_remove (pwl, str->str + 1, -1); + else + enchant_dict_remove (dict, str->str + 1, -1); break; case '_': /* Remove from this session */ if (str->len == 1) @@ -375,9 +395,9 @@ parse_file (FILE * in, IspellMode_t mode, gboolean countLines, gchar *dictionary tokens = tokens->next; if (mode == MODE_A) - do_mode_a (dict, word, pos, lineCount, terse_mode); + do_mode_a (dict, pwl, word, pos, lineCount, terse_mode); else if (mode == MODE_L) - do_mode_l (dict, word, lineCount); + do_mode_l (dict, pwl, word, lineCount); g_string_free(word, TRUE); } @@ -409,6 +429,7 @@ int main (int argc, char ** argv) FILE * fp = stdin; gboolean countLines = FALSE; gchar *dictionary = NULL; /* -d dictionary */ + gchar *perslist = NULL ; /* -p personal_word_list */ /* Initialize system locale */ setlocale(LC_ALL, ""); @@ -422,11 +443,14 @@ int main (int argc, char ** argv) #endif int optchar; - while ((optchar = getopt (argc, argv, ":d:alvLmB")) != -1) { + while ((optchar = getopt (argc, argv, ":d:p:alvLmB")) != -1) { switch (optchar) { case 'd': dictionary = optarg; /* Emacs calls ispell with '-d dictionary'. */ break; + case 'p': + perslist = optarg; + break; /* The first mode specified takes precedence. */ case 'a': if (mode == MODE_NONE) @@ -478,7 +502,17 @@ int main (int argc, char ** argv) exit (1); } } - rval = parse_file (fp, mode, countLines, dictionary); + EnchantPWL *pwl = NULL; + if (perslist) { + pwl = enchant_pwl_init_with_file (perslist); + if (!pwl) { + fprintf (stderr, "Error: Could not read the personal word list \"%s\"", perslist); + exit (1); + } + } + rval = parse_file (fp, mode, countLines, dictionary, pwl); + if (pwl) + enchant_pwl_free (pwl); if (file) fclose (fp); @@ -313,8 +313,11 @@ static void enchant_pwl_remove_from_trie(EnchantPWL *pwl, } void enchant_pwl_add(EnchantPWL *pwl, - const char *const word, size_t len) + const char *const word, ssize_t len) { + if (len < 0) + len = strlen (word); + enchant_pwl_refresh_from_file(pwl); enchant_pwl_add_to_trie(pwl, word, len); @@ -342,7 +345,7 @@ void enchant_pwl_add(EnchantPWL *pwl, putc ('\n', f); } - if (fwrite (word, sizeof(char), len, f) == len) + if (fwrite (word, sizeof(char), len, f) == (size_t)len) { putc ('\n', f); } @@ -353,8 +356,11 @@ void enchant_pwl_add(EnchantPWL *pwl, } void enchant_pwl_remove(EnchantPWL *pwl, - const char *const word, size_t len) + const char *const word, ssize_t len) { + if (len < 0) + len = strlen (word); + if(enchant_pwl_check(pwl, word, len) == 1) return; @@ -525,8 +531,11 @@ static gchar* enchant_utf8_strtitle(const gchar*str, gssize len) return result; } -int enchant_pwl_check(EnchantPWL *pwl, const char *const word, size_t len) +int enchant_pwl_check(EnchantPWL *pwl, const char *const word, ssize_t len) { + if (len < 0) + len = strlen (word); + enchant_pwl_refresh_from_file(pwl); int exists = enchant_pwl_contains(pwl, word, len); @@ -609,8 +618,11 @@ static int best_distance(char** suggs, const char *const word, size_t len) /* gives the best set of suggestions from pwl that are at least as good as the * given suggs (if suggs == NULL just best from pwl) */ char** enchant_pwl_suggest(EnchantPWL *pwl, const char *const word, - size_t len, char** suggs, size_t* out_n_suggs) + ssize_t len, char** suggs, size_t* out_n_suggs) { + if (len < 0) + len = strlen (word); + int max_dist = suggs ? best_distance(suggs, word, len) : ENCHANT_PWL_MAX_ERRORS; max_dist = MIN (max_dist, ENCHANT_PWL_MAX_ERRORS); @@ -42,12 +42,12 @@ typedef struct str_enchant_pwl EnchantPWL; EnchantPWL* enchant_pwl_init(void); EnchantPWL* enchant_pwl_init_with_file(const char * file); -void enchant_pwl_add(EnchantPWL * me, const char *const word, size_t len); -void enchant_pwl_remove(EnchantPWL * me, const char *const word, size_t len); -int enchant_pwl_check(EnchantPWL * me,const char *const word, size_t len); +void enchant_pwl_add(EnchantPWL * me, const char *const word, ssize_t len); +void enchant_pwl_remove(EnchantPWL * me, const char *const word, ssize_t len); +int enchant_pwl_check(EnchantPWL * me, const char *const word, ssize_t len); /*gives the best set of suggestions from pwl that are at least as good as the given suggs*/ char** enchant_pwl_suggest(EnchantPWL *me, const char *const word, - size_t len, char ** suggs, size_t* out_n_suggs); + ssize_t len, char ** suggs, size_t* out_n_suggs); void enchant_pwl_free(EnchantPWL* me); #ifdef __cplusplus |