summaryrefslogtreecommitdiff
path: root/app/xedit/ispell.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-10-13 20:53:33 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-10-13 20:53:33 +0000
commit8e286580df3e8b7ca7e4e5486eb4cd162cf86180 (patch)
tree4bbf4994c048154103e8741c8d65270b4c4a5c38 /app/xedit/ispell.c
parent28c1518dc93984a96b373daafef1ff07c88d62fb (diff)
xedit 1.1.1
Diffstat (limited to 'app/xedit/ispell.c')
-rw-r--r--app/xedit/ispell.c314
1 files changed, 168 insertions, 146 deletions
diff --git a/app/xedit/ispell.c b/app/xedit/ispell.c
index 9a554d617..842927c2e 100644
--- a/app/xedit/ispell.c
+++ b/app/xedit/ispell.c
@@ -27,15 +27,17 @@
* Author: Paulo César Pereira de Andrade
*/
-/* $XdotOrg: app/xedit/ispell.c,v 1.7 2005/04/04 10:17:07 eich Exp $ */
+/* $XdotOrg: xc/programs/xedit/ispell.c,v 1.6 2004/12/04 00:43:13 kuhn Exp $ */
/* $XFree86: xc/programs/xedit/ispell.c,v 1.19 2002/10/19 20:04:20 herrb Exp $ */
#include "xedit.h"
+#include "util.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
+#include <locale.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -133,17 +135,19 @@ struct _ispell {
struct _ispell_format *format_info;
};
-typedef struct _ReplaceList {
- char *word;
- char *replace;
- struct _ReplaceList *next;
-} ReplaceList;
+typedef struct _ReplaceEntry ReplaceEntry;
+struct _ReplaceEntry {
+ hash_key *word;
+ ReplaceEntry*next;
+ char *replace;
+};
-typedef struct _IgnoreList {
- char *word;
- int add;
- struct _IgnoreList *next;
-} IgnoreList;
+typedef struct _IgnoreEntry IgnoreEntry;
+struct _IgnoreEntry {
+ hash_key *word;
+ IgnoreEntry *next;
+ int add;
+};
/*
* Prototypes
@@ -169,6 +173,7 @@ static void IspellSetSensitive(Bool);
static void IspellSetStatus(char*);
static void IspellSetTerseMode(Bool);
static Bool IspellStartProcess(void);
+static Bool IspellCheckProcess(void);
static Bool IspellEndProcess(Bool, Bool);
static void LookIspell(Widget, XtPointer, XtPointer);
static void PopdownIspell(Widget, XtPointer, XtPointer);
@@ -194,8 +199,8 @@ static struct _ispell ispell;
#define RSTRTBLSZ 23
#define ISTRTBLSZ 71
-static ReplaceList *replace_list[RSTRTBLSZ];
-static IgnoreList *ignore_list[ISTRTBLSZ];
+static hash_table *replace_hash;
+static hash_table *ignore_hash;
#ifndef XtCStatus
#define XtCStatus "Status"
@@ -441,71 +446,59 @@ IspellCheckUndo(void)
static char *
IspellReplacedWord(char *word, char *replace)
{
- ReplaceList *list;
- int ii = 0;
- char *pp = word;
-
- while (*pp)
- ii = (ii << 1) ^ *pp++;
- if (ii < 0)
- ii = -ii;
- ii %= RSTRTBLSZ;
- for (list = replace_list[ii]; list; list = list->next)
- if (strcmp(list->word, word) == 0) {
- if (replace) {
- XtFree(list->replace);
- list->replace = XtNewString(replace);
- }
- return (list->replace);
- }
-
- if (!replace)
- return (NULL);
+ int word_len;
+ hash_key *word_key;
+ ReplaceEntry *entry;
+
+ word_len = strlen(word);
+ entry = (ReplaceEntry *)hash_check(replace_hash, word, word_len);
+ if (entry == NULL) {
+ word_key = XtNew(hash_key);
+ word_key->value = XtNewString(word);
+ word_key->length = word_len;
+ entry = XtNew(ReplaceEntry);
+ entry->word = word_key;
+ entry->replace = NULL;
+ entry->next = NULL;
+ hash_put(replace_hash, (hash_entry *)entry);
+ }
- list = XtNew(ReplaceList);
- list->word = XtNewString(word);
- list->replace = XtNewString(replace);
- list->next = replace_list[ii];
- replace_list[ii] = list;
+ if (replace) {
+ XtFree(entry->replace);
+ entry->replace = XtNewString(replace);
+ }
- return (list->replace);
+ return (entry->replace);
}
static Bool
IspellDoIgnoredWord(char *word, int cmd, int add)
{
- IgnoreList *list, *prev;
- int ii = 0;
- char *pp = word;
-
- while (*pp)
- ii = (ii << 1) ^ *pp++;
- if (ii < 0)
- ii = -ii;
- ii %= ISTRTBLSZ;
- for (prev = list = ignore_list[ii]; list; prev = list, list = list->next)
- if (strcmp(list->word, word) == 0) {
- if (cmd == REMOVE) {
- XtFree(list->word);
- prev->next = list->next;
- XtFree((char*)list);
- if (prev == list)
- ignore_list[ii] = NULL;
- return (True);
- }
- return (cmd == CHECK);
- }
+ int word_len;
+ hash_key *word_key;
+ IgnoreEntry *entry;
+
+ word_len = strlen(word);
+ entry = (IgnoreEntry *)hash_check(ignore_hash, word, word_len);
+ if (entry == NULL) {
+ if (cmd != ADD)
+ return (False);
- if (cmd != ADD)
- return (False);
+ word_key = XtNew(hash_key);
+ word_key->value = XtNewString(word);
+ word_key->length = word_len;
+ entry = XtNew(IgnoreEntry);
+ entry->word = word_key;
+ entry->add = add;
+ entry->next = NULL;
+ hash_put(ignore_hash, (hash_entry *)entry);
- list = XtNew(IgnoreList);
- list->word = XtNewString(word);
- list->add = add;
- list->next = ignore_list[ii];
- ignore_list[ii] = list;
+ return (True);
+ }
+ else if (cmd == REMOVE)
+ hash_rem(ignore_hash, (hash_entry *)entry);
- return (True);
+ return (cmd == CHECK);
}
static Bool
@@ -938,7 +931,10 @@ IspellSend(void)
return (-1);
}
for (i = 0; i < block.length; i++) {
- wctomb(mb, ((wchar_t*)block.ptr)[i]);
+ if (international)
+ wctomb(mb, ((wchar_t*)block.ptr)[i]);
+ else
+ mb[0] = block.ptr[i];
if (amplen) {
if (amplen + 2 >= sizeof(ampbuf)) {
if (!ispell.terse_mode)
@@ -1036,7 +1032,10 @@ IspellSend(void)
return (-1);
}
for (i = 0; i < block.length; i++) {
- wctomb(mb, ((wchar_t*)block.ptr)[i]);
+ if (international)
+ wctomb(mb, ((wchar_t*)block.ptr)[i]);
+ else
+ mb[0] = block.ptr[i];
if (amplen) {
if (amplen + 2 >= sizeof(ampbuf)) {
if (!ispell.terse_mode)
@@ -1322,14 +1321,26 @@ IspellStartProcess(void)
{
if (!ispell.pid) {
int len;
- char *command;
+ char format[32];
+ static char *command;
ispell.source = XawTextGetSource(ispell.ascii);
- len = strlen(ispell.cmd) + strlen(ispell.dictionary) +
- strlen(ispell.wchars) + 16;
+ if (command)
+ XtFree(command);
+
+ strcpy(format, "%s -a");
+ len = strlen(ispell.cmd) + 4;
+ if (ispell.dictionary && *ispell.dictionary) {
+ len += strlen(ispell.dictionary) + 6;
+ strcat(format, " -d '%s'");
+ if (ispell.wchars && *ispell.wchars) {
+ len += strlen(ispell.wchars + 6);
+ strcat(format, " -w '%s'");
+ }
+ }
command = XtMalloc(len);
- XmuSnprintf(command, len, "%s -a -d '%s' -w '%s'",
+ XmuSnprintf(command, len, format,
ispell.cmd, ispell.dictionary, ispell.wchars);
pipe(ispell.ifd);
@@ -1343,7 +1354,9 @@ IspellStartProcess(void)
close(ispell.ofd[1]);
close(ispell.ifd[0]);
close(ispell.ifd[1]);
- execl("/bin/sh", "sh", "-c", command, (void *)NULL);
+ if (!international)
+ setlocale(LC_ALL, "ISO-8859-1");
+ execl("/bin/sh", "sh", "-c", command, NULL);
exit(-127);
}
else if (ispell.pid < 0) {
@@ -1373,44 +1386,48 @@ PopdownIspell(Widget w, XtPointer client_data, XtPointer call_data)
}
static Bool
+IspellCheckProcess(void)
+{
+ int status;
+
+ if (ispell.pid) {
+ waitpid(ispell.pid, &status, WNOHANG);
+ if (WIFEXITED(status)) {
+ ispell.pid = 0;
+ }
+ else
+ return (True);
+ }
+
+ return (False);
+}
+
+static Bool
IspellEndProcess(Bool killit, Bool killundo)
{
ispell.source = NULL;
if (ispell.pid) {
- IgnoreList *il, *pil, *nil;
- int i;
+ IgnoreEntry *ientry;
+ ReplaceEntry *rentry;
/* insert added words in private dictionary */
- for (i = 0; i < ISTRTBLSZ; i++) {
- pil = il = ignore_list[i];
- while (il) {
- if (il->add) {
- nil = il->next;
- if (il == pil)
- ignore_list[i] = nil;
- else
- pil->next = nil;
- if (il->add == UNCAP)
- write(ispell.ofd[1], "&", 1);
- else
- write(ispell.ofd[1], "*", 1);
- write(ispell.ofd[1], il->word, strlen(il->word));
- write(ispell.ofd[1], "\n", 1);
- XtFree(il->word);
- XtFree((char*)il);
- il = nil;
- }
+ for (ientry = (IgnoreEntry *)hash_iter_first(ignore_hash);
+ ientry;
+ ientry = (IgnoreEntry *)hash_iter_next(ignore_hash)) {
+ if (ientry->add) {
+ if (ientry->add == UNCAP)
+ write(ispell.ofd[1], "&", 1);
else
- il = il->next;
- pil = il;
+ write(ispell.ofd[1], "*", 1);
+ write(ispell.ofd[1], ientry->word->value, ientry->word->length);
+ write(ispell.ofd[1], "\n", 1);
}
}
write(ispell.ofd[1], "#\n", 2); /* save dictionary */
+ hash_clr(ignore_hash);
if (killit) {
- ReplaceList *rl, *prl;
-
XtRemoveInput(ispell.id);
close(ispell.ofd[0]);
@@ -1430,27 +1447,13 @@ IspellEndProcess(Bool killit, Bool killundo)
XtFree(ispell.buf);
ispell.buf = NULL;
- for (i = 0; i < RSTRTBLSZ; i++) {
- prl = rl = replace_list[i];
- while (prl) {
- rl = rl->next;
- XtFree(prl->word);
- XtFree(prl->replace);
- XtFree((char*)prl);
- prl = rl;
- }
- replace_list[i] = NULL;
- }
- for (i = 0; i < ISTRTBLSZ; i++) {
- pil = il = ignore_list[i];
- while (pil) {
- il = il->next;
- XtFree(pil->word);
- XtFree((char*)pil);
- pil = il;
- }
- ignore_list[i] = NULL;
+ /* forget about replace matches */
+ for (rentry = (ReplaceEntry *)hash_iter_first(replace_hash);
+ rentry;
+ rentry = (ReplaceEntry *)hash_iter_next(replace_hash)) {
+ XtFree(rentry->replace);
}
+ hash_clr(replace_hash);
}
if (killundo)
@@ -1560,12 +1563,18 @@ ReplaceIspell(Widget w, XtPointer client_data, XtPointer call_data)
char mb[sizeof(wchar_t)];
if (XawTextSourceRead(ispell.source, pos - 1, &check, 1) > 0) {
- wctomb(mb, *(wchar_t*)check.ptr);
+ if (international)
+ wctomb(mb, *(wchar_t*)check.ptr);
+ else
+ mb[0] = check.ptr[0];
do_replace = !isalpha(*mb) && *mb && !strchr(ispell.wchars, *mb);
}
if (do_replace &&
XawTextSourceRead(ispell.source, pos + search.length, &check, 1) > 0) {
- wctomb(mb, *(wchar_t*)check.ptr);
+ if (international)
+ wctomb(mb, *(wchar_t*)check.ptr);
+ else
+ mb[0] = check.ptr[0];
do_replace = !isalpha(*mb) && *mb && !strchr(ispell.wchars, *mb);
}
if (do_replace) {
@@ -1957,8 +1966,10 @@ ChangeDictionaryIspell(Widget w, XtPointer client_data, XtPointer call_data)
return;
if (!ispell.lock) {
- Feep();
- return;
+ if (IspellCheckProcess()) {
+ Feep();
+ return;
+ }
}
for (tmp = ispell.dict_info; tmp; tmp = tmp->next)
@@ -2024,6 +2035,7 @@ InitIspell(void)
Atom delete_window;
char *str, *list;
XtResource dict_res;
+ ispell_dict *dict, *prev_dict;
int i;
static XtResource text_res[] = {
{"skipLines", "Skip", XtRString, sizeof(char*),
@@ -2033,6 +2045,9 @@ InitIspell(void)
if (ispell.shell)
return (False);
+ replace_hash = hash_new(RSTRTBLSZ, NULL);
+ ignore_hash = hash_new(ISTRTBLSZ, NULL);
+
ispell.shell = XtCreatePopupShell("ispell", transientShellWidgetClass,
topwindow, NULL, 0);
@@ -2169,36 +2184,43 @@ InitIspell(void)
dict_res.default_addr = "";
list = XtNewString(ispell.dict_list);
- for (str = strtok(list, " \t,"); str; str = strtok(NULL, " \t,")) {
- ispell_dict *dic = XtNew(ispell_dict);
- dic->sme = XtCreateManagedWidget(str, smeBSBObjectClass,
- ispell.dictMenu, NULL, 0);
- XtGetApplicationResources(dic->sme, (XtPointer)dic, &dict_res,
+ /* Create first empty entry */
+ dict = XtNew(ispell_dict);
+ dict->sme = XtCreateManagedWidget("", smeBSBObjectClass,
+ ispell.dictMenu, NULL, 0);
+ dict->wchars = "";
+ XtAddCallback(dict->sme, XtNcallback, ChangeDictionaryIspell,
+ (XtPointer)dict);
+ ispell.dict_info = prev_dict = dict;
+
+ for (str = strtok(list, " \t,"); str; str = strtok(NULL, " \t,")) {
+ dict = XtNew(ispell_dict);
+ dict->sme = XtCreateManagedWidget(str, smeBSBObjectClass,
+ ispell.dictMenu, NULL, 0);
+ XtGetApplicationResources(dict->sme, (XtPointer)dict, &dict_res,
1, NULL, 0);
- XtAddCallback(dic->sme, XtNcallback, ChangeDictionaryIspell,
- (XtPointer)dic);
- dic->next = NULL;
- if (!ispell.dict_info)
- ispell.dict_info = dic;
- else {
- ispell_dict *tmp = ispell.dict_info;
-
- for (; tmp->next; tmp = tmp->next)
- ;
- tmp->next = dic;
- }
- if (strcmp(str, ispell.dictionary) == 0) {
+ XtAddCallback(dict->sme, XtNcallback, ChangeDictionaryIspell,
+ (XtPointer)dict);
+ prev_dict->next = dict;
+ prev_dict = dict;
+ dict->next = NULL;
+ }
+ XtFree(list);
+
+ for (dict = ispell.dict_info; dict; dict = dict->next) {
+ if (strcmp(XtName(dict->sme), ispell.dictionary) == 0) {
Arg args[1];
XtSetArg(args[0], XtNleftBitmap, flist.pixmap);
- XtSetValues(dic->sme, args, 1);
- XtSetArg(args[0], XtNlabel, str);
+ XtSetValues(dict->sme, args, 1);
+ XtSetArg(args[0], XtNlabel, XtName(dict->sme));
XtSetValues(ispell.dict, args, 1);
- ispell.wchars = dic->wchars;
+ ispell.wchars = dict->wchars;
+ break;
}
}
- XtFree(list);
+
delete_window = XInternAtom(XtDisplay(ispell.shell), "WM_DELETE_WINDOW", False);
XSetWMProtocols(XtDisplay(ispell.shell), XtWindow(ispell.shell), &delete_window, 1);