[net.sources] vc hacks

bernerus@chalmers.UUCP (Christer Bernerus) (03/08/85)

The number of requests for the vc hacks was amazing! Here they are,
the bug reports published on the net was installed befor I started my
hacking, so you might have to fix those bugs first.

I also corrected a bug that caused all constants to be set to zero when
a line was copied with ^J.

Chris.
-----------------------------------------------------------------------
*** /tmp/,RCSt1009610	Fri Mar  8 14:54:45 1985
--- gram.y	Fri Mar  8 14:48:33 1985
***************
*** 44,73
  %token S_PROGLET
  %token K_EXEC
  %token K_FIXED
- %token K_EXP
- %token K_LOG
- %token K_LOGD
- %token K_POW
- %token K_SQRT
- %token K_FIXED
- %token K_FLOOR
- %token K_CEIL
- %token K_HYPOT
- %token K_FABS
- %token K_SIN
- %token K_COS
- %token K_ASIN
- %token K_ACOS
- %token K_ATAN
- %token K_ATANII
- %token K_DTR
- %token K_RTD
- %token K_SINH
- %token K_COSH
- %token K_TANH
- %token K_PI
- %token K_MAX
- %token K_MIN
  %token K_R
  %token K_C
  

--- 44,49 -----
  %token S_PROGLET
  %token K_EXEC
  %token K_FIXED
  %token K_R
  %token K_C
  
***************
*** 76,83
  %left '&'
  %nonassoc '<' '=' '>'
  %left '+' '-'
! %left '*' '/' '%'
! %left '^'
  
  %%
  command:	S_LET var '=' e	{ let ($2, $4); }

--- 52,58 -----
  %left '&'
  %nonassoc '<' '=' '>'
  %left '+' '-'
! %left '*' '/'
  
  %%
  command:	S_LET var '=' e	{ let ($2, $4); }
***************
*** 118,124
  	|	'-' term	{ $$ = new ('m', 0, $2); }
  	|	NUMBER		{ $$ = new ('k', (double) $1); }
  	|	FNUMBER		{ $$ = new ('k', $1); }
- 	|	K_PI		{ $$ = new ('X',0,0); }
  	|	'~' term	{ $$ = new ('~', 0, $2); }
  	|	'!' term	{ $$ = new ('~', 0, $2); }
  	;

--- 93,98 -----
  	|	'-' term	{ $$ = new ('m', 0, $2); }
  	|	NUMBER		{ $$ = new ('k', (double) $1); }
  	|	FNUMBER		{ $$ = new ('k', $1); }
  	|	'~' term	{ $$ = new ('~', 0, $2); }
  	|	'!' term	{ $$ = new ('~', 0, $2); }
  	;
***************
*** 127,134
  	|	e '-' e		{ $$ = new ('-', $1, $3); }
  	|	e '*' e		{ $$ = new ('*', $1, $3); }
  	|	e '/' e		{ $$ = new ('/', $1, $3); }
- 	|	e '%' e		{ $$ = new ('%', $1, $3); }
- 	|	e '^' e		{ $$ = new ('^', $1, $3); }
  	|	term
  	|	e '?' e ':' e	{ $$ = new ('?', $1, new(':', $3, $5)); }
  	|	e '<' e		{ $$ = new ('<', $1, $3); }

--- 101,106 -----
  	|	e '-' e		{ $$ = new ('-', $1, $3); }
  	|	e '*' e		{ $$ = new ('*', $1, $3); }
  	|	e '/' e		{ $$ = new ('/', $1, $3); }
  	|	term
  	|	e '?' e ':' e	{ $$ = new ('?', $1, new(':', $3, $5)); }
  	|	e '<' e		{ $$ = new ('<', $1, $3); }
***************
*** 139,172
  	|	e '<' '=' e	{ $$ = new ('~', 0, new ('>', $1, $4)); }
  	|	e '!' '=' e	{ $$ = new ('~', 0, new ('=', $1, $4)); }
  	|	e '>' '=' e	{ $$ = new ('~', 0, new ('<', $1, $4)); }
- 	|	K_EXP '(' e ')' { $$ = new ('E', 0, $3);}
- 	|	K_LOG '(' e ')' { $$ = new ('N', 0, $3);}
- 	|	K_LOGD '(' e ')'{ $$ = new ('L', 0, $3);}
- 	|	K_POW '(' e ',' e ')'
- 				{ $$ = new ('P', $5, $3);}
- 	|	K_SQRT '(' e ')'{ $$ = new ('Q', 0, $3);}
- 	|	K_FLOOR '(' e ')'
- 				{ $$ = new ('F', 0, $3);}
- 	|	K_CEIL '(' e ')'{ $$ = new ('C', 0, $3);}
- 	|	K_FABS '(' e ')'{ $$ = new ('A', 0, $3);}
- 	|	K_HYPOT '(' e ',' e ')'
- 				{ $$ = new ('H', $5, $3);}
- 	|	K_SIN '(' e ')' { $$ = new ('S', 0, $3);}
- 	|	K_COS '(' e ')' { $$ = new ('T', 0, $3);}
- 	|	K_ASIN '(' e ')'{ $$ = new ('B', 0, $3);}
- 	|	K_ACOS '(' e ')'{ $$ = new ('U', 0, $3);}
- 	|	K_ATAN '(' e ')'{ $$ = new ('I', 0, $3);}
- 	|	K_ATANII '(' e ',' e ')'
- 				{ $$ = new ('J', $5, $3);}
- 	|	K_DTR '(' e ')' { $$ = new ('R', 0, $3);}
- 	|	K_RTD '(' e ')' { $$ = new ('D', 0, $3);}
- 	|	K_SINH '(' e ')'{ $$ = new ('K', 0, $3);}
- 	|	K_COSH '(' e ')'{ $$ = new ('M', 0, $3);}
- 	|	K_TANH '(' e ')'{ $$ = new ('O', 0, $3);}
- 	|	K_MAX '(' e ',' e ')'
- 				{ $$ = new ('V', $5, $3);}
- 	|	K_MIN '(' e ',' e ')'
- 				{ $$ = new ('W', $5, $3);}
  	;
  
  row:		K_R NUMBER	{ $$ = $2; };

--- 111,116 -----
  	|	e '<' '=' e	{ $$ = new ('~', 0, new ('>', $1, $4)); }
  	|	e '!' '=' e	{ $$ = new ('~', 0, new ('=', $1, $4)); }
  	|	e '>' '=' e	{ $$ = new ('~', 0, new ('<', $1, $4)); }
  	;
  
  row:		K_R NUMBER	{ $$ = $2; };
*** /tmp/,RCSt1009610	Fri Mar  8 14:54:52 1985
--- interp.c	Fri Mar  8 14:52:10 1985
***************
*** 8,14
  
  #include "sc.h"
  #include <stdio.h>
- #include <math.h>
  #define DEFCOLDELIM ':'
  
  double pi(),dtr(),rtd();

--- 8,13 -----
  
  #include "sc.h"
  #include <stdio.h>
  #define DEFCOLDELIM ':'
  
  char *malloc();
***************
*** 11,17
  #include <math.h>
  #define DEFCOLDELIM ':'
  
- double pi(),dtr(),rtd();
  char *malloc();
  
  double eval(e)

--- 10,15 -----
  #include <stdio.h>
  #define DEFCOLDELIM ':'
  
  char *malloc();
  
  double eval(e)
***************
*** 35,74
  	case '~':	return (!eval(e->e.o.right));
  	case 'k':	return (e->e.k);
  	case 'v':	return (e->e.v->v);
- 	case 'E':	return (exp(eval(e->e.o.right)));
- 	case 'N':	return (log(eval(e->e.o.right)));
- 	case 'L':	return (log10(eval(e->e.o.right)));
- 	case 'P':	return (pow(eval(e->e.o.right),eval(e->e.o.left)));
- 	case 'Q':	return (sqrt(eval(e->e.o.right)));
- 	case 'F':	return (floor(eval(e->e.o.right)));
- 	case 'C':	return (ceil(eval(e->e.o.right)));
- 	case 'A':	return (fabs(eval(e->e.o.right)));
- 	case 'H':	return (hypot(eval(e->e.o.right),eval(e->e.o.left)));
- 	case 'S':	return (sin(eval(e->e.o.right)));
- 	case 'T':	return (cos(eval(e->e.o.right)));
- 	case 'B':	return (asin(eval(e->e.o.right)));
- 	case 'U':	return (acos(eval(e->e.o.right)));
- 	case 'I':	return (atan(eval(e->e.o.right)));
- 	case 'J':	return (atan2(eval(e->e.o.right),eval(e->e.o.left)));
- 	case 'R':	return (dtr(eval(e->e.o.right)));
- 	case 'D':	return (rtd(eval(e->e.o.right)));
- 	case 'K':	return (sinh(eval(e->e.o.right)));
- 	case 'M':	return (cosh(eval(e->e.o.right)));
- 	case 'O':	return (tanh(eval(e->e.o.right)));
- 	case 'V':       {
- 			  register double left,right;
- 			  left = eval(e->e.o.left);
- 			  right= eval(e->e.o.right);
- 			  return left>right?left:right;
- 			}
- 	case 'W':       {
- 			  register double left,right;
- 			  left = eval(e->e.o.left);
- 			  right= eval(e->e.o.right);
- 			  return left<right?left:right;
- 			}
- 	case 'X':	return pi();
- 	case '^':	return (pow(eval(e->e.o.left), eval(e->e.o.right)));
  	case 'p':	return (executeprogram(e));
  	case O_REDUCE('+'):
  	case O_REDUCE('*'):

--- 33,38 -----
  	case '~':	return (!eval(e->e.o.right));
  	case 'k':	return (e->e.k);
  	case 'v':	return (e->e.v->v);
  	case 'p':	return (executeprogram(e));
  	case O_REDUCE('+'):
  	case O_REDUCE('*'):
***************
*** 103,122
  
  #define MAXPROP 7
  
- double pi()
- {
- 	return 3.14159265358979323846264338327950288419716939937511;
- }
- double dtr(x) double x;
- {
- 	return (pi() * x / 180.0);
- }
- double rtd(x) double x;
- {
- 	return (180.0 * x /  pi());
- }
- 
- 
  EvalAll () {
      int lastct,repct = 0;
  

--- 67,72 -----
  
  #define MAXPROP 7
  
  EvalAll () {
      int lastct,repct = 0;
  
***************
*** 254,259
  	}
  	if (mypriority<priority) line[linelim++] = '(';
  	switch (e->op) {
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;

--- 204,218 -----
  	}
  	if (mypriority<priority) line[linelim++] = '(';
  	switch (e->op) {
+ 	case 'f':	{   register char *s;
+ 			    for (s="fixed "; line[linelim++] = *s++;);
+ 			    linelim--;
+ 			    decompile (e->e.o.right, 30);
+ 			    break;
+ 			}
+ 	case 'm':	line[linelim++] = '-';
+ 			decompile (e->e.o.right, 30);
+ 			break;
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;
***************
*** 257,262
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;
  	case O_REDUCE('+'):
  	case O_REDUCE('*'):
  			line[linelim++] = e->op&0177;

--- 216,226 -----
  	case '~':	line[linelim++] = '~';
  			decompile (e->e.o.right, 30);
  			break;
+ 	case 'v':	decodev (e->e.v);
+ 			break;
+ 	case 'k':	sprintf (line+linelim,"%g",e->e.k);
+ 			linelim += strlen (line+linelim);
+ 			break;
  	case O_REDUCE('+'):
  	case O_REDUCE('*'):
  			line[linelim++] = e->op&0177;
***************
*** 291,456
  			line[linelim++] = ')';
  			break;
  			}
- #define emit(x) for(s=x;line[linelim++] = *s++;);linelim--
- 	case 'f':	{   register char *s;
- 			    emit("fixed ");
- 			    decompile (e->e.o.right, 30);
- 			    break;
- 	 		}
- 	case 'E':	{   register char *s;
- 			    emit("EXP(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'N':	{   register char *s;
- 			    emit("LOG(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'L':	{   register char *s;
- 			    emit("LOGD(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'P':	{   register char *s;
- 			    emit("POW(");
- 			    decompile(e->e.o.right, 30);
-   			    emit(",");
- 			    decompile(e->e.o.left,30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'Q':	{   register char *s;
- 			    emit("SQRT(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'F':	{   register char *s;
- 			    emit("FLOOR(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'C':	{   register char *s;
- 			    emit("CEIL(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'A':	{   register char *s;
- 			    emit("FABS(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'H':	{   register char *s;
- 			    emit("HYPOT(");
- 			    decompile(e->e.o.right, 30);
-   			    emit(",");
- 			    decompile(e->e.o.left,30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'S':	{   register char *s;
- 			    emit("SIN(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'T':	{   register char *s;
- 			    emit("COS(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'B':	{   register char *s;
- 			    emit("ASIN(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'U':	{   register char *s;
- 			    emit("ACOS(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'I':	{   register char *s;
- 			    emit("ATAN(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'J':	{   register char *s;
- 			    emit("ATANII(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(",");
- 			    decompile (e->e.o.left, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'R':	{   register char *s;
- 			    emit("DTR(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'D':	{   register char *s;
- 			    emit("RTD(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'K':	{   register char *s;
- 			    emit("SINH(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'M':	{   register char *s;
- 			    emit("COSH(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'O':	{   register char *s;
- 			    emit("TANH(");
- 			    decompile (e->e.o.right, 30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'V':	{   register char *s;
- 			    emit("MAX(");
- 			    decompile(e->e.o.right, 30);
-   			    emit(",");
- 			    decompile(e->e.o.left,30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'W':	{   register char *s;
- 			    emit("MIN(");
- 			    decompile(e->e.o.right, 30);
-   			    emit(",");
- 			    decompile(e->e.o.left,30);
- 			    emit(")");
- 			    break;
- 	 		}
- 	case 'X':	{   register char *s;
- 			    emit("PI");
- 			    break;
- 			}
- 	case 'm':	line[linelim++] = '-';
- 			decompile (e->e.o.right, 30);
- 			break;
- 	case 'v':	decodev (e->e.v);
- 			break;
- 	case 'k':	sprintf (line+linelim,"%g",e->e.k);
- 			linelim += strlen (line+linelim);
- 			break;
  	default:	decompile (e->e.o.left, mypriority);
  			line[linelim++] = e->op;
  			decompile (e->e.o.right, mypriority+1);

--- 255,260 -----
  			line[linelim++] = ')';
  			break;
  			}
  	default:	decompile (e->e.o.left, mypriority);
  			line[linelim++] = e->op;
  			decompile (e->e.o.right, mypriority+1);
***************
*** 574,580
  		ret->e.v = lookat (e->e.v->row+Rdelta, e->e.v->col+Cdelta);
  		break;
  	case 'k':
- 		ret->e.k = e->e.k;
  		break;
  	case 'f':
  		ret->e.o.right = copye (e->e.o.right,0,0);

--- 378,383 -----
  		ret->e.v = lookat (e->e.v->row+Rdelta, e->e.v->col+Cdelta);
  		break;
  	case 'k':
  		break;
  	case 'f':
  		ret->e.o.right = copye (e->e.o.right,0,0);
*** /tmp/,RCSt1009610	Fri Mar  8 14:55:01 1985
--- lex.c	Fri Mar  8 14:52:11 1985
***************
*** 94,105
  	if (*p) p++;
  	linelim = p-line;
  	return yylex();
!     } else if(*p == '*' && *(p+1) == '*')
! 	{
! 		ret = '^';
! 		p+=2;
! 	}
!     else ret = *p++;
      linelim = p-line;
      return ret;
  }

--- 94,100 -----
  	if (*p) p++;
  	linelim = p-line;
  	return yylex();
!     } else ret = *p++;
      linelim = p-line;
      return ret;
  }
***************
*** 108,114
  int dbline;
  
  debug (fmt, a, b, c) {
! 	mvprintw (1+(dbline++%23),14,fmt,a,b,c);
  	clrtoeol();
  }
  

--- 103,109 -----
  int dbline;
  
  debug (fmt, a, b, c) {
! 	mvprintw (2+(dbline++%22),40,fmt,a,b,c);
  	clrtoeol();
  }
  
***************
*** 112,119
  	clrtoeol();
  }
  
! help ()
! {
      dbline = 0;
      debug (" ***** Functions  ****** *********** Commands ********************");
      debug (" EXP(e) exponential      j,^N next row        k,^P previous row");

--- 107,113 -----
  	clrtoeol();
  }
  
! help () {
      dbline = 0;
  /*	   "====================!===================" */
      debug ("|^N next row         ^P previous row");
***************
*** 115,141
  help ()
  {
      dbline = 0;
!     debug (" ***** Functions  ****** *********** Commands ********************");
!     debug (" EXP(e) exponential      j,^N next row        k,^P previous row");
!     debug (" LOG(e) natural log      ^A type var value    ^E type var expr");
!     debug (" LOGD(e) Base 10 log     l,^F next column     h,^B previous column");
!     debug (" POW(e,e) power function ^R redraw screen     ?  help (this msg)");
!     debug (" SQRT(e) square root     ^C exit              ^G erase command");
!     debug (" FLOOR(e) last integer   DEL,^H erase char    ^L fix screen");
!     debug (" CEIL(e)  next integer   ^J open new row      ^V type var name");
!     debug (" FABS(e) absolute value  =  enter new value   ?  help (this msg)");
!     debug (" HYPOT(e,e) trig. dist.  \"  label             e  edit value");
!     debug (" PI value of pi.         <  left flush str    >  right flush str");
!     debug (" SIN(e) sine function    g  get database      p  put database");
!     debug (" COS(e) cosine function  w  write listing     f  set format");
!     debug (" ATAN(e) arc tangent     O,r  open row here   c  open col here");
!     debug (" ATANII(e,e) arc tangent C  clear entry       T  write tbl fmt");
!     debug (" DTR(e) degrees to rad.  d  delete this row   D  delete this col");
!     debug (" RTD(e) rad. to degrees  E  edit string       M  merge in database");
!     debug (" SINH(e) sine hyp fnc    ***************operators*****************");
!     debug (" COSH(e) cosine hyp fnc  +,-,*,/  add,subtract,multiply,divide");
!     debug (" TANH(e) tangent hyp     e%%e   modulo op      e**e  power op.");
!     debug (" MAX(e,e) maximum fnc    +/v:v sum region      e^e   power op.");
!     debug (" MIN(e,e) minimum fnc    */v:v multiply region e?e:e conditional");
!     debug ("                         <,=,>,<=,>= relations &,| booleans");
  }

--- 109,135 -----
  
  help () {
      dbline = 0;
! /*	   "====================!===================" */
!     debug ("|^N next row         ^P previous row");
!     debug ("|^F next column      ^B previous column");
!     debug ("|^C exit             ^G erase command");
!     debug ("|DEL,^H erase char   ^L fix screen");
!     debug ("|^J open new row     ^V type var name");
!     debug ("|^A type var value   ^E type var expr");
!     debug ("|^R redraw screen    ?  help (this msg)");
!     debug ("|");
!     debug ("|=  enter new value  C  clear entry");
!     debug ("|\"  label            f  set format");
!     debug ("|<  left flush str   >  right flush str");
!     debug ("|g  get database     p  put database");
!     debug ("|w  write listing    T  write tbl fmt");
!     debug ("|r  open row here    c  open col here");
!     debug ("|d  delete this row  D  delete this col");
!     debug ("|E  edit string      e  edit value");
!     debug ("|M  merge in database");
!     debug ("|");
!     debug ("| ***operators***");
!     debug ("|+,-,*,/   add,subtract,multiply,divide");
!     debug ("|+/v:v sum region     e?e:e conditional");
!     debug ("|<,=,>,<=,>= relations  &,| booleans");
  }
No differences encountered
*** /tmp/,RCSt1009610	Fri Mar  8 14:55:10 1985
--- sc.c	Fri Mar  8 14:52:15 1985
***************
*** 35,42
  int seenerr;
  
  yyerror (err)
! char *err;
! {
      if (seenerr) return;
      seenerr++;
      move (1,0);

--- 35,41 -----
  int seenerr;
  
  yyerror (err)
! char *err; {
      if (seenerr) return;
      seenerr++;
      move (1,0);
***************
*** 44,51
      printw ("%s: %.*s<=%s",err,linelim,line,line+linelim);
  }
  
! struct ent *lookat(row,col)
! {
      register struct ent **p = &tbl[row][col];
      if (*p==0) {
  	*p = (struct ent *) malloc (sizeof (struct ent));

--- 43,49 -----
      printw ("%s: %.*s<=%s",err,linelim,line,line+linelim);
  }
  
! struct ent *lookat(row,col){
      register struct ent **p = &tbl[row][col];
      if (*p==0) {
  	*p = (struct ent *) malloc (sizeof (struct ent));
***************
*** 60,67
      return *p;
  }
  
! update ()
! {
      register    row,
                  col;
      register struct ent **p;

--- 58,64 -----
      return *p;
  }
  
! update () {
      register    row,
                  col;
      register struct ent **p;
***************
*** 105,111
  		if ((*p) -> flags & is_valid)
  		    printw ("%*.*f", fwidth[col], precision[col], (*p) -> v);
  		if (s = (*p) -> label) {
! /*		    char field[1024];
  
  		    strncpy(field,s,fwidth[col]);
  		    field[fwidth[col]] = 0; */

--- 102,108 -----
  		if ((*p) -> flags & is_valid)
  		    printw ("%*.*f", fwidth[col], precision[col], (*p) -> v);
  		if (s = (*p) -> label) {
! 		    char field[1024];
  
  		    strncpy(field,s,fwidth[col]);
  		    field[fwidth[col]] = 0;
***************
*** 108,114
  /*		    char field[1024];
  
  		    strncpy(field,s,fwidth[col]);
! 		    field[fwidth[col]] = 0; */
  		    mvaddstr (r,
  			    (*p) -> flags & is_leftflush
  			    ? c : c - strlen (/* field*/ s) + fwidth[col],

--- 105,111 -----
  		    char field[1024];
  
  		    strncpy(field,s,fwidth[col]);
! 		    field[fwidth[col]] = 0;
  		    mvaddstr (r,
  			    (*p) -> flags & is_leftflush
  			    ? c : c - strlen (field) + fwidth[col],
***************
*** 111,118
  		    field[fwidth[col]] = 0; */
  		    mvaddstr (r,
  			    (*p) -> flags & is_leftflush
! 			    ? c : c - strlen (/* field*/ s) + fwidth[col],
! 			    /*field*/ s);
  		}
  	    }
  	    c += fwidth[col];

--- 108,115 -----
  		    field[fwidth[col]] = 0;
  		    mvaddstr (r,
  			    (*p) -> flags & is_leftflush
! 			    ? c : c - strlen (field) + fwidth[col],
! 			    field);
  		}
  	    }
  	    c += fwidth[col];
***************
*** 423,429
  			    editv (currow, curcol);
  			    break;
  			case 'E':
- 			    instring = 1;
  			    edits (currow, curcol);
  			    break;
  			case 'f':

--- 420,425 -----
  			    editv (currow, curcol);
  			    break;
  			case 'E':
  			    edits (currow, curcol);
  			    break;
  			case 'f':
***************
*** 534,543
      endwin ();
  }
  
! modcheck(endstr) char *endstr;
! {
!     char ch, lin[100];
! 
      if (modflg && curfile[0]) {
  
  	move(0, 0);

--- 530,536 -----
      endwin ();
  }
  
! modcheck(endstr) char *endstr; {
      if (modflg && curfile[0]) {
  	char ch, lin[100];
  
***************
*** 539,544
      char ch, lin[100];
  
      if (modflg && curfile[0]) {
  
  	move(0, 0);
  	clrtoeol();

--- 532,538 -----
  
  modcheck(endstr) char *endstr; {
      if (modflg && curfile[0]) {
+ 	char ch, lin[100];
  
  	move (0, 0);
  	clrtoeol ();
***************
*** 540,549
  
      if (modflg && curfile[0]) {
  
! 	move(0, 0);
! 	clrtoeol();
! 	sprintf(lin,"File '%s' is modified, save%s? ",curfile,endstr);
! 	addstr(lin);
  	refresh();
  	ch = nmgetch();
  	if (ch == 'y' || ch == 'Y') writefile(curfile);

--- 534,543 -----
      if (modflg && curfile[0]) {
  	char ch, lin[100];
  
! 	move (0, 0);
! 	clrtoeol ();
! 	sprintf (lin,"File '%s' is modified, save%s? ",curfile,endstr);
! 	addstr (lin);
  	refresh();
  	ch = nmgetch();
  	if (ch == 'y' || ch == 'Y') writefile(curfile);
***************
*** 549,565
  	if (ch == 'y' || ch == 'Y') writefile(curfile);
  	else if (ch == ctl (g)) return(1);
      }
-     if (modflg && (curfile[0] == '\0'))
-     {
- 	move(0,0);
- 	clrtoeol();
- 	sprintf(lin,"You have changed the spreadsheet, sure you don't want to save%s",endstr);
- 	addstr(lin);
- 	refresh();
- 	ch = nmgetch();
- 	if (ch == 'y' || ch == 'Y') return 0;
- 	else if (ch == ctl (g)) return(1);
-      }
      return(0);
  }
      

--- 543,548 -----
  	if (ch == 'y' || ch == 'Y') writefile(curfile);
  	else if (ch == ctl (g)) return(1);
      }
      return(0);
  }
      
*** /tmp/,RCSt1009758	Fri Mar  8 15:02:09 1985
--- vc.1	Fri Mar  8 15:00:53 1985
***************
*** 26,32
  The following single control character commands are recognized no matter
  where the character cursor is.
  
! .IP "^N or j"
  Move the entry cursor to the next row.
  
  .IP "^P or k"

--- 26,32 -----
  The following single control character commands are recognized no matter
  where the character cursor is.
  
! .IP ^N
  Move the entry cursor to the next row.
  
  .IP ^P
***************
*** 29,35
  .IP "^N or j"
  Move the entry cursor to the next row.
  
! .IP "^P or k"
  Move the entry cursor to the previous row.
  
  .IP "^F or l"

--- 29,35 -----
  .IP ^N
  Move the entry cursor to the next row.
  
! .IP ^P
  Move the entry cursor to the previous row.
  
  .IP ^F
***************
*** 32,38
  .IP "^P or k"
  Move the entry cursor to the previous row.
  
! .IP "^F or l"
  Move the entry cursor forward one column.
  
  .IP "^B or h"

--- 32,38 -----
  .IP ^P
  Move the entry cursor to the previous row.
  
! .IP ^F
  Move the entry cursor forward one column.
  
  .IP ^B
***************
*** 35,41
  .IP "^F or l"
  Move the entry cursor forward one column.
  
! .IP "^B or h"
  Move the entry cursor backward one column.
  
  .IP ^C

--- 35,41 -----
  .IP ^F
  Move the entry cursor forward one column.
  
! .IP ^B
  Move the entry cursor backward one column.
  
  .IP ^C
***************
*** 93,98
  are the same.  That is, when no long command is being entered.  Most of them
  introduce a new long command.
  
  .IP Q
  Alternate exit command.
  

--- 93,101 -----
  are the same.  That is, when no long command is being entered.  Most of them
  introduce a new long command.
  
+ .IP "h, j, k, l"
+ Alternate cursor controls (left, down, up, right).
+ 
  .IP Q
  Alternate exit command.
  
***************
*** 105,111
  Clears the current entry as if there were none.
  
  .IP ?
! Types a helpful message.
  
  .IP """
  Enter a label for the current entry.

--- 108,114 -----
  Clears the current entry as if there were none.
  
  .IP ?
! Types a brief helpful message.
  
  .IP """
  Enter a label for the current entry.
***************
*** 182,190
  conventional syntax.  Terms may be variable names (from the ^V command),
  parenthesised expressions, negated terms, and constants.  The +/ term sums
  values in rectangular regions of the table (the notation +/ is reminiscent
! of apl's additive reduction.)  The */ multiplies values in a region.
! Terms may be combined using many binary
! operators.  Their precedences (from highest to lowest) are: **,^; *,/,%; +,-;
  <,=,>,<=,>=; &; |; ?.
  
  .TP 15

--- 185,192 -----
  conventional syntax.  Terms may be variable names (from the ^V command),
  parenthesised expressions, negated terms, and constants.  The +/ term sums
  values in rectangular regions of the table (the notation +/ is reminiscent
! of apl's additive reduction.)  Terms may be combined using many binary
! operators.  Their precedences (from highest to lowest) are: *,/; +,-;
  <,=,>,<=,>=; &; |; ?.
  
  .TP 15
***************
*** 211,224
  Division.
  
  .TP 15
- e%e
- Remainder (as in C);
- 
- .TP 15
- e**e or e^e
- Power function.
- 
- .TP 15
  +/v:v
  Sum all valid (nonblank) entries in the region whose two corners are defined
  by the two variable (entry) names given.

--- 213,218 -----
  Division.
  
  .TP 15
  +/v:v
  Sum all valid (nonblank) entries in the region whose two corners are defined
  by the two variable (entry) names given.
***************
*** 224,234
  by the two variable (entry) names given.
  
  .TP 15
- */v:v
- Multiply all valid (nonblank) entries in the region whose two corners are defined
- by the two variable (entry) names given.
- 
- .TP 15
  e?e:e
  Conditional: If the first expression is true then the value of the second is
  returned, otherwise the value of the third is.

--- 218,223 -----
  by the two variable (entry) names given.
  
  .TP 15
  e?e:e
  Conditional: If the first expression is true then the value of the second is
  returned, otherwise the value of the third is.
***************
*** 242,248
  Boolean connectives.
  
  .TP 15
- fixed
  To make a variable not change automatically when a row is duplicated with
  ^J, put the word \*(lqfixed\*(rq in front of it.  I.e.
  r2c1*fixed r3c1 

--- 231,236 -----
  Boolean connectives.
  
  .TP 15
  To make a variable not change automatically when a row is duplicated with
  ^J, put the word \*(lqfixed\*(rq in front of it.  I.e.
  r2c1*fixed r3c1 
***************
*** 247,335
  ^J, put the word \*(lqfixed\*(rq in front of it.  I.e.
  r2c1*fixed r3c1 
  
- .SH "MATHEMATICAL FUNCTIONS"
- A number of mathematical functions have been built into the calculator.
- All of them operates on float numbers (double), the trig functions operate
- with angles in radians.
- .TP 15
- EXP(expr)
- Returns exponential function of <expr>.
- 
- .TP 15
- LOG(expr)
- Returns the natural logarithm of <expr>.
- 
- .TP 15
- LOGD(expr)
- Returns the base 10 logarithm of <expr>.
- 
- .TP 15
- POW(expr1,expr2)
- Returns <expr1> raised to the power of <expr2>.
- 
- .TP 15
- FLOOR(expr)
- Returns returns the largest integer not greater than <expr>.
- 
- .TP 15
- CEIL(expr)
- Returns the smallest integer not less than <expr>.
- 
- .TP 15
- HYPOT(x,y)
- Returns SQRT(x*x+y*y), taking precautions against unwarranted overflows.
- 
- .TP 15
- FABS(expr)
- Returns the absolute value |expr|.
- 
- .TP 15
- SIN(expr) and COS(expr)
- Return trigonometric functions of radian arguments. The magnitude of the
- arguments are not checked to assure meaningful results.
- 
- .TP 15
- ASIN(expr)
- Returns the arc sin in the range -\(*p/2 to \(*p/2
- 
- .TP 15
- ACOS(expr)
- Returns the arc cosine in the range 0 to \(*p.
- 
- .TP 15
- ATAN(expr)
- Returns the arc tangent of <expr> in the range -\(*p/2 to \(*p/2.
- 
- .TP 15
- ATANII(x,y)
- Returns the arc tangent of x/y in the range -\(*p to \(*p.
- 
- .TP 15
- DTR(expr)
- Converts <expr> in degrees to radians.
- 
- .TP 15
- RTD(expr)
- Converts <expr> in radians to degrees.
- 
- .TP 15
- SINH(expr), COSH(expr), TANH(expr)
- These functions return their designated hyperbolic functions.
- 
- .TP 15
- PI
- A constant quite close to \(*p.
- 
- .TP 15
- MAX(expr1,expr2)
- Returns the largest value of the two expressions;
- 
- .TP 15
- MIN(expr1,expr2)
- Returns the smallest value of the two expressions;
- 
- 
- 
  .SH FILES
  expense.sc \- a sample expense report.
  

--- 235,240 -----
  ^J, put the word \*(lqfixed\*(rq in front of it.  I.e.
  r2c1*fixed r3c1 
  
  .SH FILES
  expense.sc \- a sample expense report.
  
***************
*** 334,341
  expense.sc \- a sample expense report.
  
  .SH SEE ALSO
! bc(1), dc(1), the VisiCalc or T/Maker manuals, exp(3m), floor(3m),
! hypot(3m), sin(3m), sinh(3m).
  
  .SH BUGS
  

--- 239,245 -----
  expense.sc \- a sample expense report.
  
  .SH SEE ALSO
! bc(1), dc(1), the VisiCalc or T/Maker manuals.
  
  .SH BUGS
  There should be a */ operator.
***************
*** 338,343
  hypot(3m), sin(3m), sinh(3m).
  
  .SH BUGS
  
  Expression reevaluation is done in the same top-to-bottom, left-to-right
  manner as is done in other spreadsheet calculators.  This is silly.  A

--- 242,248 -----
  bc(1), dc(1), the VisiCalc or T/Maker manuals.
  
  .SH BUGS
+ There should be a */ operator.
  
  Expression reevaluation is done in the same top-to-bottom, left-to-right
  manner as is done in other spreadsheet calculators.  This is silly.  A

bernerus@chalmers.UUCP (Christer Bernerus) (03/11/85)

Some comments about the vc hacks recently posted:

1.	You have to modify your makefile to compile with the -lm flag.

2.	I have commented out the code that enforced the column format on
	strings, since I found the previous "bug" in sc very handy.

3.	Mark Weiser at seismo { ..seismo!mark} is  collecting suggested
	hacks and I hope he will redistribute a new version soon.

4.	If you don't want the hjkl cursor control keys, you might be able
	to remove te pieces of code that implement it. Look for the variable
	"instring" in sc.c. Somebody (Mark ?) might put in some #ifdef's
	to make it easier. If the hjkl keys isn't used, the functions could
	have been written in lower case. I am aware that 

6.	There is a bug that doesn't give you any chance when you hit ^C even
	if it looks as if you have one. Diff to sc.c follows below.

7.	Suggested future hacks (I won't have time to do them myself):

	Make it possible to edit the expressions, not just backing up
	with BS, changing one character and then rewrite the rest of the line.
	
	Make it possible to write row and columns like expressions, e.g.
	let r11c4 = r(r10c7)c(r0c0+1) which would do some kind of table lookup.

	It should be possible to have some kind of symbolic names of the
	variables, e.g. let tax = income * localtax.

	Why not making vc three dimensional so that we could have a bunch
	of "pages" to switch between. The variables could then be called
	p??r??c?? instead.

If there is somebody out there who have experience from other vc look-alike's
it would be interesting to see more ideas.

Chris.

*** /tmp/,RCSt1026507	Mon Mar 11 16:06:41 1985
--- sc.c	Mon Mar 11 16:06:11 1985
***************
*** 558,564
  	refresh();
  	ch = nmgetch();
  	if (ch == 'y' || ch == 'Y') return 0;
! 	else if (ch == ctl (g)) return(1);
       }
      return(0);
  }

--- 558,564 -----
  	refresh();
  	ch = nmgetch();
  	if (ch == 'y' || ch == 'Y') return 0;
! 	else return(1);
       }
      return(0);
  }

mark@tove.UUCP (Mark Weiser) (03/18/85)

In article <265@chalmers.UUCP> bernerus@chalmers.UUCP (Christer Bernerus) writes:
>...
>3.	Mark Weiser at seismo { ..seismo!mark} is  collecting suggested
>	hacks and I hope he will redistribute a new version soon.
>

I am, I will, but I am NOT at seismo.  The actual mark at seismo occasionally
(every year) sends me the misdirected mail that should have gone to 
me that went to him.  Send vc suggestions to me at one of the addresses below:
-------
Spoken: Mark Weiser 	ARPA:	mark@maryland	Phone: +1-301-454-7817
CSNet:	mark@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!mark
USPS: Computer Science Dept., University of Maryland, College Park, MD 20742
-- 
Spoken: Mark Weiser 	ARPA:	mark@maryland	Phone: +1-301-454-7817
CSNet:	mark@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!mark
USPS: Computer Science Dept., University of Maryland, College Park, MD 20742