diff -cp -r -N ispell-3.1-orig/buildhas.c ispell-3.1/buildhas.c
*** ispell-3.1-orig/buildhas.c	Mon Jan 23 18:28:24 1995
--- ispell-3.1/buildhas.c	Sat Nov  9 13:53:36 1996
*************** int main (argc, argv)
*** 138,145 ****
--- 138,199 ----
      if (yyparse ())			/* Parse the language tables */
  	exit (1);
  
+ #ifdef MSDOS
+     /*
+     ** Use Hfile as the base to derive the Cfile and Sfile names,
+     ** since Dfile doesn't include the med/lrg/xlg part in its
+     ** basename.  Using Dfile could cause a collision with Cfile
+     ** from another dictionary, which in turn will fail us due to
+     ** overflow of the hash table in `filltable'.
+     */
+     strncpy (Cfile, Hfile, strlen (Hfile) - strlen (HASHSUFFIX));
+     strcpy (Sfile, Cfile);
+     strcat (Cfile, COUNTSUFFIX);
+     strcat (Sfile, STATSUFFIX);
+     /*
+     ** MS-DOS doesn't allow more than one dot in the filename part.
+     ** If we have more than that, convert all the dots but the last into
+     ** underscores.  The OS will truncate excess characters beyond 8+3.
+     */
+ 	{
+ 	char *forwslash, *backslash, *base, *last_dot, *p;
+ 
+ 	/*
+ 	** Find the basename of [CS]file.  It begins after the
+ 	** rightmost slash, or after a colon of the drive letter,
+ 	** if there are no slashes in the pathname.
+ 	*/
+ 	base = Cfile[1] == ':' ? Cfile + 1 : Cfile;
+ 	/*
+ 	** Some environments might use mixed forward- and backslashes.
+ 	** We need the rightmost one of either gender.
+ 	*/
+ 	forwslash = strrchr (Cfile, '/');
+ 	backslash = strrchr (Cfile, '\\');
+ 	if (forwslash)
+ 	    base = forwslash;
+ 	if (backslash && backslash > base)
+ 	    base = backslash;
+ 	if (base != Cfile)
+ 	    base++;
+ 
+ 	/* Assume that COUNTSUFFIX and STATSUFFIX begin with a dot.  */
+ 	last_dot = Cfile + strlen (Cfile) - strlen (COUNTSUFFIX);
+ 	for (p = base; p < last_dot; p++)
+ 	    if (*p == '.')
+ 	        *p = '_';
+ 
+ 	last_dot = Sfile + strlen (Sfile) - strlen (STATSUFFIX);
+ 	for (p = Sfile + (base - Cfile); p < last_dot; p++)
+ 	    if (*p == '.')
+ 	        *p = '_';
+ 	}
+ #else  /* not MSDOS */
+ 
      (void) sprintf (Cfile, "%s%s", Dfile, COUNTSUFFIX);
      (void) sprintf (Sfile, "%s%s", Dfile, STATSUFFIX);
+ 
+ #endif /* MSDOS */
  
      if (stat (Dfile, &dstat) < 0)
  	{
diff -cp -r -N ispell-3.1-orig/config.x ispell-3.1/config.x
*** ispell-3.1-orig/config.x	Mon Jan 23 18:28:24 1995
--- ispell-3.1/config.x	Sat Nov 16 17:06:06 1996
***************
*** 258,263 ****
--- 258,267 ----
  ** one or the other of these.  If you select both, the setting of
  ** MASTERHASH will determine which becomes the language linked to
  ** DEFHASH (which will usually be named english.hash).
+ **
+ ** On MSDOS systems you must use names which are consistent with the
+ ** 8+3 filename restrictions, or you will risk filename collision.  See
+ ** the file pc/local.djgpp for details.
  */
  #ifndef LANGUAGES
  #define LANGUAGES "{american,MASTERDICTS=american.med+,HASHFILES=americanmed+.hash,EXTRADICT=/usr/dict/words}"
***************
*** 319,324 ****
--- 323,338 ----
  #endif
  
  /*
+ ** If your shell needs ": Use /bin/sh" at the first line of a shell
+ ** script, make the following variable the null string.  Otherwise
+ ** leave it as this sed script which will put a "#!/bin/sh" there.
+ */
+ #ifndef MAKE_POUND_BANG
+ #define MAKE_POUND_BANG "-e 1s,^:.*Use.*/bin/sh,#!/bin/sh,"
+ #endif
+ 
+ 
+ /*
  ** INSTALL program. Could be a copy program like cp or something fancier
  ** like /usr/ucb/install -c
  */
***************
*** 415,429 ****
  ** Choose the proper type of regular-expression routines here.  BSD
  ** and public-domain systems have routines called re_comp and re_exec;
  ** System V uses regcmp and regex.
  */
  #ifdef REGEX_LOOKUP
  #ifndef REGCMP
  #ifdef USG
! #define REGCMP(str)		regcmp (str, (char *) 0)
  #define REGEX(re, str, dummy)	regex (re, str, dummy, dummy, dummy, dummy, \
  				    dummy, dummy, dummy, dummy, dummy, dummy)
  #else /* USG */
! #define REGCMP(str)		re_comp (str)
  #define REGEX(re, str, dummy)	re_exec (str)
  #endif /* USG */
  #endif /* REGCMP */
--- 429,479 ----
  ** Choose the proper type of regular-expression routines here.  BSD
  ** and public-domain systems have routines called re_comp and re_exec;
  ** System V uses regcmp and regex.
+ **
+ ** REGCTYPE             is the type of a variable to hold the compiled regexp
+ ** REGCMP(re,str)	is the function which compiles a regexp in `str' into
+ **		        a compiled regexp `re' declared as REGCTYPE and
+ **			returns `re'.
+ ** REGEX(re,str,dummy)  is a function which matches `str' against a compiled
+ **			regexp in `re' and returns a non-NULL pointer if it
+ **			matches, NULL otherwise.
+ ** REGFREE(re)		is anything that should be done when the compiled
+ **			regexp `re' is no longer needed.  It can be also used
+ **			to allocate any structures required to compile a
+ **			regexp, since it is called *before* compiling a new
+ **			regexp (that's where we know that the old one will no
+ **			longer be used).
+ **
+ ** Here is one way of defining these if you have POSIX regexp functions:
+ **
+ **  #include <sys/types.h>
+ **  #include <regex.h>
+ **  #define REGCTYPE		regex_t *
+ **  #define REGCMP(re,str)	(regcomp (re, str, 0), re)
+ **  #define REGEX(re, str, dummy) \
+ **    (re != 0 && regexec (re, str, 0, 0, 0) == 0 ? (char *)1 : NULL)
+ **  #define REGFREE(re) \
+ **    do { 							\
+ **        if (re == 0)						\
+ **          re = (regex_t *)calloc (1, sizeof (regex_t));	\
+ **        else							\
+ **          regfree(re);					\
+ **    } while (0)
+ **
  */
  #ifdef REGEX_LOOKUP
  #ifndef REGCMP
  #ifdef USG
! #define REGCTYPE		char *
! #define REGCMP(re,str)		regcmp (str, (char *) 0)
  #define REGEX(re, str, dummy)	regex (re, str, dummy, dummy, dummy, dummy, \
  				    dummy, dummy, dummy, dummy, dummy, dummy)
+ #define REGFREE(re)		do {if (re != NULL) free (re); re = NULL;} \
+ 				    while (0)
  #else /* USG */
! #define REGCTYPE		char *
! #define REGFREE(re)		(void)0
! #define REGCMP(re,str)		re_comp (str)
  #define REGEX(re, str, dummy)	re_exec (str)
  #endif /* USG */
  #endif /* REGCMP */
***************
*** 813,819 ****
  ** MS-DOS users should also define HAS_RENAME, above, if appropriate.
  **
  ** Define PIECEMEAL_HASH_WRITES if your system can't handle huge write
! ** operations.  This is known to be a problem on some MS-DOS systems.
  */
  #ifndef PIECEMEAL_HASH_WRITES
  #undef PIECEMEAL_HASH_WRITES
--- 863,870 ----
  ** MS-DOS users should also define HAS_RENAME, above, if appropriate.
  **
  ** Define PIECEMEAL_HASH_WRITES if your system can't handle huge write
! ** operations.  This is known to be a problem on MS-DOS systems when
! ** a 16-bit compiler is used to compile Ispell.
  */
  #ifndef PIECEMEAL_HASH_WRITES
  #undef PIECEMEAL_HASH_WRITES
***************
*** 861,868 ****
  /*
  ** On MS-DOS systems, you can rename the following variables so that
  ** ispell's files have 3-character suffixes.  Note that, if you do
! ** this, you will have to redefine any variable above that
! ** incorporates one of the suffixes.
  */
  #ifndef HASHSUFFIX
  #define HASHSUFFIX	".hash"
--- 912,921 ----
  /*
  ** On MS-DOS systems, you can rename the following variables so that
  ** ispell's files have 3-character suffixes.  Note that, if you do
! ** this, you will have to redefine any variable above that incorporates
! ** one of the suffixes.  (Most MS-DOS environments will silently truncate
! ** excess characters beyond the 8+3 limit, so you usually don't need to
! ** change the suffixes just because they are longer than 3 characters.)
  */
  #ifndef HASHSUFFIX
  #define HASHSUFFIX	".hash"
diff -cp -r -N ispell-3.1-orig/correct.c ispell-3.1/correct.c
*** ispell-3.1-orig/correct.c	Thu Oct 12 19:04:06 1995
--- ispell-3.1/correct.c	Fri Nov  1 16:56:34 1996
*************** static void	save_root_cap P ((ichar_t * 
*** 161,167 ****
  		  struct flagent * sufent,
  		  ichar_t savearea[MAX_CAPS][INPUTWORDLEN + MAXAFFIXLEN],
  		  int * nsaved));
! static char *	getline P ((char * buf));
  void		askmode P ((void));
  void		copyout P ((char ** cc, int cnt));
  static void	lookharder P ((char * string));
--- 161,167 ----
  		  struct flagent * sufent,
  		  ichar_t savearea[MAX_CAPS][INPUTWORDLEN + MAXAFFIXLEN],
  		  int * nsaved));
! static char *	getline P ((char * buf, int bufsize));
  void		askmode P ((void));
  void		copyout P ((char ** cc, int cnt));
  static void	lookharder P ((char * string));
*************** void givehelp (interactive)
*** 213,219 ****
  
      if (interactive)
  	{
! 	(void) fprintf (helpout, "\r\n\r\n");
  	(void) fprintf (helpout, CORR_C_HELP_TYPE_SPACE);
  	(void) fflush (helpout);
  #ifdef COMMANDFORSPACE
--- 213,220 ----
  
      if (interactive)
  	{
! 	(void) fprintf (helpout, "\r\n");
! 	move (li - 1, 0);  /* bottom line, no matter what the screen size is */
  	(void) fprintf (helpout, CORR_C_HELP_TYPE_SPACE);
  	(void) fflush (helpout);
  #ifdef COMMANDFORSPACE
*************** checkagain:
*** 408,413 ****
--- 409,416 ----
  		    {
  		    erase ();
  		    (void) fflush (stdout);
+ 		    if (tempfile[0] != '\0')
+ 			fclose (outfile); /* so `done' may unlink it safely */
  		    done (0);
  		    }
  		goto checkagain;
*************** checkagain:
*** 443,449 ****
  
  		move (li - 1, 0);
  		(void) putchar ('!');
! 		if (getline (buf) == NULL)
  		    {
  		    (void) putchar (7);
  		    erase ();
--- 446,452 ----
  
  		move (li - 1, 0);
  		(void) putchar ('!');
! 		if (getline (buf, sizeof (buf)) == NULL)
  		    {
  		    (void) putchar (7);
  		    erase ();
*************** checkagain:
*** 468,474 ****
  		    (void) printf ("%s ", CORR_C_READONLY);
  		    }
  		(void) printf (CORR_C_REPLACE_WITH);
! 		if (getline (ctok) == NULL)
  		    {
  		    (void) putchar (7);
  		    /* Put it back */
--- 471,477 ----
  		    (void) printf ("%s ", CORR_C_READONLY);
  		    }
  		(void) printf (CORR_C_REPLACE_WITH);
! 		if (getline (ctok, ctokl) == NULL)
  		    {
  		    (void) putchar (7);
  		    /* Put it back */
*************** checkagain:
*** 530,536 ****
  		char	buf[100];
  		move (li - 1, 0);
  		(void) printf (CORR_C_LOOKUP_PROMPT);
! 		if (getline (buf) == NULL)
  		    {
  		    (void) putchar (7);
  		    erase ();
--- 533,539 ----
  		char	buf[100];
  		move (li - 1, 0);
  		(void) printf (CORR_C_LOOKUP_PROMPT);
! 		if (getline (buf, sizeof (buf)) == NULL)
  		    {
  		    (void) putchar (7);
  		    erase ();
*************** static void save_root_cap (word, pattern
*** 1384,1391 ****
  #endif /* NO_CAPITALIZATION_SUPPORT */
      }
  
! static char * getline (s)
      register char *	s;
      {
      register char *	p;
      register int	c;
--- 1387,1395 ----
  #endif /* NO_CAPITALIZATION_SUPPORT */
      }
  
! static char * getline (s, len)
      register char *	s;
+     register int	len;
      {
      register char *	p;
      register int	c;
*************** static char * getline (s)
*** 1396,1401 ****
--- 1400,1410 ----
  	{
  	(void) fflush (stdout);
  	c = (GETKEYSTROKE () & NOPARITY);
+ 	/*
+ 	** Don't let them overflow the buffer.
+ 	*/
+ 	if (p >= s + len - 1)
+ 	    c = '\n';
  	if (c == '\\')
  	    {
  	    (void) putchar ('\\');
diff -cp -r -N ispell-3.1-orig/findaffi.x ispell-3.1/findaffi.x
*** ispell-3.1-orig/findaffi.x	Tue Jan 25 18:31:58 1994
--- ispell-3.1/findaffi.x	Sat Nov  9 13:57:40 1996
*************** do
*** 198,205 ****
  	    ;;
      esac
  done
! trap "/bin/rm -f ${TMP}*; exit 1" 1 2 15
! trap "/bin/rm -f ${TMP}*; exit 0" 13
  #
  # We are ready to do the work.  First, we collect all input, translate it
  # to lowercase, sort it (dropping duplications), and save it for later.
--- 198,205 ----
  	    ;;
      esac
  done
! trap "rm -f ${TMP}*; exit 1" 1 2 15
! trap "rm -f ${TMP}*; exit 0" 13
  #
  # We are ready to do the work.  First, we collect all input, translate it
  # to lowercase, sort it (dropping duplications), and save it for later.
*************** join "-t$tabch" -o 1.2 2.2 2.3 ${TMP}a $
*** 289,292 ****
      else
  	exec cat
      fi
! /bin/rm -f ${TMP}?
--- 289,292 ----
      else
  	exec cat
      fi
! rm -f ${TMP}?
diff -cp -r -N ispell-3.1-orig/ispell.c ispell-3.1/ispell.c
*** ispell-3.1-orig/ispell.c	Thu Oct 12 19:04:06 1995
--- ispell-3.1/ispell.c	Sat Nov 16 21:15:36 1996
*************** static void initckch (wchars)
*** 242,252 ****
--- 242,280 ----
  	}
      }
  
+ /*
+ ** A trivial wrapper for rindex (file '/') on Unix, but
+ ** saves a lot of ifdef-ing on MS-DOS.
+ */
+ char * last_slash (file)
+     char *file;
+     {
+     char *slash = rindex (file, '/');
+ #ifdef MSDOS
+     /*
+     ** Can have a backslash or a colon; both mean the basename
+     ** begins right after them.
+     */
+     char *bs = rindex (file, '\\');
+ 
+     /*
+     ** We can have both forward- and backslashes; return the
+     ** place of rightmost one of either gender.
+     */
+     if (slash == NULL || (bs != NULL && bs > slash))
+ 	slash = bs;
+     if (slash == NULL && file[0] != '\0' && file[1] == ':')
+ 	slash = file + 1;
+ #endif
+     return slash;
+     }
+ 
  int main (argc, argv)
      int		argc;
      char *	argv[];
      {
      char *	p;
+     char *	libvar = NULL;	/* stays NULL unless on MS-DOS */
      char *	cpd;
      char **	versionp;
      char *	wchars = NULL;
*************** int main (argc, argv)
*** 260,290 ****
  
      Trynum = 0;
  
      p = getenv ("DICTIONARY");
      if (p != NULL)
  	{
! 	if (index (p, '/') != NULL)
  	    (void) strcpy (hashname, p);
  	else
  	    (void) sprintf (hashname, "%s/%s", LIBDIR, p);
  	(void) strcpy (libdictname, p);
  	p = rindex (p, '.');
  	if (p == NULL  ||  strcmp (p, HASHSUFFIX) != 0)
  	    (void) strcat (hashname, HASHSUFFIX);
! 	LibDict = rindex (libdictname, '/');
  	if (LibDict != NULL)
  	    LibDict++;
  	else
  	    LibDict = libdictname;
! 	p = rindex (libdictname, '.');
  	if (p != NULL)
  	    *p = '\0';
  	}
!     else
  	(void) sprintf (hashname, "%s/%s", LIBDIR, DEFHASH);
  
      cpd = NULL;
  
      argv++;
      argc--;
      while (argc && **argv == '-')
--- 288,396 ----
  
      Trynum = 0;
  
+ #ifdef MSDOS
+     /*
+     ** Allow to give the dictionary directory through an
+     ** environment variable, in addition to the default LIBDIR.
+     */
+     libvar = getenv (LIBRARYVAR);
+     if (libvar != NULL)
+ 	(void) sprintf (hashname, "%s/%s", libvar, DEFHASH);
+ #endif
+ 
      p = getenv ("DICTIONARY");
      if (p != NULL)
  	{
! 	if (last_slash (p) != NULL)
  	    (void) strcpy (hashname, p);
+ 	/*
+ 	** If LIBRARYVAR is defined, relative name means
+ 	** a file in that directory.
+ 	*/
+ 	else if (libvar != NULL)
+ 	    (void) sprintf (hashname, "%s/%s", libvar, p);
  	else
  	    (void) sprintf (hashname, "%s/%s", LIBDIR, p);
  	(void) strcpy (libdictname, p);
  	p = rindex (p, '.');
  	if (p == NULL  ||  strcmp (p, HASHSUFFIX) != 0)
  	    (void) strcat (hashname, HASHSUFFIX);
! 	/*
! 	** The dot to which p points might belong to a directory
! 	** part of the dictionary pathname, not to its basename.
! 	*/
! 	else if (p != NULL && last_slash (p) != NULL)
! 	    (void) strcat (hashname, HASHSUFFIX);
! 	LibDict = last_slash (libdictname);
  	if (LibDict != NULL)
  	    LibDict++;
  	else
  	    LibDict = libdictname;
! 	p = rindex (LibDict, '.');
  	if (p != NULL)
  	    *p = '\0';
  	}
!     else if (libvar == NULL)	/* libvar might be non-NULL only on MS-DOS */
  	(void) sprintf (hashname, "%s/%s", LIBDIR, DEFHASH);
  
      cpd = NULL;
  
+ #ifdef MSDOS
+ /*
+ ** 'OPTIONVAR' is an environment variable which holds default
+ ** options for ispell.  To allow for these options to be overridden
+ ** by the command-line arguments, we insert them in front of argv[].
+ */
+     if (getenv (OPTIONVAR))
+ 	{
+ 	register char *opt = getenv (OPTIONVAR);
+ 	char **newargv = NULL;
+ 	int maxargc = argc;
+ 	int newargc = 1;
+ 
+ 	while (*opt)
+ 	    {
+ 	    /*
+ 	    ** Allocate more space if needed.
+ 	    */
+ 	    if (newargc + argc >= maxargc)
+ 		{
+ 		char **new;
+ 
+ 		while (newargc + argc >= maxargc)
+ 		    maxargc += 100;
+ 		new = (char **) realloc (newargv, (maxargc+1)*sizeof(char *));
+ 		if (new == NULL)
+ 		    {
+ 		    (void) fprintf (stderr, ISPELL_C_NO_OPTIONS_SPACE);
+ 		    exit (-1);
+ 		    }
+ 		newargv = new;
+ 		}
+ 	    newargv[newargc++] = opt;
+ 	    /*
+ 	    ** FIXME: The following assumes that the options cannot
+ 	    ** include any whitespace.  Currently, no ispell option
+ 	    ** does, so this is OK.  For now.
+ 	    */
+ 	    while (*opt && !isspace (*opt))
+ 		opt++;
+ 	    if (*opt)
+ 		*opt++ = '\0';
+ 	    }
+ 
+ 	/*
+ 	** Copy the original command-line args after the default options.
+ 	*/
+ 	newargv[0] = *argv++;
+ 	while (--argc)
+ 	    newargv[newargc++] = *argv++;
+ 	newargv[newargc] = NULL;
+ 
+ 	argv = newargv;
+ 	argc = newargc;
+ 	}
+ #endif
      argv++;
      argc--;
      while (argc && **argv == '-')
*************** int main (argc, argv)
*** 383,388 ****
--- 489,498 ----
  		    (void) printf ("\tLANGUAGES = \"%s\"\n", LANGUAGES);
  		    (void) printf ("\tLIBDIR = \"%s\"\n", LIBDIR);
  		    (void) printf ("\tLIBES = \"%s\"\n", LIBES);
+ #ifdef MSDOS /* DOS environment */
+ 		    (void) printf ("\tENVIRONMENT VARIABLE NAME FOR\n");
+ 		    (void) printf ("\tLIBRARYVAR = \"%s\"\n", LIBRARYVAR);
+ #endif       /* DOS environment */
  		    (void) printf ("\tLINT = \"%s\"\n", LINT);
  		    (void) printf ("\tLINTFLAGS = \"%s\"\n", LINTFLAGS);
  #ifndef REGEX_LOOKUP
*************** int main (argc, argv)
*** 400,405 ****
--- 510,519 ----
  		    (void) printf ("\tMASKTYPE_WIDTH = %d\n", MASKTYPE_WIDTH);
  		    (void) printf ("\tMASTERHASH = \"%s\"\n", MASTERHASH);
  		    (void) printf ("\tMAXAFFIXLEN = %d\n", MAXAFFIXLEN);
+ #ifdef MSDOS
+ 		    (void) printf ("\tMAXBASENAMELEN = %d\n", MAXBASENAMELEN);
+ 		    (void) printf ("\tMAXEXTLEN = %d\n", MAXEXTLEN);
+ #endif
  		    (void) printf ("\tMAXCONTEXT = %d\n", MAXCONTEXT);
  		    (void) printf ("\tMAXINCLUDEFILES = %d\n",
  		      MAXINCLUDEFILES);
*************** int main (argc, argv)
*** 442,447 ****
--- 556,565 ----
  		    (void) printf ("\tNRSPECIAL = \"%s\"\n", NRSPECIAL);
  		    (void) printf ("\tOLDPAFF = \"%s\"\n", OLDPAFF);
  		    (void) printf ("\tOLDPDICT = \"%s\"\n", OLDPDICT);
+ #ifdef MSDOS /* DOS environment */
+ 		    (void) printf ("\tENVIRONMENT VARIABLE NAME FOR\n");
+ 		    (void) printf ("\tOPTIONVAR = \"%s\"\n", OPTIONVAR);
+ #endif       /* DOS environment */
  #ifdef PDICTHOME
  		    (void) printf ("\tPDICTHOME = \"%s\"\n", PDICTHOME);
  #else /* PDICTHOME */
*************** int main (argc, argv)
*** 651,658 ****
  			usage ();
  		    p = *argv;
  		    }
! 		if (index (p, '/') != NULL)
  		    (void) strcpy (hashname, p);
  		else
  		    (void) sprintf (hashname, "%s/%s", LIBDIR, p);
  		if (cpd == NULL  &&  *p != '\0')
--- 769,783 ----
  			usage ();
  		    p = *argv;
  		    }
! 		if (last_slash (p) != NULL)
  		    (void) strcpy (hashname, p);
+ #ifdef MSDOS
+ 		/*
+ 		** Let them use $LIBRARYVAR.
+ 		*/
+ 		else if (libvar != NULL)
+ 		    (void) sprintf (hashname, "%s/%s", libvar, p);
+ #endif
  		else
  		    (void) sprintf (hashname, "%s/%s", LIBDIR, p);
  		if (cpd == NULL  &&  *p != '\0')
*************** int main (argc, argv)
*** 664,670 ****
  		    (void) strcat (hashname, HASHSUFFIX);
  		if (LibDict != NULL)
  		    {
! 		    p = rindex (LibDict, '/');
  		    if (p != NULL)
  			LibDict = p + 1;
  		    }
--- 789,795 ----
  		    (void) strcat (hashname, HASHSUFFIX);
  		if (LibDict != NULL)
  		    {
! 		    p = last_slash (LibDict);
  		    if (p != NULL)
  			LibDict = p + 1;
  		    }
*************** static void dofile (filename)
*** 834,839 ****
--- 959,993 ----
  	}
  
      (void) fstat (fileno (infile), &statbuf);
+ #ifdef MSDOS
+     /*
+     ** MS-DOS doesn't map "/tmp" to every filesystem.  Get the
+     ** location of temporary files from the environment.
+     */
+     tempfile[0] = '\0';
+ 	{
+ 	char *tpl = last_slash (TEMPNAME); /* filename part only */
+ 	char *tmp = getenv ("TMP");
+ 
+ 	if (tpl != NULL)
+ 	    tpl++;
+ 	else
+ 	    tpl = TEMPNAME;
+ 
+ 	if (tmp == NULL)
+ 	    tmp = getenv ("TEMP");
+ 	if (tmp == NULL)
+ 	    tmp = getenv ("TMPDIR");
+ 	if (tmp != NULL)
+ 	    {
+ 	    int lastchar = tmp[strlen (tmp) - 1];
+ 	    (void) sprintf (tempfile, "%s%s%s", tmp,
+ 			    lastchar == '/' || lastchar == '\\' ? "" : "/",
+ 			    tpl);
+ 	    }
+ 	}
+     if (tempfile[0] == '\0')
+ #endif
      (void) strcpy (tempfile, TEMPNAME);
      if (mktemp (tempfile) == NULL  ||  tempfile[0] == '\0'
        ||  (outfile = fopen (tempfile, "w")) == NULL)
*************** static void update_file (filename, statb
*** 880,906 ****
  #ifdef TRUNCATEBAK
      (void) strncpy (bakfile, filename, sizeof bakfile - 1);
      bakfile[sizeof bakfile - 1] = '\0';
!     if (strcmp(BAKEXT, filename + strlen(filename) - sizeof BAKEXT - 1) != 0)
  	{
! 	pathtail = rindex (bakfile, '/');
! 	if (pathtail == NULL)
! 	    pathtail = bakfile;
! 	else
! 	    pathtail++;
! 	if (strlen (pathtail) > MAXNAMLEN - sizeof BAKEXT - 1)
! 	    pathtail[MAXNAMLEN - sizeof BAKEXT -1] = '\0';
  	(void) strcat (pathtail, BAKEXT);
  	}
  #else
      (void) sprintf (bakfile, "%.*s%s", (int) (sizeof bakfile - sizeof BAKEXT),
        filename, BAKEXT);
! #endif
! 
!     pathtail = rindex (bakfile, '/');
      if (pathtail == NULL)
  	pathtail = bakfile;
      else
  	pathtail++;
      if (strncmp (filename, bakfile, pathtail - bakfile + MAXNAMLEN) != 0)
  	(void) unlink (bakfile);	/* unlink so we can write a new one. */
  #ifdef HAS_RENAME
--- 1034,1106 ----
  #ifdef TRUNCATEBAK
      (void) strncpy (bakfile, filename, sizeof bakfile - 1);
      bakfile[sizeof bakfile - 1] = '\0';
!     pathtail = last_slash (bakfile);
!     if (pathtail == NULL)
! 	pathtail = bakfile;
!     else
! 	pathtail++;
!     if (strcmp(BAKEXT, filename + strlen(filename) - sizeof (BAKEXT) + 1) != 0)
  	{
! 	if (strlen (pathtail) > MAXNAMLEN - sizeof (BAKEXT) + 1)
! 	    pathtail[MAXNAMLEN - sizeof (BAKEXT) + 1] = '\0';
  	(void) strcat (pathtail, BAKEXT);
  	}
  #else
      (void) sprintf (bakfile, "%.*s%s", (int) (sizeof bakfile - sizeof BAKEXT),
        filename, BAKEXT);
!     pathtail = last_slash (bakfile);
      if (pathtail == NULL)
  	pathtail = bakfile;
      else
  	pathtail++;
+ #endif
+ 
+ #ifdef MSDOS
+     /*
+     ** Excessive characters beyond 8+3 will be truncated by the OS.
+     ** Ensure the backup extension won't be truncated, and that we
+     ** don't create an illegal filename (e.g., more than one dot).
+     ** Allow to use BAKEXT without a leading dot (such as "~").
+     */
+ 	{
+ 	char *last_dot = rindex (pathtail, '.');
+ 
+ 	/*
+ 	** If no dot in backup filename, make BAKEXT be the extension.
+ 	** This ensures we don't truncate the name more than necessary.
+ 	*/
+ 	if (last_dot == NULL && strlen (pathtail) > MAXBASENAMELEN)
+ 	    {
+ 	    pathtail[MAXBASENAMELEN] = '.';
+ 	    /*
+ 	    ** BAKEXT cannot include a dot here (or we would have
+ 	    ** found it above, and last_dot would not be NULL).
+ 	    */
+ 	    strcpy (pathtail + MAXBASENAMELEN + 1, BAKEXT);
+ 	    }
+ 	else if (last_dot != NULL)
+ 	    {
+ 	    char *p = pathtail;
+ 	    size_t ext_len = strlen (last_dot);
+ 
+ 	    /* Convert all dots but the last to underscores. */
+ 	    while (p < last_dot && *p)
+ 		{
+ 		if (*p == '.')
+ 		    *p = '_';
+ 		p++;
+ 		}
+ 
+ 	    /* Make sure we preserve as much of BAKEXT as we can. */
+ 	    if (ext_len > MAXEXTLEN && ext_len > sizeof (BAKEXT) - 1)
+ 		strcpy (MAXEXTLEN <= sizeof (BAKEXT) - 1
+ 			? last_dot + 1
+ 			: last_dot + MAXEXTLEN - sizeof (BAKEXT) + 1,
+ 			BAKEXT);
+ 	    }
+ 	}
+ #endif
+ 
      if (strncmp (filename, bakfile, pathtail - bakfile + MAXNAMLEN) != 0)
  	(void) unlink (bakfile);	/* unlink so we can write a new one. */
  #ifdef HAS_RENAME
diff -cp -r -N ispell-3.1-orig/language/english/msgs.h ispell-3.1/language/english/msgs.h
*** ispell-3.1-orig/language/english/msgs.h	Mon Jan 23 18:28:30 1995
--- ispell-3.1/language/english/msgs.h	Sat Oct 19 15:32:20 1996
***************
*** 193,198 ****
--- 193,201 ----
  #define ISPELL_C_NO_FILES	"ispell:  specified files do not exist\n"
  #define ISPELL_C_CANT_WRITE	"Warning:  Can't write to %s\r\n"
  #define ISPELL_C_OPTIONS_ARE	"Compiled-in options:\n"
+ #ifdef MSDOS
+ #define ISPELL_C_NO_OPTIONS_SPACE "ispell: no memory to read default options\n"
+ #endif
  
  /*
   * The following strings are used in lookup.c:
diff -cp -r -N ispell-3.1-orig/makefile ispell-3.1/makefile
*** ispell-3.1-orig/makefile	Thu Oct 12 19:04:06 1995
--- ispell-3.1/makefile	Sat Nov 16 17:05:18 1996
*************** config.sh:  config.X local.h
*** 416,422 ****
  	  LANGUAGES LIBDIR LIBES LINT LINTFLAGS \
  	  MAKE_SORTTMP MAN1DIR MAN1EXT MAN4DIR MAN4EXT MASTERHASH \
  	  MSGLANG REGLIB STATSUFFIX \
! 	  TERMLIB TEXINFODIR YACC \
  	  ; do \
  	    cat config.X local.h \
  	      | sed -n -e "s/^#define[ 	]*$$var[ 	]*"'"'"/$$var=/p" \
--- 416,422 ----
  	  LANGUAGES LIBDIR LIBES LINT LINTFLAGS \
  	  MAKE_SORTTMP MAN1DIR MAN1EXT MAN4DIR MAN4EXT MASTERHASH \
  	  MSGLANG REGLIB STATSUFFIX \
! 	  TERMLIB TEXINFODIR YACC MAKE_POUND_BANG \
  	  ; do \
  	    cat config.X local.h \
  	      | sed -n -e "s/^#define[ 	]*$$var[ 	]*"'"'"/$$var=/p" \
*************** doedit:
*** 434,439 ****
--- 434,440 ----
  	    -e "s@!!COUNTSUFFIX!!@$$COUNTSUFFIX@g" \
  	    -e "s@!!HASHSUFFIX!!@$$HASHSUFFIX@g" \
  	    -e "s@!!STATSUFFIX!!@$$STATSUFFIX@g" \
+ 	    $$MAKE_POUND_BANG \
  	    $$SORTTMP < $(EDITFILE) > $(OUTFILE)
  
  findaffix:	findaffix.X config.sh
diff -cp -r -N ispell-3.1-orig/munchlis.x ispell-3.1/munchlis.x
*** ispell-3.1-orig/munchlis.x	Mon Jan 23 18:28:26 1995
--- ispell-3.1/munchlis.x	Sat Nov  9 13:57:38 1996
*************** then
*** 243,249 ****
      verbose=true
      debug=yes
  fi
! trap "/bin/rm -f ${TMP}*; exit 1" 1 2 13 15
  #
  # Names of temporary files.  This is just to make the code a little easier
  # to read.
--- 243,249 ----
      verbose=true
      debug=yes
  fi
! trap "rm -f ${TMP}*; exit 1" 1 2 13 15
  #
  # Names of temporary files.  This is just to make the code a little easier
  # to read.
*************** case "X$convtabs" in
*** 306,312 ****
  esac
  echo 'QQQQQQQQ' > $FAKEDICT
  buildhash -s $FAKEDICT $convtabs $FAKEHASH \
!   ||  (echo "Couldn't create fake hash file" 1>&2; /bin/rm -f ${TMP}*; exit 1) \
    ||  exit 1
  #
  # Figure out how 'sort' sorts signed fields, for arguments to ijoin.
--- 306,312 ----
  esac
  echo 'QQQQQQQQ' > $FAKEDICT
  buildhash -s $FAKEDICT $convtabs $FAKEHASH \
!   ||  (echo "Couldn't create fake hash file" 1>&2; rm -f ${TMP}*; exit 1) \
    ||  exit 1
  #
  # Figure out how 'sort' sorts signed fields, for arguments to ijoin.
*************** case "$convtabs" in
*** 360,370 ****
      *)
  	buildhash -s $FAKEDICT $langtabs $FAKEHASH \
  	  ||  (echo "Couldn't create fake hash file" 1>&2; \
! 		/bin/rm -f ${TMP}*; exit 1) \
  	  ||  exit 1
  	;;
  esac
! /bin/rm -f ${FAKEDICT}*
  #
  # If the -s (strip) option was specified, remove all
  # expanded words that are covered by the dictionary.  This produces
--- 360,370 ----
      *)
  	buildhash -s $FAKEDICT $langtabs $FAKEHASH \
  	  ||  (echo "Couldn't create fake hash file" 1>&2; \
! 		rm -f ${TMP}*; exit 1) \
  	  ||  exit 1
  	;;
  esac
! rm -f ${FAKEDICT}*
  #
  # If the -s (strip) option was specified, remove all
  # expanded words that are covered by the dictionary.  This produces
*************** sort $SORTTMP -o $CRUNCHEDINPUT $CRUNCHE
*** 458,466 ****
  
  $verbose  &&  echo 'Creating list of legal roots/flags.' 1>&2
  comm -13 $JOINEDPAIRS $EXPANDEDPAIRS \
!   | (sed -e 's; .*$;;' ; /bin/rm -f $JOINEDPAIRS $EXPANDEDPAIRS) \
    | uniq \
!   | (comm -13 - $CRUNCHEDINPUT ; /bin/rm -f $CRUNCHEDINPUT) \
    | sort $SORTTMP -u "-t$flagmarker" +0f -1 +0 \
    | $COMBINE $langtabs > $LEGALFLAGLIST
  
--- 458,466 ----
  
  $verbose  &&  echo 'Creating list of legal roots/flags.' 1>&2
  comm -13 $JOINEDPAIRS $EXPANDEDPAIRS \
!   | (sed -e 's; .*$;;' ; rm -f $JOINEDPAIRS $EXPANDEDPAIRS) \
    | uniq \
!   | (comm -13 - $CRUNCHEDINPUT ; rm -f $CRUNCHEDINPUT) \
    | sort $SORTTMP -u "-t$flagmarker" +0f -1 +0 \
    | $COMBINE $langtabs > $LEGALFLAGLIST
  
*************** ENDOFAWKSCRIPT
*** 650,660 ****
  	awk "-F$flagmarker" -f $AWKSCRIPT $CROSSILLEGAL > $CROSSROOTS
  	if [ "$debug" = yes ]
  	then
! 	    /bin/rm -f $CROSSEXPANDED $CROSSPAIRS $CROSSILLEGAL
  	fi
  	dbnum=`expr $dbnum + 1`
      done
!     /bin/rm -f $CROSSEXPANDED $CROSSPAIRS $CROSSILLEGAL $AWKSCRIPT
      #
      # Now we have, in ILLEGALCOMBOS, a list of root/flag combinations
      # that must be removed from LEGALFLAGLIST to get the final list
--- 650,660 ----
  	awk "-F$flagmarker" -f $AWKSCRIPT $CROSSILLEGAL > $CROSSROOTS
  	if [ "$debug" = yes ]
  	then
! 	    rm -f $CROSSEXPANDED $CROSSPAIRS $CROSSILLEGAL
  	fi
  	dbnum=`expr $dbnum + 1`
      done
!     rm -f $CROSSEXPANDED $CROSSPAIRS $CROSSILLEGAL $AWKSCRIPT
      #
      # Now we have, in ILLEGALCOMBOS, a list of root/flag combinations
      # that must be removed from LEGALFLAGLIST to get the final list
*************** ENDOFAWKSCRIPT
*** 686,692 ****
  	fi
      fi
  fi
! /bin/rm -f $PRODUCTLIST $CROSSROOTS $ILLEGALCOMBOS $EXPANDEDINPUT
  #
  
  # We now have (in LEGALFLAGLIST) a list of roots and flags which will
--- 686,692 ----
  	fi
      fi
  fi
! rm -f $PRODUCTLIST $CROSSROOTS $ILLEGALCOMBOS $EXPANDEDINPUT
  #
  
  # We now have (in LEGALFLAGLIST) a list of roots and flags which will
*************** ispell "$wchars" -e4 -d $FAKEHASH -p /de
*** 716,722 ****
    | sort $SORTTMP -um +1 -2 \
    | sed -e 's; .*$;;' \
    | sort $SORTTMP -u "-t$flagmarker" +0f -1 +0 > $MINIMALAFFIXES
! /bin/rm -f $LEGALFLAGLIST
  #
  # Now we're almost done.  MINIMALAFFIXES covers some (with luck, most)
  # of the words in STRIPPEDINPUT.  Now we must create a list of the remaining
--- 716,722 ----
    | sort $SORTTMP -um +1 -2 \
    | sed -e 's; .*$;;' \
    | sort $SORTTMP -u "-t$flagmarker" +0f -1 +0 > $MINIMALAFFIXES
! rm -f $LEGALFLAGLIST
  #
  # Now we're almost done.  MINIMALAFFIXES covers some (with luck, most)
  # of the words in STRIPPEDINPUT.  Now we must create a list of the remaining
*************** if [ -s $MINIMALAFFIXES ]
*** 731,744 ****
  then
      buildhash -s $MINIMALAFFIXES $langtabs $FAKEHASH > /dev/null \
        ||  (echo "Couldn't create intermediate hash file" 1>&2;
! 	/bin/rm -f ${TMP}*;
  	exit 1) \
        ||  exit 1
      if [ "$debug" = yes ]
      then
! 	rm -f ${TDIR}/MINAFFIXES.!!COUNTSUFFIX!! \
  	  ${TDIR}/MINAFFIXES!!STATSUFFIX!!
! 	ln $MINIMALAFFIXES.!!COUNTSUFFIX!! ${TDIR}/MINAFFIXES.!!COUNTSUFFIX!!
  	ln $MINIMALAFFIXES!!STATSUFFIX!! ${TDIR}/MINAFFIXES!!STATSUFFIX!!
      fi
      (ispell "$wchars" -l -d $FAKEHASH -p /dev/null < $STRIPPEDINPUT; \
--- 731,744 ----
  then
      buildhash -s $MINIMALAFFIXES $langtabs $FAKEHASH > /dev/null \
        ||  (echo "Couldn't create intermediate hash file" 1>&2;
! 	rm -f ${TMP}*;
  	exit 1) \
        ||  exit 1
      if [ "$debug" = yes ]
      then
! 	rm -f ${TDIR}/MINAFFIXES!!COUNTSUFFIX!! \
  	  ${TDIR}/MINAFFIXES!!STATSUFFIX!!
! 	ln $MINIMALAFFIXES!!COUNTSUFFIX!! ${TDIR}/MINAFFIXES!!COUNTSUFFIX!!
  	ln $MINIMALAFFIXES!!STATSUFFIX!! ${TDIR}/MINAFFIXES!!STATSUFFIX!!
      fi
      (ispell "$wchars" -l -d $FAKEHASH -p /dev/null < $STRIPPEDINPUT; \
*************** else
*** 748,760 ****
      # MINIMALAFFIXES is empty;  just produce a sorted version of STRIPPEDINPUT
      sort $SORTTMP "-t$flagmarker" -u +0f -1 +0 $STRIPPEDINPUT
  fi
! /bin/rm -f ${TMP}*
  if [ "X$MUNCHMAIL" != X ]
  then
      (
      ls -ld ${TDIR}/[A-Z]*
      cat /tmp/munchlist.mail
      ) | mail "$MUNCHMAIL"
!     /bin/rm -f /tmp/munchlist.mail
  fi
  exit 0
--- 748,760 ----
      # MINIMALAFFIXES is empty;  just produce a sorted version of STRIPPEDINPUT
      sort $SORTTMP "-t$flagmarker" -u +0f -1 +0 $STRIPPEDINPUT
  fi
! rm -f ${TMP}*
  if [ "X$MUNCHMAIL" != X ]
  then
      (
      ls -ld ${TDIR}/[A-Z]*
      cat /tmp/munchlist.mail
      ) | mail "$MUNCHMAIL"
!     rm -f /tmp/munchlist.mail
  fi
  exit 0
diff -cp -r -N ispell-3.1-orig/pc/cfglang.sed ispell-3.1/pc/cfglang.sed
*** ispell-3.1-orig/pc/cfglang.sed	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/cfglang.sed	Sat Nov  2 10:57:06 1996
***************
*** 0 ****
--- 1,21 ----
+ #!/bin/sed -f
+ #
+ # Fix up filenames which are illegal on MSDOS, or clash with each
+ # other in the restricted 8+3 filename space
+ #
+ s/americansml/amersml/g
+ s/americanmed/amermed/g
+ s/americanlrg/amerlrg/g
+ s/americanxlg/amerxlg/g
+ s/altamersml/altasml/g
+ s/altamermed/altamed/g
+ s/altamerlrg/altalrg/g
+ s/altamerxlg/altaxlg/g
+ s/britishsml/britsml/g
+ s/britishmed/britmed/g
+ s/britishlrg/britlrg/g
+ s/britishxlg/britxlg/g
+ s/\(..*\)-alt\./alt\1./g
+ s/+\.hash/x.hash/g
+ s/\([^.]\)\.\([^.+][^.+]*\)+/\1x.\2/g
+ s/americanx/americax/g
diff -cp -r -N ispell-3.1-orig/pc/cfgmain.sed ispell-3.1/pc/cfgmain.sed
*** ispell-3.1-orig/pc/cfgmain.sed	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/cfgmain.sed	Sat Nov  9 17:12:58 1996
***************
*** 0 ****
--- 1,15 ----
+ s|y\.tab|y_tab|g
+ /^	  *\$\$SORTTMP/i\
+ 	    -e 's@/munch\\$$\\$$@/mu$$$$@g' \\\
+ 	    -e 's@/faff\\$$\\$$@/fa$$$$@g' \\\
+ 	    -e 's@/sset\\$$\\$$\\.@/se$$$$@g' \\
+ /^	  *while \[ "X\$\$LANGUAGES" != X \]/i\
+ 	    [ -r languages/english/Makefile.orig ] \\\
+ 	      || (cd languages/english; mv -f Makefile Makefile.orig; \\\
+ 	          ../../pc/cfglang.sed Makefile.orig > Makefile); \\
+ /^		cd languages\/$$dir; \\/a\
+ 		[ -r Makefile.orig ] \\\
+ 		   || (mv -f Makefile Makefile.orig; \\\
+ 		       ../../pc/cfglang.sed Makefile.orig > Makefile); \\
+ /^ijoin.o:/i\
+ term.o: pc/djterm.c
diff -cp -r -N ispell-3.1-orig/pc/configdj.bat ispell-3.1/pc/configdj.bat
*** ispell-3.1-orig/pc/configdj.bat	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/configdj.bat	Sat Nov  9 17:12:30 1996
***************
*** 0 ****
--- 1,11 ----
+ @echo off
+ echo Configuring Ispell for DJGPP...
+ update pc/local.djgpp local.h
+ if not exist Makefile.orig ren Makefile Makefile.orig
+ sed -f pc/cfgmain.sed Makefile.orig > Makefile
+ if "%TMPDIR%"=="" set TMPDIR=.
+ if "%SYSROOT%"=="" set SYSROOT=c:
+ if "%PATH_SEPARATOR%"=="" set PATH_SEPARATOR=:
+ if not exist %SYSROOT%\tmp\nul md %SYSROOT%\tmp
+ echo You are now ready to run Make
+ :End
diff -cp -r -N ispell-3.1-orig/pc/djterm.c ispell-3.1/pc/djterm.c
*** ispell-3.1-orig/pc/djterm.c	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/djterm.c	Sat Nov 16 19:17:46 1996
***************
*** 0 ****
--- 1,304 ----
+ #ifndef lint
+ static char DJGPP_Rcs_Id[] =
+     "$Id";
+ #endif
+ 
+ /*
+  * djterm.c - DJGPP-specific terminal driver for Ispell
+  *
+  * Eli Zaretskii <eliz@is.elta.co.il>, 1996
+  *
+  * Copyright 1996, Geoff Kuenning, Granada Hills, CA
+  * All rights reserved.
+  *
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  *
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. All modifications to the source code must be clearly marked as
+  *    such.  Binary redistributions based on modified source code
+  *    must be clearly marked as modified versions in the documentation
+  *    and/or other materials provided with the distribution.
+  * 4. All advertising materials mentioning features or use of this software
+  *    must display the following acknowledgment:
+  *      This product includes software developed by Geoff Kuenning and
+  *      other unpaid contributors.
+  * 5. The name of Geoff Kuenning may not be used to endorse or promote
+  *    products derived from this software without specific prior
+  *    written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ 
+ /*
+  * $Log$
+  */
+ 
+ /*
+ ** DJGPP currently doesn't support Unixy ioctl directly, so we
+ ** have to define minimal support here via the filesystem extensions.
+ */
+ 
+ #include <errno.h>
+ #include <unistd.h>
+ #include <limits.h>
+ #include <sys/ioctl.h>
+ #include <conio.h>
+ #include <sys/fsext.h>
+ 
+ static struct text_info txinfo;
+ static unsigned char *saved_screen;
+ static unsigned char ispell_norm_attr, ispell_sout_attr;
+ 
+ /* These declarations are on <sys/ioctl.h>, but as of DJGPP v2.01
+    they are ifdefed away.  */
+ struct winsize {
+ 	unsigned short	ws_row;
+ 	unsigned short	ws_col;
+ 	unsigned short	ws_xpixel;
+ 	unsigned short	ws_ypixel;
+ };
+ 
+ struct sgttyb {
+ 	char	sg_ispeed;
+ 	char	sg_ospeed;
+ 	char	sg_erase;
+ 	char	sg_kill;
+ 	short	sg_flags;
+ };
+ 
+ #define IOCPARM_MASK    0x7f
+ #define IOC_OUT         0x40000000
+ #define IOC_IN          0x80000000
+ #define IOC_INOUT       (IOC_IN|IOC_OUT)
+ 
+ #define _IOR(x,y,t)     (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
+ #define _IOW(x,y,t)     (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
+ #define _IOWR(x,y,t)    (IOC_INOUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
+ 
+ /* These are the only ones we support here.  */
+ #define TIOCGWINSZ  _IOR('t', 104, struct winsize)
+ #define TIOCGPGRP   _IOR('t', 119, int)
+ #define TIOCGETP    _IOR('t', 8, struct sgttyb)
+ #define TIOCSETP    _IOW('t', 9, struct sgttyb)
+ #define CBREAK      0x00000002
+ #define ECHO        0x00000008
+ 
+ /* This will be called by low-level I/O functions.  */
+ static int djgpp_term (__FSEXT_Fnumber func, int *retval, va_list rest_args)
+     {
+     int fhandle = va_arg (rest_args, int);
+ 
+     /*
+     ** We only support ioctl on STDIN and write on STDOUT/STDERR.
+     */
+     if (func == __FSEXT_ioctl
+ 	     && fhandle == fileno (stdin)
+ 	     && isatty (fhandle))
+ 	{
+ 	int cmd = va_arg (rest_args, int);
+ 	switch (cmd)
+ 	  {
+ 	  case TIOCGWINSZ:
+ 		{
+ 		struct winsize *winfo = va_arg (rest_args, struct winsize *);
+ 		winfo->ws_row = ScreenRows ();
+ 		winfo->ws_col = ScreenCols ();
+ 		winfo->ws_xpixel = winfo->ws_row;
+ 		winfo->ws_ypixel = winfo->ws_col;
+ 		*retval = 0;
+ 		break;
+ 		}
+ 	  case TIOCGPGRP:
+ 		*retval = 0;
+ 		break;
+ 	  case TIOCGETP:
+ 		{
+ 		struct sgttyb * gtty = va_arg (rest_args, struct sgttyb *);
+ 		gtty->sg_ispeed = gtty->sg_ospeed = 0; /* unused */
+ 		gtty->sg_erase = K_BackSpace;
+ 		gtty->sg_kill  = K_Control_U;
+ 		gtty->sg_flags = 0; /* unused */
+ 		*retval = 0;
+ 		break;
+ 		}
+ 	  case TIOCSETP:
+ 		*retval = 0;
+ 		break;
+ 	  default:
+ 		*retval = -1;
+ 		break;
+ 	  }
+ 	return 1;
+ 	}
+     else if (func == __FSEXT_write
+ 	     && (fhandle == fileno (stdout) || fhandle == fileno (stderr))
+ 	     && isatty (fhandle)
+ 	     && termchanged)
+ 	{
+ 	/*
+ 	** Cannot write the output as is, because it might include
+ 	** TABS.  We need to expand them into suitable number of spaces.
+ 	*/
+ 	int col, dummy;
+ 	char *buf = va_arg (rest_args, char *);
+ 	size_t buflen = va_arg (rest_args, size_t);
+ 	char *local_buf, *s, *d;
+ 	if (!buf)
+ 	    {
+ 	    errno = EINVAL;
+ 	    *retval = -1;
+ 	    return 1;
+ 	    }
+ 	*retval = buflen;	/* `_write' expects number of bytes written */
+ 	local_buf = (char *)alloca (buflen + 8+1); /* 8 for TAB, 1 for '\0' */
+ 	ScreenGetCursor (&dummy, &col);
+ 	for (s = buf, d = local_buf; buflen--; s++)
+ 	    {
+ 	    if (*s == '\0')	/* `cputs' treats '\0' as end of string */
+ 		{
+ 		*d = *s;
+ 		cputs (local_buf);
+ 		putch (*s);
+ 		d = local_buf;
+ 		col++;
+ 		}
+ 	    else if (*s == '\t')
+ 		{
+ 		*d++ = ' ';
+ 		col++;
+ 		while (col % 8)
+ 		    {
+ 		    *d++ = ' ';
+ 		    col++;
+ 		    }
+ 		*d = '\0';
+ 		cputs (local_buf);
+ 		d = local_buf;
+ 		}
+ 	    else
+ 	        {
+ 		*d++ = *s;
+ 		if (*s == '\r')
+ 		    col = 0;
+ 		else if (*s != '\n')
+ 		    col++;
+ 		}
+ 	    }
+ 	if (d > local_buf)
+ 	    {
+ 	    *d = '\0';
+ 	    cputs (local_buf);
+ 	    }
+ 
+ 	return 1;
+ 	}
+     else
+         return 0;
+     }
+ 
+ 
+ /* This is called before `main' to install our terminal handler. */
+ static void __attribute__((constructor))
+ djgpp_ispell_startup (void)
+ {
+   __FSEXT_set_function (fileno (stdin), djgpp_term);
+   __FSEXT_set_function (fileno (stdout), djgpp_term);
+ }
+ 
+ /* DJGPP-specific screen initialization and deinitialization.  */
+ static void djgpp_init_terminal (void)
+     {
+     if (li == 0)
+ 	{
+ 	/*
+ 	** On MSDOS/DJGPP platforms, colors are used for normal and
+ 	** inverse-video displays.  The colors and screen size seen
+ 	** at program startup are saved, to be restored before exit.
+ 	** The screen contents are also saved and restored.
+ 	*/
+ 	char *ispell_colors;
+ 
+ 	gettextinfo (&txinfo);
+ 	saved_screen = (unsigned char *)
+ 		       malloc (txinfo.screenwidth * txinfo.screenheight * 2);
+ 	if (saved_screen)
+ 	    ScreenRetrieve (saved_screen);
+ 
+ 	/*
+ 	** Let the user specify their favorite colors for normal
+ 	** and standout text, like so:
+ 	**
+ 	**         set ISPELL_COLORS=0x1e.0x74
+ 	**                            se   so
+ 	*/
+ 	ispell_colors = getenv ("ISPELL_COLORS");
+ 	if (ispell_colors != (char *)0)
+ 	    {
+ 	    char *next;
+ 	    unsigned long coldesc = strtoul (ispell_colors, &next, 0);
+ 
+ 	    if (next == ispell_colors || coldesc > UCHAR_MAX)
+ 	        ispell_colors = (char *)0;
+ 	    else
+ 		{
+ 		char *endp;
+ 		ispell_norm_attr = (unsigned char)coldesc;
+ 		coldesc = strtoul (next + 1, &endp, 0);
+ 		if (endp == next + 1 || coldesc > UCHAR_MAX)
+ 		    ispell_colors = (char *)0;
+ 		else
+ 		    ispell_sout_attr = (unsigned char)coldesc;
+ 		}
+ 	    }
+ 	if (ispell_colors == (char *)0)
+ 	    {  /* Use dull B&W color scheme */
+ 	    ispell_norm_attr = LIGHTGRAY + (BLACK << 4);
+ 	    ispell_sout_attr  = BLACK + (LIGHTGRAY << 4);
+ 	    }
+ 	}
+     }
+ 
+ static void djgpp_restore_screen (void)
+     {
+     if (li != txinfo.screenheight)
+         _set_screen_lines (txinfo.screenheight);
+     textmode (txinfo.currmode);
+     textattr (txinfo.attribute);
+     gotoxy (1, txinfo.screenheight);
+     }
+ 
+ static void djgpp_deinit_term (void)
+     {
+     termchanged = 0;	/* so output uses stdio again */
+     printf ("\r\n");	/* in case some garbage is pending */
+     fflush (stdout);
+     if (saved_screen)
+ 	{
+ 	ScreenUpdate (saved_screen);
+ 	gotoxy (txinfo.curx, txinfo.cury);
+ 	}
+     }
+ 
+ static void djgpp_ispell_screen ()
+     {
+     fflush (stdout);
+     if (li != txinfo.screenheight)
+ 	_set_screen_lines (li);
+     textattr (ispell_norm_attr);
+     }
diff -cp -r -N ispell-3.1-orig/pc/local.djg ispell-3.1/pc/local.djg
*** ispell-3.1-orig/pc/local.djg	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/local.djg	Sat Nov  9 22:11:30 1996
***************
*** 0 ****
--- 1,333 ----
+ /*
+  * Written by Eli Zaretskii <eliz@is.elta.co.il>
+  *
+  * This is local.h file suitable for compiling Ispell on MS-DOS systems
+  * with version 2.x of DJGPP port of GNU C/C++ compiler.
+  *
+  * $Id$
+  *
+  * $Log$
+  */
+ 
+ /*
+  * WARNING WARNING WARNING
+  *
+  * This file is *NOT* a normal C header file!  Although it uses C
+  * syntax and is included in C programs, it is also processed by shell
+  * scripts that are very stupid about format.
+  *
+  * Do not try to use #if constructs to configure this file for more
+  * than one configuration.  Do not place whitespace after the "#" in
+  * "#define".  Do not attempt to disable lines by commenting them out.
+  * Do not use backslashes to reduce the length of long lines.
+  * None of these things will work the way you expect them to.
+  *
+  * WARNING WARNING WARNING
+  */
+ 
+ /*
+ ** Things that normally go in a Makefile.  Define these just like you
+ ** might in the Makefile, except you should use #define instead of
+ ** make's assignment syntax.  Everything must be double-quoted, and
+ ** (unlike make) you can't use any sort of $-syntax to pick up the
+ ** values of other definitions.
+ */
+ 
+ #define CC      "gcc"
+ #define CFLAGS  "-O2 -g"
+ #define YACC    "bison -y"
+ 
+ /*
+ ** TERMLIB - DJGPP doesn't have one, it uses direct screen writes.
+ */
+ #define TERMLIB ""
+ 
+ /*
+ ** Where to install various components of ispell.  BINDIR contains
+ ** binaries.  LIBDIR contains hash tables and affix files.  ELISPDIR
+ ** contains emacs lisp files (if any) and TEXINFODIR contains emacs
+ ** TeXinfo files.  MAN1DIR and MAN1EXT will hold the chapter-1 and
+ ** chapter-4 manual pages, respectively.
+ **
+ ** If you intend to use multiple dictionary files, I would suggest
+ ** LIBDIR be a directory which will contain nothing else, so sensible
+ ** names can be constructed for the -d option without conflict.
+ */
+ #define BINDIR      "c:/djgpp/bin"
+ #define LIBDIR      "c:/djgpp/lib"
+ #define ELISPDIR    "c:/djgpp/gnu/emacs/site-lisp"
+ #define TEXINFODIR  "c:/djgpp/gnu/emacs/info"
+ #define MAN1DIR     "c:/djgpp/info"
+ #define MAN4DIR     "c:/djgpp/info"
+ 
+ /*
+ ** List of all hash files (languages) which will be supported by ispell.
+ **
+ ** This variable has a complex format so that many options can be
+ ** specified.  The format is as follows:
+ **
+ **	<language>[,<make-options>...] [<language> [,<make-options> ...] ...]
+ **
+ ** where
+ **
+ **	language	is the name of a subdirectory of the
+ **			"languages" directory
+ **	make-options	are options that are to be passed to "make" in
+ **			the specified directory.  The make-options
+ **			should not, in general, specify a target, as
+ **			this will be provided by the make process.
+ **
+ ** For example, if LANGUAGES is:
+ **
+ **	"{american,EXTRADICT=/usr/dict/words /usr/dict/web2} {deutsch}",
+ **
+ ** then the American-English and Deutsch (German) languages will be supported,
+ ** and when the English dictionary is built, the variable
+ ** 'EXTRADICT=/usr/dict/words /usr/dict/web2' will be passed to the makefile.
+ **
+ ** Notes on the syntax: The makefile is not very robust.  If you have
+ ** make problems, or if make seems to in the language-subdirs
+ ** dependency, check your syntax.  The makefile adds single quotes to
+ ** the individual variables in the LANGUAGES specification, so don't
+ ** use quotes of any kind.
+ **
+ ** In the future, the first language listed in this variable will
+ ** become the default, and the DEFHASH, DEFLANG, and DEFPAFF,
+ ** variables will all become obsolete.  So be sure to put your default
+ ** language first, to make later conversion easier!
+ **
+ ** Notes on options for the various languages will be found in the
+ ** Makefiles for those languages.  Some of those languages may require
+ ** you to also change various limits limits like MASKBITS or the
+ ** length parameters.
+ **
+ ** A special note on the English language: because the British and
+ ** American dialects use different spelling, you should usually select
+ ** one or the other of these.  If you select both, the setting of
+ ** MASTERHASH will determine which becomes the language linked to
+ ** DEFHASH (which will usually be named english.hash).
+ **
+ ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ ** !!! Note the pathname for the `words' file: it might be different !!!
+ ** !!! If you don't have this file, make EXTRADICT empty             !!!
+ ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+ #define LANGUAGES "{american,MASTERDICTS=americax.med,HASHFILES=amermedx.hash,EXTRADICT=c:/usr/lib/words}"
+ 
+ /*
+ ** Master hash file for DEFHASH.  This is the name of a hash file
+ ** built by a language Makefile.  It should be the most-popular hash
+ ** file on your system, because it is the one that will be used by
+ ** default.  It must be listed in LANGUAGES, above.
+ */
+ #define MASTERHASH	"amermedx.hash"
+ 
+ /*
+ ** Default native-language hash file.  This is the name given to the
+ ** hash table that will be used if no language is specified to
+ ** ispell.  It is a link to MASTERHASH, above.
+ */
+ #define DEFHASH "englishx.hash"
+ 
+ /*
+ ** If your sort command accepts the -T switch to set temp file
+ ** locations (try it out; on some systems it exists but is
+ ** undocumented), make the following variable the null string.
+ ** Otherwise leave it as the sed script.
+ **
+ ** With DJGPP, you will probably use GNU Sort which accepts -T, so:
+ */
+ #define SORTTMP ""
+ 
+ /*
+ ** If your system has the rename(2) system call, define HAS_RENAME and
+ ** ispell will use that call to rename backup files.  Otherwise, it
+ ** will use link/unlink.  There is no harm in this except on MS-DOS,
+ ** which might not support link/unlink (DJGPP does, but also has rename).
+ */
+ #define HAS_RENAME 1
+ 
+ /* environment variable for user's word list */
+ #ifndef PDICTVAR
+ #define PDICTVAR "WORDLIST"
+ #endif
+ 
+ /*
+ ** Prefix part of default private dictionary.  Under MS-DOS 8.3
+ ** filename limitation, we are in trouble...
+ */
+ #define DEFPDICT "_isp_"
+ 
+ /* old place to look for default word list */
+ #define OLDPDICT   "_isp_"
+ 
+ /*
+ ** mktemp template for temporary file - MUST contain 6 consecutive X's.
+ ** On MSDOS the directory part of TEMPNAME is only used if neither $TMP
+ ** nor $TEMP nor $TMPDIR (in that order) are defined.  If any of these
+ ** variables is defined, the filename part of TEMPNAME is appended to
+ ** their value.
+ */
+ #define TEMPNAME "c:/isXXXXXX"
+ 
+ /*
+ ** If REGEX_LOOKUP is NOT defined, the lookup command (L) will use the look(1)
+ ** command (if available) or the egrep command.  If REGEX_LOOKUP is defined,
+ ** the lookup command will use the internal dictionary and the
+ ** regular-expression library (which you must supply separately.
+ ** DJGPP v2 has POSIX regexp functions.
+ */
+ #define REGEX_LOOKUP    1
+ 
+ /*
+ ** Choose the proper type of regular-expression routines here.  BSD
+ ** and public-domain systems have routines called re_comp and re_exec;
+ ** System V uses regcmp and regex.
+ */
+ #include <sys/types.h>
+ #include <regex.h>
+ #define REGCTYPE		regex_t *
+ #define REGCMP(re,str)		(regcomp (re, str, 0), re)
+ #define REGEX(re, str, dummy) \
+   (re != 0 && regexec (re, str, 0, 0, 0) == 0 ? (char *)1 : NULL)
+ #define REGFREE(re) \
+   do { 							\
+       if (re == 0)					\
+         re = (regex_t *)calloc (1, sizeof (regex_t));	\
+       else						\
+ 	regfree(re);					\
+   } while (0)
+ 
+ /*
+ **
+ ** The 2 following definitions are only meaningfull if you don't use
+ ** any regex library.
+ */
+ /* path to egrep (use speeded up version if available);
+    defined without explicit path, since there are no
+    standard places for programs on MS-DOS.  */
+ #define  EGREPCMD "egrep -i"
+ 
+ /* path to wordlist for Lookup command (typically /usr/dict/{words|web2}) */
+ /* note that /usr/dict/web2 is usually a bad idea due to obscure words */
+ #undef WORDS
+ 
+ /*
+ ** FIXME: The filename truncation below is not flexible enough for DJGPP
+ **	  which can support long filenames on some platforms, since we
+ **	  will only know if the support is available at runtime.
+ */
+ 
+ /* max file name length (will truncate to fit BAKEXT) if not in sys/param.h */
+ #ifdef NAME_MAX
+ #define MAXNAMLEN NAME_MAX
+ #else
+ #define MAXNAMLEN 12
+ #endif
+ 
+ #define MAXEXTLEN        4    /* max. extension length including '.'   */
+ #define MAXBASENAMELEN   8    /* max. base filename length without ext */
+ 
+ /* define if you want .bak file names truncated to MAXNAMLEN characters */
+ /* On MS-DOS, we really have no choice... */
+ #define TRUNCATEBAK 1
+ 
+ /*
+ ** This is the extension that will be added to backup files.
+ ** On MS-DOS, it makes sense to use the shortest possible extension.
+ */
+ #define	BAKEXT	"~"
+ 
+ /*
+ ** Define the following to suppress the 8-bit character feature.
+ ** FIXME: does this defeat support of foreign languages?
+ */ 
+ #define NO8BIT  1
+ 
+ /*
+ ** Define this if you want to use the shell for interpretation of commands
+ ** issued via the "L" command, "^Z" under System V, and "!".  If this is
+ ** not defined then a direct spawnvp() will be used in place of the
+ ** normal system().  This may speed up these operations if the SHELL
+ ** environment variable points to a Unix-like shell (such as `sh' or `bash').
+ **
+ ** However, if you undefine USESH, commands which use pipes, redirection
+ ** and shell wildcards won't work, and you will need support for the SIGTSTP
+ ** signal, for the above commands to work at all.
+ */
+ 
+ #define USESH	1
+ 
+ /*
+ ** Define this if you want to be able to type any command at a "type space
+ ** to continue" prompt.
+ */
+ #define COMMANDFORSPACE 1
+ 
+ /*
+ ** The next three variables are used to provide a variable-size context
+ ** display at the bottom of the screen.  Normally, the user will see
+ ** a number of lines equal to CONTEXTPCT of his screen, rounded down
+ ** (thus, with CONTEXTPCT == 10, a 24-line screen will produce two lines
+ ** of context).  The context will never be greater than MAXCONTEXT or
+ ** less than MINCONTEXT.  To disable this feature entirely, set MAXCONTEXT
+ ** and MINCONTEXT to the same value.  To round context percentages up,
+ ** define CONTEXTROUNDUP.
+ **
+ ** Warning: don't set MAXCONTEXT ridiculously large.  There is a
+ ** static buffer of size MAXCONTEXT*BUFSIZ; since BUFSIZ is frequently
+ ** 1K or larger, this can create a remarkably large executable.
+ */
+ #define CONTEXTPCT	20	/* Use 20% of the screen for context */
+ #define MINCONTEXT	2	/* Always show at least 2 lines of context */
+ #define MAXCONTEXT	10	/* Never show more than 10 lines of context */
+ #define CONTEXTROUNDUP	1       /* Round context up */
+ 
+ /*
+ ** Define this if you want the "mini-menu," which gives the most important
+ ** options at the bottom of the screen, to be the default (in any case, it
+ ** can be controlled with the "-M" switch).
+ */
+ #define MINIMENU
+ 
+ /*
+ ** Redefine GETKEYSTROKE() to whatever appropriate on some MS-DOS systems
+ ** where getchar() doesn't operate properly in raw mode.
+ */
+ #ifdef __DJGPP__
+ #include <pc.h>
+ #include <keys.h>
+ #define GETKEYSTROKE()	getxkey()
+ #else
+ #define GETKEYSTROKE()	getch()
+ #endif
+ 
+ /*
+ ** We include <fcntl.h> to have the definition of O_BINARY.  The
+ ** configuration script will notice this and define MSDOS_BINARY_OPEN.
+ */
+ #include <fcntl.h>
+ 
+ /*
+ ** Environment variable to use to locate the home directory.  On DOS
+ ** systems we set this to ISPELL_HOME to avoid conflicts with
+ ** other programs that look for a HOME environment variable.
+ */
+ #define HOME              "ISPELL_HOME"
+ #define PDICTHOME         "c:"
+ #define OPTIONVAR         "ISPELL_OPTIONS"
+ #define LIBRARYVAR        "ISPELL_DICTDIR"
+ 
+ /*
+ ** On MS-DOS systems, we define the following variables so that
+ ** ispell's files have legal suffixes.  Note that these suffixes
+ ** must agree with the way you've defined dictionary files which
+ ** incorporate these suffixes.
+ **
+ ** Actually, it is not recommended at all to change the suffixes,
+ ** since they are hardwired in the Makefile's under languages/
+ ** subdirectory, and MS-DOS will silently truncate excess letters anyway.
+ */
+ #define HASHSUFFIX	".hash"
+ #define STATSUFFIX	".stat"
+ #define COUNTSUFFIX	".cnt"
diff -cp -r -N ispell-3.1-orig/pc/local.emx ispell-3.1/pc/local.emx
*** ispell-3.1-orig/pc/local.emx	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/local.emx	Wed May 29 17:45:08 1996
***************
*** 0 ****
--- 1,81 ----
+ /*
+  *         Local.h for MSDOS emx
+ */
+ 
+ #define CC       "gcc"
+ 
+ #define MSDOS
+ 
+ #define BINDIR  "c:/ispell/bin"
+ #define LIBDIR  "c:/ispell/lib"
+ #define ELISPDIR "c:/ispell/lib/emacs/site-el"
+ #define TEXINFODIR "c:/ispell/info"
+ #define MAN1DIR "c:/ispell/man"
+ #define MAN4DIR "c:/ispell/man"
+ 
+ #define LANGUAGES "{american,MASTERDICTS=american.med+,HASHFILES=amerimed+.has,EXTRADICT=c:/ispell/dict/words} {deutsch,DICTALWAYS=deutsch.sml,DICTOPTIONS=}"
+ #define MASTERHASH      "amermed+.has"
+ /* above only for Makefiles not for ispell! */
+ 
+ #define DEFHASH "english.has"
+ 
+ #define SORTTMP "-e '/!!SORTTMP!!/s/=.*$/=/'"
+ #define MAKE_SORTTMP ""
+ 
+ 
+ #include <fcntl.h>
+ #include <conio.h>
+ #include <regexp.h>
+ 
+ #undef NO8BIT
+ 
+ #define HAS_RENAME
+ 
+ #define REGLIB   "-lregexp"
+ 
+ #define DEFPDICT "_"
+ #define DEFPAFF "words"
+ #define OLDPDICT "_"
+ #define OLDPAFF "words"
+ #define TEMPNAME  "isXXXXXX"
+ #define REGEX_LOOKUP
+ #define REGCMP(str)             regcomp (str,(char *) 0)
+ #define REGEX(re, str, dummy)   regexec (re, str, dummy, dummy, dummy, dummy, \
+                                     dummy, dummy, dummy, dummy, dummy, dummy)
+ #define EGREPCMD "grep386 -E"
+ 
+ #define WORDS   "c:/ispell/dict/words"
+ #define MAXNAMLEN       12    /* basename + "." + extension            */
+ 
+ #ifdef MSDOS
+ #define MAXEXTLEN        4    /* max. extension length including '.'   */
+ #define MAXBASENAMELEN   8    /* max. base filename length without ext */
+ #define MAXARGS        100    /* max. number of arguments passed to
+                                * ispell by OPTIONVAR
+                                */
+ #endif  /* MSDOS */
+ 
+ #define TRUNCATEBAK
+ 
+ #define INPUTWORDLEN    100  /* word accepted from a file + 1;     dflt: 100 */
+ #define MAXAFFIXLEN      20  /* amount a word might be extended;   dflt: 20  */
+ #define MASKBITS         32  /* # of affix flags;                  dflt: 32  */
+ #define MAXSTRINGCHARS  100  /* # of "string" chars in affix file; dflt: 100 */
+ #define MAXSTRINGCHARLEN 10  /* max. length of a "string" char;    dflt: 10  */
+ 
+ #define USESH
+ #define DEFTEXFLAG      1
+ #define MINIMENU
+ #define PIECEMEAL_HASH_WRITES
+ #define GETKEYSTROKE()  getch ()
+ 
+ #define HOME              "ISPELL_HOME"
+ #define OPTIONVAR         "ISPELL_OPTIONS"
+ #define LIBRARYVAR        "ISPELL_DICTDIR"
+ #define PDICTHOME         "c:"
+ #define HASHSUFFIX        ".has"
+ #define STATSUFFIX        ".stt"
+ #define COUNTSUFFIX       ".cnt"
+ 
+ #define MASKTYPE_STRING "long"
+ #define SIGNAL_TYPE_STRING "void"
diff -cp -r -N ispell-3.1-orig/pc/make-dj.bat ispell-3.1/pc/make-dj.bat
*** ispell-3.1-orig/pc/make-dj.bat	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/make-dj.bat	Sat Nov 16 15:20:40 1996
***************
*** 0 ****
--- 1,45 ----
+ @Rem Do not turn echo off so they will see what is going on
+ copy language\english\msgs.h msgs.h > nul
+ copy pc\local.djgpp local.h > nul
+ copy config.X config.h > nul
+ echo /* AUTOMATICALLY-GENERATED SYMBOLS */ >> config.h
+ echo #define SIGNAL_TYPE_STRING "void" >> config.h
+ echo #define MASKTYPE_STRING "long" >> config.h
+ @Rem
+ @Rem Use the following Goto when you only change a few source
+ @Rem files and do not want to recompile all of them
+ :: goto build
+ gcc -c -O2 -g buildhas.c
+ gcc -c -O2 -g correct.c
+ gcc -c -O2 -g defmt.c
+ gcc -c -O2 -g dump.c
+ gcc -c -O2 -g fields.c
+ gcc -c -O2 -g good.c
+ gcc -c -O2 -g hash.c
+ gcc -c -O2 -g icombine.c
+ gcc -c -O2 -g ijoin.c
+ gcc -c -O2 -g ispell.c
+ gcc -c -O2 -g lookup.c
+ gcc -c -O2 -g makedent.c
+ gcc -c -O2 -g sq.c
+ gcc -c -O2 -g term.c
+ gcc -c -O2 -g tgood.c
+ gcc -c -O2 -g tree.c
+ gcc -c -O2 -g unsq.c
+ gcc -c -O2 -g xgets.c
+ bison -y parse.y
+ gcc -c -O2 -g y_tab.c -o parse.o
+ if exist y_tab.c del y_tab.c
+ gcc -o buildhash buildhash.o hash.o makedent.o parse.o
+ gcc -o icombine icombine.o makedent.o parse.o
+ gcc -o ijoin ijoin.o fields.o
+ gcc -o sq sq.o
+ gcc -o unsq unsq.o
+ :build
+ @echo ispell.o term.o correct.o defmt.o dump.o good.o > link.lst
+ @echo lookup.o hash.o makedent.o tgood.o tree.o xgets.o >> link.lst
+ gcc -o ispell @link.lst
+ @del link.lst
+ @Rem
+ @Rem Strip the .exe but leave the COFF output with debug info
+ strip *.exe
diff -cp -r -N ispell-3.1-orig/pc/makeemx.bat ispell-3.1/pc/makeemx.bat
*** ispell-3.1-orig/pc/makeemx.bat	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/makeemx.bat	Sat Nov 16 15:19:24 1996
***************
*** 0 ****
--- 1,66 ----
+ set CC=gcc
+ set CFLAGS=-O
+ set REGLIB=-lregexp
+ set TERMLIB=-ltermcap
+ set YACC=yacc
+ 
+ copy language\english\msgs.h
+ copy pc\local.emx local.h
+ copy config.x config.h
+ :: goto build
+ gcc -O -c buildhas.c
+ gcc -O -c correct.c
+ gcc -O -c defmt.c
+ gcc -O -c dump.c
+ gcc -O -c fields.c
+ gcc -O -c good.c
+ gcc -O -c hash.c
+ gcc -O -c icombine.c
+ gcc -O -c ijoin.c
+ gcc -O -c ispell.c
+ gcc -O -c lookup.c
+ gcc -O -c makedent.c
+ gcc -O -c sq.c
+ gcc -O -DUSG -c term.c
+ gcc -O -c tgood.c
+ gcc -O -c tree.c
+ gcc -O -c unsq.c
+ gcc -O -c xgets.c
+ 
+ yacc parse.y
+ gcc -O -c y_tab.c
+ move y_tab.o parse.o
+ del y_tab.c
+ 
+ gcc -O -o buildhash buildhash.o hash.o makedent.o parse.o %LIBES%
+ emxbind -b buildhash
+ emxbind -s buildhas.exe
+ 
+ gcc -O -o icombine icombine.o makedent.o parse.o %LIBES%
+ emxbind -b icombine
+ emxbind -s icombine.exe
+ 
+ gcc -O -o ijoin ijoin.o fields.o %LIBES%
+ emxbind -b ijoin
+ emxbind -s ijoin.exe
+ 
+ gcc -O -o sq sq.o
+ emxbind -b sq
+ emxbind -s sq.exe
+ 
+ gcc -O -o unsq unsq.o
+ emxbind -b unsq
+ emxbind -s unsq.exe
+ 
+ :build
+ ar -q ispell.a term.o ispell.o correct.o defmt.o dump.o good.o lookup.o hash.o makedent.o tgood.o tree.o xgets.o
+ gcc -O -o ispell ispell.a %TERMLIB% %REGLIB% %LIBES%
+ :: strip ispell
+ emxbind -b -s ispell
+ :: because of use of system()
+ emxbind -a ispell -p
+ :: goto end
+ 
+ 
+ :end
+ del ispell.a
diff -cp -r -N ispell-3.1-orig/pc/readme ispell-3.1/pc/readme
*** ispell-3.1-orig/pc/readme	Thu Jan  1 00:00:00 1970
--- ispell-3.1/pc/readme	Sat Nov 16 20:08:30 1996
***************
*** 0 ****
--- 1,330 ----
+                 How to build Ispell on MS-DOS
+ 		-----------------------------
+ 
+ This directory includes files necessary to build Ispell on MS-DOS
+ systems.  Two environments are supported: EMX/GCC and DJGPP; they both
+ generate 32-bit protected-mode programs and therefore aren't afflicted
+ by most of the MS-DOS memory-related limitations.  The EMX setup does
+ not currently support building the dictionaries, so you will need to
+ either build the dictionaries with DJGPP tools or get them elsewhere.
+ The DJGPP executables will also run on MS-Windows (3.x or 9x) as DOS
+ console applications.
+ 
+ 
+ 1.  Building Ispell with EMX/GCC
+     ----------------------------
+ 
+     You will only need the basic EMX development tools to compile
+     Ispell.  After unzipping the source archive, invoke the
+     MAKEEMX.BAT batch file, like so:
+ 
+ 	   pc\makeemx
+ 
+     This generates ispell.exe and the following auxiliary programs:
+ 
+ 	   buildhas.exe icombine.exe ijoin.exe sq.exe unsq.exe
+ 
+     Install the programs anywhere along your PATH.  See the section
+     named "Environment Variables" for information on environment
+     variables used by the MS-DOS port of Ispell.
+ 
+ 
+ 2.  Building Ispell (no dictionaries) with DJGPP
+     --------------------------------------------
+ 
+     If you only need to compile Ispell without building the
+     dictionaries, use the MAKE-DJ.BAT batch file:
+ 
+ 	   pc\make-dj
+ 
+     You will need the standard DJGPP development environment
+     (djdevNNN.zip, gccNNNNb.zip, bnuNNNb.zip) and the DJGPP port of
+     GNU Bison (bsnNNNb.zip) for the above to work.  After the build is
+     finished, read the section below about environment variables and
+     install the executables and the dictionaries as you see fit.
+ 
+ 
+ 3.  Building Ispell and the dictionaries with DJGPP
+     -----------------------------------------------
+ 
+     In addition to the standard development environment, you will need
+     these tools to build Ispell and the dictionaries:
+ 
+     a. A port of Unix-like shell.
+        The only shell that was used successfully to build Ispell on
+        MS-DOS is the `bash' port by Daisuke Aoyama <jack@st.rim.or.jp>
+        which should be available from DJGPP archives; if not, try one
+        of the URLs below (or write to the author of the port):
+        
+ 	  http://www.st.rim.or.jp/~jack/alpha/index.html
+ 	  http://www.neongenesis.com/~jack/djgpp-work/alpha/index.html
+ 
+        You should create a ``symlink'' named `sh.exe' which will run
+        `bash.exe', for the Ispell Makefiles to work.  Here is how:
+ 
+ 		stubify -g c:/djgpp/bin/sh.exe
+ 		stubedit c:/djgpp/bin/sh.exe runfile=bash
+ 
+ 
+        (change the pathname as appropriate for your installation of
+        `bash').
+ 
+        If you are thinking about using Stewartson's `ms_sh', don't:
+        its method of passing long command lines is incompatible with
+        DJGPP, and it will crash and burn on complex shell scripts.
+ 
+     b. A DJGPP port of GNU Make 3.75 or later.
+        This is available from DJGPP archives at the following URL:
+ 
+ 	ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/mak375b.zip
+ 
+        Note that ports of GNU Make prior to 3.75 didn't support a
+        Unix-like shell, so you won't be able to build Ispell with them.
+ 
+     c. A DJGPP port of GNU Fileutils, GNU Textutils and GNU Sh-utils,
+        also available from DJGPP archives:
+ 
+ 	ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/fil313b.zip
+ 	ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/txt119b.zip
+ 	ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/shl112b.zip
+ 
+        The build process doesn't need *all* of the programs from these
+        packages, so if you are short on disk space, you should be able
+        to get away with these programs (I hope I didn't forget some):
+ 
+ 	 Fileutils: rm, mv, chmod, install, mkdir, ln, cp, touch, ls
+ 	 Textutils: cat, head, tail, sort, comm, wc, join, uniq
+ 	 Sh-utils:  echo, expr, false, true
+ 
+     d. GNU Sed (sed118b.zip from the DJGPP archives).
+ 
+     e. GNU Awk (or any other port of Awk).  Gawk is available from the
+        DJGPP site above (gwk300b.zip); if you use it, make a
+        ``symlink'' called `awk.exe' to it:
+ 
+ 		stubify -g c:/djgpp/bin/awk.exe
+ 		stubedit c:/djgpp/bin/awk.exe runfile=gawk
+ 
+     f. GNU Bison (bsn124b.zip from the DJGPP site).
+ 
+     g. GNU Grep (grep20b.zip from the DJGPP site).
+ 
+     h. Makeinfo from GNU Texinfo distribution (to produce the
+        hypertext Info docs for Ispell).  Get txi390b.zip from the
+        DJGPP site above.  If you have Emacs installed, you can use it
+        to generate Info files instead.  The Makefile target which
+        generates Info docs doesn't work on MS-DOS (see below), so you
+        will have to invoke it manually.
+ 
+     i. ctags and etags (for the `TAGS' and `tags' targets of the
+        Makefile).  These are available from the Emacs distribution,
+        also on the DJGPP archive site above (em1934b.zip).
+ 
+     While you probably can find quite a few different ports of the
+     above utilities, I would generally advise against using anything
+     but the DJGPP ports, since the Makefiles and the shell scripts
+     depend on long command lines and will most probably break
+     otherwise.  DJGPP ports are a coherent set of tools which will
+     work together well and ensure that the Makefiles and the scripts
+     work as advertised.
+ 
+     Here is what you should do to build Ispell:
+ 
+     1) Install the above utilities anywhere along your PATH.  Make
+        sure that you don't have any other executable called `sh'
+        neither in /bin (if you have such a directory) nor anywhere
+        along your PATH *prior* to the directory where you installed
+        the bash port.  When Make runs, it will invoke the first
+        program named `sh' that it finds in /bin or along the PATH, and
+        you need to ensure that the right program is called.
+ 
+     2) Review the options set on pc/local.djgpp and change them as you
+        see fit.  Some things that you might consider changing are the
+        pathnames of the standard directories, the dictionaries that
+        will be built (see below), the backup extension ("~" by
+        default), and the extra dictionary pathname (default:
+        "c:/usr/lib/words"; make it empty if you have no extra
+        dictionary).
+ 
+     3) Set TMPDIR environment variable to point to a place which has
+        at least 20MB of free space, for the temporary files produced
+        by the dictionary build process.
+ 
+     4) Type these commands:
+ 
+ 	    pc\configdj
+ 	    make
+ 
+        This will run for some time, depending on the dictionaries that
+        you've chosen to build.  The default setup builds a plus
+        version of a medium-sized american dictionary, and should take
+        about 20 minutes on an average 486-DX2/66.  Note that on MS-DOS
+        the build time does not depend so much on the dictionary size
+        as it is on Unix: it takes only about 25 minutes to build the
+        extra-large plus version with /usr/dict/words file.  I believe
+        the reason for this is that the build process is much more I/O
+        bound on MS-DOS than it is on Unix, since MS-DOS pipes are
+        simulated with disk files.
+ 
+        If pc/configdj.bat complains that it runs out of environment
+        space, enlarge the environment available to COMMAND.COM (or
+        whatever your interactive command processor is).
+ 
+        When the dictionaries are built, you will see error messages,
+        about ``Improper links'', like so:
+ 
+          c:/djgpp/bin/ln: cannot create symbolic link `./english.0' \
+ 		to `../english/english.0': Improper link (EXDEV)
+ 
+        You can safely disregard these messages: they are due to the
+        fact that MS-DOS doesn't support symbolic links. The Makefile
+        already has a provision for alternative methods which are
+        automatically used in case of failures and which do work on
+        MS-DOS.
+ 
+        Another error message that you might see is something like
+        this:
+ 
+          Word 'U.S.A' contains illegal characters
+ 
+        This means that some of the words in the EXTRADICT dictionary
+        are incompatible with Ispell, and Ispell is ignoring them when
+        it builds hashed dictionary.  (The file `/usr/dict/words' from
+        Solaris machines is known to have this problem.)  The rest of
+        the words are OK and will be used by Ispell, so here, too, you
+        don't have to do anything about the error message.
+ 
+     5) To produce the Info docs, you will have to invoke Makeinfo
+        manually:
+ 
+ 	    makeinfo ispell.texinfo
+ 
+        This is because the `ispell.info' target of the Makefile fails
+        on MS-DOS.  It uses the `iwhich' shell script which assumes too
+        many Unixy things about where the binaries reside, and I
+        decided it was not worth fixing for such a simple job.
+ 
+     6) After Make finishes, install the programs and the dictionaries
+        as you see fit.  The dictionary files you need to install are
+        the files with a .hash extension in the subdirectories of
+        languages/ directory (e.g. languages/american/amermedx.hash)
+        and the file languages/english/english.aff. 
+ 
+     7) If you need to use some of the shell scripts (such as iwhich,
+        Makekit and splitdict), you will need to edit them to replace
+        the first line which says:
+ 
+ 	   : Use /bin/sh
+ 
+        to say this instead:
+ 
+ 	   #!/bin/sh
+ 
+ 
+ 4.  Dictionary names
+     ----------------
+ 
+     The filenames used for the dictionaries on Unix are too long for
+     MS-DOS, and will cause filename clashes or failed programs.
+     Therefore, the MS-DOS configuration script for DJGPP edits the
+     Makefiles to change these names as follows:
+ 
+          americansml -> amersml
+ 	 americanmed -> amermed
+ 	 americanlrg -> amerlrg
+ 	 americanxlg -> amerxlg
+ 	 altamersml  -> altasml
+ 	 altamermed  -> altamed
+ 	 altamerlrg  -> altalrg
+ 	 altamerxlg  -> altaxlg
+ 	 britishsml  -> britsml
+ 	 britishmed  -> britmed
+ 	 britishlrg  -> britlrg
+ 	 britishxlg  -> britxlg
+ 
+     In addition, the `+' character (which is illegal in MS-DOS
+     filenames) is converted into an `x', and if the `+' is at the end
+     of the extension, it is moved into the first 8 characters of the
+     basename.  Thus, americanlrg+.hash is converted into amerlrgx.hash
+     and american.sml+ into americax.sml.
+ 
+     These DOSified filenames are the ones that you should use if you
+     decide to change the dictionaries generated by the build process.
+     The easiest way to know what are the DOS names of the different
+     dictionaries is to look at the edited Makefiles in language/
+     subdirectories after you build Ispell once for the default
+     dictionaries.
+ 
+ 
+ 5.  Environment variables
+     ---------------------
+ 
+     Ispell uses environment variables to make it easier to support
+     different installations.  Most of these variables tell Ispell
+     where to look for its hashed and private dictionaries.  These
+     variables are documented on the ispell.1 man page and in the Info
+     docs for Ispell.  Below is the list of DOS-specific environment
+     variables which are not covered by the Ispell docs:
+ 
+ 	ISPELL_OPTIONS - the default options to pass to Ispell.  These
+ 			 are passed to Ispell as if they were typed by
+ 			 you before all the options you actually
+ 			 mentioned on the Ispell command line.  Since
+ 			 Ispell parses options left to right,
+ 			 options from the command line may override
+ 			 those in `ISPELL_OPTIONS' variable.
+ 
+ 	ISPELL_DICTDIR - the directory where Ispell will look for the
+ 			 alternate hashed dictionary file.  The
+ 			 default dictionary pathname is built into
+ 			 Ispell when it is compiled (see the
+ 			 definition of LIBDIR and DEFHASH on local.h
+ 			 file, local.djgpp or local.emx), but you can
+ 			 set this variable which will allow you to
+ 			 name alternate dictionaries relative to the
+ 			 directory named by it, avoiding a long
+ 			 pathname.
+ 
+ 	ISPELL_HOME    - replaces HOME on Unix systems.  This is where
+ 			 Ispell looks for a personal dictionary if it
+ 			 is given as a relative pathname.
+ 
+ 	ISPELL_COLORS -  the colors which will be used by Ispell for
+ 			 the normal and "standout" text.  By defualt,
+ 			 these are the normal and inverse video
+ 			 colors, but you may set them to any colors
+ 			 you like.  The color descriptor is a pair of
+ 			 numbers separated by a dot; the first number
+ 			 is the color text attribute which will be set
+ 			 for the normal text, and the second is the
+ 			 attribute for the "standout" text (the
+ 			 misspelled words).  The text color attributes
+ 			 are the usual PC background/foreground
+ 			 definitions.  My favorite setting is this:
+ 
+ 			    set ISPELL_COLORS=0x1e.0x74
+ 
+ 			 which sets the normal colors to yellow on
+ 			 blue and the "standout" colors to red on
+ 			 white.  The color descriptor is parsed by a
+ 			 call to `strtoul' library function, so you
+ 			 can use octal and hex numbers as well as
+ 			 decimal ones.
+ 
+ 			 This color feature is only supported by the
+ 			 DJGPP port of Ispell.
+ 
+ 	LINES	      -  the size of the screen to be used by Ispell.
+ 			 Although this is not a DOS-specific variable,
+ 			 it does have a DOS-specific effect on the
+ 			 DJGPP port of Ispell: if the value of this
+ 			 variable is different from the current screen
+ 			 size, Ispell will set the screen size to the
+ 			 size given by LINES (and restore the original
+ 			 size when it exits or shells out to DOS).
+ 			 The following sizes are supported by the
+ 			 DJGPP port on a standard VGA display: 25, 28,
+ 			 35, 40, 43 and 50 lines.  If you want to run
+ 			 Ispell in some other non-standard screen
+ 			 size, set the display to that size before
+ 			 running Ispell and set LINES to that size.
diff -cp -r -N ispell-3.1-orig/readme ispell-3.1/readme
*** ispell-3.1-orig/readme	Thu Oct 12 19:04:04 1995
--- ispell-3.1/readme	Sat Nov 16 19:32:56 1996
*************** What's New in This Version?
*** 33,38 ****
--- 33,40 ----
      ispell 3.1 has many bug fixes, a number of minor improvements, and
      vastly improved support for multiple languages.
  
+     Ispell now can be built for MS-DOS.
+ 
      The only truly important difference between 3.0 and 3.1 is in the
      format of the "defstringtype" and "altstringtype" statements,
      which now require a deformatter argument.  Existing affix files
*************** Where Can I Get Ispell?
*** 71,76 ****
--- 73,81 ----
  
  OK, How Do I Install It?
  
+     (For installation on MS-DOS, see the section about MS-DOS at the
+     end of this file.)
+ 
      Ispell is quite portable (thanks to many people).  If you speak
      American English and have a BSD-like system, you may be able to
      get away with simply typing "make all" to finish unpacking
*************** Special Installation Notes for Certain M
*** 375,387 ****
  
  What About Ispell for MS-DOS?
  
!     Although ispell is not officially supported on MS-DOS, there are a
!     couple of #defines that you might find useful if you want to do
!     such a thing.  Check the end of config.X.  Several people have
!     reported success building DOS versions using emx/gcc.  Others have
!     used the djgpp package, with bison replacing yacc.  Some places to
!     look for a DOS ispell if you have an x86:
  
  	ftp.cdrom.com:pub/os2/unix/isp3009b.zip.
  	or
  	ftp-os2.cdrom.com:pub/os2/2_x/unix/
--- 380,393 ----
  
  What About Ispell for MS-DOS?
  
!     Ispell now supports MS-DOS officially.  You can build Ispell for
!     MS-DOS with either EMX/GCC or DJGPP.  See the file pc/README for
!     compilation instructions.
! 
!     Some other places to look for a DOS ispell if you have an x86:
  
+ 	ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/isp3120b.zip
+ 	or
  	ftp.cdrom.com:pub/os2/unix/isp3009b.zip.
  	or
  	ftp-os2.cdrom.com:pub/os2/2_x/unix/
diff -cp -r -N ispell-3.1-orig/subset.x ispell-3.1/subset.x
*** ispell-3.1-orig/subset.x	Mon Jan 23 18:28:28 1995
--- ispell-3.1/subset.x	Sat Nov  9 13:57:38 1996
*************** TEMPDICT=${TMP}c
*** 118,125 ****
  FAKEDICT=${TMP}d
  FAKEHASH=${TMP}e!!HASHSUFFIX!!
  
! trap "/bin/rm -f ${TMP}*; exit 1" 1 2 15
! trap "/bin/rm -f ${TMP}*; exit 0" 13
  
  #
  # Create a dummy dictionary to hold a compiled copy of the language
--- 118,125 ----
  FAKEDICT=${TMP}d
  FAKEHASH=${TMP}e!!HASHSUFFIX!!
  
! trap "rm -f ${TMP}*; exit 1" 1 2 15
! trap "rm -f ${TMP}*; exit 0" 13
  
  #
  # Create a dummy dictionary to hold a compiled copy of the language
*************** trap "/bin/rm -f ${TMP}*; exit 0" 13
*** 127,135 ****
  #
  echo 'QQQQQQQQ' > $FAKEDICT
  buildhash -s $FAKEDICT $langtabs $FAKEHASH \
!   ||  (echo "Couldn't create fake hash file" 1>&2; /bin/rm -f ${TMP}*; exit 1) \
    ||  exit 1
! /bin/rm -f ${FAKEDICT}*
  #
  # Figure out what the flag-marking character is.
  #
--- 127,135 ----
  #
  echo 'QQQQQQQQ' > $FAKEDICT
  buildhash -s $FAKEDICT $langtabs $FAKEHASH \
!   ||  (echo "Couldn't create fake hash file" 1>&2; rm -f ${TMP}*; exit 1) \
    ||  exit 1
! rm -f ${FAKEDICT}*
  #
  # Figure out what the flag-marking character is.
  #
*************** do
*** 159,165 ****
        | sort -u $SORTTMP > ${TEMPDICT}.$dictno
      dictno=`expr $dictno + 1`
  done
! /bin/rm -f $MUNCHOUTPUT
  #
  #	(3) For each adjacent pair of dictionaries, use comm to find words
  #	    in the smaller that are missing from the larger, and add them
--- 159,165 ----
        | sort -u $SORTTMP > ${TEMPDICT}.$dictno
      dictno=`expr $dictno + 1`
  done
! rm -f $MUNCHOUTPUT
  #
  #	(3) For each adjacent pair of dictionaries, use comm to find words
  #	    in the smaller that are missing from the larger, and add them
*************** do
*** 180,186 ****
      lastdict="${TEMPDICT}.$dictno"
      dictno=`expr $dictno + 1`
  done
! /bin/rm -f $MISSINGWORDS.*
  #
  #	(4) For each pair of dictionaries, use comm to eliminate words in
  #	    the smaller from the larger, and shrink the result with munchlist.
--- 180,186 ----
      lastdict="${TEMPDICT}.$dictno"
      dictno=`expr $dictno + 1`
  done
! rm -f $MISSINGWORDS.*
  #
  #	(4) For each pair of dictionaries, use comm to eliminate words in
  #	    the smaller from the larger, and shrink the result with munchlist.
*************** for dictfile
*** 194,201 ****
  do
      comm -13 $lastdict ${TEMPDICT}.$dictno \
        | munchlist -l $langtabs > $outbase.$dictno
!     /bin/rm -f $lastdict
      lastdict="${TEMPDICT}.$dictno"
      dictno=`expr $dictno + 1`
  done
! /bin/rm -f ${TMP}*
--- 194,201 ----
  do
      comm -13 $lastdict ${TEMPDICT}.$dictno \
        | munchlist -l $langtabs > $outbase.$dictno
!     rm -f $lastdict
      lastdict="${TEMPDICT}.$dictno"
      dictno=`expr $dictno + 1`
  done
! rm -f ${TMP}*
diff -cp -r -N ispell-3.1-orig/term.c ispell-3.1/term.c
*** ispell-3.1-orig/term.c	Wed Nov  2 18:44:28 1994
--- ispell-3.1/term.c	Sat Nov  9 16:55:04 1996
*************** static char Rcs_Id[] =
*** 67,74 ****
--- 67,76 ----
  #ifdef USG
  #include <termio.h>
  #else
+ #ifndef __DJGPP__
  #include <sgtty.h>
  #endif
+ #endif
  #include <signal.h>
  
  void		erase P ((void));
*************** void		move P ((int row, int col));
*** 76,82 ****
--- 78,86 ----
  void		inverse P ((void));
  void		normal P ((void));
  void		backup P ((void));
+ #ifndef __DJGPP__
  static int	putch P ((int c));
+ #endif
  void		terminit P ((void));
  SIGNAL_TYPE	done P ((int signo));
  #ifdef SIGTSTP
*************** int		shellescape P ((char * buf));
*** 88,95 ****
--- 92,108 ----
  void		shescape P ((char * buf));
  #endif /* USESH */
  
+ static int	termchanged = 0;
+ 
+ #ifdef __DJGPP__
+ #include "pc/djterm.c"
+ #endif
+ 
  void erase ()
      {
+ #ifdef __DJGPP__
+     clrscr ();
+ #else
  
      if (cl)
  	tputs (cl, li, putch);
*************** void erase ()
*** 101,139 ****
  	    tputs (tgoto (cm, 0, 0), 100, putch);
  	tputs (cd, li, putch);
  	}
      }
  
  void move (row, col)
      int		row;
      int		col;
      {
      tputs (tgoto (cm, col, row), 100, putch);
      }
  
  void inverse ()
      {
      tputs (so, 10, putch);
      }
  
  void normal ()
      {
      tputs (se, 10, putch);
      }
  
  void backup ()
      {
      if (BC)
  	tputs (BC, 1, putch);
      else
! 	(void) putchar ('\b');
      }
  
  static int putch (c)
      int			c;
      {
  
      return putchar (c);
      }
  
  #ifdef USG
  static struct termio	sbuf;
--- 114,172 ----
  	    tputs (tgoto (cm, 0, 0), 100, putch);
  	tputs (cd, li, putch);
  	}
+ #endif /* __DJGPP__ */
      }
  
  void move (row, col)
      int		row;
      int		col;
      {
+ #ifdef __DJGPP__
+     fflush (stdout);
+     gotoxy (col + 1, row + 1);
+ #else
      tputs (tgoto (cm, col, row), 100, putch);
+ #endif
      }
  
  void inverse ()
      {
+ #ifdef __DJGPP__
+     fflush (stdout);
+     textattr (ispell_sout_attr);
+ #else
      tputs (so, 10, putch);
+ #endif
      }
  
  void normal ()
      {
+ #ifdef __DJGPP__
+     fflush (stdout);
+     textattr (ispell_norm_attr);
+ #else
      tputs (se, 10, putch);
+ #endif
      }
  
  void backup ()
      {
+ #ifndef __DJGPP__
      if (BC)
  	tputs (BC, 1, putch);
      else
! #endif
!     (void) putchar ('\b');
      }
  
+ #ifndef __DJGPP__
  static int putch (c)
      int			c;
      {
  
      return putchar (c);
      }
+ #endif
  
  #ifdef USG
  static struct termio	sbuf;
*************** static struct ltchars	ltc;
*** 146,152 ****
  static struct ltchars	oltc;
  #endif
  #endif
- static int		termchanged = 0;
  static SIGNAL_TYPE	(*oldint) ();
  static SIGNAL_TYPE	(*oldterm) ();
  #ifdef SIGTSTP
--- 179,184 ----
*************** void terminit ()
*** 168,173 ****
--- 200,208 ----
      struct winsize	wsize;
  #endif /* TIOCGWINSZ */
  
+ #ifdef __DJGPP__
+     djgpp_init_terminal ();
+ #else  /* ! __DJGPP__ */
      tgetent (termcap, getenv ("TERM"));
      termptr = termstr;
      BC = tgetstr ("bc", &termptr);
*************** void terminit ()
*** 184,189 ****
--- 219,225 ----
      te = tgetstr ("te", &termptr);	/* terminal termination */
      co = tgetnum ("co");
      li = tgetnum ("li");
+ #endif /* ! __DJGPP__ */
  #ifdef TIOCGWINSZ
      if (ioctl (0, TIOCGWINSZ, (char *) &wsize) >= 0)
  	{
*************** retry:
*** 329,336 ****
--- 365,377 ----
      if ((oldtstp = signal (SIGTSTP, SIG_IGN)) != SIG_IGN)
  	(void) signal (SIGTSTP, onstop);
  #endif
+ #ifndef __DJGPP__
      if (ti)
  	tputs (ti, 1, putch);
+ #else
+     djgpp_ispell_screen ();
+     erase ();
+ #endif
      }
  
  /* ARGSUSED */
*************** SIGNAL_TYPE done (signo)
*** 341,348 ****
--- 382,391 ----
  	(void) unlink (tempfile);
      if (termchanged)
  	{
+ #ifndef __DJGPP__
  	if (te)
  	    tputs (te, 1, putch);
+ #endif
  #ifdef USG
  	(void) ioctl (0, TCSETAW, (char *) &osbuf);
  #else
*************** SIGNAL_TYPE done (signo)
*** 351,356 ****
--- 394,403 ----
  	(void) ioctl (0, TIOCSLTC, (char *) &oltc);
  #endif
  #endif
+ #ifdef __DJGPP__
+ 	djgpp_restore_screen ();
+ 	djgpp_deinit_term ();
+ #endif /* __DJGPP__ */
  	}
      exit (0);
      }
*************** static SIGNAL_TYPE onstop (signo)
*** 385,415 ****
      }
  #endif
  
  void stop ()
      {
  #ifdef SIGTSTP
      onstop (SIGTSTP);
  #else
!     /* for System V */
      move (li - 1, 0);
      (void) fflush (stdout);
      if (getenv ("SHELL"))
  	(void) shellescape (getenv ("SHELL"));
      else
  	(void) shellescape ("sh");
! #endif
      }
  
  /* Fork and exec a process.  Returns NZ if command found, regardless of
  ** command's return status.  Returns zero if command was not found.
  ** Doesn't use a shell.
  */
- #ifndef USESH
- #define NEED_SHELLESCAPE
- #endif /* USESH */
- #ifndef REGEX_LOOKUP
- #define NEED_SHELLESCAPE
- #endif /* REGEX_LOOKUP */
  #ifdef NEED_SHELLESCAPE
  int shellescape	(buf)
      char *	buf;
--- 432,467 ----
      }
  #endif
  
+ #ifndef USESH
+ #define NEED_SHELLESCAPE
+ #endif /* USESH */
+ #ifndef REGEX_LOOKUP
+ #define NEED_SHELLESCAPE
+ #endif /* REGEX_LOOKUP */
+ 
  void stop ()
      {
  #ifdef SIGTSTP
      onstop (SIGTSTP);
  #else
!     /* for System V and MSDOS */
      move (li - 1, 0);
      (void) fflush (stdout);
+ #ifdef NEED_SHELLESCAPE
      if (getenv ("SHELL"))
  	(void) shellescape (getenv ("SHELL"));
      else
  	(void) shellescape ("sh");
! #else
!     shescape ("");
! #endif /* NEED_SHELLESCAPE */
! #endif /* SIGTSTP */
      }
  
  /* Fork and exec a process.  Returns NZ if command found, regardless of
  ** command's return status.  Returns zero if command was not found.
  ** Doesn't use a shell.
  */
  #ifdef NEED_SHELLESCAPE
  int shellescape	(buf)
      char *	buf;
*************** void shescape (buf)
*** 521,526 ****
--- 573,583 ----
      (void) ioctl (0, TIOCSLTC, (char *) &oltc);
  #endif
  #endif
+ 
+ #ifdef __DJGPP__
+     djgpp_restore_screen ();
+ #endif
+ 
      (void) signal (SIGINT, oldint);
      (void) signal (SIGTERM, oldterm);
  #ifdef SIGTSTP
*************** void shescape (buf)
*** 553,558 ****
--- 610,616 ----
      (void) ioctl (0, TIOCSLTC, (char *) &ltc);
  #endif
  #endif
+ 
      (void) printf (TERM_C_TYPE_SPACE);
      (void) fflush (stdout);
  #ifdef COMMANDFORSPACE
*************** void shescape (buf)
*** 562,567 ****
--- 620,629 ----
  #else
      while (GETKEYSTROKE () != ' ')
  	;
+ #endif
+ 
+ #ifdef __DJGPP__
+     djgpp_ispell_screen ();
  #endif
      }
  #endif
diff -cp -r -N ispell-3.1-orig/tree.c ispell-3.1/tree.c
*** ispell-3.1-orig/tree.c	Mon Jan 23 18:28:28 1995
--- ispell-3.1/tree.c	Sat Nov  9 16:46:56 1996
*************** void treeinit (p, LibDict)
*** 200,205 ****
--- 200,211 ----
  	*/
  	abspath = (*p == '/'  ||  strncmp (p, "./", 2) == 0
  	  ||  strncmp (p, "../", 3) == 0);
+ #ifdef MSDOS
+ 	if (!abspath)
+ 	    abspath = (*p == '\\' || strncmp (p, ".\\", 2) == 0
+ 		       || strncmp (p, "..\\", 3) == 0
+ 		       || (p[0] && p[1] == ':'));
+ #endif
  	if (abspath)
  	    {
  	    (void) strcpy (personaldict, p);
*************** char * do_regex_lookup (expr, whence)
*** 690,705 ****
      static int		    curindex;
      static struct dent *    curpersent;
      static int		    curpersindex;
!     static char *	    cmp_expr;
      char		    dummy[INPUTWORDLEN + MAXAFFIXLEN];
      ichar_t *		    is;
  
      if (whence == 0)
  	{
! 	is = strtosichar (expr, 0);
! 	upcase (is);
! 	expr = ichartosstr (is, 1);
!         cmp_expr = REGCMP (expr);
          curent = hashtbl;
          curindex = 0;
          curpersent = pershtab;
--- 696,712 ----
      static int		    curindex;
      static struct dent *    curpersent;
      static int		    curpersindex;
!     static REGCTYPE	    cmp_expr = (REGCTYPE)0;
      char		    dummy[INPUTWORDLEN + MAXAFFIXLEN];
      ichar_t *		    is;
  
      if (whence == 0)
  	{
!         is = strtosichar (expr, 0);
!         upcase (is);
!         expr = ichartosstr (is, 1);
!         REGFREE (cmp_expr);	/* free previous compiled pattern, if any */
!         cmp_expr = REGCMP (cmp_expr, expr);
          curent = hashtbl;
          curindex = 0;
          curpersent = pershtab;
diff -cp -r -N ispell-3.1-orig/zapdups.x ispell-3.1/zapdups.x
*** ispell-3.1-orig/zapdups.x	Mon Jan 23 18:28:28 1995
--- ispell-3.1/zapdups.x	Sat Nov  2 13:37:54 1996
*************** then
*** 107,113 ****
      exit 1
  fi
  
! FAKEHASH=$TMP.a!!HASHSUFFIX!!
  FAKEDICT=$TMP.b
  SEEN=$TMP.c
  LATEST=$TMP.d
--- 107,113 ----
      exit 1
  fi
  
! FAKEHASH=$TMP!!HASHSUFFIX!!
  FAKEDICT=$TMP.b
  SEEN=$TMP.c
  LATEST=$TMP.d
*** ispell.c~0	Sat Nov 16 21:15:36 1996
--- ispell-3.1/ispell.c	Sun Nov  2 15:45:46 1997
*************** int main (argc, argv)
*** 837,843 ****
       */
      for (argno = 0;  argno < argc;  argno++)
  	{
! 	if (access (argv[argno], 4) >= 0)
  	    break;
  	}
      if (argno >= argc  &&  !lflag  &&  !aflag  &&  !eflag  &&  !dumpflag)
--- 837,843 ----
       */
      for (argno = 0;  argno < argc;  argno++)
  	{
! 	if (access (argv[argno], R_OK) >= 0)
  	    break;
  	}
      if (argno >= argc  &&  !lflag  &&  !aflag  &&  !eflag  &&  !dumpflag)
*************** static void dofile (filename)
*** 951,957 ****
  	return;
  	}
  
!     readonly = access (filename, 2) < 0;
      if (readonly)
  	{
  	(void) fprintf (stderr, ISPELL_C_CANT_WRITE, filename);
--- 951,957 ----
  	return;
  	}
  
!     readonly = access (filename, W_OK) < 0;
      if (readonly)
  	{
  	(void) fprintf (stderr, ISPELL_C_CANT_WRITE, filename);
*************** static void dofile (filename)
*** 998,1004 ****
--- 998,1009 ----
  	(void) sleep ((unsigned) 2);
  	return;
  	}
+ #ifndef MSDOS
+     /* This is usually a no-op on MS-DOS, but with file-sharing installed,
+        it was reported to produce empty spelled files!  Apparently, the
+        file-sharing module would close the file when `chmod' is called.  */
      (void) chmod (tempfile, statbuf.st_mode);
+ #endif
  
      quit = 0;
      changes = 0;
*************** static void update_file (filename, statb
*** 1118,1124 ****
--- 1123,1132 ----
  	return;
  	}
  
+ #ifndef MSDOS
+     /* See the commentary where `chmod' is called above.  */
      (void) chmod (filename, statbuf->st_mode);
+ #endif
  
      while ((c = getc (infile)) != EOF)
  	(void) putc (c, outfile);
*** config.X~0	Sat Nov 16 17:06:06 1996
--- ispell-3.1/config.X	Mon Oct 27 15:25:26 1997
***************
*** 847,852 ****
--- 847,865 ----
  #endif /* NO_STDLIB_H */
  
  /*
+ ** Not all systems have the same definitions for R_OK and W_OK
+ ** flags for calling `access'.  If the defaults below are not
+ ** good for your system, define different values on "local.h".
+ ** Usually, the system header <unistd.h> defines these.
+ */
+ #ifndef R_OK
+ #define R_OK 4
+ #endif
+ #ifndef W_OK
+ #define W_OK 2
+ #endif
+ 
+ /*
  ** The following define is used by the ispell developer to help
  ** double-check the software.  Leave it undefined on other systems
  ** unless you are especially fond of warning messages, or are pursuing
*** pc/local.d~0	Sat Nov  9 22:11:30 1996
--- ispell-3.1/pc/local.djgpp	Mon Oct 27 15:27:28 1997
***************
*** 240,248 ****
  
  /*
  ** Define the following to suppress the 8-bit character feature.
- ** FIXME: does this defeat support of foreign languages?
  */ 
! #define NO8BIT  1
  
  /*
  ** Define this if you want to use the shell for interpretation of commands
--- 240,247 ----
  
  /*
  ** Define the following to suppress the 8-bit character feature.
  */ 
! #undef NO8BIT  1
  
  /*
  ** Define this if you want to use the shell for interpretation of commands
***************
*** 307,312 ****
--- 306,316 ----
  ** configuration script will notice this and define MSDOS_BINARY_OPEN.
  */
  #include <fcntl.h>
+ 
+ /*
+ ** We include <unistd.h> to get the definitions of R_OK and W_OK.
+ */
+ #include <unistd.h>
  
  /*
  ** Environment variable to use to locate the home directory.  On DOS
