summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReuben Thomas <rrt@sc3d.org>2021-06-14 22:04:17 +0100
committerGitHub <noreply@github.com>2021-06-14 22:04:17 +0100
commite5ae20ffca11ef73c6564dc0f71c798eca208f99 (patch)
treee30384860394ac50c0404e3abbf8bdc8dd95870c
parent32fc9f475f0c45b3532ed186cc312508c9049840 (diff)
parent6ed01f461c8d3599df1e7270630cd67ca786b03e (diff)
downloadenchant-e5ae20ffca11ef73c6564dc0f71c798eca208f99.tar.gz
Merge pull request #275 from rrthomas/masterv2.3.0
Add -p option to enchant
-rw-r--r--NEWS17
-rw-r--r--configure.ac2
-rw-r--r--src/enchant.1.in3
-rw-r--r--src/enchant.c58
-rw-r--r--src/pwl.c22
-rw-r--r--src/pwl.h8
6 files changed, 88 insertions, 22 deletions
diff --git a/NEWS b/NEWS
index dc0808d..8e13503 100644
--- a/NEWS
+++ b/NEWS
@@ -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);
diff --git a/src/pwl.c b/src/pwl.c
index 4f118a1..db645d5 100644
--- a/src/pwl.c
+++ b/src/pwl.c
@@ -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);
diff --git a/src/pwl.h b/src/pwl.h
index f713b29..c945e3c 100644
--- a/src/pwl.h
+++ b/src/pwl.h
@@ -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