Would you please add me to the Micro-Emacs mailing list as
maillist@candle.pha.pa.us?

Version 4.0 looks like it turned out very well.  I had dropped out of
the beta testing because I couldn't use the early beta's for performance
reasons, but the final version looks great.

Here are some fixes and enhancements.  Once you apply them, is there a
way I can get your current source tree or a diff against the 4.0 final
sources so I can submit future patches that will apply to your source
cleanly?

I am running BSD/OS 2.1.

---------------------------------------------------------------------------

Removed trailing comma from I/O and Memory error text because new code
writes them without any trailing text.

Added code to longjump() out of read under Unix when getting winch. 
Newer OS's will not terminate a terminal read when receiving a signal
like WINCH but will restart it, so a resize does not get redrawn until
the user presses a key.  This code will do a longjump to exit from the
terminal read properly and do the redraw.

getregion() now takes a mark number for its start region marker.  This
is done so kill-region and copy-region can use an argument to mark the
region start marker number to use, and not always mark zero.

Added FREEBSD and SUN to the HANDLE_WINCH line.  It would be nice to
move this option up into the upper part of the file where COLOR and
other options are available for users to choose.  We could also check to
see if it defines the WINCH signal.

Fixed highlight problem in display.c.  If you have a line that is wider
than the screen, and you put mark-10 on the end of the line, and then go
to the start of the next line, which causes a horizontal scroll to the
far left margin, and put a mark-11 there, the region is highlighted.  If
you move back to the previous line causing another horizontal scroll,
there is garbage printed at the end of the line.  The code was computing
the minimum of two values, but one of them was negative, so the code was
putting the reverse codes in a negative array reference.  You see this
most often when you search for "word<NL>word" and the matched line is
wider than the screen with.  The region is highlighted, but there is
garbage at the end of the line.  This fixes the problem.  If the value
should not be negative, this fix only masks the problem.

If you defined FILOCK, in file.c, there was a reference to a variable
force_read, that did not exist.  This is fixed.

The file.c code was very confused about printing I/O errors, and had
un-needed gotos.  This is a code cleanup and handles a new I/O error
from ffropen().

fileio.c now reports an I/O ERROR if you try to edit a non-regular file,
like a directory.  All systems should have fileno(), fstat(), and
S_IFREG, I think.  Included files are also checked.

In main.c, errors printed during a quick-exit often scrolled off the
screen, causing a screen shift.  This fixes the problem by printing the
name before the save without \n, and re-printing the save only after a
successful save with a \n.

Added extra getregion arg.

Added an untag stack, so you can tag a function, tag a function in that
function, and so on, and you can untag repeatedly to return to the
original function.  This enhances the usefulness of tagging.  It also
uses <NL> to replace '^' in the tag string to improve the reliability of
searches performed in the tag, because MAGIC is not used in tag
searches.  I also improve the file name recognition code when finding
existing buffers being tagged.  This is useful when you have a
multi-directory source tree with a common tag file.

Added longjump() for WINCH in unix.c.

In unix.c, window size was being taken from termcap by default rather
than first checking a window size query, and only on failure using
termcap.

A confusion of #defines caused the shell to always be csh/sh, even if
SHELL was defined.

Only one un-fixed bug -- I can't bind ^U to anything but
universal-argument.  The bind-to-key succeeds, and ^X-? tells me it is
re-bound, but it still only does univeral-argument.  I was trying to
bind undo to ^U.

---------------------------------------------------------------------------
*** ./h/dutch.h.orig	Sat Feb 22 21:43:32 1997
--- ./h/dutch.h	Sat Feb 22 21:43:32 1997
***************
*** 148,155 ****
  #define	TEXT138	"[Nieuwe file]"
  #define	TEXT139	"[Lezen van file]"
  #define	TEXT140	"Lees "
! #define	TEXT141	"I/O FOUT, "
! #define	TEXT142	"GEEN GEHEUGEN MEER, "
  #define	TEXT143	" lijn"
  #define	TEXT144	"Schrijf file: "
  #define	TEXT145	"Geen filenaam"
--- 148,155 ----
  #define	TEXT138	"[Nieuwe file]"
  #define	TEXT139	"[Lezen van file]"
  #define	TEXT140	"Lees "
! #define	TEXT141	"I/O FOUT"
! #define	TEXT142	"GEEN GEHEUGEN MEER"
  #define	TEXT143	" lijn"
  #define	TEXT144	"Schrijf file: "
  #define	TEXT145	"Geen filenaam"
*** ./h/edef.h.orig	Sat Feb 22 21:43:34 1997
--- ./h/edef.h	Sun Feb 23 17:41:22 1997
***************
*** 243,249 ****
  #endif
  
  #if	HANDLE_WINCH
! int winch_flag=0;			/* Window size changed flag */
  #endif
  
  #else
--- 243,250 ----
  #endif
  
  #if	HANDLE_WINCH
! int winch_has_changed = FALSE;	/* Window size changed flag */
! int winch_can_longjump = FALSE;	/* winch signal longjump enabled */
  #endif
  
  #else
***************
*** 457,463 ****
  #endif
  
  #if	HANDLE_WINCH
! NOSHARE extern int winch_flag;		/* Window size changed flag */
  #endif
  
  #endif
--- 458,465 ----
  #endif
  
  #if	HANDLE_WINCH
! NOSHARE extern int winch_has_changed;	/* Window size changed flag */
! NOSHARE extern int winch_can_longjump;	/* winch signal longjump enabled */
  #endif
  
  #endif
*** ./h/english.h.orig	Sat Feb 22 21:43:36 1997
--- ./h/english.h	Sat Feb 22 21:43:36 1997
***************
*** 144,151 ****
  #define	TEXT138	"[New file]"
  #define	TEXT139	"[Reading file]"
  #define	TEXT140	"Read "
! #define	TEXT141	"I/O ERROR, "
! #define	TEXT142	"OUT OF MEMORY, "
  #define	TEXT143	" line"
  #define	TEXT144	"Write file: "
  #define	TEXT145	"No file name"
--- 144,151 ----
  #define	TEXT138	"[New file]"
  #define	TEXT139	"[Reading file]"
  #define	TEXT140	"Read "
! #define	TEXT141	"I/O ERROR"
! #define	TEXT142	"OUT OF MEMORY"
  #define	TEXT143	" line"
  #define	TEXT144	"Write file: "
  #define	TEXT145	"No file name"
*** ./h/eproto.h.orig	Sat Feb 22 21:43:38 1997
--- ./h/eproto.h	Sat Feb 22 21:43:37 1997
***************
*** 323,329 ****
  extern int PASCAL NEAR getfence(int f, int n);
  extern int PASCAL NEAR getfile(char fname[], int lockfl);
  extern int PASCAL NEAR get_key(VOID);
! extern int PASCAL NEAR getregion(REGION *rp);
  extern int PASCAL NEAR gotobob(int f, int n);
  extern int PASCAL NEAR gotobol(int f, int n);
  extern int PASCAL NEAR gotobop(int f, int n);
--- 323,329 ----
  extern int PASCAL NEAR getfence(int f, int n);
  extern int PASCAL NEAR getfile(char fname[], int lockfl);
  extern int PASCAL NEAR get_key(VOID);
! extern int PASCAL NEAR getregion(int n, REGION *rp);
  extern int PASCAL NEAR gotobob(int f, int n);
  extern int PASCAL NEAR gotobol(int f, int n);
  extern int PASCAL NEAR gotobop(int f, int n);
*** ./h/estruct.h.orig	Sat Feb 22 21:43:39 1997
--- ./h/estruct.h	Sun Feb 23 16:58:00 1997
***************
*** 224,230 ****
  
  /*	Can we catch the SIGWINCH (the window size change signal)? */
  
! #if AIX || HPUX9
  #define HANDLE_WINCH	1
  #else
  #define HANDLE_WINCH	0
--- 224,230 ----
  
  /*	Can we catch the SIGWINCH (the window size change signal)? */
  
! #if AIX || HPUX9 || FREEBSD || SUN
  #define HANDLE_WINCH	1
  #else
  #define HANDLE_WINCH	0
*** ./h/german.h.orig	Sat Feb 22 21:43:42 1997
--- ./h/german.h	Sat Feb 22 21:43:42 1997
***************
*** 175,182 ****
  #define	TEXT140	"Lese "
  /* probably a bad choice, has to be checked against its context. */
  
! #define	TEXT141	"I/O FEHLER, "
! #define	TEXT142	"FREIER SPEICHERPLATZ VERBRAUCHT, "
  #define	TEXT143	" Zeile"
  #define	TEXT144	"Abspeichern in Datei: "
  #define	TEXT145	"Kein Dateiname"
--- 175,182 ----
  #define	TEXT140	"Lese "
  /* probably a bad choice, has to be checked against its context. */
  
! #define	TEXT141	"I/O FEHLER"
! #define	TEXT142	"FREIER SPEICHERPLATZ VERBRAUCHT"
  #define	TEXT143	" Zeile"
  #define	TEXT144	"Abspeichern in Datei: "
  #define	TEXT145	"Kein Dateiname"
*** ./h/japan.h.orig	Sat Feb 22 21:43:43 1997
--- ./h/japan.h	Sun Feb 23 17:00:36 1997
***************
*** 145,152 ****
  #define	TEXT138	"[\220V\213K\203t\203@\203C\203\213]"
  #define	TEXT139	"[\203t\203@\203C\203\213\223\307\202\335\217o\202\265\222\206]"
  #define	TEXT140	"\223\307\202\335\217o\202\265"
! #define	TEXT141	"I/O \203G\203\211\201[, "
! #define	TEXT142	"\203\201\203\202\203\212\225s\221\253, "
  #define	TEXT143	" \215s"
  #define	TEXT144	"\217\221\202\253\215\236\202\336\203t\203@\203C\203\213: "
  #define	TEXT145	"\203t\203@\203C\203\213\226\274\226\242\216w\222\350"
--- 145,152 ----
  #define	TEXT138	"[\220V\213K\203t\203@\203C\203\213]"
  #define	TEXT139	"[\203t\203@\203C\203\213\223\307\202\335\217o\202\265\222\206]"
  #define	TEXT140	"\223\307\202\335\217o\202\265"
! #define	TEXT141	"I/O \203G\203\211\201["
! #define	TEXT142	"\203\201\203\202\203\212\225s\221\253"
  #define	TEXT143	" \215s"
  #define	TEXT144	"\217\221\202\253\215\236\202\336\203t\203@\203C\203\213: "
  #define	TEXT145	"\203t\203@\203C\203\213\226\274\226\242\216w\222\350"
*** ./h/platin.h.orig	Sat Feb 22 21:43:48 1997
--- ./h/platin.h	Sat Feb 22 21:43:47 1997
***************
*** 146,153 ****
  #define	TEXT138	"[Ewnay ilefay]"
  #define	TEXT139	"[Eadingray ilefay]"
  #define	TEXT140	"Eadray "
! #define	TEXT141	"I/O ERRORWAY, "
! #define	TEXT142	"OUTWAY OFWAY EMORYMAY, "
  #define	TEXT143	" inelay"
  #define	TEXT144	"Riteway ilefay: "
  #define	TEXT145	"Onay ilefay amenay"
--- 146,153 ----
  #define	TEXT138	"[Ewnay ilefay]"
  #define	TEXT139	"[Eadingray ilefay]"
  #define	TEXT140	"Eadray "
! #define	TEXT141	"I/O ERRORWAY"
! #define	TEXT142	"OUTWAY OFWAY EMORYMAY"
  #define	TEXT143	" inelay"
  #define	TEXT144	"Riteway ilefay: "
  #define	TEXT145	"Onay ilefay amenay"
*** ./h/spanish.h.orig	Sat Feb 22 21:43:48 1997
--- ./h/spanish.h	Sat Feb 22 21:43:48 1997
***************
*** 145,152 ****
  #define	TEXT138	"[Nuevo archivo]"
  #define	TEXT139	"[Leyendo archivo]"
  #define	TEXT140	"Leyendo "
! #define	TEXT141	"I/O ERROR, "
! #define	TEXT142	"Fueara de memoria, "
  #define	TEXT143	" linea"
  #define	TEXT144	"Escribir a que archivo: "
  #define	TEXT145	"No tengo el nombre del archivo"
--- 145,152 ----
  #define	TEXT138	"[Nuevo archivo]"
  #define	TEXT139	"[Leyendo archivo]"
  #define	TEXT140	"Leyendo "
! #define	TEXT141	"I/O ERROR"
! #define	TEXT142	"Fueara de memoria"
  #define	TEXT143	" linea"
  #define	TEXT144	"Escribir a que archivo: "
  #define	TEXT145	"No tengo el nombre del archivo"
*** ./src/display.c.orig	Sat Feb 22 21:43:49 1997
--- ./src/display.c	Thu Feb 13 01:44:04 1997
***************
*** 1281,1286 ****
--- 1281,1288 ----
                          rev_left = vp->v_left;
                  else
                          rev_left = pp->v_left;
+ 				if (rev_left < 0)
+ 					rev_left = 0;
                  pp->v_left = vp->v_left;
                  if (rev_left < update_column) {
                          vir_left = &vp->v_text[rev_left];
***************
*** 1293,1298 ****
--- 1295,1302 ----
                          rev_right = vp->v_right;
                  else
                          rev_right = pp->v_right;
+ 				if (rev_right < 0)
+ 					rev_right = 0;
                  pp->v_right = vp->v_right;
                  if (&vp->v_text[rev_right] > vir_right) {
                          vir_right = &vp->v_text[rev_right];
***************
*** 2167,2173 ****
  {
    int i;
    register VIDEO *vp;
! 
    for (i = 0; i < term.t_mrow; ++i) {
      free(vscreen[i]);
      free(pscreen[i]);
--- 2171,2177 ----
  {
    int i;
    register VIDEO *vp;
!   
    for (i = 0; i < term.t_mrow; ++i) {
      free(vscreen[i]);
      free(pscreen[i]);
***************
*** 2218,2224 ****
  #if	INSDEL
        vp->v_rline = i;	/* set requested line position */
  #endif
!       
        pscreen[i] = vp;
      }
  }
--- 2222,2228 ----
  #if	INSDEL
        vp->v_rline = i;	/* set requested line position */
  #endif
! 
        pscreen[i] = vp;
      }
  }
*** ./src/file.c.orig	Sat Feb 22 21:43:50 1997
--- ./src/file.c	Sat Feb 22 21:06:37 1997
***************
*** 268,275 ****
  	register int cmark;	/* current mark */
  	int nbytes;
  	char mesg[NSTRING];
- 
  #if	FILOCK
  	force_read = FALSE;
  	if (lockfl && lockchk(fname) == ABORT)
  		force_read = TRUE;
--- 268,276 ----
  	register int cmark;	/* current mark */
  	int nbytes;
  	char mesg[NSTRING];
  #if	FILOCK
+     int force_read;
+     
  	force_read = FALSE;
  	if (lockfl && lockchk(fname) == ABORT)
  		force_read = TRUE;
***************
*** 294,358 ****
  	/* turn off ALL keyboard translation in case we get a dos error */
  	TTkclose();
  
! 	if ((s=ffropen(fname)) == FIOERR)	/* Hard file open.	*/
! 		goto out;
! 
! 	if (s == FIOFNF) {			/* File not found.	*/
! 		mlwrite(TEXT138);
! /*                      "[New file]" */
! 		goto out;
! 	}
  
! 	/* read the file in */
! 	mlwrite(TEXT139);
! /*              "[Reading file]" */
! 	nline = 0L;
! 	while ((s=ffgetline(&nbytes)) == FIOSUC) {
! 		if ((lp1=lalloc(nbytes)) == NULL) {
! 			s = FIOMEM;		/* Keep message on the	*/
! 			break;			/* display.		*/
  		}
! 		lp2 = lback(curbp->b_linep);
! 		lp2->l_fp = lp1;
! 		lp1->l_fp = curbp->b_linep;
! 		lp1->l_bp = lp2;
! 		curbp->b_linep->l_bp = lp1;
! 		for (i=0; i<nbytes; ++i)
! 			lputc(lp1, i, fline[i]);
! 		++nline;
  	}
- 	ffclose();				/* Ignore errors.	*/
  
  #if	BSD || FREEBSD || USG || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || AVION
  	/* if we don't have write priviledges, make this in VIEW mode */
! 	if (s !=FIOERR && s != FIOFNF) {
! 		if (access(fname, 2 /* W_OK*/) != 0)
  			curbp->b_mode |= MDVIEW;
- 	}
  #endif
  
! 	strcpy(mesg, "[");
! 	if (s==FIOERR) {
! 		strcat(mesg, TEXT141);
  /*                           "I/O ERROR, " */
  		curbp->b_flag |= BFTRUNC;
  	}
! 	if (s == FIOMEM) {
! 		strcat(mesg, TEXT142);
  /*                           "OUT OF MEMORY, " */
  		curbp->b_flag |= BFTRUNC;
  	}
! 	strcat(mesg, TEXT140);
! /*                   "Read " */
! 	strcat(mesg, long_asc(nline));
! 	strcat(mesg, TEXT143);
! /*                   " line" */
! 	if (nline > 1L)
! 		strcat(mesg, "s");
! 	strcat(mesg, "]");
! 	mlwrite(mesg);
! 
! out:
  	TTkopen();	/* open the keyboard again */
  	for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  		if (wp->w_bufp == curbp) {
--- 295,357 ----
  	/* turn off ALL keyboard translation in case we get a dos error */
  	TTkclose();
  
! 	s = ffropen(fname);	/* Hard file open.	*/
  
! 	if (s != FIOERR && s != FIOFNF)
! 	{
! 		/* read the file in */
! 		mlwrite(TEXT139);
! 		/*              "[Reading file]" */
! 		nline = 0L;
! 		while ((s=ffgetline(&nbytes)) == FIOSUC) {
! 			if ((lp1=lalloc(nbytes)) == NULL) {
! 				s = FIOMEM;		/* Keep message on the	*/
! 				break;			/* display.		*/
! 			}
! 			lp2 = lback(curbp->b_linep);
! 			lp2->l_fp = lp1;
! 			lp1->l_fp = curbp->b_linep;
! 			lp1->l_bp = lp2;
! 			curbp->b_linep->l_bp = lp1;
! 			for (i=0; i<nbytes; ++i)
! 				lputc(lp1, i, fline[i]);
! 			++nline;
  		}
! 		ffclose();				/* Ignore errors.	*/
  	}
  
  #if	BSD || FREEBSD || USG || AUX || SMOS || HPUX8 || HPUX9 || SUN || XENIX || AVION
  	/* if we don't have write priviledges, make this in VIEW mode */
! 	if (s != FIOFNF &&
! 		(s == FIOERR || s == FIOMEM || access(fname, 2 /* W_OK*/) != 0))
  			curbp->b_mode |= MDVIEW;
  #endif
  
! 	if (s == FIOFNF) 		/* File not found.	*/
! 		mlwrite(TEXT138);
! 	else if (s==FIOERR) {
! 		mlwrite(TEXT141);
  /*                           "I/O ERROR, " */
  		curbp->b_flag |= BFTRUNC;
  	}
! 	else if (s == FIOMEM) {
! 		mlwrite(TEXT142);
  /*                           "OUT OF MEMORY, " */
  		curbp->b_flag |= BFTRUNC;
  	}
! 	else {
! 		strcpy(mesg, "[");
! 		strcat(mesg, TEXT140);
! 	/*                   "Read " */
! 		strcat(mesg, long_asc(nline));
! 		strcat(mesg, TEXT143);
! 	/*                   " line" */
! 		if (nline > 1L)
! 			strcat(mesg, "s");
! 		strcat(mesg, "]");
! 		mlwrite(mesg);
! 	}
! 	
  	TTkopen();	/* open the keyboard again */
  	for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  		if (wp->w_bufp == curbp) {
***************
*** 764,776 ****
  	bp = curbp;				/* Cheap.		*/
  	bp->b_flag |= BFCHG;			/* we have changed	*/
  	bp->b_flag &= ~BFINVS;			/* and are not temporary*/
! 	if ((s=ffropen(fname)) == FIOERR)	/* Hard file open.	*/
! 		goto out;
  	if (s == FIOFNF) {			/* File not found.	*/
  		mlwrite(TEXT152);
! /*                      "[No such file]" */
  		return(FALSE);
  	}
  	mlwrite(TEXT153);
  /*              "[Inserting file]" */
  
--- 763,784 ----
  	bp = curbp;				/* Cheap.		*/
  	bp->b_flag |= BFCHG;			/* we have changed	*/
  	bp->b_flag &= ~BFINVS;			/* and are not temporary*/
! 
! 	s = ffropen(fname);	/* Hard file open.	*/
! 
! 	if (s == FIOERR) {
! 		mlwrite(TEXT141);
! /*                           "I/O ERROR, " */
! 		curbp->b_flag |= BFTRUNC;
! 		return(FALSE);
! 	}
! 
  	if (s == FIOFNF) {			/* File not found.	*/
  		mlwrite(TEXT152);
! /*                           "[No such file]" */
  		return(FALSE);
  	}
+ 
  	mlwrite(TEXT153);
  /*              "[Inserting file]" */
  
***************
*** 815,831 ****
  		if (curwp->w_markp[cmark] == lback(curwp->w_dotp))
  			curwp->w_markp[cmark] = lforw(curwp->w_markp[cmark]);
  
! 	strcpy(mesg, "[");
! 	if (s==FIOERR) {
! 		strcat(mesg, TEXT141);
  /*                           "I/O ERROR, " */
  		curbp->b_flag |= BFTRUNC;
  	}
  	if (s == FIOMEM) {
  		strcat(mesg, TEXT142);
  /*                           "OUT OF MEMORY, " */
  		curbp->b_flag |= BFTRUNC;
  	}
  	strcat(mesg, TEXT154);
  /*                   "Inserted " */
  	strcat(mesg, long_asc(nline));
--- 823,843 ----
  		if (curwp->w_markp[cmark] == lback(curwp->w_dotp))
  			curwp->w_markp[cmark] = lforw(curwp->w_markp[cmark]);
  
! 	if (s == FIOERR) {
! 		mlwrite(TEXT141);
  /*                           "I/O ERROR, " */
  		curbp->b_flag |= BFTRUNC;
+ 		return(FALSE);
  	}
+ 
  	if (s == FIOMEM) {
  		strcat(mesg, TEXT142);
  /*                           "OUT OF MEMORY, " */
  		curbp->b_flag |= BFTRUNC;
+ 		return(FALSE);
  	}
+ 	
+ 	strcpy(mesg, "[");
  	strcat(mesg, TEXT154);
  /*                   "Inserted " */
  	strcat(mesg, long_asc(nline));
***************
*** 836,842 ****
  	strcat(mesg, "]");
  	mlwrite(mesg);
  
- out:
  	/* advance to the next line and mark the window for changes */
  	curwp->w_dotp = lforw(curwp->w_dotp);
  	curwp->w_flag |= WFHARD | WFMODE;
--- 848,853 ----
***************
*** 850,857 ****
  	}
  	curbp->b_fcol = curwp->w_fcol;
  
- 	if (s == FIOERR)			/* False if error.	*/
- 		return(FALSE);
  	return(TRUE);
  }
  
--- 861,866 ----
*** ./src/fileio.c.orig	Sat Feb 22 21:43:50 1997
--- ./src/fileio.c	Sat Feb 22 19:47:03 1997
***************
*** 6,11 ****
--- 6,13 ----
   */
  
  #include        <stdio.h>
+ #include        <sys/types.h>
+ #include        <sys/stat.h>
  #include	"estruct.h"
  #include	"eproto.h"
  #include        "edef.h"
***************
*** 31,39 ****
--- 33,47 ----
  PASCAL NEAR ffropen(fn)
  char    *fn;
  {
+ 	struct stat open_stat;
+ 	
  	if ((ffp=fopen(fn, "r")) == NULL)
  		return(FIOFNF);
  
+ 	if (fstat(fileno(ffp),&open_stat) != 0 ||
+ 		(open_stat.st_mode & S_IFREG) == 0)
+ 		return(FIOERR);
+ 
  #if	(MSC || TURBO || IC) && MSDOS
  	/* tell the library to give us a LARGE buffer to speed I/O */
  	setvbuf(ffp, file_buffer, _IOFBF, FILE_BUFSIZE);
***************
*** 56,61 ****
--- 64,70 ----
  char *mode;	/* mode to open file for */
  {
  	char xmode[6];		/* extended file open mode */
+ 	struct stat open_stat;
  
  	/* nonstandard line terminators? */
  	if (*lterm) {
***************
*** 75,80 ****
--- 84,93 ----
  /*			"Cannot open file for writing" */
  		return(FIOERR);
  	}
+ 
+ 	if (fstat(fileno(ffp),&open_stat) != 0 ||
+ 		(open_stat.st_mode & S_IFREG) == 0)
+ 		return(FIOERR);
  
  #if	(MSC || TURBO || IC) && MSDOS
  	/* tell the library to give us a LARGE buffer to speed I/O */
*** ./src/main.c.orig	Sat Feb 22 21:43:50 1997
--- ./src/main.c	Sun Feb 23 17:38:08 1997
***************
*** 532,538 ****
  	 * Did our window get resized?
  	 */
  #if HANDLE_WINCH
! 	if (winch_flag) winch_new_size();
  #endif
  	/* Fix up the screen	*/
  	update(FALSE);
--- 532,539 ----
  	 * Did our window get resized?
  	 */
  #if HANDLE_WINCH
! 	if (winch_has_changed)
! 		winch_new_size();
  #endif
  	/* Fix up the screen	*/
  	update(FALSE);
***************
*** 898,908 ****
  			curbp = bp;	/* make that buffer cur */
  			mlwrite(TEXT103, bp->b_fname);
  /*				"[Saving %s]" */
- 			mlwrite("\n");
  			if ((status = filesave(f, n)) != TRUE) {
  				curbp = oldcb;	/* restore curbp */
  				return(status);
  			}
  		}
  		bp = bp->b_bufp;	/* on to the next buffer */
  	}
--- 899,911 ----
  			curbp = bp;	/* make that buffer cur */
  			mlwrite(TEXT103, bp->b_fname);
  /*				"[Saving %s]" */
  			if ((status = filesave(f, n)) != TRUE) {
  				curbp = oldcb;	/* restore curbp */
  				return(status);
  			}
+ 			/* if we didn't get an error, reprint the file name */
+ 			mlwrite(TEXT103, bp->b_fname);
+ 			mlwrite("\n");
  		}
  		bp = bp->b_bufp;	/* on to the next buffer */
  	}
*** ./src/mswemacs.c.orig	Sat Feb 22 21:43:51 1997
--- ./src/mswemacs.c	Mon Feb 10 12:07:20 1997
***************
*** 107,114 ****
  
      /*-don't allow command if read-only mode */
      if (curbp->b_mode & MDVIEW) return rdonly();
! 
!     if ((Result = getregion (&Region)) != TRUE) return Result;
  
      if ((Result = CopyToClipboard (&Region)) != TRUE) return Result;
      curwp->w_dotp = Region.r_linep;
--- 107,116 ----
  
      /*-don't allow command if read-only mode */
      if (curbp->b_mode & MDVIEW) return rdonly();
! 	if (f == FALSE)
! 		n = 0;
!                         
!     if ((Result = getregion (n, &Region)) != TRUE) return Result;
  
      if ((Result = CopyToClipboard (&Region)) != TRUE) return Result;
      curwp->w_dotp = Region.r_linep;
***************
*** 123,130 ****
  {
      REGION  Region;
      int     Result;
!     
!     if ((Result = getregion (&Region)) != TRUE) return Result;
  
      return CopyToClipboard (&Region);
  } /* clipregion */
--- 125,134 ----
  {
      REGION  Region;
      int     Result;
! 
! 	if (f == FALSE)
! 		n = 0;
!     if ((Result = getregion (n, &Region)) != TRUE) return Result;
  
      return CopyToClipboard (&Region);
  } /* clipregion */
*** ./src/region.c.orig	Sat Feb 22 21:43:51 1997
--- ./src/region.c	Mon Feb 10 12:07:20 1997
***************
*** 23,29 ****
  	REGION region;
  
  	/* check for a valid region first */
! 	if (getregion(&region) != TRUE)
  		return(0);
  
  	/* start at the top of the region.... */
--- 23,29 ----
  	REGION region;
  
  	/* check for a valid region first */
! 	if (getregion(0, &region) != TRUE)
  		return(0);
  
  	/* start at the top of the region.... */
***************
*** 62,70 ****
  	/* Don't do this command in read-only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 
  	/* get the boundries of the region to kill */
! 	if ((s=getregion(&region)) != TRUE)
  		return(s);
  
  	/* flag this command as a kill */
--- 62,72 ----
  	/* Don't do this command in read-only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 	if (f == FALSE)
! 		n = 0;
! 		
  	/* get the boundries of the region to kill */
! 	if ((s=getregion(n, &region)) != TRUE)
  		return(s);
  
  	/* flag this command as a kill */
***************
*** 97,103 ****
  	register int	s;
  	REGION		region;
  
! 	if ((s=getregion(&region)) != TRUE)
  		return(s);
  	if ((lastflag&CFKILL) == 0)		/* Kill type command.	*/
  		next_kill();
--- 99,108 ----
  	register int	s;
  	REGION		region;
  
! 	if (f == FALSE)
! 		n = 0;
! 		
! 	if ((s=getregion(n, &region)) != TRUE)
  		return(s);
  	if ((lastflag&CFKILL) == 0)		/* Kill type command.	*/
  		next_kill();
***************
*** 143,151 ****
  	/* don't bother if we are in read only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 
  	/* get the limits of the current region */
! 	if ((status = getregion(&region)) != TRUE)
  		return(status);
  
  	/* flag that we are changing this text */
--- 148,158 ----
  	/* don't bother if we are in read only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 	if (f == FALSE)
! 		n = 0;
! 		
  	/* get the limits of the current region */
! 	if ((status = getregion(n, &region)) != TRUE)
  		return(status);
  
  	/* flag that we are changing this text */
***************
*** 208,216 ****
  	/* don't bother if we are in read only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 
  	/* get the limits of the current region */
! 	if ((status = getregion(&region)) != TRUE)
  		return(status);
  
  	/* flag that we are changing this text */
--- 215,225 ----
  	/* don't bother if we are in read only mode */
  	if (curbp->b_mode&MDVIEW)
  		return(rdonly());
! 	if (f == FALSE)
! 		n = 0;
! 		
  	/* get the limits of the current region */
! 	if ((status = getregion(n, &region)) != TRUE)
  		return(status);
  
  	/* flag that we are changing this text */
***************
*** 274,282 ****
  /*			"%%This buffer is already narrowed" */
  		return(FALSE);
  	}
! 
  	/* find the boundries of the current region */
! 	if ((status=getregion(&creg)) != TRUE)
  		return(status);
  	curwp->w_dotp = creg.r_linep;	/* only by full lines please! */
  	curwp->w_doto = 0;
--- 283,293 ----
  /*			"%%This buffer is already narrowed" */
  		return(FALSE);
  	}
! 	if (f == FALSE)
! 		n = 0;
! 		
  	/* find the boundries of the current region */
! 	if ((status=getregion(n, &creg)) != TRUE)
  		return(status);
  	curwp->w_dotp = creg.r_linep;	/* only by full lines please! */
  	curwp->w_doto = 0;
***************
*** 438,445 ****
   * "ABORT" status; we might make this have the confirm thing later.
   */
  
! PASCAL NEAR getregion(rp)
  
  register REGION *rp;
  
  {
--- 449,457 ----
   * "ABORT" status; we might make this have the confirm thing later.
   */
  
! PASCAL NEAR getregion(n, rp)
  
+ int n;	/* mark number */
  register REGION *rp;
  
  {
***************
*** 448,466 ****
  	long fsize;
  	long bsize;
  
! 	if (curwp->w_markp[0] == (LINE *)NULL) {
  		mlwrite(TEXT76);
  /*			"No mark set in this window" */
  		return(FALSE);
  	}
! 	if (curwp->w_dotp == curwp->w_markp[0]) {
  		rp->r_linep = curwp->w_dotp;
! 		if (curwp->w_doto < curwp->w_marko[0]) {
  			rp->r_offset = curwp->w_doto;
! 			rp->r_size = (long)(curwp->w_marko[0]-curwp->w_doto);
  		} else {
! 			rp->r_offset = curwp->w_marko[0];
! 			rp->r_size = (long)(curwp->w_doto-curwp->w_marko[0]);
  		}
  		return(TRUE);
  	}
--- 460,478 ----
  	long fsize;
  	long bsize;
  
! 	if (curwp->w_markp[n] == (LINE *)NULL) {
  		mlwrite(TEXT76);
  /*			"No mark set in this window" */
  		return(FALSE);
  	}
! 	if (curwp->w_dotp == curwp->w_markp[n]) {
  		rp->r_linep = curwp->w_dotp;
! 		if (curwp->w_doto < curwp->w_marko[n]) {
  			rp->r_offset = curwp->w_doto;
! 			rp->r_size = (long)(curwp->w_marko[n]-curwp->w_doto);
  		} else {
! 			rp->r_offset = curwp->w_marko[n];
! 			rp->r_size = (long)(curwp->w_doto-curwp->w_marko[n]);
  		}
  		return(TRUE);
  	}
***************
*** 471,480 ****
  	while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  		if (flp != curbp->b_linep) {
  			flp = lforw(flp);
! 			if (flp == curwp->w_markp[0]) {
  				rp->r_linep = curwp->w_dotp;
  				rp->r_offset = curwp->w_doto;
! 				rp->r_size = fsize+curwp->w_marko[0];
  				return(TRUE);
  			}
  			fsize += lused(flp)+1;
--- 483,492 ----
  	while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  		if (flp != curbp->b_linep) {
  			flp = lforw(flp);
! 			if (flp == curwp->w_markp[n]) {
  				rp->r_linep = curwp->w_dotp;
  				rp->r_offset = curwp->w_doto;
! 				rp->r_size = fsize+curwp->w_marko[n];
  				return(TRUE);
  			}
  			fsize += lused(flp)+1;
***************
*** 482,491 ****
  		if (lback(blp) != curbp->b_linep) {
  			blp = lback(blp);
  			bsize += lused(blp)+1;
! 			if (blp == curwp->w_markp[0]) {
  				rp->r_linep = blp;
! 				rp->r_offset = curwp->w_marko[0];
! 				rp->r_size = bsize - curwp->w_marko[0];
  				return(TRUE);
  			}
  		}
--- 494,503 ----
  		if (lback(blp) != curbp->b_linep) {
  			blp = lback(blp);
  			bsize += lused(blp)+1;
! 			if (blp == curwp->w_markp[n]) {
  				rp->r_linep = blp;
! 				rp->r_offset = curwp->w_marko[n];
! 				rp->r_size = bsize - curwp->w_marko[n];
  				return(TRUE);
  			}
  		}
***************
*** 538,544 ****
  	REGION region;
  
  	/* get the region limits */
! 	if (getregion(&region) != TRUE)
  		return(errorm);
  
  	/* don't let the region be larger than a string can hold */
--- 550,556 ----
  	REGION region;
  
  	/* get the region limits */
! 	if (getregion(0, &region) != TRUE)
  		return(errorm);
  
  	/* don't let the region be larger than a string can hold */
*** ./src/tags.c.orig	Sat Feb 22 21:43:51 1997
--- ./src/tags.c	Sun Feb  9 22:49:09 1997
***************
*** 38,44 ****
  
  #define INDEX(c)	(is_lower(c) ? c-'a'+27 : (is_letter(c) ? c-'A'+1: ((c == '_') ? 0 : -1)))
  #define NINDEXES	26+26+1
! #define TAGWIDTH	30
  
  typedef struct	TAG
  	{
--- 38,52 ----
  
  #define INDEX(c)	(is_lower(c) ? c-'a'+27 : (is_letter(c) ? c-'A'+1: ((c == '_') ? 0 : -1)))
  #define NINDEXES	26+26+1
! #define TAGWIDTH	60
! 
! #define TAGSTACKSIZE	32
! 
! typedef struct TAGSTACK {
! 	char	t_fname[NFILEN];/* Holds name of file from where we tagged. */
! 	int	w_dotp;		/* line */
! 	int	w_doto;		/* column */
! }	TAGSTACK;
  
  typedef struct	TAG
  	{
***************
*** 53,58 ****
--- 61,70 ----
  					/* for speed-up purposes only).	*/
  	}	TAG;
  
+ static TAGSTACK tagstack[TAGSTACKSIZE];
+ 
+ static int stacktop = -1;
+ 
  static TAG *theadp = NULL;	/* Pointer to the head of the	*/
  					/* 'tags'-chain.		*/
  static TAG *curtp = NULL;	/* Currently in-use 'tags'.	*/
***************
*** 88,94 ****
  
  	tnewp->t_tagp = theadp;
  	curtp = theadp = tnewp;
- 	strcpy(tnewp->t_fname, curbp->b_fname);
  	strcpy(tnewp->t_wd, "");
  
  	/* Initialize index...	*/
--- 100,105 ----
***************
*** 236,247 ****
  register char pattern[];
  	{
  	register int	i = 0;	/* EMACS pattern index	*/
! 	register int	j = 1;	/* VI pattern -skip /or?*/
  	int		len = strlen(pattern) - 1;	/* pattern length - 1	*/
  						/* i.e. drop '/' or '?'	*/
  
  	if (pattern[len - 1] == '$')
! 		len--;
  
  	while (++j < len)
  		if (pattern[j] != '\\')
--- 247,260 ----
  register char pattern[];
  	{
  	register int	i = 0;	/* EMACS pattern index	*/
! 	register int	j = 0;	/* VI pattern index, we drop '/' or '?' */
  	int		len = strlen(pattern) - 1;	/* pattern length - 1	*/
  						/* i.e. drop '/' or '?'	*/
  
+ 	if (pattern[1] == '^')
+ 		pattern[1] = '\r';
  	if (pattern[len - 1] == '$')
! 		pattern[len - 1] = '\r';
  
  	while (++j < len)
  		if (pattern[j] != '\\')
***************
*** 311,316 ****
--- 324,330 ----
  	int	oldbmode;		/* For preserving bmode	*/
  	int	taglen = strlen(curtp->t_wd);
  	int	file_ok;		/* TRUE if file found	*/
+ 	char 	*cp1, *cp2;
  
  	/* Tell user what we are doing		*/
  	mlwrite("[Tagging '%s'...]", curtp->t_wd);
***************
*** 340,347 ****
  	/* Add path to tagf if necessary...	*/
  	add_path(tagf);
  	/* Should we search the current file?	*/
! 	thisfile = strcmp(tagf, curbp->b_fname) == 0;
! 	file_ok = thisfile ? TRUE : getfile(tagf, TRUE);
  	oldbmode = curbp->b_mode;	/* Preserve buffer mode		*/
  	if (file_ok)
  		{				/* Ok, we got the file. Search!	*/
--- 354,378 ----
  	/* Add path to tagf if necessary...	*/
  	add_path(tagf);
  	/* Should we search the current file?	*/
! 
! 	cp1 = curbp->b_fname + strlen(curbp->b_fname) - 1;
! #if	MSDOS
! 	while (cp1 > curbp->b_fname  &&  *(cp1-1) != DIRSEPCHAR  &&  *(cp1-1) != ':')
! #else
! 	while (cp1 > curbp->b_fname  &&  *(cp1-1) != DIRSEPCHAR)
! #endif
! 		cp1--;
! 
! 	cp2 = tagf + strlen(tagf) - 1;
! #if	MSDOS
! 	while (cp2 > tagf  &&  *(cp2-1) != DIRSEPCHAR  &&  *(cp2-1) != ':')
! #else
! 	while (cp2 > tagf  &&  *(cp2-1) != DIRSEPCHAR)
! #endif
! 		cp2--;
! 
! 	thisfile = strcmp(cp1, cp2) == 0;
! 	file_ok  = thisfile ? TRUE : getfile(tagf, TRUE);
  	oldbmode = curbp->b_mode;	/* Preserve buffer mode		*/
  	if (file_ok)
  		{				/* Ok, we got the file. Search!	*/
***************
*** 371,377 ****
  				/* It's the same file so simply swapmark*/
  				swapmark(FALSE, FALSE);
  			else 		/* Get old file	*/
! 				getfile(curtp->t_fname, TRUE);
  			/* Tell user about our misfortune	*/
  			mlwrite("[Failed to tag '%s']", curtp->t_wd);
  			}
--- 402,408 ----
  				/* It's the same file so simply swapmark*/
  				swapmark(FALSE, FALSE);
  			else 		/* Get old file	*/
! 				getfile(tagstack[stacktop].t_fname, TRUE);
  			/* Tell user about our misfortune	*/
  			mlwrite("[Failed to tag '%s']", curtp->t_wd);
  			}
***************
*** 408,413 ****
--- 439,445 ----
  	LINE	*pretagdotp = curwp->w_dotp;	/* Preserve '.' info	*/
  	int	pretagdoto = curwp->w_doto;
  	int	i;
+ 	int	cur_doto;
  
  	if (restflag == TRUE)	/* Don't allow when in restricted mode	*/
  		return (resterr());
***************
*** 427,432 ****
--- 459,465 ----
  	else if (mlreply("Word to tag: ", curtp->t_wd, TAGWIDTH) != TRUE)
  		return (FALSE);
  
+ 	cur_doto = curwp->w_doto;
  	fix_index();
  
  	curwp->w_dotp = pretagdotp;	/* Restore '.'	*/
***************
*** 440,447 ****
  		}
  	fseek(curtp->t_fp, curtp->t_dotos[i], 0);
  
! 	strcpy(curtp->t_fname, curbp->b_fname);	/* Save name of current file */
! 	return (tagvalid = tagger("[No tag entry for '%s' found]", FALSE));
  }
  
  /*
--- 473,489 ----
  		}
  	fseek(curtp->t_fp, curtp->t_dotos[i], 0);
  
! 	if (stacktop >= TAGSTACKSIZE-1)
! 		for (i=0; i < TAGSTACKSIZE-1; i++)
! 			tagstack[i] = tagstack[i+1];
! 
! 	strcpy(tagstack[++stacktop].t_fname, curbp->b_fname);
! 	tagstack[stacktop].w_dotp = getlinenum(curbp, curwp->w_dotp);
! 	tagstack[stacktop].w_doto = cur_doto;
! 	tagvalid = tagger("[No tag entry for '%s' found]", FALSE);
! 	if (tagvalid == FALSE)
! 		stacktop--;
! 	return tagvalid;
  }
  
  /*
***************
*** 456,470 ****
  
  int f, n;
  
! 	{
  	if (restflag == TRUE)	/* Don't allow when in restricted mode	*/
  		return (resterr());
  
! 	if (*curtp->t_fname == '\0' || !tagvalid)
  		return (FALSE);
  
  	return (tagger("[No additional tag entry for '%s' found]", TRUE));
! 	}
  
  
  /*
--- 498,512 ----
  
  int f, n;
  
! {
  	if (restflag == TRUE)	/* Don't allow when in restricted mode	*/
  		return (resterr());
  
! 	if (*tagstack[stacktop].t_fname == '\0'  ||  !tagvalid)
  		return (FALSE);
  
  	return (tagger("[No additional tag entry for '%s' found]", TRUE));
! }
  
  
  /*
***************
*** 477,497 ****
  
  int f, n;
  
! 	{
  	if (restflag == TRUE)	/* Don't allow when in restricted mode	*/
  		return (resterr());
  
! 	if (*curtp->t_fname != '\0')
! 		{
! 		if (thisfile)
! 			swapmark(FALSE, FALSE);
! 		else
! 			getfile(curtp->t_fname, TRUE);
! 		*curtp->t_fname = '\0';
! 		}
! 
! 	return (TRUE);
  	}
  
  #else
  tagshello()
--- 519,549 ----
  
  int f, n;
  
! {
! 	BUFFER *buf;
! 	char *cp1, *cp2;
! 
  	if (restflag == TRUE)	/* Don't allow when in restricted mode	*/
  		return (resterr());
  
! 	if (stacktop >= 0 &&
! 		curtp != NULL && *tagstack[stacktop].t_fname != '\0') {
! 		cp1 = tagstack[stacktop].t_fname + strlen(tagstack[stacktop].t_fname) - 1;
! #if	MSDOS
! 		while (cp1 > tagstack[stacktop].t_fname  &&  *(cp1-1) != DIRSEPCHAR  &&  *(cp1-1) != ':')
! #else
! 		while (cp1 > tagstack[stacktop].t_fname  &&  *(cp1-1) != DIRSEPCHAR)
! #endif
! 			cp1--;
! 		if ((buf = bfind(cp1,FALSE,0)) != NULL)
! 			swbuffer(buf);
! 		else	getfile(tagstack[stacktop].t_fname, TRUE);
! 		gotoline(TRUE,tagstack[stacktop].w_dotp);
! 		forwchar(TRUE,tagstack[stacktop].w_doto);
! 		*tagstack[stacktop--].t_fname = '\0';
  	}
+ 	return (TRUE);
+ }
  
  #else
  tagshello()
*** ./src/unix.c.orig	Sat Feb 22 21:43:52 1997
--- ./src/unix.c	Sun Feb 23 20:28:14 1997
***************
*** 93,102 ****
  
  
  /** Overall include files **/
  #include <sys/types.h>			/* System type definitions	*/
  #include <sys/stat.h>			/* File status definitions	*/
  #include <sys/ioctl.h>			/* I/O control definitions	*/
- 
  /** Additional include files **/
  #if	FREEBSD
  #define TERMIOS 1
--- 93,102 ----
  
  
  /** Overall include files **/
+ #include <errno.h>
  #include <sys/types.h>			/* System type definitions	*/
  #include <sys/stat.h>			/* File status definitions	*/
  #include <sys/ioctl.h>			/* I/O control definitions	*/
  /** Additional include files **/
  #if	FREEBSD
  #define TERMIOS 1
***************
*** 367,372 ****
--- 367,377 ----
  
  int hpterm;				/* global flag braindead HP-terminal */
  
+ #ifdef HANDLE_WINCH
+ #include <setjmp.h>
+ static jmp_buf winch_sig;	/* terminate read call */
+ #endif
+ 
  /** Open terminal device **/
  int ttopen()
  {
***************
*** 594,610 ****
  	}
  
  	/* Perform read */
  #if HANDLE_WINCH
! 	while (read(0, &ch, 1) != 1) {
! 		if (winch_flag)
! 			return 0;
  	}
! #else
  	if (read(0, &ch, 1) != 1) {
  		puts("** Horrible read error occured **");
  		exit(1);
  	}
  #endif
  	/* Return new character */
  	return(ch);
  #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX || (AVVION || TERMIOS) */
--- 599,625 ----
  	}
  
  	/* Perform read */
+ 
  #if HANDLE_WINCH
! 	if (winch_has_changed == TRUE)
! 		return(0);
! 	ch = 0;	/* this could be changed by the read call */
! 	if (setjmp(winch_sig) != 0)	/* terminate read, many OS's restart reads */
! 	{
! 		winch_can_longjump = FALSE;
! 		return(ch);
  	}
! 	winch_can_longjump = TRUE;
! #endif
! 
  	if (read(0, &ch, 1) != 1) {
  		puts("** Horrible read error occured **");
  		exit(1);
  	}
+ #if HANDLE_WINCH
+ 	winch_can_longjump = FALSE;
  #endif
+ 
  	/* Return new character */
  	return(ch);
  #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || (SUN && !TERMIOS) || XENIX || (AVVION || TERMIOS) */
***************
*** 648,664 ****
  
  	/* Perform read */
  #if HANDLE_WINCH
! 	while ((count = read(0, &ch, 1)) < 0) {
! 		if (winch_flag)
! 			return 0;
  	}
! #else
  	count = read(0, &ch, 1);
  	if (count < 0) {
  		puts("** Horrible read error occured **");
  		exit(1);
  	}
- #endif
  	if (count == 0)
  		return(TIMEOUT);
  
--- 663,689 ----
  
  	/* Perform read */
  #if HANDLE_WINCH
! 	if (winch_has_changed == TRUE)
! 		return(0);
! 	ch = 0;
! 	if (setjmp(winch_sig) != 0)	/* terminate read, many OS's restart reads */
! 	{
! 		winch_can_longjump = FALSE;
! 		if (count == 0)
! 			return(TIMEOUT);
! 		return(ch);
  	}
! 	winch_can_longjump = TRUE;
! #endif
  	count = read(0, &ch, 1);
+ #if HANDLE_WINCH
+ 	winch_can_longjump = FALSE;
+ #endif
+ 
  	if (count < 0) {
  		puts("** Horrible read error occured **");
  		exit(1);
  	}
  	if (count == 0)
  		return(TIMEOUT);
  
***************
*** 770,775 ****
--- 795,803 ----
  /** Initialize screen package **/
  int scopen()
  {
+ #ifdef	HANDLE_WINCH
+ 	struct winsize ws;
+ #endif
  #if TERMCAP || TERMIOS
  	char * cp, tcbuf[1024];
  	int status;
***************
*** 816,824 ****
  		exit(1);
  	}
  
! 	/* Get size from termcap */
! 	term.t_nrow = tgetnum("li") - 1;
! 	term.t_ncol = tgetnum("co");
  	if (term.t_nrow < 3 || term.t_ncol < 3) {
  		puts("Screen size is too small!");
  		exit(1);
--- 844,866 ----
  		exit(1);
  	}
  
! 
! #ifdef HANDLE_WINCH
! 	if (ioctl(0,TIOCGWINSZ,&ws) != -1 && ws.ws_row > 0 && ws.ws_col > 0)
! 	{
! 		term.t_nrow = ws.ws_row - 1;
! 		term.t_ncol = ws.ws_col;
! 	}
! 	else
! 	{
! #endif
!   	/* Get size from termcap */
!   	term.t_nrow = tgetnum("li") - 1;
!   	term.t_ncol = tgetnum("co");
! #ifdef HANDLE_WINCH
! 	}
! #endif
! 
  	if (term.t_nrow < 3 || term.t_ncol < 3) {
  		puts("Screen size is too small!");
  		exit(1);
***************
*** 1329,1338 ****
  	if (!sh)
  #if BSD || FREEBSD || SUN
  		sh = "/bin/csh";
! #endif /* BSD || FREEBSD || SUN */
! #if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS)
  		sh = "/bin/sh";
! #endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS) */
  
  	/* Do shell */
  	return(callout(sh));
--- 1371,1381 ----
  	if (!sh)
  #if BSD || FREEBSD || SUN
  		sh = "/bin/csh";
! #else
! #  if USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS)
  		sh = "/bin/sh";
! #  endif /* USG || AIX || AUX || SMOS || HPUX8 || HPUX9 || XENIX || (AVVION || TERMIOS) */
! #endif /* BSD || FREEBSD || SUN */
  
  	/* Do shell */
  	return(callout(sh));
***************
*** 1709,1723 ****
  void winch_changed()
  {
  	signal(SIGWINCH,winch_changed);
! 	winch_flag = 1;
  }
  
  void winch_new_size()
  {
- 	EWINDOW *wp;
  	struct winsize win;
    
! 	winch_flag=0;
  	ioctl(fileno(stdin),TIOCGWINSZ,&win);
  	winch_vtresize(win.ws_row,win.ws_col);
  	onlywind(0,0);
--- 1752,1767 ----
  void winch_changed()
  {
  	signal(SIGWINCH,winch_changed);
! 	winch_has_changed = TRUE;
! 	if (winch_can_longjump == TRUE)
! 		longjmp(winch_sig, 1);	/* terminates read */
  }
  
  void winch_new_size()
  {
  	struct winsize win;
    
! 	winch_has_changed = FALSE;
  	ioctl(fileno(stdin),TIOCGWINSZ,&win);
  	winch_vtresize(win.ws_row,win.ws_col);
  	onlywind(0,0);
*** ./src/word.c.orig	Sat Feb 22 21:43:52 1997
--- ./src/word.c	Mon Feb 10 12:07:20 1997
***************
*** 653,660 ****
  	int status;		/* status return code */
  	REGION region;		/* region to look at */
  
  	/* make sure we have a region to count */
! 	if ((status = getregion(&region)) != TRUE)
  		return(status);
  	lp = region.r_linep;
  	offset = region.r_offset;
--- 653,663 ----
  	int status;		/* status return code */
  	REGION region;		/* region to look at */
  
+ 	if (f == FALSE)
+ 		n = 0;
+ 		
  	/* make sure we have a region to count */
! 	if ((status = getregion(n, &region)) != TRUE)
  		return(status);
  	lp = region.r_linep;
  	offset = region.r_offset;
