Official Sc6.9 -> Sc6.10 patches (Please Apply) (2 of 2)

Jeffery A Buhrt buhrt at sawmill.uucp
Sat Oct 27 08:20:13 AEST 1990


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);
  }



More information about the Comp.sources.bugs mailing list