[comp.sources.bugs] Official Sc6.9 -> Sc6.10 patches

buhrt@sawmill.uucp (Jeffery A Buhrt) (10/27/90)

These are patches to Sc6.9 and fix core dumping plus adds some new features;
see below for details.

Please mail me any new changes or additions. Sorry 6.9 -> 6.10 took so
long but news/mail has been unstable upline.

Assuming things go right your checksums should be: (SysV: sum -r, BSD:sum)
46813    12 CHANGES
64088     6 Makefile
02321     3 README
25584     2 TODO
06605     5 VMS_NOTES
02715    33 cmds.c
60659     4 crypt.c
32988     1 eres.sed
03167    14 format.c
30490    13 gram.y
01508    17 help.c
20140    49 interp.c
01181    14 lex.c
63789     7 psc.c
26774     3 psc.doc
44645     6 range.c
09435    35 sc.c
59554    51 sc.doc
33138    10 sc.h
44252     1 sres.sed
10320     5 tutorial.sc
43349     1 version.c
49264    13 vi.c
29399     5 vmtbl.c
04679     1 xmalloc.c

						-Jeff Buhrt
						317-477-6000
					sequent!sawmill!buhrt


*** 69/CHANGES	Thu Oct  4 09:12:41 1990
--- CHANGES	Fri Oct 26 16:57:00 1990
***************
*** 1,4
  
  CHANGES BETWEEN 6.9 and 6.8
  
  Jim Richardson

--- 1,36 -----
  
+ CHANGES BETWEEN 6.10 and 6.9
+ 
+ Tom Tkacik
+ 	- when moving off the current table (resizing) now move the cursor
+ 		on 'l' or 'k'.
+ 	- patches to sc.doc to correctly format the vi-mode notes
+ Jim Clausing
+ 	- made sure / doesn't try to divide by zero.
+ Tom Kloos
+ 	- correction to substr() example in help.c
+ Piercarlo "Peter" Grandi
+ 	- Disable non-constant expressions while loading
+ 	- Added extra code in dealing w/ floating point exceptions
+ 	- #ifdef'd SAVENAME (vs hardcoded SC.SAVE) to allowing changing the
+ 		emergency save name.
+ Casey Leedom
+ 	- Makefile changes: man extension, RINT note, make values should
+ 		never be left undefined and then referenced, don't leave
+ 		around *.old's
+ Tom Anderson
+ 	- patches to add type of column format (note format now has 3 args)
+ Jeff Buhrt
+ 	- xmalloc/xfree fatal() will now call diesave()
+ 		(MAKE SURE the saved file is ok if this were to happen)
+ 	- history[] is now a circular queue, this will cut down on the
+ 		number of data moves and also xmalloc/xfree calls
+ 		(idea from Keith Bostic)
+ 	- cells with an error (ex: divide by 0) will show 'ERROR'
+ 	- you can 'goto error' (or 'goto') to find an ERROR (for next ERROR)
+ Robert Bond
+ 	- When in numeric mode the ^B, ^F, ^N, ^P key will end a numeric entry.
+ 
  CHANGES BETWEEN 6.9 and 6.8
  
  Jim Richardson
*** 69/Makefile	Thu Oct  4 09:13:03 1990
--- Makefile	Fri Oct 26 17:00:51 1990
***************
*** 10,15
  
  # This is where the man page goes.
  #MANDIR=/site/man/man1
  MANDIR=/usr/man/manl
  
  # This is where the library file (tutorial) goes.

--- 10,16 -----
  
  # This is where the man page goes.
  #MANDIR=/site/man/man1
+ #MANEXT=1
  MANDIR=/usr/man/manl
  MANEXT=l
  
***************
*** 11,16
  # This is where the man page goes.
  #MANDIR=/site/man/man1
  MANDIR=/usr/man/manl
  
  # This is where the library file (tutorial) goes.
  #LIBDIR=/site/lib/sc

--- 12,18 -----
  #MANDIR=/site/man/man1
  #MANEXT=1
  MANDIR=/usr/man/manl
+ MANEXT=l
  
  # This is where the library file (tutorial) goes.
  #LIBDIR=/site/lib/sc
***************
*** 17,22
  LIBDIR=/usr/local/lib/sc
  
  # Set SIMPLE for lex.c if you don't want arrow keys or lex.c blows up
  #SIMPLE=-DSIMPLE
  
  # Set DOBACKUPS if you would like a backup copy of a source file on a save

--- 19,25 -----
  LIBDIR=/usr/local/lib/sc
  
  # Set SIMPLE for lex.c if you don't want arrow keys or lex.c blows up
+ SIMPLE=
  #SIMPLE=-DSIMPLE
  
  # Set DOBACKUPS if you would like a backup copy of a source file on a save
***************
*** 20,25
  #SIMPLE=-DSIMPLE
  
  # Set DOBACKUPS if you would like a backup copy of a source file on a save
  DOBACKUPS=-DDOBACKUPS
  
  # Set INTERNATIONAL if you need 8 bit characters.  You should

--- 23,29 -----
  #SIMPLE=-DSIMPLE
  
  # Set DOBACKUPS if you would like a backup copy of a source file on a save
+ #DOBACKUPS=
  DOBACKUPS=-DDOBACKUPS
  
  # Set INTERNATIONAL if you need 8 bit characters.  You should
***************
*** 25,30
  # Set INTERNATIONAL if you need 8 bit characters.  You should
  # not set this if you are running 5.3.0.  I think it is OK in 5.3.1.
  #INTERNATIONAL=-DINTERNATIONAL
  # Set SIGVOID if signal routines are type void.  System 5.3, VMS and ANSI C
  # Compliant systems use this.  Most BSD systems do not.
  #SIGVOID=-DSIGVOID

--- 29,36 -----
  # Set INTERNATIONAL if you need 8 bit characters.  You should
  # not set this if you are running 5.3.0.  I think it is OK in 5.3.1.
  #INTERNATIONAL=-DINTERNATIONAL
+ INTERNATIONAL=
+ 
  # Set SIGVOID if signal routines are type void.  System 5.3, VMS and ANSI C
  # Compliant systems use this.  Most BSD systems do not.
  SIGVOID=-DSIGVOID
***************
*** 27,33
  #INTERNATIONAL=-DINTERNATIONAL
  # Set SIGVOID if signal routines are type void.  System 5.3, VMS and ANSI C
  # Compliant systems use this.  Most BSD systems do not.
! #SIGVOID=-DSIGVOID
  
  # Set IEEE_MATH if you need setsticky() calls in your signal handlers
  #

--- 33,40 -----
  
  # Set SIGVOID if signal routines are type void.  System 5.3, VMS and ANSI C
  # Compliant systems use this.  Most BSD systems do not.
! SIGVOID=-DSIGVOID
! #SIGVOID=
  
  # Set IEEE_MATH if you need setsticky() calls in your signal handlers
  #
***************
*** 32,37
  # Set IEEE_MATH if you need setsticky() calls in your signal handlers
  #
  #IEEE_MATH=-DIEEE_MATH
  
  # Set RINT if you do not have rint() in math.h
  RINT=-DRINT

--- 39,45 -----
  # Set IEEE_MATH if you need setsticky() calls in your signal handlers
  #
  #IEEE_MATH=-DIEEE_MATH
+ IEEE_MATH=
  
  # Set RINT if you do not have rint() in math.h
  # So far I know you what to undefine this on/with:
***************
*** 34,39
  #IEEE_MATH=-DIEEE_MATH
  
  # Set RINT if you do not have rint() in math.h
  RINT=-DRINT
  
  # This is the name of a pager like "more" If the line is commented out

--- 42,50 -----
  IEEE_MATH=
  
  # Set RINT if you do not have rint() in math.h
+ # So far I know you what to undefine this on/with:
+ #	SunOS 4.0.3c compiler
+ #RINT=
  RINT=-DRINT
  
  # This is the name of a pager like "more".
***************
*** 36,44
  # Set RINT if you do not have rint() in math.h
  RINT=-DRINT
  
! # This is the name of a pager like "more" If the line is commented out
! # then "more" will be used. "pg" may be appropriate for SYSV
! PAGER=-DDFLT_PAGER=\"less\"
  
  # For ULTRIX: define the BSD4.2 section and SIGVOID above
  #	tdw@cl.cam.ac.uk tested on Ultrix 3.1C-0

--- 47,56 -----
  #RINT=
  RINT=-DRINT
  
! # This is the name of a pager like "more".
! # "pg" may be appropriate for SYSV.
! #DFLTPAGER=-DDFLT_PAGER=\"less\"
! DFLT_PAGER=-DDFLT_PAGER=\"more\"
  
  # For ULTRIX: define the BSD4.2 section and SIGVOID above
  #	tdw@cl.cam.ac.uk tested on Ultrix 3.1C-0
***************
*** 98,104
  
  # All of the source files
  SRC=sc.h sc.c lex.c gram.y interp.c crypt.c xmalloc.c cmds.c range.c help.c \
! 	vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c
  
  # The objects
  OBJS=sc.o interp.o cmds.o crypt.o xmalloc.o range.o help.o vi.o lex.o gram.o \

--- 110,116 -----
  
  # All of the source files
  SRC=sc.h sc.c lex.c gram.y interp.c crypt.c xmalloc.c cmds.c range.c help.c \
! 	vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c 
  
  # The objects
  OBJS=sc.o interp.o cmds.o gram.o lex.o crypt.o xmalloc.o range.o help.o vi.o \
***************
*** 101,108
  	vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c
  
  # The objects
! OBJS=sc.o interp.o cmds.o crypt.o xmalloc.o range.o help.o vi.o lex.o gram.o \
! 	vmtbl.o format.o version.o
  
  # The documents in the Archive
  DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES BSD_BUGS

--- 113,120 -----
  	vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c 
  
  # The objects
! OBJS=sc.o interp.o cmds.o gram.o lex.o crypt.o xmalloc.o range.o help.o vi.o \
! 	vmtbl.o format.o version.o 
  
  # The documents in the Archive
  DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES
***************
*** 105,111
  	vmtbl.o format.o version.o
  
  # The documents in the Archive
! DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES BSD_BUGS
  
  $(name):$(PAR) 	$(OBJS)
  	$(CC) ${CFLAGS} ${LDFLAGS} ${OBJS} ${LIB} -o $(name)

--- 117,123 -----
  	vmtbl.o format.o version.o 
  
  # The documents in the Archive
! DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES
  
  $(name):$(PAR) 	$(OBJS)
  	$(CC) ${CFLAGS} ${LDFLAGS} ${OBJS} ${LIB} -o $(name)
***************
*** 125,131
  	$(CC) ${CFLAGS} ${SIMPLE} ${IEEE_MATH} ${INTERNATIONAL} ${SIGVOID} -c lex.c
  
  sc.o:	sc.h sc.c
! 	$(CC) ${CFLAGS} ${INTERNATIONAL} ${PAGER} ${SIGVOID} -c sc.c
  
  interp.o:	interp.c sc.h
  	$(CC) ${CFLAGS} ${IEEE_MATH} ${SIGVOID} ${RINT} -c interp.c

--- 137,143 -----
  	$(CC) ${CFLAGS} ${SIMPLE} ${IEEE_MATH} ${INTERNATIONAL} ${SIGVOID} -c lex.c
  
  sc.o:	sc.h sc.c
! 	$(CC) ${CFLAGS} ${INTERNATIONAL} ${DFLT_PAGER} ${SIGVOID} -c sc.c
  
  interp.o:	interp.c sc.h
  	$(CC) ${CFLAGS} ${IEEE_MATH} ${SIGVOID} ${RINT} -c interp.c
***************
*** 192,198
  p$(name).man:	p$(name).1
  	nroff -man p$(name).1 > p$(name).man
  
! install: $(EXDIR)/$(name) $(LIBDIR)/tutorial
  
  inst-man: $(MANDIR)/$(name).1
  

--- 204,210 -----
  p$(name).man:	p$(name).1
  	nroff -man p$(name).1 > p$(name).man
  
! install: $(EXDIR)/$(name) $(LIBDIR)/tutorial $(MANDIR)/$(name).$(MANEXT)
  
  $(EXDIR)/$(name): $(name)
  	cp $(name) $(EXDIR)
***************
*** 194,201
  
  install: $(EXDIR)/$(name) $(LIBDIR)/tutorial
  
- inst-man: $(MANDIR)/$(name).1
- 
  $(EXDIR)/$(name): $(name)
  	-mv $(EXDIR)/$(name) $(EXDIR)/$(name).old
  	cp $(name) $(EXDIR)

--- 206,211 -----
  
  install: $(EXDIR)/$(name) $(LIBDIR)/tutorial $(MANDIR)/$(name).$(MANEXT)
  
  $(EXDIR)/$(name): $(name)
  	cp $(name) $(EXDIR)
  	strip $(EXDIR)/$(name)
***************
*** 197,203
  inst-man: $(MANDIR)/$(name).1
  
  $(EXDIR)/$(name): $(name)
- 	-mv $(EXDIR)/$(name) $(EXDIR)/$(name).old
  	cp $(name) $(EXDIR)
  	strip $(EXDIR)/$(name)
  

--- 207,212 -----
  install: $(EXDIR)/$(name) $(LIBDIR)/tutorial $(MANDIR)/$(name).$(MANEXT)
  
  $(EXDIR)/$(name): $(name)
  	cp $(name) $(EXDIR)
  	strip $(EXDIR)/$(name)
  
***************
*** 201,208
  	cp $(name) $(EXDIR)
  	strip $(EXDIR)/$(name)
  
! $(LIBDIR)/tutorial: tutorial.sc
! 	-mkdir $(LIBDIR)
  	cp tutorial.sc $(LIBDIR)
  
  $(MANDIR)/$(name).1: $(name).1

--- 210,216 -----
  	cp $(name) $(EXDIR)
  	strip $(EXDIR)/$(name)
  
! $(LIBDIR)/tutorial: tutorial.sc $(LIBDIR)
  	cp tutorial.sc $(LIBDIR)
  
  $(LIBDIR):
***************
*** 205,212
  	-mkdir $(LIBDIR)
  	cp tutorial.sc $(LIBDIR)
  
! $(MANDIR)/$(name).1: $(name).1
! 	cp $(name).1 $(MANDIR)
  
  diffs: ${SRC}
  	for i in ${SRC} ${DOCS} ;\

--- 213,220 -----
  $(LIBDIR)/tutorial: tutorial.sc $(LIBDIR)
  	cp tutorial.sc $(LIBDIR)
  
! $(LIBDIR):
! 	mkdir $(LIBDIR)
  
  $(MANDIR)/$(name).$(MANEXT): $(name).1
  	cp $(name).1 $(MANDIR)/$(name).$(MANEXT)
***************
*** 208,213
  $(MANDIR)/$(name).1: $(name).1
  	cp $(name).1 $(MANDIR)
  
  diffs: ${SRC}
  	for i in ${SRC} ${DOCS} ;\
  		do \

--- 216,224 -----
  $(LIBDIR):
  	mkdir $(LIBDIR)
  
+ $(MANDIR)/$(name).$(MANEXT): $(name).1
+ 	cp $(name).1 $(MANDIR)/$(name).$(MANEXT)
+ 
  diffs: ${SRC}
  	for i in ${SRC} ${DOCS} ;\
  		do \
***************
*** 212,217
  	for i in ${SRC} ${DOCS} ;\
  		do \
  		rcsdiff -c -r6.1 $$i ;\
  		done
  
  test: test.o vmtbl.o

--- 223,236 -----
  	for i in ${SRC} ${DOCS} ;\
  		do \
  		rcsdiff -c -r6.1 $$i ;\
+ 		done
+ 
+ # THA 10/14/90  Added code to make a patchfile
+ patchfile: ${SRC}
+ 	rm -f patchfile
+ 	for i in ${SRC} ${DOCS} format.c ;\
+ 		do \
+ 		diffc $$i /users/toma/sc6.8me/$$i >> patchfile ;\
  		done
  
  test: test.o vmtbl.o
*** 69/README	Thu Oct  4 09:13:17 1990
--- README	Fri Oct 26 17:04:45 1990
***************
*** 1,8
  This is a much modified version of the public domain spread sheet sc,
  posted several years ago by Mark Weiser as vc, originally by James Gosling.
  
! Changes since my last version (5.1) are detailed at great length :-)
! in CHANGES (sequent!rgb (Robert Bond)).
  
  When you get it built, try "sc tutorial.sc" for a simple introduction
  to the basic commands.

--- 1,8 -----
  This is a much modified version of the public domain spread sheet sc,
  posted several years ago by Mark Weiser as vc, originally by James Gosling.
  
! CHANGES lists the changes since 6.1 to 6.10.
! Current maintainer: sequent!sawmill!buhrt (Jeff Buhrt)
  
  When you get it built, try "sc tutorial.sc" for a simple introduction
  to the basic commands.
***************
*** 25,32
  have nroff, you will have to change sc.man yourself.
  
  This release has been tested against a Sequent S81 running DYNIX 3.0.14
! (BSD 4.2) and an ICM-3216 with system V.3.  The ICM has a National Semi
! 32016.  Just check the makefile for the system flags.   I have heard
  reports of lots of other machines that work. If you have problems with
  lex.c, and don't care about arrow keys, define SIMPLE (-DSIMPLE in the
  makefile).  SIMPLE causes the arrow keys to not be used.

--- 25,32 -----
  have nroff, you will have to change sc.man yourself.
  
  This release has been tested against a Sequent S81 running DYNIX 3.0.14
! (BSD 4.2), AT&T SysV 3.2.2, ESIX SysV 3.2 Rev D.
! Just check the makefile for the system flags.   I have heard
  reports of lots of other machines that work. If you have problems with
  lex.c, and don't care about arrow keys, define SIMPLE (-DSIMPLE in the
  makefile).  SIMPLE causes the arrow keys to not be used.
***************
*** 59,62
  
  					Jeff Buhrt
  					Grauel Enterprises, Inc.
! 	{pur-phy (aka: newton.physics.purdue.edu), sequent}!sawmill!buhrt

--- 59,63 -----
  
  					Jeff Buhrt
  					Grauel Enterprises, Inc.
! 					sequent!sawmill!buhrt
! 
*** 69/cmds.c	Thu Oct  4 09:16:00 1990
--- cmds.c	Fri Oct 26 17:00:59 1990
***************
*** 7,13
   *
   *              More mods Robert Bond, 12/86
   *
!  *		$Revision: 6.9 $
   */
  
  #include <curses.h>

--- 7,13 -----
   *
   *              More mods Robert Bond, 12/86
   *
!  *		$Revision: 6.10 $
   */
  
  #include <curses.h>
***************
*** 422,427
      for (i = maxcol; i > cs; i--) {
  	fwidth[i] = fwidth[i-numcol];
  	precision[i] = precision[i-numcol];
  	col_hidden[i] = col_hidden[i-numcol];
      }
      for (c = cs; c - cs < numcol; c++)

--- 422,428 -----
      for (i = maxcol; i > cs; i--) {
  	fwidth[i] = fwidth[i-numcol];
  	precision[i] = precision[i-numcol];
+ 	realfmt[i] = realfmt[i-numcol];
  	col_hidden[i] = col_hidden[i-numcol];
      }
      for (c = cs; c - cs < numcol; c++)
***************
*** 427,432
      for (c = cs; c - cs < numcol; c++)
      {	fwidth[c] = DEFWIDTH;
  	precision[c] =  DEFPREC;
      }
  	
      for (r=0; r<=maxrow; r++) {

--- 428,434 -----
      for (c = cs; c - cs < numcol; c++)
      {	fwidth[c] = DEFWIDTH;
  	precision[c] =  DEFPREC;
+ 	realfmt[c] = DEFREFMT;
      }
  	
      for (r=0; r<=maxrow; r++) {
***************
*** 490,495
      for (i = cs; i < maxcols - numcol - 1; i++) {
  	fwidth[i] = fwidth[i+numcol];
  	precision[i] = precision[i+numcol];
  	col_hidden[i] = col_hidden[i+numcol];
      }
      for (; i < maxcols - 1; i++) {

--- 492,498 -----
      for (i = cs; i < maxcols - numcol - 1; i++) {
  	fwidth[i] = fwidth[i+numcol];
  	precision[i] = precision[i+numcol];
+ 	realfmt[i] = realfmt[i+numcol];
  	col_hidden[i] = col_hidden[i+numcol];
      }
      for (; i < maxcols - 1; i++) {
***************
*** 495,500
      for (; i < maxcols - 1; i++) {
  	fwidth[i] = DEFWIDTH;
  	precision[i] = DEFPREC;
  	col_hidden[i] = 0;
      }
  

--- 498,504 -----
      for (; i < maxcols - 1; i++) {
  	fwidth[i] = DEFWIDTH;
  	precision[i] = DEFPREC;
+ 	realfmt[i] = DEFREFMT;
  	col_hidden[i] = 0;
      }
  
***************
*** 577,582
      }
  }
  
  void
  doformat(c1,c2,w,p)
  int c1,c2,w,p;

--- 581,587 -----
      }
  }
  
+ /* Modified 9/17/90 THA to handle more formats */
  void
  doformat(c1,c2,w,p,r)
  int c1,c2,w,p,r;
***************
*** 578,585
  }
  
  void
! doformat(c1,c2,w,p)
! int c1,c2,w,p;
  {
      register int i;
  

--- 583,590 -----
  
  /* Modified 9/17/90 THA to handle more formats */
  void
! doformat(c1,c2,w,p,r)
! int c1,c2,w,p,r;
  {
      register int i;
  
***************
*** 597,603
      }
  
      for(i = c1; i<=c2; i++)
! 	fwidth[i] = w, precision[i] = p;
  
      FullUpdate++;
      modflg++;

--- 602,608 -----
      }
  
      for(i = c1; i<=c2; i++)
! 	fwidth[i] = w, precision[i] = p, realfmt[i] = r;
  
      FullUpdate++;
      modflg++;
***************
*** 658,668
      register row, col;
      register struct ent **pp;
  
-     if((pline = (char *)malloc(FBUFLEN * ++fbufs_allocated)) == (char *)NULL) {
-         error("Malloc failed in printfile()");
-         return;
-     }
- 
      if ((strcmp(fname, curfile) == 0) &&
  	!yn_ask("Confirm that you want to destroy the data base: (y,n)")) {
          free((char *)pline);

--- 663,668 -----
      register row, col;
      register struct ent **pp;
  
      if ((strcmp(fname, curfile) == 0) &&
  	!yn_ask("Confirm that you want to destroy the data base: (y,n)")) {
          free((char *)pline);
***************
*** 669,674
  	return;
      }
  
      if ((f = openout(fname, &pid)) == (FILE *)0)
      {	error ("Can't create file \"%s\"", fname);
          free((char *)pline);

--- 669,679 -----
  	return;
      }
  
+     if((pline = (char *)malloc(FBUFLEN * ++fbufs_allocated)) == (char *)NULL) {
+         error("Malloc failed in printfile()");
+         return;
+     }
+ 
      if ((f = openout(fname, &pid)) == (FILE *)0)
      {	error ("Can't create file \"%s\"", fname);
          free((char *)pline);
***************
*** 721,731
  			free((char *)pline);
  			return;
  		      }
! 		    }		  
! 		    if ((*pp)->format) {
! 			char field[FBUFLEN];
! 
! 			(void) format ((*pp)->format, (*pp)->v, field,
  				       sizeof(field));
  			(void) sprintf (pline+plinelim, "%*s", fwidth[col],
  					field);

--- 726,740 -----
  			free((char *)pline);
  			return;
  		      }
! 		    }
! 		    if ((*pp)->cellerror)
! 			(void) sprintf (pline+plinelim, "%*s", "ERROR",
! 						fwidth[col]);
! 		    else
! 		    {
! 		      if ((*pp)->format) {
! 	   	        char field[FBUFLEN];
! 			format ((*pp)->format, (*pp)->v, field,
  				       sizeof(field));
  			(void) sprintf (pline+plinelim, "%*s", fwidth[col],
  					field);
***************
*** 729,737
  				       sizeof(field));
  			(void) sprintf (pline+plinelim, "%*s", fwidth[col],
  					field);
! 		    } else {
! 			(void)sprintf (pline+plinelim,"%*.*f",fwidth[col],
! 				       precision[col], (*pp)->v);
  		    }
  		    plinelim += strlen (pline+plinelim);
  		}

--- 738,751 -----
  				       sizeof(field));
  			(void) sprintf (pline+plinelim, "%*s", fwidth[col],
  					field);
! 		      } else {
! 	   	        char field[FBUFLEN];
! 			engformat(realfmt[col], fwidth[col],
!                                              precision[col], (*pp) -> v,
!                                              field, sizeof(field));
! 			(void)sprintf (pline+plinelim, "%*s", fwidth[col],
! 				       field);
! 		      }
  		    }
  		    plinelim += strlen (pline+plinelim);
  		}
***************
*** 846,853
  				       sizeof(field));
  			(void) fprintf (f, "%s", field);
  		    } else {
! 		        (void) fprintf (f,"%.*f",precision[col],
! 					(*pp)->v);
  		    }
  		}
  		if (s = (*pp)->label) {

--- 860,870 -----
  				       sizeof(field));
  			(void) fprintf (f, "%s", field);
  		    } else {
! 		        char field[FBUFLEN];
!                         engformat(realfmt[col], fwidth[col],
!                                              precision[col], (*pp) -> v,
!                                              field, sizeof(field));
! 			(void) fprintf (f, "%s", field);
  		    }
  		}
  		if (s = (*pp)->label) {
***************
*** 1181,1188
      (void) fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
      print_options(f);
      for (c=0; c<maxcols; c++)
! 	if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
! 	    (void) fprintf (f, "format %s %d %d\n",coltoa(c),fwidth[c],precision[c]);
      for (c=c0; c<cn; c++) {
          if (col_hidden[c]) {
              (void) fprintf(f, "hide %s\n", coltoa(c));

--- 1198,1205 -----
      (void) fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
      print_options(f);
      for (c=0; c<maxcols; c++)
! 	if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC || realfmt[c] != DEFREFMT )
! 	    (void) fprintf (f, "format %s %d %d %d\n",coltoa(c),fwidth[c],precision[c],realfmt[c]);
      for (c=c0; c<cn; c++) {
          if (col_hidden[c]) {
              (void) fprintf(f, "hide %s\n", coltoa(c));
***************
*** 1314,1319
      for (c = 0; c<=maxcol; c++) {
  	fwidth[c] = DEFWIDTH;
  	precision[c] = DEFPREC;
      }
  
      for (r = 0; r<=maxrow; r++) {

--- 1331,1337 -----
      for (c = 0; c<=maxcol; c++) {
  	fwidth[c] = DEFWIDTH;
  	precision[c] = DEFPREC;
+ 	realfmt[c] = DEFREFMT;
      }
  
      for (r = 0; r<=maxrow; r++) {
***************
*** 1356,1361
  	else
  	if (!growtbl(GROWCOL, 0, arg))	/* get as much as needed */
  		break;
  	while(col_hidden[curcol]&&(curcol<maxcols-1))
  	    curcol++;
      }

--- 1374,1381 -----
  	else
  	if (!growtbl(GROWCOL, 0, arg))	/* get as much as needed */
  		break;
+ 	else
+ 		curcol++;
  	while(col_hidden[curcol]&&(curcol<maxcols-1))
  	    curcol++;
      }
***************
*** 1371,1376
  	else
  	if (!growtbl(GROWROW, arg, 0))	/* get as much as needed */
  		break;
  	while (row_hidden[currow]&&(currow<maxrows-1))
  	    currow++;
      }

--- 1391,1398 -----
  	else
  	if (!growtbl(GROWROW, arg, 0))	/* get as much as needed */
  		break;
+ 	else
+ 		currow++;
  	while (row_hidden[currow]&&(currow<maxrows-1))
  	    currow++;
      }
*** 69/crypt.c	Thu Oct  4 09:16:09 1990
--- crypt.c	Fri Oct 26 16:57:11 1990
***************
*** 2,8
   * Encryption utilites
   * Bradley Williams	
   * {allegra,ihnp4,uiucdcs,ctvax}!convex!williams
!  * $Revision: 6.9 $
   */
  
  #include <stdio.h>

--- 2,8 -----
   * Encryption utilites
   * Bradley Williams	
   * {allegra,ihnp4,uiucdcs,ctvax}!convex!williams
!  * $Revision: 6.10 $
   */
  
  #include <stdio.h>
***************
*** 24,30
  
  int         Crypt = 0;
  #define MAXKEYWORDSIZE 30
! char	    KeyWord[MAXKEYWORDSIZE] = NULL;
  
  creadfile (save, eraseflg)
  char *save;

--- 24,30 -----
  
  int         Crypt = 0;
  #define MAXKEYWORDSIZE 30
! char	    KeyWord[MAXKEYWORDSIZE] = {NULL};
  
  void
  creadfile (save, eraseflg)
***************
*** 26,31
  #define MAXKEYWORDSIZE 30
  char	    KeyWord[MAXKEYWORDSIZE] = NULL;
  
  creadfile (save, eraseflg)
  char *save;
  int  eraseflg;

--- 26,32 -----
  #define MAXKEYWORDSIZE 30
  char	    KeyWord[MAXKEYWORDSIZE] = {NULL};
  
+ void
  creadfile (save, eraseflg)
  char *save;
  int  eraseflg;
***************
*** 97,102
      EvalAll();
  }
  
  cwritefile (fname, r0, c0, rn, cn)
  char *fname;
  int r0, c0, rn, cn;

--- 98,104 -----
      EvalAll();
  }
  
+ int
  cwritefile (fname, r0, c0, rn, cn)
  char *fname;
  int r0, c0, rn, cn;
*** 69/gram.y	Thu Oct  4 09:13:08 1990
--- gram.y	Fri Oct 26 16:57:41 1990
***************
*** 9,15
   *
   *		More mods by Alan Silverstein, 3/88, see list of changes.
   *
!  *		$Revision: 6.9 $
   */
  
  

--- 9,15 -----
   *
   *		More mods by Alan Silverstein, 3/88, see list of changes.
   *
!  *		$Revision: 6.10 $
   */
  
  
***************
*** 68,73
  %token S_HIDE
  %token S_SET
  
  %token K_FIXED
  %token K_SUM
  %token K_PROD

--- 68,75 -----
  %token S_HIDE
  %token S_SET
  
+ %token K_ERROR
+ %token K_INVALID
  %token K_FIXED
  %token K_SUM
  %token K_PROD
***************
*** 160,169
  				{ slet($2.left.vp, $4, -1); }
  	|	S_RIGHTSTRING var_or_range '=' e
  				{ slet($2.left.vp, $4, 1); }
! 	|	S_FORMAT COL ':' COL NUMBER NUMBER
! 				{ doformat($2,$4,$5,$6); }
! 	|	S_FORMAT COL NUMBER NUMBER
! 				{ doformat($2,$2,$3,$4); }
  	|	S_GET strarg	{  /* This tmp hack is because readfile
  				    * recurses back through yyparse. */
  				  char *tmp;

--- 162,175 -----
  				{ slet($2.left.vp, $4, -1); }
  	|	S_RIGHTSTRING var_or_range '=' e
  				{ slet($2.left.vp, $4, 1); }
! 	|	S_FORMAT COL ':' COL NUMBER NUMBER NUMBER
! 				{ doformat($2,$4,$5,$6,$7); }
! 	|	S_FORMAT COL NUMBER NUMBER NUMBER
! 				{ doformat($2,$2,$3,$4,$5); }
!         |       S_FORMAT COL ':' COL NUMBER NUMBER
!                                 { doformat($2,$4,$5,$6, 0); }
!         |       S_FORMAT COL NUMBER NUMBER
!                                 { doformat($2,$2,$3,$4, 0); }
  	|	S_GET strarg	{  /* This tmp hack is because readfile
  				    * recurses back through yyparse. */
  				  char *tmp;
***************
*** 228,235
  	|	S_FMT var_or_range STRING
  				{ format_cell($2.left.vp, $2.right.vp, $3); }
  	|	S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
! 	|       S_GOTO num          {num_search($2);}
! 	|       S_GOTO STRING       {str_search($2);}
  	|	S_GOTO              {go_last();}
  	|	S_DEFINE strarg       { struct ent_ptr arg1, arg2;
  					arg1.vp = lookat(showsr, showsc);

--- 234,242 -----
  	|	S_FMT var_or_range STRING
  				{ format_cell($2.left.vp, $2.right.vp, $3); }
  	|	S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
! 	|       S_GOTO num          {num_search($2, 0);}
! 	|       S_GOTO errlist
! 	|       S_GOTO STRING	    {str_search($2);}
  	|	S_GOTO              {go_last();}
  	|	S_DEFINE strarg       { struct ent_ptr arg1, arg2;
  					arg1.vp = lookat(showsr, showsc);
***************
*** 241,247
  	|	S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
  	|	S_DEFINE strarg var   { add_range($2, $3, $3, 0); }
  	|	S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
!  	|	S_SET setlist
  	|	/* nothing */
  	|	error;
  

--- 248,254 -----
  	|	S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
  	|	S_DEFINE strarg var   { add_range($2, $3, $3, 0); }
  	|	S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
!  	|	S_SET setitem
  	|	/* nothing */
  	|	error;
  
***************
*** 245,251
  	|	/* nothing */
  	|	error;
  
! term: 		var		{ $$ = new_var('v', $1); }
  	|	K_FIXED term	{ $$ = new ('f', ENULL, $2); }
  	|       '@' K_SUM '(' var_or_range ')' 
  				{ $$ = new_range(REDUCE | '+', $4); }

--- 252,258 -----
  	|	/* nothing */
  	|	error;
  
! term: 		var		{ $$ = new_var(O_VAR, $1); }
  	|	K_FIXED term	{ $$ = new ('f', ENULL, $2); }
  	|       '@' K_SUM '(' var_or_range ')' 
  				{ $$ = new_range(REDUCE | '+', $4); }
***************
*** 327,335
  	|	'(' e ')'	 { $$ = $2; }
  	|	'+' term	 { $$ = $2; }
  	|	'-' term	 { $$ = new ('m', ENULL, $2); }
! 	|	NUMBER		 { $$ = new_const('k', (double) $1); }
! 	|	FNUMBER		 { $$ = new_const('k', $1); }
! 	|	K_PI	{ $$ = new_const('k', (double)3.14159265358979323846); }
  	|	STRING	         { $$ = new_str($1); }
  	|	'~' term	 { $$ = new ('~', ENULL, $2); }
  	|	'!' term	 { $$ = new ('~', ENULL, $2); }

--- 334,342 -----
  	|	'(' e ')'	 { $$ = $2; }
  	|	'+' term	 { $$ = $2; }
  	|	'-' term	 { $$ = new ('m', ENULL, $2); }
! 	|	NUMBER		 { $$ = new_const(O_CONST, (double) $1); }
! 	|	FNUMBER		 { $$ = new_const(O_CONST, $1); }
! 	|	K_PI	{ $$ = new_const(O_CONST, (double)3.14159265358979323846); }
  	|	STRING	         { $$ = new_str($1); }
  	|	'~' term	 { $$ = new ('~', ENULL, $2); }
  	|	'!' term	 { $$ = new ('~', ENULL, $2); }
***************
*** 394,403
  				}
    	;
  
- setlist :	
- 	|	setlist setitem
- 	;
- 
  setitem	:	K_AUTO		{ setauto(1); }
  	|	K_AUTOCALC	{ setauto(1); }
  	|	'~' K_AUTO	{ setauto(0); }

--- 401,406 -----
  				}
    	;
  
  setitem	:	K_AUTO		{ setauto(1); }
  	|	K_AUTOCALC	{ setauto(1); }
  	|	'~' K_AUTO	{ setauto(0); }
***************
*** 425,427
  	|	K_RNDINFINITY		{ rndinfinity = 1; FullUpdate++;}
  	|	'!' K_RNDINFINITY	{ rndinfinity = 0; FullUpdate++;}
    	;

--- 428,434 -----
  	|	K_RNDINFINITY		{ rndinfinity = 1; FullUpdate++;}
  	|	'!' K_RNDINFINITY	{ rndinfinity = 0; FullUpdate++;}
    	;
+ 
+ errlist :	K_ERROR		{num_search((double)0, CELLERROR);}
+ 	|	K_INVALID	{num_search((double)0, CELLINVALID);}
+ 	;
*** 69/help.c	Thu Oct  4 09:14:19 1990
--- help.c	Fri Oct 26 16:57:44 1990
***************
*** 1,7
  /*
   * Help functions for sc 
   * R. Bond, 1988
!  * $Revision: 6.9 $
   */
  
  #include <curses.h>

--- 1,7 -----
  /*
   * Help functions for sc 
   * R. Bond, 1988
!  * $Revision: 6.10 $
   */
  
  #include <curses.h>
***************
*** 78,84
  "     b          Back then up to the previous valid cell.",
  "     w          Forward then down to the next valid cell.",
  "     g          Go to a cell.  Cell name, range name, quoted string,",
! "                or a number specify which cell.",
  (char *)0
  };
  

--- 78,84 -----
  "     b          Back then up to the previous valid cell.",
  "     w          Forward then down to the next valid cell.",
  "     g          Go to a cell.  Cell name, range name, quoted string,",
! "                a number, 'error', or 'invalid' to specify which cell.",
  (char *)0
  };
  
***************
*** 317,323
  "     @substr(se,e1,e2) Extract characters e1 through e2 from the",
  "                       string expression se.  For example,",
  "                       ``@substr(\"Nice jacket\" 4, 7)'' yields ",
! "                       ``e jac''.",
  "     @fmt(se,e)        Convert a number to a string using sprintf(3).",
  "                       For example,  ``@fmt(\"*%6.3f*\",10.5)'' yields",
  "                       ``*10.500*''.  Use formats are e, E, f, g, and G.", 

--- 317,323 -----
  "     @substr(se,e1,e2) Extract characters e1 through e2 from the",
  "                       string expression se.  For example,",
  "                       ``@substr(\"Nice jacket\" 4, 7)'' yields ",
! "                       ``e ja''.",
  "     @fmt(se,e)        Convert a number to a string using sprintf(3).",
  "                       For example,  ``@fmt(\"*%6.3f*\",10.5)'' yields",
  "                       ``*10.500*''.  Use formats are e, E, f, g, and G.", 
***************
*** 385,390
  "                       last full minute: 0 to 59.",
  (char *)0
  };
  void
  help()
  {

--- 385,393 -----
  "                       last full minute: 0 to 59.",
  (char *)0
  };
+ 
+ static	int	pscreen();
+ 
  void
  help()
  {
***************
*** 416,421
      (void) clrtobot();
  }
  
  pscreen(screen)
  char *screen[];
  {

--- 419,425 -----
      (void) clrtobot();
  }
  
+ static	int
  pscreen(screen)
  char *screen[];
  {
***************
*** 431,437
  	(void) clrtoeol();
      }
      (void) move(0,0);
!     (void) printw("Which Screen? [a-n, q]");
      (void) clrtoeol();
      (void) refresh();
      return(nmgetch());

--- 435,441 -----
  	(void) clrtoeol();
      }
      (void) move(0,0);
!     (void) printw("Which Screen? [a-o, q]");
      (void) clrtoeol();
      (void) refresh();
      return(nmgetch());
*** 69/interp.c	Thu Oct  4 09:17:13 1990
--- interp.c	Fri Oct 26 16:57:53 1990
***************
*** 7,13
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		$Revision: 6.9 $
   */
  
  #define DEBUGDTS 1		/* REMOVE ME */

--- 7,13 -----
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		$Revision: 6.10 $
   */
  
  #define DEBUGDTS 1		/* REMOVE ME */
***************
*** 11,17
   */
  
  #define DEBUGDTS 1		/* REMOVE ME */
- /* #define EXPRTREE	/* expr. dependency tree stuff, not ready yet */
  
  #ifdef aiws
  #undef _C_func			/* Fixes for undefined symbols on AIX */

--- 11,16 -----
   */
  
  #define DEBUGDTS 1		/* REMOVE ME */
  
  #ifdef aiws
  #undef _C_func			/* Fixes for undefined symbols on AIX */
***************
*** 57,62
      int quit();
  #endif
  
  /* Use this structure to save the the last 'g' command */
  
  struct go_save {

--- 56,65 -----
      int quit();
  #endif
  
+ /* Suffixes for engineering notation THA 9/19/88 */
+ extern char engmult[];
+ 
+ 
  /* Use this structure to save the the last 'g' command */
  
  struct go_save {
***************
*** 65,70
  	char *g_s;
  	int  g_row;
  	int  g_col;
  } gs;
  
  /* g_type can be: */

--- 68,74 -----
  	char *g_s;
  	int  g_row;
  	int  g_col;
+ 	int  errsearch;
  } gs;
  
  /* g_type can be: */
***************
*** 87,92
  double fn2_eval();
  struct	ent *firstev = (struct ent *)0;	/* first expr in the eval list */
  double	rint();
  
  #define PI (double)3.14159265358979323846
  #define dtr(x) ((x)*(PI/(double)180.0))

--- 91,97 -----
  double fn2_eval();
  struct	ent *firstev = (struct ent *)0;	/* first expr in the eval list */
  double	rint();
+ int	cellerror = CELLOK;	/* is there an error in this cell */
  
  #define PI (double)3.14159265358979323846
  #define dtr(x) ((x)*(PI/(double)180.0))
***************
*** 103,109
   	switch(fun)
   	{
   	case PV:
!  		answer = v1 * (1 - 1/p) / v2;
   		break;
   	case FV:
   		answer = v1 * (p - 1) / v2;

--- 108,119 -----
   	switch(fun)
   	{
   	case PV:
! 		if (v2)
! 			answer = v1 * (1 - 1/p) / v2;
! 		else
! 		{	cellerror = CELLERROR;
! 			answer = (double)0;
! 		}
   		break;
   	case FV:
  		if (v2)
***************
*** 106,112
   		answer = v1 * (1 - 1/p) / v2;
   		break;
   	case FV:
!  		answer = v1 * (p - 1) / v2;
   		break;
   	case PMT:
   		answer = v1 * v2 / (1 - 1/p);

--- 116,127 -----
  		}
   		break;
   	case FV:
! 		if (v2)
! 			answer = v1 * (p - 1) / v2;
! 		else
! 		{	cellerror = CELLERROR;
! 			answer = (double)0;
! 		}
   		break;
   	case PMT:
  		/* CHECK IF ~= 1 - 1/1 */
***************
*** 109,115
   		answer = v1 * (p - 1) / v2;
   		break;
   	case PMT:
!  		answer = v1 * v2 / (1 - 1/p);
   		break;
  	default:
  		error("Unknown function in finfunc");

--- 124,137 -----
  		}
   		break;
   	case PMT:
! 		/* CHECK IF ~= 1 - 1/1 */
! 		if (p && p != (double)1)
! 			answer = v1 * v2 / (1 - 1/p);
! 		else
! 		{	cellerror = CELLERROR;
! 			answer = (double)0;
! 		}
! 		
   		break;
  	default:
  		error("Unknown function in finfunc");
***************
*** 113,118
   		break;
  	default:
  		error("Unknown function in finfunc");
  		return((double)0);
  	}
  	return(answer);

--- 135,141 -----
   		break;
  	default:
  		error("Unknown function in finfunc");
+ 		cellerror = CELLERROR;
  		return((double)0);
  	}
  	return(answer);
***************
*** 141,146
  	    p = *ATBL(tbl, r, c);
      } else {
  	error ("range specified to @stindex");
  	return((char *)0);
      }
  

--- 164,170 -----
  	    p = *ATBL(tbl, r, c);
      } else {
  	error ("range specified to @stindex");
+ 	cellerror = CELLERROR;
  	return((char *)0);
      }
  
***************
*** 147,152
      if (p && p->label) {
  	pr = xmalloc((unsigned)(strlen(p->label)+1));
  	(void)strcpy(pr, p->label);
  	return (pr);
       } else
  	return((char *)0);

--- 171,178 -----
      if (p && p->label) {
  	pr = xmalloc((unsigned)(strlen(p->label)+1));
  	(void)strcpy(pr, p->label);
+ 	if (p->cellerror)
+ 		cellerror = CELLINVALID;
  	return (pr);
       } else
  	return((char *)0);
***************
*** 169,175
  	c = minc + x - 1;
  	if (c <= maxc && c >=minc 
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
! 					return p->v;
  	}
      else if ( minc == maxc ){ /* look down the column */
  	r = minr + x - 1;

--- 195,203 -----
  	c = minc + x - 1;
  	if (c <= maxc && c >=minc 
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
! 	{	if (p->cellerror)
! 			cellerror = CELLINVALID;
! 		return p->v;
  	}
      }
      else if ( minc == maxc ){ /* look down the column */
***************
*** 171,176
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
  					return p->v;
  	}
      else if ( minc == maxc ){ /* look down the column */
  	r = minr + x - 1;
  	if (r <= maxr && r >=minr 

--- 199,205 -----
  			cellerror = CELLINVALID;
  		return p->v;
  	}
+     }
      else if ( minc == maxc ){ /* look down the column */
  	r = minr + x - 1;
  	if (r <= maxr && r >=minr 
***************
*** 175,181
  	r = minr + x - 1;
  	if (r <= maxr && r >=minr 
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
! 					return p->v;
  	}
      else error(" range specified to @index");
      return v;

--- 204,212 -----
  	r = minr + x - 1;
  	if (r <= maxr && r >=minr 
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
! 	{	if (p->cellerror)
! 			cellerror = CELLINVALID;
! 		return p->v;
  	}
      }
      else {
***************
*** 177,183
  		&& (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
  					return p->v;
  	}
!     else error(" range specified to @index");
      return v;
  }
  

--- 208,218 -----
  			cellerror = CELLINVALID;
  		return p->v;
  	}
!     }
!     else {
! 	error(" range specified to @index");
! 	cellerror = CELLERROR;
!     }
      return v;
  }
  
***************
*** 202,208
  		    fndc = incr ? (minc + offc) : c;
  		    if (ISVALID(fndr,fndc))
  			p = *ATBL(tbl, fndr, fndc);
! 		    else error(" range specified to @[hv]lookup");
  		    if ( p && p->flags&is_valid)
  			ret = p->v;
  		} else break;

--- 237,246 -----
  		    fndc = incr ? (minc + offc) : c;
  		    if (ISVALID(fndr,fndc))
  			p = *ATBL(tbl, fndr, fndc);
! 		    else {
! 			error(" range specified to @[hv]lookup");
! 			cellerror = CELLERROR;
! 		    }
  		    if ( p && p->flags&is_valid)
  		    {	if (p->cellerror)
  				cellerror = CELLINVALID;
***************
*** 204,209
  			p = *ATBL(tbl, fndr, fndc);
  		    else error(" range specified to @[hv]lookup");
  		    if ( p && p->flags&is_valid)
  			ret = p->v;
  		} else break;
  	    }

--- 242,249 -----
  			cellerror = CELLERROR;
  		    }
  		    if ( p && p->flags&is_valid)
+ 		    {	if (p->cellerror)
+ 				cellerror = CELLINVALID;
  			ret = p->v;
  		    }
  		} else break;
***************
*** 205,210
  		    else error(" range specified to @[hv]lookup");
  		    if ( p && p->flags&is_valid)
  			ret = p->v;
  		} else break;
  	    }
  	}

--- 245,251 -----
  		    {	if (p->cellerror)
  				cellerror = CELLINVALID;
  			ret = p->v;
+ 		    }
  		} else break;
  	    }
  	}
***************
*** 216,223
  		    fndr = incc ? (minr + offr) : r;
  		    fndc = incr ? (minc + offc) : c;
  		    if (ISVALID(fndr,fndc))
! 			p = *ATBL(tbl, fndr, fndc);
! 		    else error(" range specified to @[hv]lookup");
  		    break;
  		}
  	    }

--- 257,270 -----
  		    fndr = incc ? (minr + offr) : r;
  		    fndc = incr ? (minc + offc) : c;
  		    if (ISVALID(fndr,fndc))
! 		    {	p = *ATBL(tbl, fndr, fndc);
! 			if (p->cellerror)
! 				cellerror = CELLINVALID;
! 		    }
! 		    else {
! 			error(" range specified to @[hv]lookup");
! 			cellerror = CELLERROR;
! 		    }
  		    break;
  		}
  	    }
***************
*** 241,246
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v++;
      return v;
  }

--- 288,295 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
+ 	    {	if (p->cellerror)
+ 			cellerror = CELLINVALID;
  		v++;
  	    }
      return v;
***************
*** 242,247
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v++;
      return v;
  }
  

--- 291,297 -----
  	    {	if (p->cellerror)
  			cellerror = CELLINVALID;
  		v++;
+ 	    }
      return v;
  }
  
***************
*** 257,262
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v += p->v;
      return v;
  }

--- 307,314 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
+ 	    {	if (p->cellerror)
+ 			cellerror = CELLINVALID;
  		v += p->v;
  	    }
      return v;
***************
*** 258,263
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v += p->v;
      return v;
  }
  

--- 310,316 -----
  	    {	if (p->cellerror)
  			cellerror = CELLINVALID;
  		v += p->v;
+ 	    }
      return v;
  }
  
***************
*** 273,278
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v *= p->v;
      return v;
  }

--- 326,333 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
+ 	    {	if (p->cellerror)
+ 			cellerror = CELLINVALID;
  		v *= p->v;
  	    }
      return v;
***************
*** 274,279
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  		v *= p->v;
      return v;
  }
  

--- 329,335 -----
  	    {	if (p->cellerror)
  			cellerror = CELLINVALID;
  		v *= p->v;
+ 	    }
      return v;
  }
  
***************
*** 290,295
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  		v += p->v;
  		count++;
  	    }

--- 346,354 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ 		if (p->cellerror)
+ 			cellerror = CELLINVALID;
+ 
  		v += p->v;
  		count++;
  	    }
***************
*** 314,319
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  		v = p->v;
  		lp += v*v;
  		rp += v;

--- 373,381 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ 		if (p->cellerror)
+ 			cellerror = CELLINVALID;
+ 
  		v = p->v;
  		lp += v*v;
  		rp += v;
***************
*** 338,343
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  		if (!count) {
  		    v = p->v;
  		    count++;

--- 400,408 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ 		if (p->cellerror)
+ 			cellerror = CELLINVALID;
+ 
  		if (!count) {
  		    v = p->v;
  		    count++;
***************
*** 363,368
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  		if (!count) {
  		    v = p->v;
  		    count++;

--- 428,436 -----
      for (r = minr; r<=maxr; r++)
  	for (c = minc; c<=maxc; c++)
  	    if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
+ 		if (p->cellerror)
+ 			cellerror = CELLINVALID;
+ 
  		if (!count) {
  		    v = p->v;
  		    count++;
***************
*** 397,402
      if (mo < 1 || mo > 12 || day < 1 || day > mdays[--mo] ||
  		yr > 1999 || yr < 1970) {
  	error("@dts: invalid argument");
  	return(0.0);
      }
  

--- 465,471 -----
      if (mo < 1 || mo > 12 || day < 1 || day > mdays[--mo] ||
  		yr > 1999 || yr < 1970) {
  	error("@dts: invalid argument");
+ 	cellerror = CELLERROR;
  	return(0.0);
      }
  
***************
*** 436,442
      tp = localtime(&trial);
      if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec + 
  	tp->tm_year + tp->tm_mon != yr+mo+day)
! 		error("Dts broke down");
  #endif
  
      return ((double)trial);

--- 505,513 -----
      tp = localtime(&trial);
      if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec + 
  	tp->tm_year + tp->tm_mon != yr+mo+day)
! 	{	error("Dts broke down");
! 		cellerror = CELLERROR;
! 	}
  #endif
  
      return ((double)trial);
***************
*** 448,453
  {
      if (hr < 0 || hr > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) {
  	error ("@tts: Invalid argument");
  	return ((double)0);
      }
      return ((double)(sec+min*60+hr*3600));

--- 519,525 -----
  {
      if (hr < 0 || hr > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) {
  	error ("@tts: Invalid argument");
+ 	cellerror = CELLERROR;
  	return ((double)0);
      }
      return ((double)(sec+min*60+hr*3600));
***************
*** 487,492
  	    case YEAR: return((double)(tm_cache.tm_year));
  	}
  	/* Safety net */
  	return ((double)0);
  }
  

--- 559,565 -----
  	    case YEAR: return((double)(tm_cache.tm_year));
  	}
  	/* Safety net */
+ 	cellerror = CELLERROR;
  	return ((double)0);
  }
  
***************
*** 544,550
  {
      int collen;		/* length of string */
      int row, col;	/* integer values   */
!     struct ent *ep = (struct ent *)0;	/* selected entry   */
  
      if (((row = (int) floor (rowdoub)) >= 0)
       && (row < maxrows)				/* in range */

--- 617,623 -----
  {
      int collen;		/* length of string */
      int row, col;	/* integer values   */
!     struct ent *p = (struct ent *)0;	/* selected entry   */
  
      if (((row = (int) floor (rowdoub)) >= 0)
       && (row < maxrows)				/* in range */
***************
*** 552,558
       && ((col = atocol (colstr, collen)) >= 0)
       && (col < maxcols))			/* in range */
      {
! 	ep = *ATBL(tbl, row, col);
      }
  
      xfree (colstr);

--- 625,633 -----
       && ((col = atocol (colstr, collen)) >= 0)
       && (col < maxcols))			/* in range */
      {
! 	p = *ATBL(tbl, row, col);
! 	if (p->cellerror)
! 		cellerror = CELLINVALID;
      }
  
      xfree (colstr);
***************
*** 556,562
      }
  
      xfree (colstr);
!     return (ep);
  }
  
  

--- 631,637 -----
      }
  
      xfree (colstr);
!     return (p);
  }
  
  
***************
*** 590,595
  	register double maxval = 0; /* Assignment to shut up lint */
  	register struct enode *p;
  	register double v;
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);

--- 665,671 -----
  	register double maxval = 0; /* Assignment to shut up lint */
  	register struct enode *p;
  	register double v;
+ 	int	lcellerror = 0;	/* if any error occurs return so */
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
***************
*** 593,598
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
  		if (!count || v > maxval) {
  			maxval = v; count++;
  		}

--- 669,676 -----
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
+ 		if (cellerror)
+ 			lcellerror++;
  		if (!count || v > maxval) {
  			maxval = v; count++;
  		}
***************
*** 597,602
  			maxval = v; count++;
  		}
  	}
  	if (count) return maxval;
  	else return (double)0;
  }

--- 675,682 -----
  			maxval = v; count++;
  		}
  	}
+ 	if (lcellerror)
+ 		cellerror = CELLINVALID;
  	if (count) return maxval;
  	else return (double)0;
  }
***************
*** 609,614
  	register double minval = 0; /* Assignment to shut up lint */
  	register struct enode *p;
  	register double v;
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);

--- 689,695 -----
  	register double minval = 0; /* Assignment to shut up lint */
  	register struct enode *p;
  	register double v;
+ 	int	lcellerror = 0;	/* if any error occurs return so */
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
***************
*** 612,617
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
  		if (!count || v < minval) {
  			minval = v; count++;
  		}

--- 693,700 -----
  
  	for (p = ep; p; p = p->e.o.left) {
  		v = eval(p->e.o.right);
+ 		if (cellerror)
+ 			lcellerror++;
  		if (!count || v < minval) {
  			minval = v; count++;
  		}
***************
*** 616,621
  			minval = v; count++;
  		}
  	}
  	if (count) return minval;
  	else return (double)0;
  }

--- 699,706 -----
  			minval = v; count++;
  		}
  	}
+ 	if (lcellerror)
+ 		cellerror = CELLINVALID;
  	if (count) return minval;
  	else return (double)0;
  }
***************
*** 625,630
  register struct enode *e;
  {
      if (e == (struct enode *)0) return (double)0;
      switch (e->op) {
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));

--- 710,716 -----
  register struct enode *e;
  {
      if (e == (struct enode *)0) return (double)0;
+     cellerror = CELLOK;
      switch (e->op) {
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));
***************
*** 629,635
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));
  	case '*':	return (eval(e->e.o.left) * eval(e->e.o.right));
! 	case '/':       return (eval(e->e.o.left) / eval(e->e.o.right));
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));

--- 715,730 -----
  	case '+':	return (eval(e->e.o.left) + eval(e->e.o.right));
  	case '-':	return (eval(e->e.o.left) - eval(e->e.o.right));
  	case '*':	return (eval(e->e.o.left) * eval(e->e.o.right));
! 	case '/':     { double num, denom;
! 			num = eval(e->e.o.left);
! 			denom = eval(e->e.o.right);
! 			if (denom)
! 				return(num/denom);
! 			else
! 			{	cellerror = CELLERROR;
! 				return((double) 0);
! 			}
! 	}
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));
***************
*** 633,639
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));
! 			return denom ? num - floor(num/denom)*denom : (double)0; }
  	case '^':	return (fn2_eval(pow,eval(e->e.o.left),eval(e->e.o.right)));
  	case '<':	return (eval(e->e.o.left) < eval(e->e.o.right));
  	case '=':	return (eval(e->e.o.left) == eval(e->e.o.right));

--- 728,740 -----
  	case '%':     {	double num, denom;
  			num = floor(eval(e->e.o.left));
  			denom = floor(eval (e->e.o.right));
! 			if (denom)
! 				return(num - floor(num/denom)*denom);
! 			else
! 			{	cellerror = CELLERROR;
! 				return((double) 0);
! 			}
! 	}
  	case '^':	return (fn2_eval(pow,eval(e->e.o.left),eval(e->e.o.right)));
  	case '<':	return (eval(e->e.o.left) < eval(e->e.o.right));
  	case '=':	return (eval(e->e.o.left) == eval(e->e.o.right));
***************
*** 646,653
  	case 'm':	return (-eval(e->e.o.right));
  	case 'f':	return (eval(e->e.o.right));
  	case '~':	return (eval(e->e.o.right) == 0.0);
! 	case 'k':	return (e->e.k);
! 	case 'v':	return (e->e.v.vp->v);
  	case INDEX:
  	case LOOKUP:
  	case HLOOKUP:

--- 747,756 -----
  	case 'm':	return (-eval(e->e.o.right));
  	case 'f':	return (eval(e->e.o.right));
  	case '~':	return (eval(e->e.o.right) == 0.0);
! 	case O_CONST:	return (e->e.k);
! 	case O_VAR:	if (e->e.v.vp->cellerror)
! 				cellerror = CELLINVALID;
! 			return (e->e.v.vp->v);
  	case INDEX:
  	case LOOKUP:
  	case HLOOKUP:
***************
*** 772,777
  	default:	 error ("Illegal numeric expression");
  			 exprerr = 1;
      }
      return((double)0.0);
  }
  

--- 875,881 -----
  	default:	 error ("Illegal numeric expression");
  			 exprerr = 1;
      }
+     cellerror = CELLERROR;
      return((double)0.0);
  }
  
***************
*** 777,782
  
  #ifdef SIGVOID
  void
  #endif
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;

--- 881,888 -----
  
  #ifdef SIGVOID
  void
+ #else
+ int
  #endif
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;
***************
*** 781,786
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;
  {
  #ifdef IEEE_MATH
  	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
  #endif /* IEEE_MATH */

--- 887,896 -----
  eval_fpe(signo) /* Trap for FPE errors in eval */
  int signo;
  {
+ #ifdef i386
+ 	asm("	fnclex");
+ 	asm("	fwait");
+ #else
  #ifdef IEEE_MATH
  	(void)fpsetsticky((fp_except)0);	/* Clear exception */
  #endif /* IEEE_MATH */
***************
*** 782,788
  int signo;
  {
  #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
  #endif /* IEEE_MATH */
  	longjmp(fpe_save, 1);
  }

--- 892,898 -----
  	asm("	fwait");
  #else
  #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0);	/* Clear exception */
  #endif /* IEEE_MATH */
  #endif
  	longjmp(fpe_save, 1);
***************
*** 784,789
  #ifdef IEEE_MATH
  	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
  #endif /* IEEE_MATH */
  	longjmp(fpe_save, 1);
  }
  

--- 894,900 -----
  #ifdef IEEE_MATH
  	(void)fpsetsticky((fp_except)0);	/* Clear exception */
  #endif /* IEEE_MATH */
+ #endif
  	longjmp(fpe_save, 1);
  }
  
***************
*** 795,802
  	errno = 0;
  	res = (*fn)(arg);
  	if(errno)
! 	  eval_fpe(0);
! 
  	return res;
  }
  

--- 906,914 -----
  	errno = 0;
  	res = (*fn)(arg);
  	if(errno)
! 	{	cellerror = CELLERROR;
! 		eval_fpe(0);
! 	}
  	return res;
  }
  
***************
*** 807,814
  	double res;
  	errno = 0;
  	res = (*fn)(arg1, arg2);
! 	if(errno) 
! 	    eval_fpe(0);
  
  	return res;
  }

--- 919,928 -----
  	double res;
  	errno = 0;
  	res = (*fn)(arg1, arg2);
! 	if(errno)
! 	{	cellerror = CELLERROR;
! 		eval_fpe(0);
! 	}
  
  	return res;
  }
***************
*** 890,895
  double value;
  {
      error("Warning: External functions unavailable on VMS");
      if (command)
  	xfree(command);
      return (strcpy (xmalloc((unsigned) 1), "\0"));

--- 1004,1010 -----
  double value;
  {
      error("Warning: External functions unavailable on VMS");
+     cellerror = CELLERROR	/* not sure if this should be a cellerror */
      if (command)
  	xfree(command);
      return (strcpy (xmalloc((unsigned) 1), "\0"));
***************
*** 920,925
  
  	if ((! command) || (! *command)) {
  	    error ("Warning: external function given null command name");
  	    if (command) xfree (command);
  	} else {
  	    FILE *pp;

--- 1035,1041 -----
  
  	if ((! command) || (! *command)) {
  	    error ("Warning: external function given null command name");
+ 	    cellerror = CELLERROR;
  	    if (command) xfree (command);
  	} else {
  	    FILE *pp;
***************
*** 930,936
  	    error ("Running external function...");
  	    (void) refresh();
  
! 	    if ((pp = popen (buff, "r")) == (FILE *) NULL)	/* run it */
  		error ("Warning: running \"%s\" failed", buff);
  	    else {
  		if (fgets (buff, sizeof(buff)-1, pp) == NULL)	/* one line */

--- 1046,1052 -----
  	    error ("Running external function...");
  	    (void) refresh();
  
! 	    if ((pp = popen (buff, "r")) == (FILE *) NULL) {	/* run it */
  		error ("Warning: running \"%s\" failed", buff);
  		cellerror = CELLERROR;
  	    }
***************
*** 932,937
  
  	    if ((pp = popen (buff, "r")) == (FILE *) NULL)	/* run it */
  		error ("Warning: running \"%s\" failed", buff);
  	    else {
  		if (fgets (buff, sizeof(buff)-1, pp) == NULL)	/* one line */
  		    error ("Warning: external function returned nothing");

--- 1048,1055 -----
  
  	    if ((pp = popen (buff, "r")) == (FILE *) NULL) {	/* run it */
  		error ("Warning: running \"%s\" failed", buff);
+ 		cellerror = CELLERROR;
+ 	    }
  	    else {
  		if (fgets (buff, sizeof(buff)-1, pp) == NULL)	/* one line */
  		    error ("Warning: external function returned nothing");
***************
*** 1020,1025
      register char *p;
  
      if (se == (struct enode *)0) return (char *)0;
      switch (se->op) {
  	case O_SCONST: p = xmalloc((unsigned)(strlen(se->e.s)+1));
  		     (void) strcpy(p, se->e.s);

--- 1138,1144 -----
      register char *p;
  
      if (se == (struct enode *)0) return (char *)0;
+     cellerror = CELLOK;
      switch (se->op) {
  	case O_SCONST: p = xmalloc((unsigned)(strlen(se->e.s)+1));
  		     (void) strcpy(p, se->e.s);
***************
*** 1109,1118
      register struct ent *p;
  
      (void) signal(SIGFPE, eval_fpe);
- #ifdef EXPRTREE
-     for (p = firstev; p; p = p->evnext)
- 	    RealEvalOne(p, &chgct);
- #else
      if(calc_order == BYROWS ) {
  	for (i=0; i<=maxrow; i++)
  	    for (j=0; j<=maxcol; j++)

--- 1228,1233 -----
      register struct ent *p;
  
      (void) signal(SIGFPE, eval_fpe);
      if(calc_order == BYROWS ) {
  	for (i=0; i<=maxrow; i++)
  	    for (j=0; j<=maxcol; j++)
***************
*** 1125,1131
  	}
      }
      else error("Internal error calc_order");
- #endif
   
      (void) signal(SIGFPE, quit);
      return(chgct);

--- 1240,1245 -----
  	}
      }
      else error("Internal error calc_order");
   
      (void) signal(SIGFPE, quit);
      return(chgct);
***************
*** 1132,1142
  }
  
  void
- #ifdef EXPRTREE
- RealEvalOne(p, chgct)
- register struct ent *p;
- int *chgct;
- #else
  RealEvalOne(p, i, j, chgct)
  register struct ent *p;
  int i, j, *chgct;

--- 1246,1251 -----
  }
  
  void
  RealEvalOne(p, i, j, chgct)
  register struct ent *p;
  int i, j, *chgct;
***************
*** 1140,1146
  RealEvalOne(p, i, j, chgct)
  register struct ent *p;
  int i, j, *chgct;
- #endif
  {
  	if (p->flags & is_strexpr) {
  	    char *v;

--- 1249,1254 -----
  RealEvalOne(p, i, j, chgct)
  register struct ent *p;
  int i, j, *chgct;
  {
  	(void) signal(SIGFPE, eval_fpe);
  	if (p->flags & is_strexpr) {
***************
*** 1142,1147
  int i, j, *chgct;
  #endif
  {
  	if (p->flags & is_strexpr) {
  	    char *v;
  	    if (setjmp(fpe_save)) {

--- 1250,1256 -----
  register struct ent *p;
  int i, j, *chgct;
  {
+ 	(void) signal(SIGFPE, eval_fpe);
  	if (p->flags & is_strexpr) {
  	    char *v;
  	    if (setjmp(fpe_save)) {
***************
*** 1145,1153
  	if (p->flags & is_strexpr) {
  	    char *v;
  	    if (setjmp(fpe_save)) {
- #ifdef EXPRTREE
- 		error("Floating point exception %s", v_name(p->row, p->col));
- #else
  		error("Floating point exception %s", v_name(i, j));
  #endif
  		v = "";

--- 1254,1259 -----
  	if (p->flags & is_strexpr) {
  	    char *v;
  	    if (setjmp(fpe_save)) {
  		error("Floating point exception %s", v_name(i, j));
  		cellerror = CELLERROR;
  		v = "";
***************
*** 1149,1155
  		error("Floating point exception %s", v_name(p->row, p->col));
  #else
  		error("Floating point exception %s", v_name(i, j));
! #endif
  		v = "";
  	    } else {
  		v = seval(p->expr);

--- 1255,1261 -----
  	    char *v;
  	    if (setjmp(fpe_save)) {
  		error("Floating point exception %s", v_name(i, j));
! 		cellerror = CELLERROR;
  		v = "";
  	    } else {
  		v = seval(p->expr);
***************
*** 1154,1159
  	    } else {
  		v = seval(p->expr);
  	    }
  	    if (!v && !p->label) /* Everything's fine */
  		return;
  	    if (!p->label || !v || strcmp(v, p->label) != 0) {

--- 1260,1266 -----
  	    } else {
  		v = seval(p->expr);
  	    }
+ 	    p->cellerror = cellerror;
  	    if (!v && !p->label) /* Everything's fine */
  		return;
  	    if (!p->label || !v || strcmp(v, p->label) != 0) {
***************
*** 1167,1175
  	} else {
  	    double v;
  	    if (setjmp(fpe_save)) {
- #ifdef EXPRTREE
- 		error("Floating point exception %s", v_name(p->row, p->col));
- #else
  		error("Floating point exception %s", v_name(i, j));
  #endif
  		v = (double)0.0;

--- 1274,1279 -----
  	} else {
  	    double v;
  	    if (setjmp(fpe_save)) {
  		error("Floating point exception %s", v_name(i, j));
  		cellerror = CELLERROR;
  		v = (double)0.0;
***************
*** 1171,1177
  		error("Floating point exception %s", v_name(p->row, p->col));
  #else
  		error("Floating point exception %s", v_name(i, j));
! #endif
  		v = (double)0.0;
  	    } else {
  		v = eval (p->expr);

--- 1275,1281 -----
  	    double v;
  	    if (setjmp(fpe_save)) {
  		error("Floating point exception %s", v_name(i, j));
! 		cellerror = CELLERROR;
  		v = (double)0.0;
  	    } else {
  		v = eval (p->expr);
***************
*** 1176,1181
  	    } else {
  		v = eval (p->expr);
  	    }
  	    if (v != p->v) {
  		p->v = v; (*chgct)++;
  		p->flags |= is_changed|is_valid;

--- 1280,1286 -----
  	    } else {
  		v = eval (p->expr);
  	    }
+ 	    p->cellerror = cellerror;
  	    if (v != p->v) {
  		p->v = v; (*chgct)++;
  		p->flags |= is_changed|is_valid;
***************
*** 1333,1338
      default: break;
      }
      gs.g_type = G_NONE;
  }
  
  void

--- 1438,1444 -----
      default: break;
      }
      gs.g_type = G_NONE;
+     gs.errsearch = 0;
  }
  
  void
***************
*** 1342,1348
      case G_NONE:
  		error("Nothing to repeat"); break;
      case G_NUM:
! 		num_search(gs.g_n);
  		break;
      case  G_CELL:
  		moveto(gs.g_row, gs.g_col);

--- 1448,1454 -----
      case G_NONE:
  		error("Nothing to repeat"); break;
      case G_NUM:
! 		num_search(gs.g_n, gs.errsearch);
  		break;
      case  G_CELL:
  		moveto(gs.g_row, gs.g_col);
***************
*** 1369,1375
  }
  
  void
! num_search(n)
  double n;
  {
      register struct ent *p;

--- 1475,1481 -----
  }
  
  void
! num_search(n, errsearch)
  double n;
  int	errsearch;
  {
***************
*** 1371,1376
  void
  num_search(n)
  double n;
  {
      register struct ent *p;
      register int r,c;

--- 1477,1483 -----
  void
  num_search(n, errsearch)
  double n;
+ int	errsearch;
  {
      register struct ent *p;
      register int r,c;
***************
*** 1379,1384
      g_free();
      gs.g_type = G_NUM;
      gs.g_n = n;
  
      if (currow > maxrow)
  	endr = maxrow ? maxrow-1 : 0;

--- 1486,1492 -----
      g_free();
      gs.g_type = G_NUM;
      gs.g_n = n;
+     gs.errsearch = errsearch;
  
      if (currow > maxrow)
  	endr = maxrow ? maxrow-1 : 0;
***************
*** 1403,1409
  	    }
  	}
  	if (r == endr && c == endc) {
! 	    error("Number not found");
  	    return;
  	}
  	p = *ATBL(tbl, r, c);

--- 1511,1521 -----
  	    }
  	}
  	if (r == endr && c == endc) {
! 	    if (errsearch)
! 		error("no %s cell found", errsearch == CELLERROR ? "ERROR" :
! 		      "INVALID");
! 	    else
! 		error("Number not found");
  	    return;
  	}
  	p = *ATBL(tbl, r, c);
***************
*** 1407,1414
  	    return;
  	}
  	p = *ATBL(tbl, r, c);
!     } while(col_hidden[c] || !p || p && (!(p->flags & is_valid) 
!                                         || (p->flags&is_valid) && p->v != n));
      currow = r;
      curcol = c;
  }

--- 1519,1529 -----
  	    return;
  	}
  	p = *ATBL(tbl, r, c);
!     } while (col_hidden[c] || !p || !(p->flags & is_valid)
! 	|| (!errsearch && (p->v != n))
! 	|| (errsearch && !((p->cellerror == errsearch) ||
! 		(p->cellerror == errsearch))));	/* CELLERROR vs CELLINVALID */
! 		
      currow = r;
      curcol = c;
  }
***************
*** 1432,1437
  #if defined(SYSV2) || defined(SYSV3)
      if ((tmp = regcmp(s, (char *)0)) == (char *)0) {
  	xfree(s);
  	error("Invalid search string");
  	return;
      }

--- 1547,1553 -----
  #if defined(SYSV2) || defined(SYSV3)
      if ((tmp = regcmp(s, (char *)0)) == (char *)0) {
  	xfree(s);
+ 	cellerror = CELLERROR;
  	error("Invalid search string");
  	return;
      }
***************
*** 1469,1475
  	    return;
  	}
  	p = *ATBL(tbl, r, c);
!     } while(col_hidden[c] || !p || p && (!(p->label) 
  #if defined(BSD42) || defined(BSD43)
  		  			|| (re_exec(p->label) == 0)));
  #else

--- 1585,1591 -----
  	    return;
  	}
  	p = *ATBL(tbl, r, c);
!     } while(col_hidden[c] || !p || !(p->label)
  #if defined(BSD42) || defined(BSD43)
  		  			|| (re_exec(p->label) == 0));
  #else
***************
*** 1471,1477
  	p = *ATBL(tbl, r, c);
      } while(col_hidden[c] || !p || p && (!(p->label) 
  #if defined(BSD42) || defined(BSD43)
! 		  			|| (re_exec(p->label) == 0)));
  #else
  #if defined(SYSV2) || defined(SYSV3)
                                         || (regex(tmp, p->label) == (char *)0)));

--- 1587,1593 -----
  	p = *ATBL(tbl, r, c);
      } while(col_hidden[c] || !p || !(p->label)
  #if defined(BSD42) || defined(BSD43)
! 		  			|| (re_exec(p->label) == 0));
  #else
  #if defined(SYSV2) || defined(SYSV3)
  				|| (regex(tmp, p->label) == (char *)0));
***************
*** 1474,1480
  		  			|| (re_exec(p->label) == 0)));
  #else
  #if defined(SYSV2) || defined(SYSV3)
!                                        || (regex(tmp, p->label) == (char *)0)));
  #else
                                         || (strcmp(s, p->label) != 0)));
  #endif

--- 1590,1596 -----
  		  			|| (re_exec(p->label) == 0));
  #else
  #if defined(SYSV2) || defined(SYSV3)
! 				|| (regex(tmp, p->label) == (char *)0));
  #else
  					|| (strcmp(s, p->label) != 0));
  #endif
***************
*** 1476,1482
  #if defined(SYSV2) || defined(SYSV3)
                                         || (regex(tmp, p->label) == (char *)0)));
  #else
!                                        || (strcmp(s, p->label) != 0)));
  #endif
  #endif
      currow = r;

--- 1592,1598 -----
  #if defined(SYSV2) || defined(SYSV3)
  				|| (regex(tmp, p->label) == (char *)0));
  #else
! 					|| (strcmp(s, p->label) != 0));
  #endif
  #endif
      currow = r;
***************
*** 1537,1542
  struct enode *e;
  {
      double val;
  
      exprerr = 0;
      (void) signal(SIGFPE, eval_fpe);

--- 1653,1659 -----
  struct enode *e;
  {
      double val;
+     unsigned isconstant = constant(e);
  
      if (loading && !isconstant)
  	val = (double)0.0;
***************
*** 1538,1547
  {
      double val;
  
!     exprerr = 0;
!     (void) signal(SIGFPE, eval_fpe);
!     if (setjmp(fpe_save)) {
! 	error ("Floating point exception in cell %s", v_name(v->row, v->col));
  	val = (double)0.0;
      } else {
  	val = eval(e);

--- 1655,1661 -----
      double val;
      unsigned isconstant = constant(e);
  
!     if (loading && !isconstant)
  	val = (double)0.0;
      else
      {
***************
*** 1543,1550
      if (setjmp(fpe_save)) {
  	error ("Floating point exception in cell %s", v_name(v->row, v->col));
  	val = (double)0.0;
!     } else {
! 	val = eval(e);
      }
      (void) signal(SIGFPE, quit);
      if (exprerr) {

--- 1657,1679 -----
  
      if (loading && !isconstant)
  	val = (double)0.0;
!     else
!     {
! 	exprerr = 0;
! 	(void) signal(SIGFPE, eval_fpe);
! 	if (setjmp(fpe_save)) {
! 	    error ("Floating point exception in cell %s", v_name(v->row, v->col));
! 	    val = (double)0.0;
! 	    cellerror = CELLERROR;
! 	} else {
! 	    val = eval(e);
! 	}
! 	v->cellerror = cellerror;
! 	(void) signal(SIGFPE, quit);
! 	if (exprerr) {
! 	    efree((struct ent *)0, e);
! 	    return;
! 	}
      }
  
      if (isconstant) {
***************
*** 1546,1561
      } else {
  	val = eval(e);
      }
!     (void) signal(SIGFPE, quit);
!     if (exprerr) {
! 	efree((struct ent *)0, e);
! 	return;
!     }
!     if (constant(e)) {
! 	if (!loading)
! 	    v->v = val * prescale;
! 	else
! 	    v->v = val;
  	if (!(v->flags & is_strexpr)) {
              efree(v, v->expr);
  	    v->expr = (struct enode *)0;

--- 1675,1686 -----
  	    return;
  	}
      }
! 
!     if (isconstant) {
! 	if (!loading && prescale < (double)0.9999999)
! 	    val *= prescale;
! 	v->v = val;
! 
  	if (!(v->flags & is_strexpr)) {
              efree(v, v->expr);
  	    v->expr = (struct enode *)0;
***************
*** 1561,1570
  	    v->expr = (struct enode *)0;
  	}
  	efree((struct ent *)0, e);
-         v->flags |= (is_changed|is_valid);
-         changed++;
-         modflg++;
- 	return;
      }
      efree (v, v->expr);
      v->expr = e;

--- 1686,1691 -----
  	    v->expr = (struct enode *)0;
  	}
  	efree((struct ent *)0, e);
      }
      else
      {
***************
*** 1566,1575
          modflg++;
  	return;
      }
!     efree (v, v->expr);
!     v->expr = e;
!     v->flags |= (is_changed|is_valid);
!     v->flags &= ~is_strexpr;
  
  #ifdef EXPRTREE
      totoptree(v);

--- 1687,1698 -----
  	}
  	efree((struct ent *)0, e);
      }
!     else
!     {
! 	efree (v, v->expr);
! 	v->expr = e;
! 	v->flags &= ~is_strexpr;
!     }
  
      v->flags |= (is_changed|is_valid);
      changed++; modflg++;
***************
*** 1571,1581
      v->flags |= (is_changed|is_valid);
      v->flags &= ~is_strexpr;
  
! #ifdef EXPRTREE
!     totoptree(v);
! #endif
!     changed++;
!     modflg++;
  }
  
  void

--- 1694,1701 -----
  	v->flags &= ~is_strexpr;
      }
  
!     v->flags |= (is_changed|is_valid);
!     changed++; modflg++;
  }
  
  void
***************
*** 1590,1595
      (void) signal(SIGFPE, eval_fpe);
      if (setjmp(fpe_save)) {
  	error ("Floating point exception in cell %s", v_name(v->row, v->col));
  	p = "";
      } else {
  	p = seval(se);

--- 1710,1716 -----
      (void) signal(SIGFPE, eval_fpe);
      if (setjmp(fpe_save)) {
  	error ("Floating point exception in cell %s", v_name(v->row, v->col));
+ 	cellerror = CELLERROR;
  	p = "";
      } else {
  	p = seval(se);
***************
*** 1594,1599
      } else {
  	p = seval(se);
      }
      (void) signal(SIGFPE, quit);
      if (exprerr) {
  	efree((struct ent *)0, se);

--- 1715,1721 -----
      } else {
  	p = seval(se);
      }
+     v->cellerror = cellerror;
      (void) signal(SIGFPE, quit);
      if (exprerr) {
  	efree((struct ent *)0, se);
***************
*** 1617,1625
      if (flushdir<0) v->flags |= is_leftflush;
      else v->flags &= ~is_leftflush;
  
- #ifdef EXPRTREE
-     totoptree();
- #endif
      FullUpdate++;
      changed++;
      modflg++;

--- 1739,1744 -----
      if (flushdir<0) v->flags |= is_leftflush;
      else v->flags &= ~is_leftflush;
  
      FullUpdate++;
      changed++;
      modflg++;
***************
*** 1625,1749
      modflg++;
  }
  
! #ifdef EXPRTREE
! /*
!  * put an expression in the expression tree, only the top of each branch is
!  * in the firstev list
!  */
! totoptree(v)
! struct	ent *v;
! {
!     int	right;
!     int	left;
!     if (!v->expr)
! 	return;
! 
! #ifdef notdef
!     right = FALSE;
!     left = FALSE;
!     switch(v->expr->op)
!     {
! 		/* no real expression */
! 	case 'v':
! 		if (v->expr->o.v->evnext)
! 			evdel(v->expr->o.v);
! 	case 'k':
! 	case LMAX:
! 	case LMIN:
! 	case NOW:
! 	case O_SCONST:
! 	case O_VAR:
! 	default:
! 		return;
! 
! 		/* left && right */
! 	case '#':
! 	case '%':
! 	case '&':
! 	case '*':
! 	case '+':
! 	case '-':
! 	case '/':
! 	case '<':
! 	case '=':
! 	case '>':
! 	case '?':
! 	case '^':
! 	case '|':
! 	case ATAN2:
! 	case DTS:
! 	case EQS:
! 	case EXT:
! 	case FMT:
! 	case FV:
! 	case HYPOT:
! 	case IF:
! 	case NVAL:
! 	case PMT:
! 	case POW:
! 	case PV:
! 	case REDUCE | '*':
! 	case REDUCE | '+':
! 	case REDUCE | 'a':
! 	case REDUCE | 'c':
! 	case REDUCE | 's':
! 	case REDUCE | MAX:
! 	case REDUCE | MIN:
! 	case ROUND:
! 	case STINDEX:
! 	case SUBSTR:
! 	case SVAL:
! 	case TTS:
! 		left = right = TRUE;
! 		break;
! 		/* right only */
! 	case 'f':
! 	case 'm':
! 	case '~':
! 	case ABS:
! 	case ACOS:
! 	case ASIN:
! 	case ATAN:
! 	case CEIL:
! 	case COS:
! 	case DATE:
! 	case DAY:
! 	case DTR:
! 	case EXP:
! 	case FABS:
! 	case FLOOR:
! 	case HLOOKUP:
! 	case HOUR:
! 	case IF:
! 	case INDEX:
! 	case LOG10:
! 	case LOG:
! 	case LOOKUP:
! 	case MINUTE:
! 	case MONTH:
! 	case RND:
! 	case RTD:
! 	case SECOND:
! 	case SIN:
! 	case SQRT:
! 	case STON:
! 	case TAN:
! 	case VLOOKUP:
! 	case YEAR:
! 		right = TRUE;
! 		break;
!     }
! 	/* for now insert at the beginning of the list */
!     v->evnext = firstev;
!     v->evprev = (struct ent *)0;
!     if (firstev)
! 	firstev->evprev = v;
!     firstev = v;
! #endif
!     firstev = v;
! }
! #endif /* EXPRTREE*/
! 
  format_cell(v1, v2, s)
  struct ent *v1, *v2;
  char *s;

--- 1744,1750 -----
      modflg++;
  }
  
! void
  format_cell(v1, v2, s)
  struct ent *v1, *v2;
  char *s;
***************
*** 1840,1856
  constant (e)
      register struct enode *e;
  {
!     return ((e == (struct enode *)0)
! 	 || ((e -> op) == O_CONST)
! 	 || ((e -> op) == O_SCONST)
! 	 || (((e -> op) != O_VAR)
! 	  && (((e -> op) & REDUCE) != REDUCE)
! 	  && constant (e -> e.o.left)
! 	  && constant (e -> e.o.right)
! 	  && (e -> op != EXT)	 /* functions look like constants but aren't */
! 	  && (e -> op != NVAL)
! 	  && (e -> op != SVAL)
! 	  && (e -> op != NOW)));
  }
  
  void

--- 1841,1861 -----
  constant (e)
      register struct enode *e;
  {
!     return (
! 	 e == (struct enode *)0
! 	 || e -> op == O_CONST
! 	 || e -> op == O_SCONST
! 	 || (
! 	     e -> op != O_VAR
! 	     && (e -> op & REDUCE) != REDUCE
! 	     && constant (e -> e.o.left)
! 	     && constant (e -> e.o.right)
! 	     && e -> op != EXT	 /* functions look like constants but aren't */
! 	     && e -> op != NVAL
! 	     && e -> op != SVAL
! 	     && e -> op != NOW
! 	)
!     );
  }
  
  void
***************
*** 1867,1882
  	if (e->op == O_SCONST && e->e.s)
  	    xfree(e->e.s);
  	xfree ((char *)e);
- 
- #ifdef EXPRTREE
- 	/* delete this cell from the eval list */
- 	if (v)
- 	{	if (v->evprev)
- 			v->evprev->evnext = v->evnext;
- 		if (v->evnext)
- 			v->evnext->evprev = v->evprev;
- 	}
- #endif /* EXPRTREE */
      }
  }
  

--- 1872,1877 -----
  	if (e->op == O_SCONST && e->e.s)
  	    xfree(e->e.s);
  	xfree ((char *)e);
      }
  }
  
***************
*** 1988,1994
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;
! 	case 'v':	decodev (e->e.v);
  			break;
  	case 'k':	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);

--- 1983,1989 -----
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;
! 	case O_VAR:	decodev (e->e.v);
  			break;
  	case O_CONST:	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);
***************
*** 1990,1996
  			break;
  	case 'v':	decodev (e->e.v);
  			break;
! 	case 'k':	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);
  			break;
  	case '$':	(void)sprintf (line+linelim, "\"%s\"", e->e.s);

--- 1985,1991 -----
  			break;
  	case O_VAR:	decodev (e->e.v);
  			break;
! 	case O_CONST:	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);
  			break;
  	case O_SCONST:	(void)sprintf (line+linelim, "\"%s\"", e->e.s);
***************
*** 1993,1999
  	case 'k':	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);
  			break;
! 	case '$':	(void)sprintf (line+linelim, "\"%s\"", e->e.s);
  			linelim += strlen(line+linelim);
  			break;
  

--- 1988,1994 -----
  	case O_CONST:	(void)sprintf (line+linelim,"%.15g",e->e.k);
  			linelim += strlen (line+linelim);
  			break;
! 	case O_SCONST:	(void)sprintf (line+linelim, "\"%s\"", e->e.s);
  			linelim += strlen(line+linelim);
  			break;
  
***************
*** 2165,2170
      line[linelim++] = ')';
  }
  
  editfmt (row, col)
  int row, col;
  {

--- 2160,2166 -----
      line[linelim++] = ')';
  }
  
+ void
  editfmt (row, col)
  int row, col;
  {

buhrt@sawmill.uucp (Jeffery A Buhrt) (10/27/90)

Apply these patches w/ 'patch' as well.

						-Jeff Buhrt

*** 69/lex.c	Thu Oct  4 09:17:47 1990
--- lex.c	Fri Oct 26 16:57:55 1990
***************
*** 7,13
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3/88, see list of changes.
!  *		$Revision: 6.9 $
   *
   */
  

--- 7,13 -----
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3/88, see list of changes.
!  *		$Revision: 6.10 $
   *
   */
  
***************
*** 56,61
  jmp_buf wakeup;
  jmp_buf fpe_buf;
  
  struct key {
      char *key;
      int val;

--- 56,78 -----
  jmp_buf wakeup;
  jmp_buf fpe_buf;
  
+ #ifdef SIGVOID
+ void
+ #endif
+ fpe_trap(signo)
+ int signo;
+ {
+ #ifdef i386
+ 	asm("	fnclex");
+ 	asm("	fwait");
+ #else
+ #ifdef IEEE_MATH
+ 	(void)fpsetsticky((fp_except)0);	/* Clear exception */
+ #endif /* IEEE_MATH */
+ #endif
+     longjmp(fpe_buf, 1);
+ }
+ 
  struct key {
      char *key;
      int val;
***************
*** 69,74
  #include "statres.h"
      0, 0};
  
  yylex ()
  {
      register char *p = line+linelim;

--- 86,92 -----
  #include "statres.h"
      0, 0};
  
+ int
  yylex ()
  {
      register char *p = line+linelim;
***************
*** 136,142
  	    }
  	}
      } else if ((*p == '.') || isdigit(*p)) {
! 	double v = 0;
  	int temp;
  	char *nstart = p;
  	if (*p != '.') {

--- 154,165 -----
  	    }
  	}
      } else if ((*p == '.') || isdigit(*p)) {
! #ifdef SIGVOID
! 	void (*sig_save)();
! #else
! 	int (*sig_save)();
! #endif
! 	double v = 0.0;
  	int temp;
  	char *nstart = p;
  
***************
*** 139,144
  	double v = 0;
  	int temp;
  	char *nstart = p;
  	if (*p != '.') {
  	    do v = v*10 + (double)(*p-'0');
  	    while (isdigit(*++p));

--- 162,176 -----
  	double v = 0.0;
  	int temp;
  	char *nstart = p;
+ 
+ 	sig_save = signal(SIGFPE, fpe_trap);
+ 	if (setjmp(fpe_buf)) {
+ 	    (void) signal(SIGFPE, sig_save);
+ 	    yylval.fval = v;
+ 	    error("Floating point exception\n");
+ 	    return FNUMBER;
+ 	}
+ 
  	if (*p != '.') {
  	    do v = v*10.0 + (double) ((unsigned) *p - '0');
  	    while (isdigit(*++p));
***************
*** 140,146
  	int temp;
  	char *nstart = p;
  	if (*p != '.') {
! 	    do v = v*10 + (double)(*p-'0');
  	    while (isdigit(*++p));
  	}
  	if (*p=='.' || *p == 'e' || *p == 'E') {

--- 172,178 -----
  	}
  
  	if (*p != '.') {
! 	    do v = v*10.0 + (double) ((unsigned) *p - '0');
  	    while (isdigit(*++p));
  	}
  	if (*p=='.' || *p == 'e' || *p == 'E') {
***************
*** 163,168
  		}
  	    }
  	}
      } else if (*p=='"') {
  	char *ptr;
          ptr = p+1;

--- 195,201 -----
  		}
  	    }
  	}
+ 	(void) signal(SIGFPE, sig_save);
      } else if (*p=='"') {
  	char *ptr;
          ptr = p+1;
***************
*** 212,217
  
  #ifdef SIMPLE
  
  initkbd()
  {}
  

--- 245,251 -----
  
  #ifdef SIMPLE
  
+ void
  initkbd()
  {}
  
***************
*** 215,220
  initkbd()
  {}
  
  kbd_again()
  {}
  

--- 249,255 -----
  initkbd()
  {}
  
+ void
  kbd_again()
  {}
  
***************
*** 218,223
  kbd_again()
  {}
  
  resetkbd()
  {}
  

--- 253,259 -----
  kbd_again()
  {}
  
+ void
  resetkbd()
  {}
  
***************
*** 223,228
  
  #ifndef VMS
  
  nmgetch()
  {
      return (toascii(getchar()));

--- 259,265 -----
  
  #ifndef VMS
  
+ int
  nmgetch()
  {
      return (toascii(getchar()));
***************
*** 230,235
  
  #else /* VMS */
  
  nmgetch()
  /*
     This is not perfect, it doesn't move the cursor when goraw changes

--- 267,273 -----
  
  #else /* VMS */
  
+ int
  nmgetch()
  /*
     This is not perfect, it doesn't move the cursor when goraw changes
***************
*** 326,331
  	ctl('z'), 0
  };
  
  charout(c)
  int c;
  {

--- 364,370 -----
  	ctl('z'), 0
  };
  
+ void
  charout(c)
  int c;
  {
***************
*** 332,337
  	(void)putchar(c);
  }
  
  initkbd()
  {
      register struct key_map *kp;

--- 371,377 -----
  	(void)putchar(c);
  }
  
+ void
  initkbd()
  {
      register struct key_map *kp;
***************
*** 410,415
  #endif
  }
  
  nmgetch() 
  {
      register int c;

--- 450,456 -----
  #endif
  }
  
+ int
  nmgetch() 
  {
      register int c;
***************
*** 484,489
  
  #if defined(SYSV2) || defined(SYSV3)
  
  initkbd()
  {
      keypad(stdscr, TRUE);

--- 525,531 -----
  
  #if defined(SYSV2) || defined(SYSV3)
  
+ void
  initkbd()
  {
      keypad(stdscr, TRUE);
***************
*** 501,506
      keypad(stdscr, FALSE);
  }
  
  nmgetch()
  {
      register int c;

--- 543,549 -----
      keypad(stdscr, FALSE);
  }
  
+ int
  nmgetch()
  {
      register int c;
***************
*** 539,544
  
  #ifdef SIGVOID
  void
  #endif
  time_out(signo)
  int signo;

--- 582,589 -----
  
  #ifdef SIGVOID
  void
+ #else
+ int
  #endif
  time_out(signo)
  int signo;
***************
*** 543,552
  time_out(signo)
  int signo;
  {
! #ifdef IEEE_MATH
! 	(void)fpsetsticky((fp_except)0); 		/* Clear exception */
! #endif /* IEEE_MATH */
!     longjmp(wakeup, -1);
  }
  
  #ifdef SIGVOID

--- 588,594 -----
  time_out(signo)
  int signo;
  {
!     longjmp(wakeup, 1);
  }
  
  /*
***************
*** 549,563
      longjmp(wakeup, -1);
  }
  
- #ifdef SIGVOID
- void
- #endif
- fpe_trap(signo)
- int signo;
- {
-     longjmp(fpe_buf, 1);
- }
- 
  /*
   * This converts a floating point number of the form
   * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.

--- 591,596 -----
      longjmp(wakeup, 1);
  }
  
  /*
   * This converts a floating point number of the form
   * [s]ddd[.d*][esd*]  where s can be a + or - and e is E or e.
***************
*** 580,586
  #else
      int (*sig_save)();
  #endif
- 
      sig_save = signal(SIGFPE, fpe_trap);
      if (setjmp(fpe_buf)) {
  	error("Floating point exception\n");

--- 613,618 -----
  #else
      int (*sig_save)();
  #endif
      sig_save = signal(SIGFPE, fpe_trap);
      if (setjmp(fpe_buf)) {
  	error("Floating point exception\n");
*** 69/psc.c	Thu Oct  4 09:12:50 1990
--- psc.c	Fri Oct 26 17:01:02 1990
***************
*** 52,57
  int *fwidth;
  int *precision;
  int maxcols;
  
  char token[1000];
  

--- 52,58 -----
  int *fwidth;
  int *precision;
  int maxcols;
+ int *realfmt;
  
  char token[1000];
  
*** 69/range.c	Thu Oct  4 09:13:22 1990
--- range.c	Fri Oct 26 16:57:57 1990
***************
*** 4,10
   *
   *              Robert Bond, 4/87
   *
!  *		$Revision: 6.8 $
   */
  
  #include <stdio.h>

--- 4,10 -----
   *
   *              Robert Bond, 4/87
   *
!  *		$Revision: 6.10 $
   */
  
  #include <stdio.h>
***************
*** 22,27
  
  static struct range *rng_base;
  
  add_range(name, left, right, is_range)
  char *name;
  struct ent_ptr left, right;

--- 22,28 -----
  
  static struct range *rng_base;
  
+ void
  add_range(name, left, right, is_range)
  char *name;
  struct ent_ptr left, right;
***************
*** 86,91
      rng_base = r;
  }
  
  del_range(left, right)
  struct ent *left, *right;
  {

--- 87,93 -----
      rng_base = r;
  }
  
+ void
  del_range(left, right)
  struct ent *left, *right;
  {
***************
*** 113,118
      xfree((char *)r);
  }
  
  clean_range()
  {
      register struct range *r;

--- 115,121 -----
      xfree((char *)r);
  }
  
+ void
  clean_range()
  {
      register struct range *r;
***************
*** 160,165
      return((struct range *)0);
  }
  
  sync_ranges()
  {
      register struct range *r;

--- 163,169 -----
      return((struct range *)0);
  }
  
+ void
  sync_ranges()
  {
      register struct range *r;
***************
*** 172,177
      }
  }
  
  write_range(f)
  FILE *f;
  {

--- 176,182 -----
      }
  }
  
+ void
  write_range(f)
  FILE *f;
  {
***************
*** 257,262
      }
  }
  
  are_ranges()
  {
  return (rng_base != 0);

--- 262,268 -----
      }
  }
  
+ int
  are_ranges()
  {
  	return (rng_base != 0);
***************
*** 259,263
  
  are_ranges()
  {
! return (rng_base != 0);
  }

--- 265,269 -----
  int
  are_ranges()
  {
! 	return (rng_base != 0);
  }
*** 69/sc.c	Thu Oct  4 09:15:40 1990
--- sc.c	Fri Oct 26 16:58:09 1990
***************
*** 7,14
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		Currently supported by pur-phy!sawmill!buhrt (Jeff Buhrt)
!  *		$Revision: 6.9 $
   *
   */
  

--- 7,14 -----
   *
   *              More mods Robert Bond, 12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		Currently supported by sequent!sawmill!buhrt (Jeff Buhrt)
!  *		$Revision: 6.10 $
   *
   */
  
***************
*** 34,39
  void exit();
  #endif
  
  #ifndef DFLT_PAGER
  #define	DFLT_PAGER "more"	/* more is probably more widespread than less */
  #endif /* DFLT_PAGER */

--- 34,43 -----
  void exit();
  #endif
  
+ #ifndef SAVENAME
+ #define	SAVENAME "SC.SAVE" /* file name to use for emergency saves */
+ #endif /* SAVENAME */
+ 
  #ifndef DFLT_PAGER
  #define	DFLT_PAGER "more"	/* more is probably more widespread than less */
  #endif /* DFLT_PAGER */
***************
*** 53,58
  int maxrows, maxcols;
  int *fwidth;
  int *precision;
  char *col_hidden;
  char *row_hidden;
  char line[FBUFLEN];

--- 57,63 -----
  int maxrows, maxcols;
  int *fwidth;
  int *precision;
+ int *realfmt;
  char *col_hidden;
  char *row_hidden;
  char line[FBUFLEN];
***************
*** 79,84
  int  calc_order = BYROWS;
  int  tbl_style = 0;	/* headers for T command output */
  int  rndinfinity = 0;
  
  int  lastmx, lastmy;	/* Screen address of the cursor */
  int  lastcol;		/* Spreadsheet Column the cursor was in last */

--- 84,90 -----
  int  calc_order = BYROWS;
  int  tbl_style = 0;	/* headers for T command output */
  int  rndinfinity = 0;
+ int  numeric_field = 0; /* Started the line editing with a number */
  
  int  lastmx, lastmy;	/* Screen address of the cursor */
  int  lastcol;		/* Spreadsheet Column the cursor was in last */
***************
*** 379,384
  		 * Show expression; takes priority over other displays:
  		 */
  
  		if (showexpr && ((*pp) -> expr)) {
  		    linelim = 0;
  		    editexp(row, col);		/* set line to expr */

--- 385,394 -----
  		 * Show expression; takes priority over other displays:
  		 */
  
+ 		if ((*pp)->cellerror)
+ 			printw("%*.*s", fwidth[col], fwidth[col],
+ 			  (*pp)->cellerror == CELLERROR ? "ERROR" : "INVALID");
+ 		else
  		if (showexpr && ((*pp) -> expr)) {
  		    linelim = 0;
  		    editexp(row, col);		/* set line to expr */
***************
*** 385,393
  		    linelim = -1;
  		    showstring(line, /* leftflush = */ 1, /* hasvalue = */ 0,
  				row, col, & nextcol, mxcol, & fieldlen, r, c);
! 		}
! 		else {
! 
  		    /*
  		     * Show cell's numeric value:
  		     */

--- 395,401 -----
  		    linelim = -1;
  		    showstring(line, /* leftflush = */ 1, /* hasvalue = */ 0,
  				row, col, & nextcol, mxcol, & fieldlen, r, c);
! 		} else {
  		    /*
  		     * Show cell's numeric value:
                       */
***************
*** 390,396
  
  		    /*
  		     * Show cell's numeric value:
! 		     */
  
  		    if ((*pp) -> flags & is_valid) {
  			char field[FBUFLEN];

--- 398,404 -----
  		} else {
  		    /*
  		     * Show cell's numeric value:
!                      */
  
  		    if ((*pp) -> flags & is_valid) {
  			char field[FBUFLEN];
***************
*** 394,399
  
  		    if ((*pp) -> flags & is_valid) {
  			char field[FBUFLEN];
  			if ((*pp) -> format) {
  			    (void)format((*pp) -> format, (*pp) -> v, field,
  					 sizeof(field));

--- 402,408 -----
  
  		    if ((*pp) -> flags & is_valid) {
  			char field[FBUFLEN];
+ 
  			if ((*pp) -> format) {
  				format((*pp) -> format, (*pp) -> v,
  					     field, sizeof(field));
***************
*** 395,402
  		    if ((*pp) -> flags & is_valid) {
  			char field[FBUFLEN];
  			if ((*pp) -> format) {
! 			    (void)format((*pp) -> format, (*pp) -> v, field,
! 					 sizeof(field));
  			} else {
  			    (void)sprintf(field,"%*.*f", fwidth[col],
  					  precision[col], (*pp)->v);

--- 404,411 -----
  			char field[FBUFLEN];
  
  			if ((*pp) -> format) {
! 				format((*pp) -> format, (*pp) -> v,
! 					     field, sizeof(field));
  			} else {
  				engformat(realfmt[col], fwidth[col], 
                                               precision[col], (*pp) -> v, 
***************
*** 398,405
  			    (void)format((*pp) -> format, (*pp) -> v, field,
  					 sizeof(field));
  			} else {
! 			    (void)sprintf(field,"%*.*f", fwidth[col],
! 					  precision[col], (*pp)->v);
  			}
  			if(strlen(field) > fwidth[col]) {
  			    for(i = 0; i<fwidth[col]; i++)

--- 407,415 -----
  				format((*pp) -> format, (*pp) -> v,
  					     field, sizeof(field));
  			} else {
! 				engformat(realfmt[col], fwidth[col], 
!                                              precision[col], (*pp) -> v, 
!                                              field, sizeof(field));
  			}
  			if (strlen(field) > fwidth[col]) {
  				for(i = 0; i<fwidth[col]; i++)
***************
*** 401,409
  			    (void)sprintf(field,"%*.*f", fwidth[col],
  					  precision[col], (*pp)->v);
  			}
! 			if(strlen(field) > fwidth[col]) {
! 			    for(i = 0; i<fwidth[col]; i++)
! 				(void)addch('*');
  			} else {
  			    for(i = 0; i < fwidth[col] - strlen(field); i++)
  				(void)addch(' ');

--- 411,419 -----
                                               precision[col], (*pp) -> v, 
                                               field, sizeof(field));
  			}
! 			if (strlen(field) > fwidth[col]) {
! 				for(i = 0; i<fwidth[col]; i++)
! 					(void)addch('*');
  			} else {
  				for(i = 0; i < fwidth[col] - strlen(field);i++)
  					(void)addch(' ');
***************
*** 405,413
  			    for(i = 0; i<fwidth[col]; i++)
  				(void)addch('*');
  			} else {
! 			    for(i = 0; i < fwidth[col] - strlen(field); i++)
! 				(void)addch(' ');
! 			    (void)addstr(field);
  			}
  		    }
  

--- 415,423 -----
  				for(i = 0; i<fwidth[col]; i++)
  					(void)addch('*');
  			} else {
! 				for(i = 0; i < fwidth[col] - strlen(field);i++)
! 					(void)addch(' ');
! 				(void)addstr(field);
  			}
  		    }
  
***************
*** 720,725
  		    error ("No such command (^%c)", c + 0100);
  		    break;
  		case ctl('b'):
  		    backcol(arg);
  		    break;
  		case ctl('c'):

--- 730,739 -----
  		    error ("No such command (^%c)", c + 0100);
  		    break;
  		case ctl('b'):
+ 		    if (numeric_field) {
+ 			write_line(ctl('m'));
+ 			numeric_field = 0;
+ 		    }
  		    backcol(arg);
  		    break;
  		case ctl('c'):
***************
*** 748,753
  		    break;
  
  		case ctl('f'):
  		    forwcol(arg);
  		    break;
  

--- 762,771 -----
  		    break;
  
  		case ctl('f'):
+ 		    if (numeric_field) {
+ 			write_line(ctl('m'));
+ 			numeric_field = 0;
+ 		    }
  		    forwcol(arg);
  		    break;
  
***************
*** 794,799
  
  		case ctl('m'):
  		case ctl('j'):
  		    write_line(ctl('m'));
  		    break;
  

--- 812,818 -----
  
  		case ctl('m'):
  		case ctl('j'):
+ 		    numeric_field = 0;
  		    write_line(ctl('m'));
  		    break;
  
***************
*** 798,803
  		    break;
  
  		case ctl('n'):
  		    forwrow(arg);
  		    break;
  

--- 817,826 -----
  		    break;
  
  		case ctl('n'):
+ 		    if (numeric_field) {
+ 			write_line(ctl('m'));
+ 			numeric_field = 0;
+ 		    }
  		    forwrow(arg);
  		    break;
  
***************
*** 802,807
  		    break;
  
  		case ctl('p'):
  		    backrow(arg);
  		    break;
  

--- 825,834 -----
  		    break;
  
  		case ctl('p'):
+ 		    if (numeric_field) {
+ 			write_line(ctl('m'));
+ 			numeric_field = 0;
+ 		    }
  		    backrow(arg);
  		    break;
  
***************
*** 972,977
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
  		case '-': case '.': case '+':
  		    (void) sprintf(line,"let %s = %c",
  				v_name(currow, curcol), c);
  		    linelim = strlen (line);

--- 999,1005 -----
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
  		case '-': case '.': case '+':
+ 		    numeric_field = 1;
  		    (void) sprintf(line,"let %s = %c",
  				v_name(currow, curcol), c);
  		    linelim = strlen (line);
***************
*** 1295,1302
  			(void) sprintf(line+strlen(line), "%s ",
  				coltoa(curcol+arg-1));
  		    }
! 		    error("Current format is %d %d",
! 				fwidth[curcol],precision[curcol]);
  		    linelim = strlen (line);
  		    insert_mode();
  		    break;

--- 1323,1330 -----
  			(void) sprintf(line+strlen(line), "%s ",
  				coltoa(curcol+arg-1));
  		    }
! 		    error("Current format is %d %d %d",
! 			fwidth[curcol],precision[curcol],realfmt[curcol]);
  		    linelim = strlen (line);
  		    insert_mode();
  		    break;
***************
*** 1559,1564
  
  #ifdef SIGVOID
  void
  #endif
  quit()
  {

--- 1587,1594 -----
  
  #ifdef SIGVOID
  void
+ #else
+ int
  #endif
  quit()
  {
***************
*** 1571,1576
  
  #ifdef SIGVOID
  void
  #endif
  dump_me()
  {

--- 1601,1608 -----
  
  #ifdef SIGVOID
  void
+ #else
+ int
  #endif
  dump_me()
  {
***************
*** 1580,1585
  }
  
  /* try to save the current spreadsheet if we can */
  diesave()
  {   char	path[PATHLEN];
      if (modcheck(" before Spreadsheet dies") == 1)

--- 1612,1618 -----
  }
  
  /* try to save the current spreadsheet if we can */
+ void
  diesave()
  {   char	path[PATHLEN];
      if (modcheck(" before Spreadsheet dies") == 1)
***************
*** 1583,1589
  diesave()
  {   char	path[PATHLEN];
      if (modcheck(" before Spreadsheet dies") == 1)
!     {	sprintf(path, "~/SC.SAVE");
  	if (writefile(path, 0, 0, maxrow, maxcol) < 0)
  	    if (writefile("/tmp/SC.SAVE", 0, 0, maxrow, maxcol) < 0)
  		error("Couldn't save current spreadsheet, Sorry");

--- 1616,1622 -----
  diesave()
  {   char	path[PATHLEN];
      if (modcheck(" before Spreadsheet dies") == 1)
!     {	sprintf(path, "~/%s", SAVENAME);
  	if (writefile(path, 0, 0, maxrow, maxcol) < 0)
  	{
  	    sprintf(path, "/tmp/%s", SAVENAME);
***************
*** 1585,1591
      if (modcheck(" before Spreadsheet dies") == 1)
      {	sprintf(path, "~/SC.SAVE");
  	if (writefile(path, 0, 0, maxrow, maxcol) < 0)
! 	    if (writefile("/tmp/SC.SAVE", 0, 0, maxrow, maxcol) < 0)
  		error("Couldn't save current spreadsheet, Sorry");
      }
  }

--- 1618,1626 -----
      if (modcheck(" before Spreadsheet dies") == 1)
      {	sprintf(path, "~/%s", SAVENAME);
  	if (writefile(path, 0, 0, maxrow, maxcol) < 0)
! 	{
! 	    sprintf(path, "/tmp/%s", SAVENAME);
! 	    if (writefile(path, 0, 0, maxrow, maxcol) < 0)
  		error("Couldn't save current spreadsheet, Sorry");
  	}
      }
***************
*** 1587,1592
  	if (writefile(path, 0, 0, maxrow, maxcol) < 0)
  	    if (writefile("/tmp/SC.SAVE", 0, 0, maxrow, maxcol) < 0)
  		error("Couldn't save current spreadsheet, Sorry");
      }
  }
  

--- 1622,1628 -----
  	    sprintf(path, "/tmp/%s", SAVENAME);
  	    if (writefile(path, 0, 0, maxrow, maxcol) < 0)
  		error("Couldn't save current spreadsheet, Sorry");
+ 	}
      }
  }
  
*** 69/sc.doc	Thu Oct  4 09:15:56 1990
--- sc.doc	Fri Oct 26 16:58:17 1990
***************
*** 15,21
  .\" - TPs use default indent except for function names, then 18.
  .\" - Smallify uppercase strings.
  .\" - Avoid passive voice and third person.
! .\" $Revision: 6.9 $
  .\"
  .TH PNAME 1
  .SH NAME

--- 15,21 -----
  .\" - TPs use default indent except for function names, then 18.
  .\" - Smallify uppercase strings.
  .\" - Avoid passive voice and third person.
! .\" $Revision: 6.10 $
  .\"
  .TH PNAME 1
  .SH NAME
***************
*** 219,224
  the start of a numeric value for the current cell,
  not a repeat count, unless preceded by
  .IR ^U .
  .\" ----------
  .TP
  .B t

--- 219,230 -----
  the start of a numeric value for the current cell,
  not a repeat count, unless preceded by
  .IR ^U .
+ The cursor controls
+ .RI ( ^P ,
+ .IR ^N ,
+ .IR ^B ,
+ .IR ^F )
+ in this mode will end a numeric entry.
  .\" ----------
  .TP
  .B t
***************
*** 468,473
  Searches for either strings or numbers proceed forward from the
  current cell, wrapping back to a0 at the end of the table, and
  terminate at the current cell if the string or number is not found.
  The last
  .I g
  command is saved, and can be re-issued by entering 

--- 474,485 -----
  Searches for either strings or numbers proceed forward from the
  current cell, wrapping back to a0 at the end of the table, and
  terminate at the current cell if the string or number is not found.
+ You may also go to a cell with an ERROR (divide by zero, etc in this cell)
+ or INVALID (references a cell containing an ERROR).
+ .IR g error
+ will take you to the next ERROR, while
+ .IR g invalid
+ take you to the next invalid.
  The last
  .I g
  command is saved, and can be re-issued by entering 
***************
*** 561,567
  Thousands separator.
  The presence of a `,' in the format
  (multiple commas are treated as one) will cause the number
! to be formatted with a `,' separating each set of three digits
  in the integer part of the number with numbering beginning
  from the right end of the integer.
  .TP

--- 573,579 -----
  Thousands separator.
  The presence of a `,' in the format
  (multiple commas are treated as one) will cause the number
! to be formated with a `,' separating each set of three digits
  in the integer part of the number with numbering beginning
  from the right end of the integer.
  .TP
***************
*** 565,571
  in the integer part of the number with numbering beginning
  from the right end of the integer.
  .TP
! .BR \\
  Quote.
  This character causes the next character to be
  inserted into the formatted string directly with no

--- 577,583 -----
  in the integer part of the number with numbering beginning
  from the right end of the integer.
  .TP
! .BR \e
  Quote.
  This character causes the next character to be
  inserted into the formated string directly with no
***************
*** 568,574
  .BR \\
  Quote.
  This character causes the next character to be
! inserted into the formatted string directly with no
  special interpretation.
  .TP
  .BR E-\ E+\ e-\ e+

--- 580,586 -----
  .BR \e
  Quote.
  This character causes the next character to be
! inserted into the formated string directly with no
  special interpretation.
  .TP
  .BR E-\ E+\ e-\ e+
***************
*** 573,579
  .TP
  .BR E-\ E+\ e-\ e+
  Scientific format.
! Causes the number to formatted in scientific
  notation.  The case of the `E' or `e' given is preserved.  If
  the format uses a `+', then the sign is always given for the
  exponent value.  If the format uses a `-', then the sign is

--- 585,591 -----
  .TP
  .BR E-\ E+\ e-\ e+
  Scientific format.
! Causes the number to formated in scientific
  notation.  The case of the `E' or `e' given is preserved.  If
  the format uses a `+', then the sign is always given for the
  exponent value.  If the format uses a `-', then the sign is
***************
*** 579,585
  exponent value.  If the format uses a `-', then the sign is
  only given when the exponent value is negative.  Note that if
  there is no digit placeholder following the `+' or `-', then
! that part of the formatted number is left out.  In general,
  there should be one or more digit placeholders after the `+'
  or `-'.
  .TP

--- 591,597 -----
  exponent value.  If the format uses a `-', then the sign is
  only given when the exponent value is negative.  Note that if
  there is no digit placeholder following the `+' or `-', then
! that part of the formated number is left out.  In general,
  there should be one or more digit placeholders after the `+'
  or `-'.
  .TP
***************
*** 612,662
  except that the command line starts out containing
  the old numeric value or expression associated with the cell.
  The editing in this mode is vi-like.
! 	^h	move back a character
! 	+	forward through history (neat)	(same as j)
! 	-	backward through history (neat)	(same as k)
! 	ESC	done editing
! 	TAB	mark && append a range (ex: A0:A0)
! 		TAB, move around w/i a range, TAB (appends range string)
! 	CR	save
! 	$	goto last col
! 	.	insert current dot buffer
! 	/	search for a string in the history
! 		ESC	edit the you typed
! 		CR	search
! 		^h	backspace
! 	0	goto column 0
! 	D	Delete to send
! 	I	Insert at column 0
! 		ESC	revert back to edit mode
! 	R	Replace mode
! 		ESC	revert back to edit mode
! 	X	delete the char to the left
! 	a	append mode
! 	b	move back a word
! 	c	change mode
! 	d	delete ...
! 		b	back word
! 		f	forward (right)
! 		h	back char
! 		l	forward
! 		t	delete forward up to a given char (next char typed)
! 		w	delete next word forward
! 	f	find the next char typed
! 	h	move left a char
! 	i	insert mode
! 		ESC	revert back to edit mode
! 	j	forward through history (neat)	(same as +)
! 	k	backward	"	"	(same as +)
! 	l	move right a char
! 	n	continue search
! 	q	stop editing
! 	r	replace char
! 	t	goto a char
! 	u	undo
! 	w	forward a word
! 	x	delete the current char (moving to the right)
! 
  .\" ----------
  .TP
  .B E

--- 624,746 -----
  except that the command line starts out containing
  the old numeric value or expression associated with the cell.
  The editing in this mode is vi-like.
! .RS
! .TP
! .BR ^h 
! Move back a character
! .TP
! .BR +
! Forward through history (neat) (same as j)
! .TP
! .BR - 
! Backward through history (neat) (same as k)
! .TP
! .BR ESC
! Done editing
! .TP
! .BR TAB
! Mark && append a range (ex: A0:A0)
! .br
! TAB, move around w/i a range; TAB, append range string.
! .TP
! .BR CR
! Save
! .TP
! .BR $
! Goto last column
! .TP
! .BR .
! Insert current dot buffer
! .TP
! .BR /
! Search for a string in the history
! .RS
! \fBESC\fP	edit the you typed
! .br
! \fBCR\fP	search
! .br
! \fB^h\fP	backspace
! .RE
! .TP
! .BR 0
! Goto column 0
! .TP
! .BR D
! Delete to send
! .TP
! .BR I
! Insert at column 0; ESC revert back to edit mode
! .TP
! .BR R
! Replace mode; ESC revert back to edit mode
! .TP
! .BR X
! Delete the char to the left
! .TP
! .BR a
! Append after cursor; ESC revert back to edit mode
! .TP
! .BR b
! Move back a word
! .TP
! .BR c
! Change mode; ESC revert back to edit mode
! .TP
! .BR d
! Delete ...
! .RS
! \fBb\fP	back word\br
! .br
! \fBf\fP	forward (right)\br
! .br
! \fBh\fP	back char\br
! .br
! \fBl\fP	forward\br
! .br
! \fBt\fP	delete forward up to a given char (next char typed)\br
! .br
! \fBw\fP	delete next word forward\br
! .RE
! .TP
! .BR f
! Find the next char typed
! .TP
! .BR h
! Move left a char
! .TP
! .BR i
! Insert before cursor; ESC revert back to edit mode
! .TP
! .BR j
! Forward through history (neat) (same as +)
! .TP
! .BR k
! Backward through history (neat) (same as -)
! .TP
! .BR l
! Move right a char
! .TP
! .BR n
! Continue search
! .TP
! .BR q
! Stop editing
! .TP
! .BR r
! Replace char
! .TP
! .BR t
! Goto a char
! .TP
! .BR u
! Undo
! .TP
! .BR w
! Forward a word
! .TP
! .BR x
! Delete the current char (moving to the right)
! .RE
  .\" ----------
  .TP
  .B E
***************
*** 756,763
  option.  See
  .I Set
  above.
! The delimters are are a colon\ (:) for style
! .IR 0 or tbl
  and an ampersand\ (&) for style
  .IR latex or tex .
  .\" ----------

--- 840,849 -----
  option.  See
  .I Set
  above.
! The delimiters are are a colon\ (:) for style
! .IR 0
! or
! .IR tbl
  and an ampersand\ (&) for style
  .IR latex
  or
***************
*** 759,765
  The delimters are are a colon\ (:) for style
  .IR 0 or tbl
  and an ampersand\ (&) for style
! .IR latex or tex .
  .\" ----------
  .PP
  With the

--- 845,853 -----
  or
  .IR tbl
  and an ampersand\ (&) for style
! .IR latex
! or
! .IR tex .
  .\" ----------
  .PP
  With the
***************
*** 931,937
  .B f
  Set the output format to be used
  for printing the numeric values in each cell in the current column.
! Enter two numbers:
  the total width in characters of the column,
  and the number of digits to follow decimal points.
  Values are rounded off to the least significant digit displayed.

--- 1019,1025 -----
  .B f
  Set the output format to be used
  for printing the numeric values in each cell in the current column.
! Enter three numbers:
  the total width in characters of the column,
  the number of digits to follow decimal points,
  and the format type.  Format types are 0 for fixed point,
***************
*** 933,939
  for printing the numeric values in each cell in the current column.
  Enter two numbers:
  the total width in characters of the column,
! and the number of digits to follow decimal points.
  Values are rounded off to the least significant digit displayed.
  The total column width affects displays of strings as well as numbers.
  A preceding count can be used to affect more than one column.

--- 1021,1029 -----
  for printing the numeric values in each cell in the current column.
  Enter three numbers:
  the total width in characters of the column,
! the number of digits to follow decimal points,
! and the format type.  Format types are 0 for fixed point,
! 1 for scientific notation, and 2 for engineering notation.
  Values are rounded off to the least significant digit displayed.
  The total column width affects displays of strings as well as numbers.
  A preceding count can be used to affect more than one column.
***************
*** 1052,1058
  .TP
  .B /F
  Use this command to assign a value format string (see the ``F''
! cell entry commmand) to a range of cells.
  .\" ==========
  .SS "Miscellaneous Commands"
  .\" ----------

--- 1142,1148 -----
  .TP
  .B /F
  Use this command to assign a value format string (see the ``F''
! cell entry command) to a range of cells.
  .\" ==========
  .SS "Miscellaneous Commands"
  .\" ----------
***************
*** 1956,1962
  and further modified by numerous contributors,
  Jeff Buhrt
  of Grauel Enterprises, Inc.
! ({pur-phy (aka: newton.physics.purdue.edu), sequent}!sawmill!buhrt)
  and Robert Bond of Sequent,
  prominent among them.
  Other contributors include:

--- 2046,2052 -----
  and further modified by numerous contributors,
  Jeff Buhrt
  of Grauel Enterprises, Inc.
! ({pur-phy (aka: gibbs.physics.purdue.edu), sequent}!sawmill!buhrt)
  and Robert Bond of Sequent,
  prominent among them.
  Other contributors include:
***************
*** 1960,1965
  and Robert Bond of Sequent,
  prominent among them.
  Other contributors include:
  Gregory Bond,
  Peter Brower,
  John Campbell,

--- 2050,2056 -----
  and Robert Bond of Sequent,
  prominent among them.
  Other contributors include:
+ Tom Anderson
  Gregory Bond,
  Peter Brower,
  John Campbell,
***************
*** 1964,1969
  Peter Brower,
  John Campbell,
  Lawrence Cipriani,
  Chris Cole,
  Glen Ditchfield
  Sam Drake,

--- 2055,2061 -----
  Peter Brower,
  John Campbell,
  Lawrence Cipriani,
+ Jim Clausing,
  Chris Cole,
  Glen Ditchfield,
  Sam Drake,
***************
*** 1965,1971
  John Campbell,
  Lawrence Cipriani,
  Chris Cole,
! Glen Ditchfield
  Sam Drake,
  Kurt Horton,
  Peter King,

--- 2057,2063 -----
  Lawrence Cipriani,
  Jim Clausing,
  Chris Cole,
! Glen Ditchfield,
  Sam Drake,
  Paul Eggert,
  Jack Goral,
***************
*** 1967,1972
  Chris Cole,
  Glen Ditchfield
  Sam Drake,
  Kurt Horton,
  Peter King,
  Dave Lewis, 

--- 2059,2068 -----
  Chris Cole,
  Glen Ditchfield,
  Sam Drake,
+ Paul Eggert,
+ Jack Goral,
+ Piercarlo "Peter" Grandi,
+ Jeffrey C Honig,
  Kurt Horton,
  Peter King,
  Tom Kloos,
***************
*** 1969,1974
  Sam Drake,
  Kurt Horton,
  Peter King,
  Dave Lewis, 
  Rick Linck,
  Soren Lundsgaard,

--- 2065,2072 -----
  Jeffrey C Honig,
  Kurt Horton,
  Peter King,
+ Tom Kloos,
+ Casey Leedom,
  Dave Lewis, 
  Rick Linck,
  Soren Lundsgaard,
***************
*** 1974,1979
  Soren Lundsgaard,
  Tad Mannes,
  Rob McMahon,
  Marius Olafsson,
  Rick Perry,
  R. P. C. Rodgers,

--- 2072,2078 -----
  Soren Lundsgaard,
  Tad Mannes,
  Rob McMahon,
+ Mark Nagel,
  Marius Olafsson,
  Gene H. Olson,
  Rick Perry,
***************
*** 1975,1980
  Tad Mannes,
  Rob McMahon,
  Marius Olafsson,
  Rick Perry,
  R. P. C. Rodgers,
  Alan Silverstein,

--- 2074,2080 -----
  Rob McMahon,
  Mark Nagel,
  Marius Olafsson,
+ Gene H. Olson,
  Rick Perry,
  Eric Putz,
  Jim Richardson,
***************
*** 1976,1981
  Rob McMahon,
  Marius Olafsson,
  Rick Perry,
  R. P. C. Rodgers,
  Alan Silverstein,
  and

--- 2076,2083 -----
  Marius Olafsson,
  Gene H. Olson,
  Rick Perry,
+ Eric Putz,
+ Jim Richardson,
  R. P. C. Rodgers,
  Kim Sanders,
  Mike Schwartz,
***************
*** 1977,1982
  Marius Olafsson,
  Rick Perry,
  R. P. C. Rodgers,
  Alan Silverstein,
  and
  Andy Valencia.

--- 2079,2086 -----
  Eric Putz,
  Jim Richardson,
  R. P. C. Rodgers,
+ Kim Sanders,
+ Mike Schwartz,
  Alan Silverstein,
  Tom Tkacik,
  Andy Valencia,
***************
*** 1978,1983
  Rick Perry,
  R. P. C. Rodgers,
  Alan Silverstein,
  and
  Andy Valencia.
  .\" end of man page

--- 2082,2090 -----
  Kim Sanders,
  Mike Schwartz,
  Alan Silverstein,
+ Tom Tkacik,
+ Andy Valencia,
+ Adri Verhoef,
  and
  Tim Wilson.
  .\" end of man page
***************
*** 1979,1983
  R. P. C. Rodgers,
  Alan Silverstein,
  and
! Andy Valencia.
  .\" end of man page

--- 2086,2090 -----
  Andy Valencia,
  Adri Verhoef,
  and
! Tim Wilson.
  .\" end of man page
*** 69/sc.h	Thu Oct  4 09:16:27 1990
--- sc.h	Fri Oct 26 16:58:19 1990
***************
*** 6,12
   *			University of Maryland
   *		R. Bond  12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		$Revision: 6.9 $
   *
   */
  

--- 6,12 -----
   *			University of Maryland
   *		R. Bond  12/86
   *		More mods by Alan Silverstein, 3-4/88, see list of changes.
!  *		$Revision: 6.10 $
   *
   */
  
***************
*** 12,19
  
  #define	ATBL(tbl, row, col)	(*(tbl + row) + (col))
  
! #define MINROWS 40	/* minimum size at startup */
! #define MINCOLS 20
  #define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
  #define RESCOL 4	/* columns reserved for row numbers */
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */

--- 12,19 -----
  
  #define	ATBL(tbl, row, col)	(*(tbl + row) + (col))
  
! #define MINROWS 40 	/* minimum size at startup */
! #define MINCOLS 20 
  #define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
  
  #define RESCOL 4	/* columns reserved for row numbers */
***************
*** 15,20
  #define MINROWS 40	/* minimum size at startup */
  #define MINCOLS 20
  #define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
  #define RESCOL 4	/* columns reserved for row numbers */
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
  #define DEFWIDTH 10	/* Default column width and precision */

--- 15,21 -----
  #define MINROWS 40 	/* minimum size at startup */
  #define MINCOLS 20 
  #define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
+ 
  #define RESCOL 4	/* columns reserved for row numbers */
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
  
***************
*** 17,22
  #define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
  #define RESCOL 4	/* columns reserved for row numbers */
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
  #define DEFWIDTH 10	/* Default column width and precision */
  #define DEFPREC   2
  #define HISTLEN  10	/* Number of history entries for vi emulation */

--- 18,24 -----
  
  #define RESCOL 4	/* columns reserved for row numbers */
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
+ 
  #define DEFWIDTH 10	/* Default column width and precision */
  #define DEFPREC   2
  #define DEFREFMT  0     /* Make default format fixed point  THA 10/14/90 */
***************
*** 19,24
  #define RESROW 3 /* rows reserved for prompt, error, and column numbers */
  #define DEFWIDTH 10	/* Default column width and precision */
  #define DEFPREC   2
  #define HISTLEN  10	/* Number of history entries for vi emulation */
  #define error (void)move(1,0), (void)clrtoeol(), (void) printw
  #define	FBUFLEN	1024	/* buffer size for a single field */

--- 21,28 -----
  
  #define DEFWIDTH 10	/* Default column width and precision */
  #define DEFPREC   2
+ #define DEFREFMT  0     /* Make default format fixed point  THA 10/14/90 */
+ 
  #define HISTLEN  10	/* Number of history entries for vi emulation */
  #define error (void)move(1,0), (void)clrtoeol(), (void) printw
  #define	FBUFLEN	1024	/* buffer size for a single field */
***************
*** 69,74
      struct ent *evnext;		/* next ent w/ a object to eval */
      struct ent *evprev;		/* prev ent w/ a object to eval */
      char *format;
  };
  
  struct range {

--- 73,79 -----
      struct ent *evnext;		/* next ent w/ a object to eval */
      struct ent *evprev;		/* prev ent w/ a object to eval */
      char *format;
+     char cellerror;
  };
  
  struct range {
***************
*** 161,166
  #define is_leftflush 0010
  #define is_deleted   0020
  
  #define ctl(c) ((c)&037)
  #define ESC 033
  #define DEL 0177

--- 166,176 -----
  #define is_leftflush 0010
  #define is_deleted   0020
  
+ /* cell error (1st generation (ERROR) or 2nd+ (INVALID)) */
+ #define	CELLOK		0
+ #define	CELLERROR	1
+ #define	CELLINVALID	2
+ 
  #define ctl(c) ((c)&037)
  #define ESC 033
  #define DEL 0177
***************
*** 195,200
  extern	int maxrows, maxcols;	/* # cells currently allocated */
  extern	int *fwidth;
  extern	int *precision;
  extern	char *col_hidden;
  extern	char *row_hidden;
  extern	char line[FBUFLEN];

--- 205,211 -----
  extern	int maxrows, maxcols;	/* # cells currently allocated */
  extern	int *fwidth;
  extern	int *precision;
+ extern  int *realfmt;
  extern	char *col_hidden;
  extern	char *row_hidden;
  extern	char line[FBUFLEN];
***************
*** 217,222
  extern	int are_ranges();
  extern	int atocol();
  extern	int constant();
  extern	int etype();
  extern	int fork();
  extern	int get_rcqual();

--- 228,234 -----
  extern	int are_ranges();
  extern	int atocol();
  extern	int constant();
+ extern	int cwritefile();
  extern	int etype();
  extern	int fork();
  extern	int get_rcqual();
***************
*** 221,226
  extern	int fork();
  extern	int get_rcqual();
  extern	int growtbl();
  extern	int nmgetch();
  extern	int writefile();
  extern	int xfree();

--- 233,239 -----
  extern	int fork();
  extern	int get_rcqual();
  extern	int growtbl();
+ extern	int modcheck();
  extern	int nmgetch();
  extern	int writefile();
  extern	int yn_ask();
***************
*** 223,229
  extern	int growtbl();
  extern	int nmgetch();
  extern	int writefile();
- extern	int xfree();
  extern	int yn_ask();
  extern	struct enode *copye();
  extern	struct enode *new();

--- 236,241 -----
  extern	int modcheck();
  extern	int nmgetch();
  extern	int writefile();
  extern	int yn_ask();
  extern	struct enode *copye();
  extern	struct enode *new();
***************
*** 236,241
  extern	void EvalAll();
  extern	void Evalall();
  extern	void RealEvalOne();
  extern	void backcol();
  extern	void backrow();
  extern	void checkbounds();

--- 248,254 -----
  extern	void EvalAll();
  extern	void Evalall();
  extern	void RealEvalOne();
+ extern	void addrange();
  extern	void backcol();
  extern	void backrow();
  extern	void checkbounds();
***************
*** 240,245
  extern	void backrow();
  extern	void checkbounds();
  extern	void clearent();
  extern	void closecol();
  extern	void closeout();
  extern	void closerow();

--- 253,259 -----
  extern	void backrow();
  extern	void checkbounds();
  extern	void clearent();
+ extern	void clean_range();
  extern	void closecol();
  extern	void closeout();
  extern	void closerow();
***************
*** 249,254
  extern	void copy();
  extern	void copyent();
  extern	void copyrtv();
  extern	void decompile();
  extern	void deletecol();
  extern	void deleterow();

--- 263,269 -----
  extern	void copy();
  extern	void copyent();
  extern	void copyrtv();
+ extern	void creadfile();
  extern	void decompile();
  extern	void deletecol();
  extern	void deleterow();
***************
*** 252,257
  extern	void decompile();
  extern	void deletecol();
  extern	void deleterow();
  extern	void deraw();
  extern	void doend();
  extern	void doformat();

--- 267,273 -----
  extern	void decompile();
  extern	void deletecol();
  extern	void deleterow();
+ extern	void del_range();
  extern	void deraw();
  extern	void diesave();
  extern	void doend();
***************
*** 253,258
  extern	void deletecol();
  extern	void deleterow();
  extern	void deraw();
  extern	void doend();
  extern	void doformat();
  extern	void dupcol();

--- 269,275 -----
  extern	void deleterow();
  extern	void del_range();
  extern	void deraw();
+ extern	void diesave();
  extern	void doend();
  extern	void doformat();
  extern	void dupcol();
***************
*** 258,263
  extern	void dupcol();
  extern	void duprow();
  extern	void editexp();
  extern	void edits();
  extern	void editv();
  extern	void efree();

--- 275,282 -----
  extern	void dupcol();
  extern	void duprow();
  extern	void editexp();
+ extern	void editfmt();
+ extern	void edit_mode();
  extern	void edits();
  extern	void editv();
  extern	void efree();
***************
*** 261,266
  extern	void edits();
  extern	void editv();
  extern	void efree();
  extern	void erase_area();
  extern	void erasedb();
  extern	void eraser();

--- 280,286 -----
  extern	void edits();
  extern	void editv();
  extern	void efree();
+ extern	void engformat();
  extern	void erase_area();
  extern	void erasedb();
  extern	void eraser();
***************
*** 264,269
  extern	void erase_area();
  extern	void erasedb();
  extern	void eraser();
  extern	void fill();
  extern	void flush_saved();
  extern	void forwcol();

--- 284,290 -----
  extern	void erase_area();
  extern	void erasedb();
  extern	void eraser();
+ extern	void fatal();
  extern	void fill();
  extern	void flush_saved();
  extern	void format();
***************
*** 266,271
  extern	void eraser();
  extern	void fill();
  extern	void flush_saved();
  extern	void forwcol();
  extern	void forwrow();
  extern	void free_ent();

--- 287,294 -----
  extern	void fatal();
  extern	void fill();
  extern	void flush_saved();
+ extern	void format();
+ extern	void format_cell();
  extern	void forwcol();
  extern	void forwrow();
  extern	void free_ent();
***************
*** 277,282
  extern	void hidecol();
  extern	void hiderow();
  extern	void index_arg();
  extern	void ins_string();
  extern	void insert_mode();
  extern	void insertcol();

--- 300,306 -----
  extern	void hidecol();
  extern	void hiderow();
  extern	void index_arg();
+ extern	void initkbd();
  extern	void ins_string();
  extern	void insert_mode();
  extern	void insertcol();
***************
*** 310,315
  extern	void slet();
  extern	void startshow();
  extern	void str_search();
  extern	void sync_refs();
  extern	void syncref();
  extern	void tblprintfile();

--- 334,340 -----
  extern	void slet();
  extern	void startshow();
  extern	void str_search();
+ extern	void sync_ranges();
  extern	void sync_refs();
  extern	void syncref();
  extern	void tblprintfile();
***************
*** 320,325
  extern	void valueize_area();
  extern	void write_fd();
  extern	void write_line();
  extern	void yyerror();
  #ifdef DOBACKUPS
  extern	int backup_file();

--- 345,352 -----
  extern	void valueize_area();
  extern	void write_fd();
  extern	void write_line();
+ extern	void write_range();
+ extern	void xfree();
  extern	void yyerror();
  #ifdef DOBACKUPS
  extern	int backup_file();
***************
*** 349,352
  #define	nocbreak	nocrmode
  #endif
  
  #endif

--- 376,384 -----
  #define	nocbreak	nocrmode
  #endif
  
+ #endif
+ 
+ #if defined(BSD42) || defined(BSD43)
+ #define	memcpy(dest, source, len)	bcopy(source, dest, (unsigned int)len);
+ #define	memset(dest, zero, len)		bzero((dest), (unsigned int)(len));
  #endif
*** 69/tutorial.sc	Thu Oct  4 09:16:41 1990
--- tutorial.sc	Fri Oct 26 16:58:24 1990
***************
*** 1,10
  # This data file was generated by the Spreadsheet Calculator.
  # You almost certainly shouldn't edit it.
  
- define "page4" A70
- define "page3" A49
- define "page2" A29
- define "page1" A9
  define "page5" A89
  leftstring A1 = "This is a brief sc tutorial."
  leftstring A3 = "Cells are named by their column and row number.  For example,"

--- 1,6 -----
  # This data file was generated by the Spreadsheet Calculator.
  # You almost certainly shouldn't edit it.
  
  define "page5" A89
  define "page1" A9
  define "page2" A29
***************
*** 6,11
  define "page2" A29
  define "page1" A9
  define "page5" A89
  leftstring A1 = "This is a brief sc tutorial."
  leftstring A3 = "Cells are named by their column and row number.  For example,"
  leftstring A4 = "Cell A4"

--- 2,11 -----
  # You almost certainly shouldn't edit it.
  
  define "page5" A89
+ define "page1" A9
+ define "page2" A29
+ define "page3" A49
+ define "page4" A70
  leftstring A1 = "This is a brief sc tutorial."
  leftstring A3 = "Cells are named by their column and row number.  For example,"
  leftstring A4 = "Cell A4"
***************
*** 14,20
  leftstring A5 = "Cell A5"
  leftstring A6 = "Cell A6"
  leftstring C6 = "Cell C6"
! leftstring A7 = "Cells range from A0 to AN199."
  leftstring A8 = "Cells can also be named by the user.  See 'range names' in the manual."
  leftstring page1 = "You can move the cursor a couple of different ways:"
  leftstring A11 = "^n, j and the <DOWN> arrow key go down"

--- 14,20 -----
  leftstring A5 = "Cell A5"
  leftstring A6 = "Cell A6"
  leftstring C6 = "Cell C6"
! leftstring A7 = "Cells range from A0 to ZZ(some number depending on free memory)."
  leftstring A8 = "Cells can also be named by the user.  See 'range names' in the manual."
  leftstring page1 = "You can move the cursor a couple of different ways:"
  leftstring A11 = "^n, j and the <DOWN> arrow key go down"
*** 69/version.c	Thu Oct  4 09:16:43 1990
--- version.c	Fri Oct 26 16:59:01 1990
***************
*** 4,7
   * The part after the first colon, except the last char, appears on the screen.
   */
  
! char *rev = "$Revision: 6.9 $";

--- 4,7 -----
   * The part after the first colon, except the last char, appears on the screen.
   */
  
! char *rev = "$Revision: 6.10 $";
*** 69/vi.c	Thu Oct  4 09:17:17 1990
--- vi.c	Fri Oct 26 16:58:27 1990
***************
*** 1,7
  /*	SC	A Spreadsheet Calculator
   *
   *	One line vi emulation
!  *	$Revision: 6.9 $
   */
  
  

--- 1,7 -----
  /*	SC	A Spreadsheet Calculator
   *
   *	One line vi emulation
!  *	$Revision: 6.10 $
   */
  
  
***************
*** 27,32
  
  #define istext(a) (isalnum(a) || ((a) == '_'))
  
  extern int showrange;
  extern char mode_ind;		/* Mode indicator */
  

--- 27,64 -----
  
  #define istext(a) (isalnum(a) || ((a) == '_'))
  
+ static	void append_line();
+ static	void back_hist();
+ static	int  back_line();
+ static	int  back_word();
+ static	void back_space();
+ static	void change_cmd();
+ static	void col_0();
+ static	void cr_line();
+ static	void delete_cmd();
+ static	void del_chars();
+ static	void del_in_line();
+ static	void del_to_end();
+ static	void dotcmd();
+ static	int  find_char();
+ static	void for_hist();
+ static	int  for_line();
+ static	int  for_word();
+ static	void ins_in_line();
+ static	void last_col();
+ static	void rep_char();
+ static	void replace_in_line();
+ static	void replace_mode();
+ static	void restore_it();
+ static	void savedot();
+ static	void save_hist();
+ static	void search_again();
+ static	void search_hist();
+ static	void search_mode();
+ static	void stop_edit();
+ static	int  to_char();
+ static	void u_save();
+ 
  extern int showrange;
  extern char mode_ind;		/* Mode indicator */
  
***************
*** 40,46
  #define	DOTLEN		200
  
  static int mode = INSERT_MODE;
! static char *history[HISTLEN];
  static int histp = -1;
  static char *last_search;
  static char *undo_line;

--- 72,82 -----
  #define	DOTLEN		200
  
  static int mode = INSERT_MODE;
! struct	hist {
! 	unsigned	int	len;
! 	char	*histline;
! } history[HISTLEN];
! 
  static int histp = -1;
  static int lasthist = -1;
  static int endhist = -1;
***************
*** 42,47
  static int mode = INSERT_MODE;
  static char *history[HISTLEN];
  static int histp = -1;
  static char *last_search;
  static char *undo_line;
  static int undo_lim;

--- 78,85 -----
  } history[HISTLEN];
  
  static int histp = -1;
+ static int lasthist = -1;
+ static int endhist = -1;
  static char *last_search;
  static char *undo_line;
  static int undo_lim;
***************
*** 49,55
  static int doti = 0;
  static int do_dot = 0;
  
- 
  void
  write_line(c)
  int c;

--- 87,92 -----
  static int doti = 0;
  static int do_dot = 0;
  
  void
  write_line(c)
  int c;
***************
*** 114,119
      }
  }
  
  edit_mode()
  {
      mode = EDIT_MODE;

--- 151,157 -----
      }
  }
  
+ void
  edit_mode()
  {
      mode = EDIT_MODE;
***************
*** 132,137
      mode = INSERT_MODE;
  }
  
  search_mode()
  {
      line[0] = '/';

--- 170,176 -----
      mode = INSERT_MODE;
  }
  
+ static	void
  search_mode()
  {
      line[0] = '/';
***************
*** 142,147
      mode = SEARCH_MODE;
  }
  
  replace_mode()
  {
      mode_ind = 'R';

--- 181,187 -----
      mode = SEARCH_MODE;
  }
  
+ static	void
  replace_mode()
  {
      mode_ind = 'R';
***************
*** 150,155
  
  /* dot command functions.  Saves info so we can redo on a '.' command */
  
  savedot(c)
  int c;
  {

--- 190,196 -----
  
  /* dot command functions.  Saves info so we can redo on a '.' command */
  
+ static	void
  savedot(c)
  int c;
  {
***************
*** 153,159
  savedot(c)
  int c;
  {
!     if (do_dot)
  	return;
  
      if (doti < DOTLEN-1)

--- 194,200 -----
  savedot(c)
  int c;
  {
!     if (do_dot || (c == '\n'))
  	return;
  
      if (doti < DOTLEN-1)
***************
*** 165,170
  
  static int dotcalled = 0;
  
  dotcmd()
  {
      int c;

--- 206,212 -----
  
  static int dotcalled = 0;
  
+ static	void
  dotcmd()
  {
      int c;
***************
*** 183,188
      dotcalled = 0;
  }
  
  vigetch()
  {
      int c;

--- 225,231 -----
      dotcalled = 0;
  }
  
+ int
  vigetch()
  {
      int c;
***************
*** 202,208
  }
  
  /* saves the current line for possible use by an undo cmd */
! 
  u_save(c)
  int c;
  {

--- 245,251 -----
  }
  
  /* saves the current line for possible use by an undo cmd */
! static	void
  u_save(c)
  int c;
  {
***************
*** 222,228
  }
  
  /* Restores the current line saved by u_save() */
! 
  restore_it()
  {
      register char *tempc;

--- 265,271 -----
  }
  
  /* Restores the current line saved by u_save() */
! static	void
  restore_it()
  {
      register char *tempc;
***************
*** 240,246
  }
  
  /* This command stops the editing process. */
! 
  stop_edit()
  {
      showrange = 0;

--- 283,289 -----
  }
  
  /* This command stops the editing process. */
! static	void
  stop_edit()
  {
      showrange = 0;
***************
*** 255,261
   * the null at the end of the line instead of stopping at the
   * the last character of the line.
   */
! 
  for_line(stop_null)
  int stop_null;
  {

--- 298,304 -----
   * the null at the end of the line instead of stopping at the
   * the last character of the line.
   */
! static	int
  for_line(stop_null)
  int stop_null;
  {
***************
*** 266,271
  	return(linelim);
  }
  
  for_word(stop_null)
  int stop_null;
  {

--- 309,315 -----
  	return(linelim);
  }
  
+ static	int
  for_word(stop_null)
  int stop_null;
  {
***************
*** 299,304
      return(cpos);
  }
  
  back_line()
  {
      if (linelim)

--- 343,349 -----
      return(cpos);
  }
  
+ static	int
  back_line()
  {
      if (linelim)
***************
*** 307,312
  	return(0);
  }
  
  back_word()
  {
      register int c;

--- 352,358 -----
  	return(0);
  }
  
+ static	int
  back_word()
  {
      register int c;
***************
*** 345,350
  
  /* Text manipulation commands */
  
  del_in_line()
  {
      register int len, i;

--- 391,397 -----
  
  /* Text manipulation commands */
  
+ static	void
  del_in_line()
  {
      register int len, i;
***************
*** 360,365
  	--linelim;
  }
  
  ins_in_line(c)
  int c;
  {

--- 407,413 -----
  	--linelim;
  }
  
+ static	void
  ins_in_line(c)
  int c;
  {
***************
*** 384,389
  	ins_in_line(*s++);
  }
  
  append_line()
  {
      register int i;

--- 432,438 -----
  	ins_in_line(*s++);
  }
  
+ static	void
  append_line()
  {
      register int i;
***************
*** 394,399
      insert_mode();
  }
  
  rep_char()
  {
      int c;

--- 443,449 -----
      insert_mode();
  }
  
+ static	void
  rep_char()
  {
      int c;
***************
*** 411,416
      }
  }
  
  replace_in_line(c)
  {
      register int len;

--- 461,467 -----
      }
  }
  
+ static	void
  replace_in_line(c)
  int	c;
  {
***************
*** 412,417
  }
  
  replace_in_line(c)
  {
      register int len;
  

--- 463,469 -----
  
  static	void
  replace_in_line(c)
+ int	c;
  {
      register int len;
  
***************
*** 424,430
      if (linelim > len)
  	line[linelim] = 0;
  }
!     
  back_space()
  {
      if (linelim == 0)

--- 476,483 -----
      if (linelim > len)
  	line[linelim] = 0;
  }
! 
! static	void
  back_space()
  {
      if (linelim == 0)
***************
*** 440,445
      }
  }
  
  get_motion()
  {
      int c;

--- 493,499 -----
      }
  }
  
+ int
  get_motion()
  {
      int c;
***************
*** 456,461
      }
  }
  
  delete_cmd()
  {
      int cpos;

--- 510,516 -----
      }
  }
  
+ static	void
  delete_cmd()
  {
      int cpos;
***************
*** 464,469
      del_chars(cpos, linelim);
  }
  
  change_cmd()
  {
      delete_cmd();

--- 519,525 -----
      del_chars(cpos, linelim);
  }
  
+ static	void
  change_cmd()
  {
      delete_cmd();
***************
*** 470,475
      insert_mode();
  }
  
  del_chars(first, last)
  register int first, last;
  {

--- 526,532 -----
      insert_mode();
  }
  
+ static	void
  del_chars(first, last)
  register int first, last;
  {
***************
*** 489,494
      }
  }
  
  del_to_end()
  {
      if (linelim < 0)

--- 546,552 -----
      }
  }
  
+ static	void
  del_to_end()
  {
      if (linelim < 0)
***************
*** 497,502
      linelim = back_line();
  }
  
  cr_line()
  {
      showrange = 0;

--- 555,561 -----
      linelim = back_line();
  }
  
+ static	void
  cr_line()
  {
      showrange = 0;
***************
*** 509,514
  
  /* History functions */
  
  save_hist()
  {
      register int i;

--- 568,574 -----
  
  /* History functions */
  
+ static	void
  save_hist()
  {
      if (lasthist < 0)
***************
*** 511,522
  
  save_hist()
  {
!     register int i;
! 
!     /* free the oldest one */
!     if (history[HISTLEN-1]) {
! 	xfree(history[HISTLEN-1]);
! 	history[HISTLEN-1] = 0;
      }
  
      /* Move the others back */

--- 571,578 -----
  static	void
  save_hist()
  {
!     if (lasthist < 0)
!     {	lasthist = 0;
      }
      else
  	lasthist = (lasthist + 1) % HISTLEN;
***************
*** 518,523
  	xfree(history[HISTLEN-1]);
  	history[HISTLEN-1] = 0;
      }
  
      /* Move the others back */
      for (i = HISTLEN-1; i > 0; --i)

--- 574,581 -----
      if (lasthist < 0)
      {	lasthist = 0;
      }
+     else
+ 	lasthist = (lasthist + 1) % HISTLEN;
  
      if (lasthist > endhist)
  	endhist = lasthist;
***************
*** 519,527
  	history[HISTLEN-1] = 0;
      }
  
!     /* Move the others back */
!     for (i = HISTLEN-1; i > 0; --i)
! 	history[i] = history[i-1];
  
      history[0] = xmalloc((unsigned) strlen(line)+1);
      strcpy(history[0], line);

--- 577,584 -----
      else
  	lasthist = (lasthist + 1) % HISTLEN;
  
!     if (lasthist > endhist)
! 	endhist = lasthist;
  
      if (history[lasthist].len < strlen(line)+1)
      {	if (history[lasthist].len)
***************
*** 523,530
      for (i = HISTLEN-1; i > 0; --i)
  	history[i] = history[i-1];
  
!     history[0] = xmalloc((unsigned) strlen(line)+1);
!     strcpy(history[0], line);
  }
  
  back_hist()

--- 580,592 -----
      if (lasthist > endhist)
  	endhist = lasthist;
  
!     if (history[lasthist].len < strlen(line)+1)
!     {	if (history[lasthist].len)
! 		(void)xfree(history[lasthist].histline);
! 	history[lasthist].len = strlen(line)+1;
! 	history[lasthist].histline = xmalloc(history[lasthist].len);
!     }
!     strcpy(history[lasthist].histline, line);
  }
  
  static	void
***************
*** 527,532
      strcpy(history[0], line);
  }
  
  back_hist()
  {
      if (histp == -1 || histp < HISTLEN-1 && history[histp + 1])

--- 589,595 -----
      strcpy(history[lasthist].histline, line);
  }
  
+ static	void
  back_hist()
  {
      if (histp == -1)
***************
*** 529,536
  
  back_hist()
  {
!     if (histp == -1 || histp < HISTLEN-1 && history[histp + 1])
! 	histp++;
  
      if (history[histp]) {
      	strcpy(line, history[histp]);

--- 592,607 -----
  static	void
  back_hist()
  {
!     if (histp == -1)
! 	histp = lasthist;
!     else
!     if (histp == 0)
!     {	if (endhist != lasthist)
! 		histp = endhist;
!     }
!     else
!     if (histp != ((lasthist + 1) % (endhist + 1)))
! 	histp--;
  
      if (lasthist < 0)
  	line[linelim = 0] = 0;
***************
*** 532,541
      if (histp == -1 || histp < HISTLEN-1 && history[histp + 1])
  	histp++;
  
!     if (history[histp]) {
!     	strcpy(line, history[histp]);
! 	linelim = 0;
!     } else
  	line[linelim = 0] = 0;
  
  }

--- 603,609 -----
      if (histp != ((lasthist + 1) % (endhist + 1)))
  	histp--;
  
!     if (lasthist < 0)
  	line[linelim = 0] = 0;
      else {
      	strcpy(line, history[histp].histline);
***************
*** 537,543
  	linelim = 0;
      } else
  	line[linelim = 0] = 0;
! 
  }
  
  search_hist()

--- 605,614 -----
  
      if (lasthist < 0)
  	line[linelim = 0] = 0;
!     else {
!     	strcpy(line, history[histp].histline);
! 	linelim = 0;
!     }
  }
  
  static	void
***************
*** 540,545
  
  }
  
  search_hist()
  {
      if (last_search) {

--- 611,617 -----
      }
  }
  
+ static	void
  search_hist()
  {
      if (last_search) {
***************
*** 553,559
  	return;
      }
  
!     last_search = strcpy(xmalloc((unsigned)(strlen(line+1)+1)), line+1);
      search_again();
      mode = EDIT_MODE;
  }

--- 625,631 -----
  	return;
      }
  
!     last_search = strcpy(xmalloc((unsigned)(strlen(line+1))), line+1);
      search_again();
      mode = EDIT_MODE;
  }
***************
*** 558,563
      mode = EDIT_MODE;
  }
  
  search_again()
  {
      int found_it;

--- 630,636 -----
      mode = EDIT_MODE;
  }
  
+ static	void
  search_again()
  {
      int found_it;
***************
*** 589,594
      } while (!found_it);
  }
  
  for_hist()
  {
      if (histp > 0)

--- 662,668 -----
      } while (!found_it);
  }
  
+ static	void
  for_hist()
  {
      if (histp == -1)
***************
*** 591,598
  
  for_hist()
  {
!     if (histp > 0)
!         histp--;
  
      if (histp >= 0 && history[histp]) {
      	strcpy(line, history[histp]);

--- 665,675 -----
  static	void
  for_hist()
  {
!     if (histp == -1)
! 	histp = lasthist;
!     else
!     if (histp != lasthist)
! 	histp = (histp + 1) % (endhist + 1);
  
      if (lasthist < 0)
  	line[linelim = 0] = 0;
***************
*** 594,603
      if (histp > 0)
          histp--;
  
!     if (histp >= 0 && history[histp]) {
!     	strcpy(line, history[histp]);
! 	linelim = 0;
!     } else
  	line[linelim = 0] = 0;
  }
  

--- 671,677 -----
      if (histp != lasthist)
  	histp = (histp + 1) % (endhist + 1);
  
!     if (lasthist < 0)
  	line[linelim = 0] = 0;
      else {
  	strcpy(line, history[histp].histline);
***************
*** 599,604
  	linelim = 0;
      } else
  	line[linelim = 0] = 0;
  }
  
  col_0()

--- 673,682 -----
  
      if (lasthist < 0)
  	line[linelim = 0] = 0;
+     else {
+ 	strcpy(line, history[histp].histline);
+ 	linelim = 0;
+     }
  }
  
  static	void
***************
*** 601,606
  	line[linelim = 0] = 0;
  }
  
  col_0()
  {
      linelim = 0;

--- 679,685 -----
      }
  }
  
+ static	void
  col_0()
  {
      linelim = 0;
***************
*** 606,611
      linelim = 0;
  }
  
  last_col()
  {
      linelim = strlen(line);

--- 685,691 -----
      linelim = 0;
  }
  
+ static	void
  last_col()
  {
      linelim = strlen(line);
***************
*** 613,618
  	--linelim;
  }
  
  find_char()
  {
      register int c;

--- 693,699 -----
  	--linelim;
  }
  
+ static	int
  find_char()
  {
      register int c;
***************
*** 628,633
      return(i);
  }
  
  to_char()
  {
      register int i;

--- 709,715 -----
      return(i);
  }
  
+ static	int
  to_char()
  {
      register int i;
*** 69/vmtbl.c	Thu Oct  4 09:17:32 1990
--- vmtbl.c	Fri Oct 26 16:58:30 1990
***************
*** 15,24
  extern	char	*malloc();
  extern	char	*realloc();
  
- #if defined(BSD42) || defined(BSD43)
- #define	memcpy(dest, source, len)	bcopy(source, dest, (unsigned int)len);
- #define	memset(dest, zero, len)		bzero((dest), (unsigned int)(len));
- #endif
  
  /*
   * check to see if *rowp && *colp are currently allocated, if not expand the

--- 15,20 -----
  extern	char	*malloc();
  extern	char	*realloc();
  
  
  /*
   * check to see if *rowp && *colp are currently allocated, if not expand the
***************
*** 84,89
  	struct ent ***tbl2;
  	int	*fwidth2;
  	int	*precision2;
  	char	*col_hidden2;
  	char	*row_hidden2;
  	int	newrows, newcols;

--- 80,86 -----
  	struct ent ***tbl2;
  	int	*fwidth2;
  	int	*precision2;
+ 	int     *realfmt2;
  	char	*col_hidden2;
  	char	*row_hidden2;
  	int	newrows, newcols;
***************
*** 151,156
  	{
  		GROWALLOC(fwidth2, fwidth, newcols, int, nowider);
  		GROWALLOC(precision2, precision, newcols, int, nowider);
  #ifdef PSC
  		memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int));
  		memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int));

--- 148,154 -----
  	{
  		GROWALLOC(fwidth2, fwidth, newcols, int, nowider);
  		GROWALLOC(precision2, precision, newcols, int, nowider);
+ 		GROWALLOC(realfmt2, realfmt, newcols, int, nowider);
  #ifdef PSC
  		memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int));
  		memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int));
***************
*** 154,159
  #ifdef PSC
  		memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int));
  		memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int));
  	}
  #else
  		GROWALLOC(col_hidden2, col_hidden, newcols, char, nowider);

--- 152,158 -----
  #ifdef PSC
  		memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int));
  		memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int));
+ 		memset(realfmt+maxcols, 0, (newcols-maxcols)*sizeof(int));
  	}
  #else
  		GROWALLOC(col_hidden2, col_hidden, newcols, char, nowider);
***************
*** 161,166
  		for (i = maxcols; i < newcols; i++) {
  			fwidth[i] = DEFWIDTH;
  			precision[i] = DEFPREC;
  		}
  
  		/* [re]alloc the space for each row */

--- 160,166 -----
  		for (i = maxcols; i < newcols; i++) {
  			fwidth[i] = DEFWIDTH;
  			precision[i] = DEFPREC;
+ 			realfmt[i]= DEFREFMT;
  		}
  
  		/* [re]alloc the space for each row */
*** 69/xmalloc.c	Thu Oct  4 09:17:35 1990
--- xmalloc.c	Fri Oct 26 16:58:32 1990
***************
*** 1,6
  /*
   * A safer saner malloc, for careless programmers
!  * $Revision: 6.8 $
   */
  
  #include <stdio.h>

--- 1,6 -----
  /*
   * A safer saner malloc, for careless programmers
!  * $Revision: 6.10 $
   */
  
  #include <stdio.h>
***************
*** 26,31
  return(ptr + sizeof(double));
  }
  
  xfree(p)
  char *p;
  {

--- 26,32 -----
  return(ptr + sizeof(double));
  }
  
+ void
  xfree(p)
  char *p;
  {
***************
*** 37,42
  free(p);
  }
  
  fatal(str)
  char *str;
  {

--- 38,44 -----
  free(p);
  }
  
+ void
  fatal(str)
  char *str;
  {
***************
*** 42,46
  {
      deraw();
      (void) fprintf(stderr,"%s\n", str);
      exit(1);
  }

--- 44,49 -----
  {
      deraw();
      (void) fprintf(stderr,"%s\n", str);
+     diesave();
      exit(1);
  }

wgb@balkan.TNT.COM (William G. Bunton) (10/28/90)

In article <1990Oct26.221849.16881@sawmill.uucp> buhrt@sawmill.uucp (Jeffery A Buhrt) writes:
>These are patches to Sc6.9 and fix core dumping plus adds some new features;
>see below for details.

It also seems to reference the symbol 'engformat', which is undefined
here (I presume it is supposed to be defined in the Sc source).  Did I
screw something up?

Bill
-- 
William G. Bunton              | An engineer is a man who can do for five bob
wgb@balkan.tnt.com             | what any bloody fool can do for a quid.
Tools & Techniques, Austin, TX |                        -- origin unknown

walker@hpl-opus.HP.COM (Rick Walker) (10/30/90)

I've been constantly watching the net looking for any new releases of
sc beyond sc.6.8.  The 6.8 version only worked long enough without
core dumping to make me drool over some of the new features like line
editing.

Now I am seeing patches from 6.9 -> 6.10.  How did I miss the 6.9 posting?
What group was it posted to?  Is there an ftp site that I can get it from?

Thanks!

--
Rick Walker
walker@hplabs

ant@brolga.cc.uq.oz.au (Anthony Murdoch) (10/31/90)

walker@hpl-opus.HP.COM (Rick Walker) writes:
>Now I am seeing patches from 6.9 -> 6.10.  How did I miss the 6.9 posting?
>What group was it posted to?  Is there an ftp site that I can get it from?

I had a fair bit of trouble applying both patches.  Is there somewhere that
I can get the source with the patches applied via ftp ?

ant

-- 
  V   ant                       "It's great to be young and insane"
 \o/  ant@brolga.cc.uq.oz.au                    - Dream Team
 -O-  Anthony Murdoch           Prentice Computer Centre
 /0\  Phone (07) 3774078        University of Qld

dave@convex.csd.uwm.edu (David A Rasmussen) (10/31/90)

Where can I get the full current distribution of SC?
I can ftp it from somewhere, or you can leave it in my ftp directory here
I suppose. Thanks in advance to anyone.

-- 
Internet:dave@uwm.edu, Uucp:uwm!dave, Bitnet:dave%uwm.edu@INTERBIT
AT&T:414-229-5133 USnail:Dave Rasmussen-CSD,Box 413 EMS380,Milwaukee,WI 53201

marc@dumbcat.sf.ca.us (Marco S Hyman) (11/02/90)

In article <7326@uwm.edu> dave@convex.csd.uwm.edu writes:
    Where can I get the full current distribution of SC?

Several have asked the same question.  It's not ftp, but you can anonymously
UUCP sc (and a few other things) from dumbcat.  Login info follows.

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

To reduce disk usage the dumbcat archives are compressed and split tar
files.  Most tar files over 128000 bytes long (emacs, for example) are split
into 128000 byte chunks.  Grab all of the chunks, cat them into one
compressed tar file, uncompress, and un-tar.  With gnu tar you can do
something like

	[uucp smail-01 and smail-02]
	cat smail-{01,02} | tar xzvf -

which uncompresses and untars the archive in one step without requiring
copious amounts of disk space or worrying about proper ulimits.

NOTE: The files live in the directory ~src NOT ~.  A typical UUCP command
would be:

      uucp dumbcat\!~src/file.Z file.Z

dumbcat UUCP info:  Add one of the following to your L.sys/Systems file:

    dumbcat Any ACU 9600 14157850194 "" \d\r in:--in: nuucp word: guest
    dumbcat Any ACU 2400 14157850194 "" \d\r in:-BREAK-in: nuucp word: guest
    dumbcat Any ACU 1200 14157850194 "" \d\r in:-BREAK-in:-BREAK-in: nuucp word: guest

Note: dumbcat speaks 9600 at V.32 -- sorry, this is not a Telebit modem.

(Grab dumbcat!~/INDEX for a complete list)

~src/sc-01		Spreadsheet calculator version 6.10
thru sc-02		153495 bytes -- last part is 25495 bytes

// marc
-- 
// marc@dumbcat.sf.ca.us
// {ames,decwrl,sun}!pacbell!dumbcat!marc