Synopsis: Sample code for interfacing to Ispell. June 97 Date: Wed, 18 Jun 1997 21:35:41 +0200 (MET DST) From: "Erwin S. Andreasen" cc: Merc List Subject: Re: Comparing names to dictionary On Wed, 18 Jun 1997, Merlin Medici wrote: > I was wondering if anybody is willing to share the code to check for new > character names being in the dictionary, or if you would steer me in the > right direction for me to code it. Here's what AR uses. Check also man ispell to understand options! do_ispell is a command for imms/players to use. get_ispell_line can be called on a word to check if it's in the dictionary; See man ispell and do_ispell how to parse the output. Post the code once you've intergrated this into string_edit so that you can spellcheck via the string editor like ispell-interactive-mode :) Macros defined: MSL = MAX_STRING_LENGTH /* This is for making MACROS into strings, can't juse use #MACRO_NAME */ #define Stringify(x) Str(x) #define Str(x) #x "include.h" contains various standard includes, merc.h and some more. /* Interface to iSpell * Copyright (c) 1997 Erwin S. Andreasen * */ #include #include #include #include #include "include.h" #include static FILE *ispell_out; static ispell_pid=-1; static int to[2], from[2]; #define ISPELL_BUF_SIZE 1024 void ispell_init() { char ignore_buf[1024]; if (IS_SET(sysdata.options, OPT_NO_ISPELL)) { ispell_pid=-1; return; } pipe(to); pipe(from); ispell_pid = fork(); if (ispell_pid < 0) bugf ("ispell_init: fork: %s", strerror(errno)); else if (ispell_pid == 0) /* child */ { int i; dup2 (to[0], 0); /* this is where we read commands from - make it stdin */ close (to[0]); close (to[1]); dup2 (from[1], 1); /* this is where we write stuff to */ close (from[0]); close (from[1]); /* Close all the other files */ for (i = 2; i < 255; i++) close (i); execlp ("ispell", "ispell", "-a", "-p" ISPELL_DICTIONARY, (char*) NULL); exit(1); } else /* ok !*/ { close (to[0]); close (from[1]); ispell_out = fdopen (to[1], "w"); setbuf (ispell_out, NULL); #if !defined( sun ) /* that ispell on sun gives no (c) msg */ read (from[0], ignore_buf, 1024); #endif } } void ispell_done() { if (ispell_pid != -1) { fprintf (ispell_out, "#\n"); fclose (ispell_out); close (from[0]); waitpid(ispell_pid, NULL, 0); ispell_pid = -1; } } char* get_ispell_line (char *word) { static char buf[ISPELL_BUF_SIZE]; char buf2[MSL]; int len; if (ispell_pid == -1) return NULL; if (word) { fprintf (ispell_out, "^%s\n", word); fflush (ispell_out); } len = read (from[0], buf2, ISPELL_BUF_SIZE); buf2[len] = NUL; /* Read up to max 1024 characters here */ if (sscanf (buf2, "%" Stringify(ISPELL_BUF_SIZE) "[^\n]\n\n", buf) != 1) return NULL; return buf; } void do_ispell (CHAR_DATA *ch, char *argument, void *target) { char *pc; if (ispell_pid <= 0) { send_to_char ("ispell is not running.\n\r",ch); return; } if (!argument[0] || strchr (argument, ' ')) { send_to_char ("Invalid input.\n\r",ch); return; } if (argument[0] == '+') { for (pc = argument+1;*pc; pc++) if (!isalpha(*pc)) { cprintf (ch, "'%c' is not a letter.\n\r", *pc); return; } fprintf (ispell_out, "*%s\n", argument+1); fflush (ispell_out); return; /* we assume everything is OK.. better be so! */ } pc = get_ispell_line(argument); if (!pc) { send_to_char ("ispell: failed.\n\r",ch); return; } switch (pc[0]) { case '*': case '+': /* root */ case '-': /* compound */ send_to_char ("Correct.\n\r",ch); break; case '&': /* miss */ wprintf(ch, "Not found. Possible words: %s\n\r", strchr(pc, ':')+1); break; case '?': /* guess */ wprintf(ch, "Not found. Possible words: %s\n\r", strchr(pc, ':')+1); break; case '#': /* none */ send_to_char ("Unable to find anything that matches.\n\r",ch); break; default: cprintf (ch, "Weird output from ispell: %s\n\r", pc); } } ============================================================================== Erwin Andreasen Herlev, Denmark UNIX System Programmer (not speaking for) DDE ==============================================================================