On Mon, 7 Aug 2000, Juergen Vigna wrote:

> This said I'll wait for your move and will give you any information
> I can give you (I really am not so familiar with signals) and will
> do inquiries on the other developers for knowledge, also I will test
> the stuff you send me and see if it works.

Well as soon as someone tells me how to properly handle the signals I
will modify my original patch (attached) I sent Lyx-Devel to use take
advantage of the new features in Pspell .11.  The original patch will only
use PSPELL if USE_PSPELL is defined.

--- 
Kevin Atkinson
kevina at users sourceforge net
http://metalab.unc.edu/kevina/

--- spellchecker.C.orig Tue Jan 25 12:21:47 2000
+++ spellchecker.C      Mon Apr 10 20:16:33 2000
@@ -49,6 +49,14 @@
 #include "debug.h"
 #include "support/lstrings.h"
 
+//#define USE_PSPELL 1
+
+#ifdef USE_PSPELL
+
+#include <pspell/pspell.h>
+
+#endif
+
 extern LyXRC *lyxrc;
 extern BufferView *current_view;
 
@@ -64,6 +72,8 @@
 
 static bool RunSpellChecker(string const &);
 
+#ifndef USE_PSPELL
+
 static FILE *in, *out;  /* streams to communicate with ispell */
 pid_t isp_pid = -1; // pid for the `ispell' process. Also used (RO) in
                     // lyx_cb.C
@@ -74,6 +84,12 @@
 
 static int isp_fd;
 
+#else
+
+PspellManager * sc;
+
+#endif
+
 static FD_form_spell_options *fd_form_spell_options = 0;
 FD_form_spell_check *fd_form_spell_check = 0;
 
@@ -83,22 +99,57 @@
 //extern void sigchldchecker(int sig);
 extern void sigchldchecker(pid_t pid, int *status);
 
+#ifndef USE_PSPELL
+
 struct isp_result {
        int flag;
-       int count;
-       string str;
-       char **misses;
+       char * str;
+       char * b;
+       char * e;
+       const char * next_miss();
        isp_result() {
                flag = ISP_UNKNOWN;
-               count = 0;
-               misses = static_cast<char**>(0);
+               str = 0;
        }
        ~isp_result() {
-               if (misses) // DEL LINE
-                       delete[] misses;
+               if (str)
+                       delete[] str;
        }
 };
 
+const char * isp_result::next_miss() {
+       if (str == 0 || *(e+1) == '\0') return 0;
+       b = e + 2;
+       e = strpbrk(b, ",\n");
+       *e = '\0';
+       return b;
+}
+
+#else
+
+struct isp_result {
+       int flag;
+       PspellStringEmulation * els;
+       
+       const char * next_miss();
+       isp_result() {
+               flag = ISP_UNKNOWN;
+               els = 0;
+       }
+       ~isp_result() {
+               delete_pspell_string_emulation(els);
+       }
+};
+
+const char * isp_result::next_miss() 
+{
+       return pspell_string_emulation_next(els);
+}
+
+#endif
+
+const char * spell_error;
+
 
 /***** Spellchecker options *****/
 
@@ -219,13 +270,14 @@
        }
 }
 
+#ifndef USE_PSPELL
 
 /***** Spellchecker *****/
 
 // Could also use a clean up. (Asger Alstrup)
 
 static
-void create_ispell_pipe(string const & lang)
+void init_spell_checker(string const & lang)
 {
        static char o_buf[BUFSIZ];  // jc: it could be smaller
        int pipein[2], pipeout[2];
@@ -236,19 +288,19 @@
 
        if(pipe(pipein) == -1 || pipe(pipeout) == -1) {
                lyxerr << "LyX: Can't create pipe for spellchecker!" << endl;
-               return;
+               goto END;
        }
 
        if ((out = fdopen(pipein[1], "w")) == 0) {
                lyxerr << "LyX: Can't create stream for pipe for spellchecker!"
                       << endl;
-               return;
+               goto END;
        }
 
        if ((in = fdopen(pipeout[0], "r")) == 0) {
                lyxerr <<"LyX: Can't create stream for pipe for spellchecker!"
                       << endl;
-               return;
+               goto END;
        }
 
        setvbuf(out, o_buf, _IOLBF, BUFSIZ);
@@ -260,9 +312,9 @@
        if(isp_pid == -1) {
                lyxerr << "LyX: Can't create child process for spellchecker!"
                       << endl;
-               return;
+               goto END;
        }
-
+       
        if(isp_pid == 0) {        
                /* child process */
                dup2(pipein[0], STDIN_FILENO);
@@ -348,7 +400,7 @@
                lyxerr << "LyX: Failed to start ispell!" << endl;
                _exit(0);
        }
-
+       {
        /* Parent process: Read ispells identification message */
        // Hmm...what are we using this id msg for? Nothing? (Lgb)
        // Actually I used it to tell if it's truly Ispell or if it's
@@ -381,6 +433,9 @@
                  actual_spell_checker = ASC_ASPELL;
                else
                  actual_spell_checker = ASC_ISPELL;
+
+               fputs("!\n", out); // Set terse mode (silently accept correct words)
+
                
        } else if (retval == 0) {
                // timeout. Give nice message to user.
@@ -394,12 +449,35 @@
                // Select returned error
                lyxerr << "Select on ispell returned error, what now?" << endl;
        }
+       }
+ END:
+       if (isp_pid == -1) {
+               spell_error = 
+                       "\n\n"
+                       "The ispell-process has died for some reason. *One* possible 
+reason\n"
+                       "could be that you do not have a dictionary file\n"
+                       "for the language of this document installed.\n"
+                       "Check /usr/lib/ispell or set another\n"
+                       "dictionary in the Spellchecker Options menu.";
+       } else {
+               spell_error = 0;
+       }
+}
+
+static
+bool sc_still_alive() {
+       return isp_pid != -1;
 }
 
+static
+void sc_clean_up_after_error() 
+{
+       fclose(out);
+}
 
 // Send word to ispell and get reply
 static
-isp_result *ispell_check_word(char *word)
+isp_result * sc_check_word(char *word)
 {
        //Please rewrite to use string.
        isp_result *result;
@@ -437,25 +515,10 @@
        case '&': // Not found, but we have near misses
        {
                result->flag = ISP_MISSED;
-               result->str = buf;
-               // nb is leaked! where should it be freed? I have to
-               // admit I do not understand the intent of the code :(
-               // (JMarc) 
-               char * nb = new char[result->str.length() + 1];
-               result->str.copy(nb, result->str.length());
-               nb[result->str.length()]= '\0';
-               p = strpbrk(nb+2, " ");
-               sscanf(p, "%d", &count); // Get near misses count
-               result->count = count;
-               if (count) result->misses = new char*[count];
-               p = strpbrk(nb, ":");
-               p += 2;
-               for (i = 0; i < count; ++i) {
-                       result->misses[i] = p;
-                       p = strpbrk(p, ",\n");
-                       *p = 0;
-                       p += 2;
-               }
+               char * p = strpbrk(buf, ":");
+               result->str = new char[strlen(p) + 1];
+               result->e   = result->str;
+               strcpy(result->str, p);
                break;
        }
        default: // This shouldn't happend, but you know Murphy
@@ -471,7 +534,7 @@
 
 
 static
-inline void ispell_terminate()
+inline void close_spell_checker()
 {
         // Note: If you decide to optimize this out when it is not 
         // needed please note that when Aspell is used this command 
@@ -486,14 +549,7 @@
 
 
 static
-inline void ispell_terse_mode()
-{
-       fputs("!\n", out); // Set terse mode (silently accept correct words)
-}
-
-
-static
-inline void ispell_insert_word(char const *word)
+inline void sc_insert_word(char const *word)
 {
        fputc('*', out); // Insert word in personal dictionary
        fputs(word, out);
@@ -502,7 +558,7 @@
 
 
 static
-inline void ispell_accept_word(char const *word) 
+inline void sc_accept_word(char const *word) 
 {
        fputc('@', out); // Accept in this session
        fputs(word, out);
@@ -510,7 +566,7 @@
 }
 
 static
-inline void ispell_store_replacement(char const *mis, string const & cor) {
+inline void sc_store_replacement(char const *mis, string const & cor) {
         if(actual_spell_checker == ASC_ASPELL) {
                 fputs("$$ra ", out);
                 fputs(mis, out);
@@ -520,6 +576,90 @@
         }
 }
 
+#else
+
+PspellCanHaveError * spell_error_object;
+
+static
+void init_spell_checker(string const & lang)
+{
+       PspellConfig * config = new_pspell_config();
+       spell_error_object = new_pspell_manager(config);
+       if (pspell_error_number(spell_error_object) != 0) {
+               spell_error = pspell_error_message(spell_error_object);
+       } else {
+               spell_error = 0;
+               sc = to_pspell_manager(spell_error_object);
+               spell_error_object = 0;
+       }
+}
+
+static 
+bool sc_still_alive() {
+       return true;
+}
+
+static
+void sc_clean_up_after_error() 
+{
+       delete_pspell_can_have_error(spell_error_object);
+}
+
+
+
+// Send word to ispell and get reply
+static
+isp_result * sc_check_word(char *word)
+{
+       isp_result * result = new isp_result;
+       int word_ok = pspell_manager_check(sc, word);
+       assert(word_ok != -1);
+
+       if (word_ok) {
+
+               result->flag = ISP_OK;
+
+       } else {
+
+               const PspellWordList * sugs = pspell_manager_suggest(sc, word);
+               assert(sugs != 0);
+               result->els = pspell_word_list_elements(sugs);
+               if (pspell_word_list_empty(sugs)) 
+                       result->flag = ISP_UNKNOWN;
+               else 
+                       result->flag = ISP_MISSED;
+               
+       }
+       return result;
+}
+
+
+static
+inline void close_spell_checker()
+{
+       pspell_manager_save_all_word_lists(sc);
+}
+
+
+static
+inline void sc_insert_word(char const *word)
+{
+       pspell_manager_add_to_personal(sc, word);
+}
+
+
+static
+inline void sc_accept_word(char const *word) 
+{
+       pspell_manager_add_to_personal(sc, word);
+}
+
+static
+inline void sc_store_replacement(char const *mis, string const & cor) {
+       pspell_manager_store_replacement(sc, mis, cor.c_str());
+}
+
+#endif
 
 void ShowSpellChecker()
 {
@@ -652,23 +792,14 @@
        newval = 0.0;
    
        /* create ispell process */
-       create_ispell_pipe(tmp);
+       init_spell_checker(tmp);
 
-       if (isp_pid == -1) {
-               fl_show_message(
-                       _("\n\n"
-                         "The ispell-process has died for some reason. *One* possible 
reason\n"
-                         "could be that you do not have a dictionary file\n"
-                         "for the language of this document installed.\n"
-                         "Check /usr/lib/ispell or set another\n"
-                         "dictionary in the Spellchecker Options menu."), "", "");
-               fclose(out);
+       if (spell_error != 0) {
+               fl_show_message(_(spell_error), "", "");
+               sc_clean_up_after_error();
                return true;
        }
 
-       // Put ispell in terse mode to improve speed
-       ispell_terse_mode();
-
        while (true) {
                word = current_view->nextWord(newval);
                if (word == 0) break;
@@ -681,8 +812,8 @@
                        fl_set_slider_value(fd_form_spell_check->slider, oldval);
                }
 
-               result = ispell_check_word(word);
-               if (isp_pid == -1) {
+               result = sc_check_word(word);
+               if (!sc_still_alive()) {
                        delete[] word;
                        break;
                }
@@ -691,13 +822,13 @@
                if (obj == fd_form_spell_check->stop) {
                        delete result;
                        delete[] word;
-                       ispell_terminate();
+                       close_spell_checker();
                        return true;
                }
                if (obj == fd_form_spell_check->done) {
                        delete result;
                        delete[] word;
-                       ispell_terminate(); 
+                       close_spell_checker(); 
                        return false;
                }
     
@@ -708,19 +839,20 @@
                        fl_set_object_label(fd_form_spell_check->text, word);
                        fl_set_input(fd_form_spell_check->input, word);
                        fl_clear_browser(fd_form_spell_check->browser);
-                       for (i = 0; i < result->count; ++i) {
-                               fl_add_browser_line(fd_form_spell_check->browser, 
result->misses[i]);
+                       const char * w;
+                       while ((w = result->next_miss()) != 0) {
+                               fl_add_browser_line(fd_form_spell_check->browser, w);
                        }
 
                        clickline = -1;
                        while (true) {
                                obj = fl_do_forms();
                                if (obj == fd_form_spell_check->insert) {
-                                       ispell_insert_word(word);
+                                       sc_insert_word(word);
                                        break;
                                }
                                if (obj == fd_form_spell_check->accept) {
-                                       ispell_accept_word(word);
+                                       sc_accept_word(word);
                                        break;
                                }
                                if (obj == fd_form_spell_check->ignore) {
@@ -728,7 +860,7 @@
                                }
                                if (obj == fd_form_spell_check->replace || 
                                    obj == fd_form_spell_check->input) {
-                                       ispell_store_replacement(word, 
fl_get_input(fd_form_spell_check->input));
+                                       sc_store_replacement(word, 
+fl_get_input(fd_form_spell_check->input));
                                        
current_view->replaceWord(fl_get_input(fd_form_spell_check->input));
                                        break;
                                }
@@ -737,7 +869,7 @@
                                        // sent to lyx@via by Mark Burton 
<[EMAIL PROTECTED]>
                                        if (clickline == 
                                            
fl_get_browser(fd_form_spell_check->browser)) {
-                                               ispell_store_replacement(word, 
fl_get_input(fd_form_spell_check->input));
+                                               sc_store_replacement(word, 
+fl_get_input(fd_form_spell_check->input));
                                                
current_view->replaceWord(fl_get_input(fd_form_spell_check->input));
                                                break;
                                        }
@@ -750,14 +882,14 @@
                                if (obj == fd_form_spell_check->stop) {
                                        delete result;
                                        delete[] word;
-                                       ispell_terminate();
+                                       close_spell_checker();
                                        return true;
                                }
            
                                if (obj == fd_form_spell_check->done) {
                                        delete result;
                                        delete[] word;
-                                       ispell_terminate();
+                                       close_spell_checker();
                                        return false;
                                }
                        }
@@ -767,8 +899,8 @@
                }
        }
    
-       if(isp_pid!= -1) {
-               ispell_terminate();
+       if(sc_still_alive()) {
+               close_spell_checker();
                string word_msg;
                word_msg += tostr(word_count);
                if (word_count != 1) {
@@ -780,14 +912,16 @@
                                word_msg.c_str());
                return false;
        } else {
-               fl_show_message(_("The ispell-process has died for some reason.\n"
+               fl_show_message(_("The spell checker has died for some reason.\n"
                                "Maybe it has been killed."), "", "");
-               fclose(out);
+               sc_clean_up_after_error();
                return true;
        }
 }
 
 
+#ifndef USE_PSPELL
+
 //void sigchldhandler(int sig)
 void sigchldhandler(pid_t pid, int *status)
 { 
@@ -804,3 +938,12 @@
        //sigchldchecker(sig);
        sigchldchecker(pid, status);
 }
+
+#else
+
+void sigchldhandler(pid_t pid, int *status)
+{ 
+       // do nothing
+}
+
+#endif

Reply via email to