#if TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif
//void sigchldhandler(int sig); void sigchldhandler(pid_t pid, int *status);
//extern void sigchldchecker(int sig); externvoid sigchldchecker(pid_t pid, int *status);
struct isp_result { int flag; int count;
LString string; char **misses;
isp_result() {
flag = ISP_UNKNOWN;
count = 0;
misses = (char**)NULL;
}
~isp_result() { if (misses) delete[] misses;
}
};
/***** Spellchecker options *****/
// Rewritten to use ordinary LyX xforms loop and OK, Apply and Cancel set, // now also LString. Amazing, eh? (Asger)
// Set (sane) values in form to current spellchecker options void SpellOptionsUpdate()
{ // Alternate language if (lyxrc->isp_alt_lang.empty()) {
lyxrc->isp_use_alt_lang = false;
} else {
fl_set_input(fd_form_spell_options->altlang_input,
lyxrc->isp_alt_lang.c_str());
} if (lyxrc->isp_use_alt_lang) {
fl_set_button(fd_form_spell_options->buflang,0);
fl_set_button(fd_form_spell_options->altlang,1);
} else {
fl_set_button(fd_form_spell_options->buflang,1);
fl_set_button(fd_form_spell_options->altlang,0);
}
// Personal dictionary if (lyxrc->isp_pers_dict.empty()) {
lyxrc->isp_use_pers_dict = false;
} else {
fl_set_input(fd_form_spell_options->perdict_input,
lyxrc->isp_pers_dict.c_str());
}
fl_set_button(fd_form_spell_options->perdict,
lyxrc->isp_use_pers_dict ? 1:0);
// Show spellchecker options form void SpellCheckerOptions()
{ // Create form if nescessary if (fd_form_spell_options == NULL) {
fd_form_spell_options = create_form_form_spell_options(); // Make sure pressing the close box does not kill LyX. (RvdK)
fl_set_form_atclose(fd_form_spell_options->form_spell_options,
CancelCloseBoxCB, NULL);
}
// Update form to current options
SpellOptionsUpdate();
// Focus in alternate language field
fl_set_focus_object(fd_form_spell_options->form_spell_options,
fd_form_spell_options->altlang_input);
// Show form if (fd_form_spell_options->form_spell_options->visible) {
fl_raise_form(fd_form_spell_options->form_spell_options);
} else {
fl_show_form(fd_form_spell_options->form_spell_options,
FL_PLACE_MOUSE,FL_FULLBORDER,
_("Spellchecker Options"));
}
}
/***** Spellchecker *****/
// Could also use a clean up. (Asger Alstrup)
static void create_ispell_pipe(LString const & lang)
{ staticchar o_buf[BUFSIZ]; // jc: it could be smaller int pipein[2], pipeout[2]; char * argv[14]; int argc;
if (lyxrc->isp_accept_compound) // Consider run-together words as legal compounds
argv[argc++] = LString("-C").copy(); else // Report run-together words with // missing blanks as errors
argv[argc++] = LString("-B").copy();
if (lyxrc->isp_use_esc_chars) { // Specify additional characters that // can be part of a word
argv[argc++] = LString("-w").copy(); // Put the escape chars in ""s
argv[argc++] = (LString("\"") + lyxrc->isp_esc_chars +
LString("\"")).copy();
} if (lyxrc->isp_use_pers_dict) { // Specify an alternate personal dictionary
argv[argc++] = LString("-p").copy();
argv[argc++] = lyxrc->isp_pers_dict.copy();
} if (lyxrc->isp_use_input_encoding &&
current_view->currentBuffer()->params.inputenc != "default") {
argv[argc++] = LString("-T").copy(); // Input encoding
argv[argc++] = current_view->currentBuffer()->params.inputenc.copy();
}
argv[argc++] = NULL;
execvp("ispell", (char * const *) argv);
// free the memory used by LString::copy in the // setup of argv for (int i=0; i < argc -1; i++) delete[] argv[i];
fprintf(stderr, "LyX: Failed to start ispell!\n");
_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 // aspell -- (kevinatk@home.com) char buf[2048]; #ifdef WITH_WARNINGS #warning verify that this works. #endif
fd_set infds; struct timeval tv; int retval = 0;
FD_ZERO(&infds);
FD_SET(pipeout[0], &infds);
tv.tv_sec = 15; // fifteen second timeout. Probably too much, // but it can't really hurt.
tv.tv_usec = 0;
retval = select(pipeout[0]+1, &infds, 0, 0, &tv);
if (retval > 0) { // Ok, do the reading. We don't have to FD_ISSET since // there is only one fd in infds.
fgets(buf, 2048, in);
// determine if the spell checker is really Aspell if (strstr(buf, "Aspell"))
actual_spell_checker = ASC_ASPELL; else
actual_spell_checker = ASC_ISPELL;
} elseif (retval == 0) { // timeout. Give nice message to user.
fprintf(stderr, "Ispell read timed out, what now?\n"); #ifdef WITH_WARNINGS #warning Is this the correct thing to do? #endif
isp_pid = -1;
close(pipeout[0]); close(pipeout[1]);
close(pipein[0]); close(pipein[1]);
isp_fd = -1;
} else { // Select returned error
fprintf(stderr, "Select on ispell returned error, what now?\n");
}
}
// Send word to ispell and get reply static
isp_result *ispell_check_word(char *word)
{ //Please rewrite to use LString.
isp_result *result; char buf[1024], *p; int count, i;
fputs(word, out);
fputc('\n', out);
fgets(buf, 1024, in);
/* I think we have to check if ispell is still alive here because
the signal-handler could have disabled blocking on the fd */ if (isp_pid == -1) return (isp_result *) NULL;
result = new isp_result;
switch (*buf) { case'*': // Word found
result->flag = ISP_OK; break; case'+': // Word found through affix removal
result->flag = ISP_ROOT; break; case'-': // Word found through compound formation
result->flag = ISP_COMPOUNDWORD; break; case'\n': // Number or when in terse mode: no problems
result->flag = ISP_IGNORE; break; case'#': // Not found, no near misses and guesses
result->flag = ISP_UNKNOWN; break; case'?': // Not found, and no near misses, but guesses (guesses are ignored) case'&': // Not found, but we have near misses
{
result->flag = ISP_MISSED;
result->string = buf; char * nb = result->string.copy(); // This leaks.
p = strpbrk(nb+2, " ");
sscanf(p, "%d", &count); // Get near misses count
result->count = count; if (count) result->misses = newchar*[count];
p = strpbrk(nb, ":");
p +=2; for (i = 0; i<count; i++) {
result->misses[i] = p;
p = strpbrk(p, ",\n");
*p = 0;
p+=2;
} break;
} default: // This shouldn't happend, but you know Murphy
result->flag = ISP_UNKNOWN;
}
*buf = 0; if (result->flag!=ISP_IGNORE) { while (*buf!='\n') fgets(buf, 255, in); /* wait for ispell to finish */
} return result;
}
static inlinevoid ispell_terminate()
{ // Note: If you decide to optimize this out when it is not // needed please note that when Aspell is used this command // is also needed to save the replacement dictionary. // -- Kevin Atkinson (kevinatk@home.com)
void ShowSpellChecker()
{
FL_OBJECT *obj; int ret;
// Exit if we don't have a document open if (!current_view->getScreen()) return;
if (fd_form_spell_check == NULL) {
fd_form_spell_check = create_form_form_spell_check(); // Make sure pressing the close box does not kill LyX. (RvdK)
fl_set_form_atclose(fd_form_spell_check->form_spell_check, IgnoreCloseBoxCB, NULL);
}
// Show form if (fd_form_spell_check->form_spell_check->visible) {
fl_raise_form(fd_form_spell_check->form_spell_check);
} else {
fl_show_form(fd_form_spell_check->form_spell_check,
FL_PLACE_MOUSE,FL_FULLBORDER,
_("Spellchecker"));
}
fl_deactivate_object(fd_form_spell_check->slider);
oldval = 0; /* used for updating slider only when needed */
newval = 0.0;
/* create ispell process */
create_ispell_pipe(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); returntrue;
}
// Put ispell in terse mode to improve speed
ispell_terse_mode();
while (true) {
word = NextWord(newval); if (word==NULL) break;
word_count++;
// Update slider if and only if value has changed
newvalue = int(100.0*newval); if(newvalue!=oldval) {
oldval = newvalue;
fl_set_slider_value(fd_form_spell_check->slider, oldval);
}
result = ispell_check_word(word); if (isp_pid==-1) { delete[] word; break;
}
if(isp_pid!=-1) {
ispell_terminate();
LString word_msg;
word_msg += int(word_count); if (word_count != 1) {
word_msg += _(" words checked.");
} else {
word_msg += _(" word checked.");
}
fl_show_message("",_("Spellchecking completed!"),
word_msg.c_str()); returnfalse;
} else {
fl_show_message(_("The ispell-process has died for some reason.\n" "Maybe it has been killed."), "", "");
fclose(out); returntrue;
}
}
//void sigchldhandler(int sig) void sigchldhandler(pid_t pid, int *status)
{ //int status ;
if (isp_pid>0) //if (waitpid(isp_pid,&status,WNOHANG)==isp_pid) { if (pid == isp_pid) {
isp_pid=-1;
fcntl(isp_fd, F_SETFL, O_NONBLOCK); /* set the file descriptor to nonblocking so we can
continue */
} //sigchldchecker(sig);
sigchldchecker(pid, status);
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.