v23i025: The SC Spreadsheet, release 6.8, Part05/06

Rich Salz rsalz at bbn.com
Wed Sep 5 05:22:01 AEST 1990


Submitted-by: Jeff Buhrt <sawmill!buhrt>
Posting-number: Volume 23, Issue 25
Archive-name: sc6.8/part05

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents:  CHANGES eres.sed gram.y psc.doc range.c sc.h version.c
#   vi.c vmtbl.c
# Wrapped by rsalz at litchi.bbn.com on Fri Jul 13 15:24:22 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 5 (of 6)."'
if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CHANGES'\"
else
  echo shar: Extracting \"'CHANGES'\" \(5088 characters\)
  sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
XCHANGES BETWEEN 6.1 and 6.7
X
XDave Lewis - 
X	Found and fixed a null pointer derefrece in the 'R' command.
X
XRob McMahon -
X	Changed the ctl() macro to work with ANSI style compilers.
X	Cleaned up some non-readonly text problems.
X
XRick Linck -
X	Fixed a bug in lex.c - Ann Arbor Ambassadors have long ks and ke
X	termcap entries.
X
XSam Drake -
X	A fix for undefined C_* symbols in AIX.
X
XPeter Brower -
X	Cleaned up the INTERNATIONAL ifdefs with more portable code.
X
XGlen Ditchfield
X	Cleaned up a problem in crypt.c when the encrypted file shrank.
X
XBob Bond -
X	Vi style editing for the command line.
X	A bug in range name aliases.
X
XJeff Buhrt -
X	-Added "~" filename expansion.
X	-702 columns (A-ZZ) and unlimited rows/cells based on max. memory
X	-fixed a few bugs
X	-slightly decreased CPU usage
X	-MAKES backup copies of files
X	-understands ~$HOME stuff
X
XCHANGES BETWEEN 5.1 and 6.1:
X
XAndy Valencia -
X	xmalloc aligns data to a double boundary.
X
XLawrence Cipriani -
X	Fixed a bug in the "do you want to save this" sequence.
X
XSoren Lundsgaard -
X	A null pointer derefrence.
X
XRick Perry -
X	Cleaned up a problem with modchk() in sc.c.
X
XGregory Bond -
X	Added code for multi argument versions of @min and @max.
X
XTad Mannes -
X	Added code to save/restore hidden rows and columns when the
X	data base is saved or restored.
X
XMarius Olafsson -
X	INTERNATIONAL changes.  Allows full 8 bit characters (if
X	curses supports them.)
X
XKurt Horton -
X	Added support for @pv, @fv and @pmt financial functins.
X	Tested lots of different systems, linting.
X
XJohn Campbell -
X	Support for VMS.  See VMS_NOTES.
X
XPeter King -
X	 User selection of row or column order for recalculation.
X		Also affects order of traversing regions in /f and /r
X	 User setting of automatic or manual recalculation.
X	 User setting of number of times to try recalculation.
X	 + and - commands when in non-numeric mode to do 
X		increment and decrement operations.
X	@index, @stindex, @atan2, @lookup  functions.
X	Save/restore options.
X	Support for TeX, LaTeX, and better support for tbl in "T" cmd.
X	Provision of a copyent function to copy entries (same code repeated
X		in several locations)
X	Forwrow, backrow, forwcol, backcol functions to replace
X		repeated code
X	Correct interpretation of ESCAPE or ^G as an abort when in a 
X		two character command such as 'ar' or 'ac'
X	Cleanup in eval() - catches non-trap function errors.
X
XBob Bond - 
X       Added search options to "g".
X       Added supression of hidden columns to "W"
X       Added the mod operator "%"
X       New help functions.
X       Constant prescale "$"
X       Added string matching to @lookup.
X       Some more bug fixes.
X       Testing, integration, documentation.
X
XAlan Silverstein-
X	Greatly revised the manual entry.
X	Added menus for ^E command and row/column commands, which
X	involved a bunch of code cleanup.
X
X	Changed top row display to clearly indicate string labels
X	versus number parts, and to distinguish string functions from
X	constant labels.
X
X	When the character cursor is on a cell (not topline), ^H
X	(backspace) is like ^B (move back one cell), rather than being
X	ignored.
X
X	When the character cursor is on a cell (not topline), ^I (tab)
X	is like ^F (move forward one cell), rather than being ignored.
X	^R is no longer identical with ^L.  Now ^R highlights all cells
X	which should be entered by a user because they contain constant
X	numeric values (not the result of a numeric expression).
X
X	Added a ^X command, similar to ^R, which highlights cells which
X	have expressions.  It also displays the expressions in the
X	highlighted cells as left-justified strings, instead of the
X	label and/or value of the cell.
X
X	Added indirection functions (@nval() and @sval()) for simple
X	table lookups.  Given a column name and row number, they return
X	the numeric or string value of the selected cell.
X
X	Added external functions (@ext()) for non-trivial
X	computations.  Given a command name and argument, it calls the
X	command and reads back one output line.
X
X	Added a ^T,e command to toggle enabling of external functions.
X
X	Changed ^T,t to only control the top line display, and added
X	^T,c to control current cell highlighting.  (Separated the
X	functions.)
X
X	"!" (shell escape) gives a vi-style warning if there were any
X	changes since the last write.  (No change to manual entry.)
X
X	Fixed some startup, error, and prompt messages to be cleaner
X	and/or more consistent.  (No changes to manual entry.)
X
X	Fixed a bug:  If @substr() upper bound (third parameter) is
X	past the end of the string operand, return the substring
X	through the end of the string, rather than returning a null
X	string.
X
X	Fixed a bug:  Reset SIGINT to default after forking before
X	calling shell escape program and before starting pipeline (for
X	commands which support this).  Didn't reset SIGINT before
X	calling crypt and external functions because in both cases it
X	should be irrelevant.  (No change to manual entry.)
X
XCHANGES BETWEEN 6.1 and 6.2:
X
X
XChris Cole-
X	Compatibility with Lotus 1-2-3
X		a) @hlookup(expr,range,expr)
X		b) @vlookup(expr,range,expr)
X		c) @round(expr,expr)
X		d) @if(expr,expr,expr)
X		e) @abs(expr)
END_OF_FILE
  if test 5088 -ne `wc -c <'CHANGES'`; then
    echo shar: \"'CHANGES'\" unpacked with wrong size!
  fi
  # end of 'CHANGES'
fi
if test -f 'eres.sed' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'eres.sed'\"
else
  echo shar: Extracting \"'eres.sed'\" \(50 characters\)
  sed "s/^X//" >'eres.sed' <<'END_OF_FILE'
X/%token.*K_/!d
X/%token.*K_\(.*\)/s//	"\1",	K_\1,/
END_OF_FILE
  if test 50 -ne `wc -c <'eres.sed'`; then
    echo shar: \"'eres.sed'\" unpacked with wrong size!
  fi
  # end of 'eres.sed'
fi
if test -f 'gram.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gram.y'\"
else
  echo shar: Extracting \"'gram.y'\" \(12082 characters\)
  sed "s/^X//" >'gram.y' <<'END_OF_FILE'
X/*	SC	A Spreadsheet Calculator
X *		Command and expression parser
X *
X *		original by James Gosling, September 1982
X *		modified by Mark Weiser and Bruce Israel,
X *			University of Maryland
X *
X * 		more mods Robert Bond 12/86
X *
X *		More mods by Alan Silverstein, 3/88, see list of changes.
X *
X *		$Revision: 6.8 $
X */
X
X
X
X%{
X#include <curses.h>
X#include "sc.h"
X
X#define ENULL (struct enode *)0
X
Xchar *strcpy();
X%}
X
X%union {
X    int ival;
X    double fval;
X    struct ent_ptr ent;
X    struct enode *enode;
X    char *sval;
X    struct range_s rval;
X}
X
X%type <ent> var
X%type <fval> num
X%type <rval> range
X%type <rval> var_or_range
X%type <sval> strarg
X%type <enode> e term expr_list
X%token <sval> STRING
X%token <ival> NUMBER
X%token <fval> FNUMBER
X%token <rval> RANGE
X%token <rval> VAR
X%token <sval> WORD
X%token <ival> COL
X%token S_FORMAT
X%token S_LABEL
X%token S_LEFTSTRING
X%token S_RIGHTSTRING
X%token S_GET
X%token S_PUT
X%token S_MERGE
X%token S_LET
X%token S_WRITE
X%token S_TBL
X%token S_COPY
X%token S_SHOW
X%token S_ERASE
X%token S_FILL
X%token S_GOTO
X%token S_DEFINE
X%token S_UNDEFINE
X%token S_VALUE
X%token S_MDIR
X%token S_HIDE
X%token S_SET
X
X%token K_FIXED
X%token K_SUM
X%token K_PROD
X%token K_AVG
X%token K_STDDEV
X%token K_COUNT
X%token K_ABS
X%token K_ACOS
X%token K_ASIN
X%token K_ATAN
X%token K_ATAN2
X%token K_CEIL
X%token K_COS
X%token K_EXP
X%token K_FABS
X%token K_FLOOR
X%token K_HYPOT
X%token K_LN
X%token K_LOG
X%token K_PI
X%token K_POW
X%token K_SIN
X%token K_SQRT
X%token K_TAN
X%token K_DTR
X%token K_RTD
X%token K_MAX
X%token K_MIN
X%token K_RND
X%token K_ROUND
X%token K_IF
X
X%token K_PV
X%token K_FV
X%token K_PMT
X
X%token K_HOUR
X%token K_MINUTE
X%token K_SECOND
X%token K_MONTH
X%token K_DAY
X%token K_YEAR
X%token K_NOW
X%token K_DATE
X%token K_DTS
X%token K_TTS
X%token K_FMT
X%token K_SUBSTR
X%token K_STON
X%token K_EQS
X%token K_EXT
X%token K_NVAL
X%token K_SVAL
X%token K_LOOKUP
X%token K_HLOOKUP
X%token K_VLOOKUP
X%token K_INDEX
X%token K_STINDEX
X%token K_AUTO
X%token K_AUTOCALC
X%token K_BYROWS
X%token K_BYCOLS
X%token K_BYGRAPH
X%token K_ITERATIONS
X%token K_NUMERIC
X%token K_PRESCALE
X%token K_EXTFUN
X%token K_CELLCUR
X%token K_TOPROW
X%token K_TBLSTYLE
X%token K_TBL
X%token K_LATEX
X%token K_TEX
X
X%left '?' ':'
X%left '|'
X%left '&'
X%nonassoc '<' '=' '>' '!'
X%left '+' '-' '#'
X%left '*' '/' '%'
X%left '^'
X
X%%
Xcommand:	S_LET var_or_range '=' e
X				{ let($2.left.vp, $4); }
X	|	S_LABEL var_or_range '=' e
X				{ slet($2.left.vp, $4, 0); }
X	|	S_LEFTSTRING var_or_range '=' e
X				{ slet($2.left.vp, $4, -1); }
X	|	S_RIGHTSTRING var_or_range '=' e
X				{ slet($2.left.vp, $4, 1); }
X	|	S_FORMAT COL ':' COL NUMBER NUMBER
X				{ doformat($2,$4,$5,$6); }
X	|	S_FORMAT COL NUMBER NUMBER
X				{ doformat($2,$2,$3,$4); }
X	|	S_GET strarg	{  /* This tmp hack is because readfile
X				    * recurses back through yyparse. */
X				  char *tmp;
X				  tmp = $2;
X				  readfile (tmp, 1);
X				  xfree(tmp);
X				}
X	|	S_MERGE strarg	{
X				  char *tmp;
X				  tmp = $2;
X				  readfile (tmp, 0);
X				  xfree(tmp);
X				}
X	|	S_MDIR strarg	
X				{ if (mdir) xfree(mdir); mdir = $2; }
X	|       S_PUT strarg range
X				{ (void) writefile($2, ($3.left.vp)->row, 
X			 	($3.left.vp)->col, ($3.right.vp)->row,
X			 	($3.right.vp)->col);
X			 	xfree($2); }
X	|	S_PUT strarg	
X				{ (void) writefile ($2, 0, 0, maxrow, maxcol);
X			 	xfree($2); }
X	|       S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row, 
X			 ($3.left.vp)->col, ($3.right.vp)->row,
X			 ($3.right.vp)->col);
X			 xfree($2); }
X	|	S_WRITE strarg	{ (void) printfile ($2, 0, 0, maxrow, maxcol);
X			 xfree($2); }
X	|       S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row, 
X			 ($3.left.vp)->col, ($3.right.vp)->row,
X			 ($3.right.vp)->col);
X			 xfree($2); }
X	|	S_TBL strarg	{ (void)tblprintfile ($2, 0, 0, maxrow, maxcol);
X			 xfree($2); }
X	|       S_SHOW COL ':' COL
X					{ showcol( $2, $4); }
X	|       S_SHOW NUMBER ':' NUMBER
X					{ showrow( $2, $4); }
X 	|	S_HIDE COL
X 					{ hide_col( $2 ); }
X 	|	S_HIDE NUMBER
X 					{ hide_row( $2 ); }
X	|	S_COPY range var_or_range 
X					{ copy($2.left.vp,$2.right.vp,
X					$3.left.vp,$3.right.vp); }
X	|	S_ERASE       
X					{ eraser(lookat(showsr, showsc),
X				        lookat(currow, curcol)); }
X	|	S_ERASE var_or_range 
X					{ eraser($2.left.vp, $2.right.vp); }
X	|	S_VALUE       { valueize_area(showsr, showsc, currow, curcol);
X				 modflg++; }
X	|	S_VALUE var_or_range { valueize_area(($2.left.vp)->row,
X				($2.left.vp)->col,
X				($2.right.vp)->row,
X				($2.right.vp)->col); modflg++; }
X	|	S_FILL num num  { fill(lookat(showsr, showsc),
X				      lookat(currow, curcol), $2, $3); }
X	|	S_FILL var_or_range num num
X				 { fill($2.left.vp, $2.right.vp, $3, $4); }
X	|	S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
X	|       S_GOTO num          {num_search($2);}
X	|       S_GOTO STRING       {str_search($2);}
X	|	S_GOTO              {go_last();}
X	|	S_DEFINE strarg       { struct ent_ptr arg1, arg2;
X					arg1.vp = lookat(showsr, showsc);
X					arg1.vf = 0;
X					arg2.vp = lookat(currow, curcol);
X					arg2.vf = 0;
X					add_range($2, arg1, arg2, 1); }
X
X	|	S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
X	|	S_DEFINE strarg var   { add_range($2, $3, $3, 0); }
X	|	S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
X 	|	S_SET setlist
X	|	/* nothing */
X	|	error;
X
Xterm: 		var		{ $$ = new_var('v', $1); }
X	|	K_FIXED term	{ $$ = new ('f', ENULL, $2); }
X	|       '@' K_SUM '(' var_or_range ')' 
X				{ $$ = new_range(REDUCE | '+', $4); }
X	|       '@' K_PROD '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | '*', $4); }
X	|       '@' K_AVG '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | 'a', $4); }
X	|       '@' K_STDDEV '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | 's', $4); }
X	|       '@' K_COUNT '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | 'c', $4); }
X	|       '@' K_MAX '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | MAX, $4); }
X	|	'@' K_MAX '(' e ',' expr_list ')'
X				{ $$ = new(LMAX, $6, $4); }
X	|       '@' K_MIN '(' var_or_range ')' 
X				{ $$ = new_range (REDUCE | MIN, $4); }
X	|	'@' K_MIN '(' e ',' expr_list ')'
X				{ $$ = new(LMIN, $6, $4); }
X	| '@' K_ABS '(' e ')'	 { $$ = new(ABS, ENULL, $4); }
X	| '@' K_ACOS '(' e ')'	 { $$ = new(ACOS, ENULL, $4); }
X	| '@' K_ASIN '(' e ')'	 { $$ = new(ASIN, ENULL, $4); }
X	| '@' K_ATAN '(' e ')'	 { $$ = new(ATAN, ENULL, $4); }
X	| '@' K_ATAN2 '(' e ',' e ')' { $$ = new(ATAN2, $4, $6); }
X	| '@' K_CEIL '(' e ')'	 { $$ = new(CEIL, ENULL, $4); }
X	| '@' K_COS '(' e ')'	 { $$ = new(COS, ENULL, $4); }
X	| '@' K_EXP '(' e ')'	 { $$ = new(EXP, ENULL, $4); }
X	| '@' K_FABS '(' e ')'	 { $$ = new(FABS, ENULL, $4); }
X	| '@' K_FLOOR '(' e ')'	 { $$ = new(FLOOR, ENULL, $4); }
X	| '@' K_HYPOT '(' e ',' e ')'	{ $$ = new(HYPOT, $4, $6); }
X	| '@' K_LN '(' e ')'	 { $$ = new(LOG, ENULL, $4); }
X	| '@' K_LOG '(' e ')'	 { $$ = new(LOG10, ENULL, $4); }
X	| '@' K_POW '(' e ',' e ')'	{ $$ = new(POW, $4, $6); }
X	| '@' K_SIN '(' e ')'	 { $$ = new(SIN, ENULL, $4); }
X	| '@' K_SQRT '(' e ')'	 { $$ = new(SQRT, ENULL, $4); }
X	| '@' K_TAN '(' e ')'	 { $$ = new(TAN, ENULL, $4); }
X	| '@' K_DTR '(' e ')'	 { $$ = new(DTR, ENULL, $4); }
X	| '@' K_RTD '(' e ')'	 { $$ = new(RTD, ENULL, $4); }
X	| '@' K_RND '(' e ')'	 { $$ = new(RND, ENULL, $4); }
X	| '@' K_ROUND '(' e ',' e ')'	 { $$ = new(ROUND, $4, $6); }
X	| '@' K_IF  '(' e ',' e ',' e ')' { $$ = new(IF,  $4,new(',',$6,$8)); }
X
X	| '@' K_PV  '(' e ',' e ',' e ')' { $$ = new(PV,  $4,new(':',$6,$8)); }
X 	| '@' K_FV  '(' e ',' e ',' e ')' { $$ = new(FV,  $4,new(':',$6,$8)); }
X 	| '@' K_PMT '(' e ',' e ',' e ')' { $$ = new(PMT, $4,new(':',$6,$8)); }
X 
X	| '@' K_HOUR '(' e ')' 	 { $$ = new(HOUR,ENULL, $4); }
X	| '@' K_MINUTE '(' e ')' { $$ = new(MINUTE,ENULL, $4); }
X	| '@' K_SECOND '(' e ')' { $$ = new(SECOND,ENULL, $4); }
X	| '@' K_MONTH '(' e ')'	 { $$ = new(MONTH,ENULL,$4); }
X	| '@' K_DAY '(' e ')'    { $$ = new(DAY, ENULL, $4); }
X	| '@' K_YEAR '(' e ')'   { $$ = new(YEAR, ENULL, $4); }
X	| '@' K_NOW              { $$ = new(NOW, ENULL, ENULL);}
X	| '@' K_DTS '(' e ',' e ',' e ')'
X		  		 { $$ = new(DTS, $4, new(',', $6, $8));}
X	| '@' K_TTS '(' e ',' e ',' e ')'
X		  		 { $$ = new(TTS, $4, new(',', $6, $8));}
X	| '@' K_STON '(' e ')'   { $$ = new(STON, ENULL, $4); }
X	| '@' K_EQS '(' e ',' e ')' { $$ = new (EQS, $4, $6); }
X	| '@' K_DATE '(' e ')'	 { $$ = new(DATE, ENULL, $4); }
X	| '@' K_FMT  '(' e ',' e ')' { $$ = new(FMT, $4, $6); }
X	| '@' K_INDEX  '(' e ',' var_or_range ')'
X		 { $$ = new(INDEX, $4, new_range(REDUCE | INDEX, $6)); }
X	| '@' K_LOOKUP  '(' e ',' var_or_range ')'
X		 { $$ = new(LOOKUP, $4, new_range(REDUCE | LOOKUP, $6)); }
X	| '@' K_HLOOKUP  '(' e ',' var_or_range ',' e ')'
X		 { $$ = new(HLOOKUP, new(',', $4, $8),
X		    new_range(REDUCE | HLOOKUP, $6)); }
X	| '@' K_VLOOKUP  '(' e ',' var_or_range ',' e ')'
X		 { $$ = new(VLOOKUP, new(',', $4, $8),
X		    new_range(REDUCE | VLOOKUP, $6)); }
X	| '@' K_STINDEX  '(' e ',' var_or_range ')'
X		 { $$ = new(STINDEX, $4, new_range(REDUCE | STINDEX, $6)); }
X	| '@' K_EXT  '(' e ',' e ')' { $$ = new(EXT, $4, $6); }
X	| '@' K_NVAL '(' e ',' e ')' { $$ = new(NVAL, $4, $6); }
X	| '@' K_SVAL '(' e ',' e ')' { $$ = new(SVAL, $4, $6); }
X	| '@' K_SUBSTR '(' e ',' e ',' e ')'
X				 { $$ = new(SUBSTR, $4, new(',', $6, $8)); }
X	|	'(' e ')'	 { $$ = $2; }
X	|	'+' term	 { $$ = $2; }
X	|	'-' term	 { $$ = new ('m', ENULL, $2); }
X	|	NUMBER		 { $$ = new_const('k', (double) $1); }
X	|	FNUMBER		 { $$ = new_const('k', $1); }
X	|	K_PI	{ $$ = new_const('k', (double)3.14159265358979323846); }
X	|	STRING	         { $$ = new_str($1); }
X	|	'~' term	 { $$ = new ('~', ENULL, $2); }
X	|	'!' term	 { $$ = new ('~', ENULL, $2); }
X	;
X
Xe:		e '+' e		{ $$ = new ('+', $1, $3); }
X	|	e '-' e		{ $$ = new ('-', $1, $3); }
X	|	e '*' e		{ $$ = new ('*', $1, $3); }
X	|	e '/' e		{ $$ = new ('/', $1, $3); }
X	|	e '%' e		{ $$ = new ('%', $1, $3); }
X	|	e '^' e		{ $$ = new ('^', $1, $3); }
X	|	term
X	|	e '?' e ':' e	{ $$ = new ('?', $1, new(':', $3, $5)); }
X	|	e '<' e		{ $$ = new ('<', $1, $3); }
X	|	e '=' e		{ $$ = new ('=', $1, $3); }
X	|	e '>' e		{ $$ = new ('>', $1, $3); }
X	|	e '&' e		{ $$ = new ('&', $1, $3); }
X	|	e '|' e		{ $$ = new ('|', $1, $3); }
X	|	e '<' '=' e	{ $$ = new ('~', ENULL, new ('>', $1, $4)); }
X	|	e '!' '=' e	{ $$ = new ('~', ENULL, new ('=', $1, $4)); }
X	|	e '>' '=' e	{ $$ = new ('~', ENULL, new ('<', $1, $4)); }
X	|	e '#' e		{ $$ = new ('#', $1, $3); }
X	;
X
Xexpr_list:	e		{ $$ = new(ELIST, ENULL, $1); }
X	|	expr_list ',' e	{ $$ = new(ELIST, $1, $3); }
X	;
X
Xrange:		var ':' var	{ $$.left = $1; $$.right = $3; }
X	| 	RANGE		{ $$ = $1; }
X	;
X
Xvar:		COL NUMBER	{ $$.vp = lookat($2 , $1); $$.vf = 0;}
X	|	'$' COL NUMBER	{ $$.vp = lookat($3 , $2);
X					$$.vf = FIX_COL;}
X	|	COL '$' NUMBER	{ $$.vp = lookat($3 , $1);
X					$$.vf = FIX_ROW;}
X	|	'$' COL '$' NUMBER { $$.vp = lookat($4 , $2);
X					$$.vf = FIX_ROW | FIX_COL;}
X	|	VAR		{ $$ = $1.left; }
X	;
X
Xvar_or_range:	range		{ $$ = $1; }
X	|	var		{ $$.left = $1; $$.right = $1; }
X	;
X
Xnum:		NUMBER		{ $$ = (double) $1; }
X	|	FNUMBER		{ $$ = $1; }
X	|	'-' num		{ $$ = -$2; }
X	|	'+' num		{ $$ = $2; }
X	;
X
Xstrarg:		STRING		{ $$ = $1; }
X	|	var		{
X				    char *s, *s1;
X				    s1 = $1.vp->label;
X				    if (!s1)
X					s1 = "NULL_STRING";
X				    s = xmalloc((unsigned)strlen(s1)+1);
X				    (void) strcpy(s, s1);
X				    $$ = s;
X				}
X  	;
X
Xsetlist :	
X	|	setlist setitem
X	;
X
Xsetitem	:	K_AUTO		{ setauto(1); }
X	|	K_AUTOCALC	{ setauto(1); }
X	|	'~' K_AUTO	{ setauto(0); }
X	|	'~' K_AUTOCALC	{ setauto(0); }
X	|	'!' K_AUTO	{ setauto(0); }
X	|	'!' K_AUTOCALC	{ setauto(0); }
X	|	K_BYCOLS	{ setorder(BYCOLS); }
X	|	K_BYROWS	{ setorder(BYROWS); }
X	|	K_BYGRAPH	{ setorder(BYGRAPH); }
X	|	K_NUMERIC	{ numeric = 1; }
X	|	'!' K_NUMERIC	{ numeric = 0; }
X	|	K_PRESCALE	{ prescale = 0.01; }
X	|	'!' K_PRESCALE	{ prescale = 1.0; }
X	|	K_EXTFUN	{ extfunc = 1; }
X	|	'!' K_EXTFUN	{ extfunc = 0; }
X	|	K_CELLCUR	{ showcell = 1; }
X	|	'!' K_CELLCUR	{ showcell = 0; }
X	|	K_TOPROW	{ showtop = 1; }
X	|	'!' K_TOPROW	{ showtop = 0; }
X	|	K_ITERATIONS '=' NUMBER	{ setiterations($3); }
X	|	K_TBLSTYLE '=' NUMBER	{ tbl_style = $3; }
X	|	K_TBLSTYLE '=' K_TBL	{ tbl_style = TBL; }
X	|	K_TBLSTYLE '=' K_LATEX	{ tbl_style = LATEX; }
X	|	K_TBLSTYLE '=' K_TEX	{ tbl_style = TEX; }
X  	;
END_OF_FILE
  if test 12082 -ne `wc -c <'gram.y'`; then
    echo shar: \"'gram.y'\" unpacked with wrong size!
  fi
  # end of 'gram.y'
fi
if test -f 'psc.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'psc.doc'\"
else
  echo shar: Extracting \"'psc.doc'\" \(2147 characters\)
  sed "s/^X//" >'psc.doc' <<'END_OF_FILE'
X.\" $Revision $
X.TH PPNAME 1
X.SH NAME
Xppname \- prepare pname files
X.SH SYNOPSIS
X.B ppname
X[
X.I -fLkr
X]
X[
X.I -s cell
X]
X[
X.I -R n
X]
X[
X.I -C n
X]
X[
X.I -n n
X]
X[
X.I -d c
X]
X
X.SH DESCRIPTION
X.I Ppname
Xis used to prepare data for input to the spread sheet calculator
X.I pname(1).
XIt accepts normal ascii data on standard input.  Standard output
Xis a
X.I pname
Xfile.
XWith no options, 
X.I ppname
Xstarts the spread sheet in cell A0.  Strings are right justified.
XAll data on a line is entered on the same row; new input lines
Xcause the output row number to increment by one.  The default delimiters
Xare tab and space.  The column formats are set to one larger
Xthan the number of columns required to hold the largest value
Xin the column.
X
XOptions:
X
X.IP "\-f"
XOmit column width calculations.  This option is for preparing
Xdata to be merged with an existing spreadsheet.  If the option is not
Xspecified, the column widths calculated for the data read by
X.I ppname
Xwill override those already set in the existing spreadsheet.
X
X.IP "\-L"
XLeft justify strings.
X
X.IP "\-k"
XKeep all delimiters.  This option causes the output cell to change on
Xeach new delimiter encountered in the input stream.   The default
Xaction is to condense multiple delimters to one, so that the cell only
Xchanges once per input data item.
X
X.IP "\-r"
XOutput the data by row first then column.  For input consisting of a single
Xcolumn, this
Xoption will result in output of one row with multiple columns
Xinstead of a single
Xcolumn spread sheet.
X
X.IP "\-s cell"
XStart the top left corner of the spread sheet in 
X.I cell.
XFor example, 
X.I "-s B33"
Xwill arrange the output data so that the
Xspread sheet starts in column B, row 33.
X
X.IP "\-R n"
XIncrement by
X.I n 
Xon each new output row.
X
X.IP "\-C n"
XIncrement by
X.I n 
Xon each new output column.
X
X.IP "\-n n"
XOutput 
X.I n
Xrows before advancing to the next column.  This option is used when
Xthe input is arranged in a single column and the spread sheet is to
Xhave multiple columns, each of which is to be length
X.I n.
X
X.IP "\-d c"
XUse the single character
X.I c
Xas the delimiter between input fields.
X
X.SH SEE ALSO
Xpname(1)
X
X.SH AUTHOR
X
XRobert Bond
END_OF_FILE
  if test 2147 -ne `wc -c <'psc.doc'`; then
    echo shar: \"'psc.doc'\" unpacked with wrong size!
  fi
  # end of 'psc.doc'
fi
if test -f 'range.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'range.c'\"
else
  echo shar: Extracting \"'range.c'\" \(5604 characters\)
  sed "s/^X//" >'range.c' <<'END_OF_FILE'
X
X/*	SC	A Spreadsheet Calculator
X *		Range Manipulations
X *
X *              Robert Bond, 4/87
X *
X *		$Revision: 6.8 $
X */
X
X#include <stdio.h>
X#include <curses.h>
X#include <ctype.h>
X#include "sc.h"
X
X#ifdef BSD42
X#include <strings.h>
X#else
X#ifndef SYSIII
X#include <string.h>
X#endif
X#endif
X
Xstatic struct range *rng_base;
X
Xadd_range(name, left, right, is_range)
Xchar *name;
Xstruct ent_ptr left, right;
Xint is_range;
X{
X    struct range *r;
X    register char *p;
X    int len;
X    int minr,minc,maxr,maxc;
X    int minrf, mincf, maxrf, maxcf;
X
X    if (left.vp->row < right.vp->row) {
X	minr = left.vp->row; minrf = left.vf & FIX_ROW;
X	maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
X    } else {
X	minr = right.vp->row; minrf = right.vf & FIX_ROW;
X	maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
X    } 
X
X    if (left.vp->col < right.vp->col) {
X	minc = left.vp->col; mincf = left.vf & FIX_COL;
X	maxc = right.vp->col; maxcf = right.vf & FIX_COL;
X    } else {
X	minc = right.vp->col; mincf = right.vf & FIX_COL;
X	maxc = left.vp->col; maxcf = left.vf & FIX_COL;
X    } 
X
X    left.vp = lookat(minr, minc);
X    left.vf = minrf | mincf;
X    right.vp = lookat(maxr, maxc);
X    right.vf = maxrf | maxcf;
X
X    if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
X	error("Error: range name already defined");
X	xfree(name);
X	return;
X    }
X
X    if (strlen(name) <= 2) {
X	error("Invalid range name - too short");
X	xfree(name);
X	return;
X    }
X
X    for(p=name, len=0; *p; p++, len++)
X	if (!((isalpha(*p) && (len<=2)) ||
X	    ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
X	    error("Invalid range name - illegal combination");
X	    xfree(name);
X	    return;
X        }
X
X    r = (struct range *)xmalloc((unsigned)sizeof(struct range));
X    r->r_name = name;
X    r->r_left = left;
X    r->r_right = right;
X    r->r_next = rng_base;
X    r->r_prev = (struct range *)0;
X    r->r_is_range = is_range;
X    if (rng_base)
X        rng_base->r_prev = r;
X    rng_base = r;
X}
X
Xdel_range(left, right)
Xstruct ent *left, *right;
X{
X    register struct range *r;
X    int minr,minc,maxr,maxc;
X
X    minr = left->row < right->row ? left->row : right->row;
X    minc = left->col < right->col ? left->col : right->col;
X    maxr = left->row > right->row ? left->row : right->row;
X    maxc = left->col > right->col ? left->col : right->col;
X
X    left = lookat(minr, minc);
X    right = lookat(maxr, maxc);
X
X    if (!(r = find_range((char *)0, 0, left, right))) 
X	return;
X
X    if (r->r_next)
X        r->r_next->r_prev = r->r_prev;
X    if (r->r_prev)
X        r->r_prev->r_next = r->r_next;
X    else
X	rng_base = r->r_next;
X    xfree((char *)(r->r_name));
X    xfree((char *)r);
X}
X
Xclean_range()
X{
X    register struct range *r;
X    register struct range *nextr;
X
X    r = rng_base;
X    rng_base = (struct range *)0;
X
X    while (r) {
X	nextr = r->r_next;
X	xfree((char *)(r->r_name));
X	xfree((char *)r);
X	r = nextr;
X    }
X}
X
X/* Match on name or lmatch, rmatch */
X
Xstruct range *
Xfind_range(name, len, lmatch, rmatch)
Xchar *name;
Xint len;
Xstruct ent *lmatch;
Xstruct ent *rmatch;
X{
X    struct range *r;
X    register char *rp, *np;
X    register int c;
X
X    if (name) {
X	for (r = rng_base; r; r = r->r_next) {
X	    for (np = name, rp = r->r_name, c = len;
X		 c && *rp && (*rp == *np);
X		 rp++, np++, c--) /* */;
X	    if (!c && !*rp)
X		return(r);
X	}
X	return((struct range *)0);
X    }
X
X    for (r = rng_base; r; r= r->r_next) {
X	if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp)) 
X	    return(r);
X    }
X    return((struct range *)0);
X}
X
Xsync_ranges()
X{
X    register struct range *r;
X
X    r = rng_base;
X    while(r) {
X	r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
X	r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
X	r = r->r_next;
X    }
X}
X
Xwrite_range(f)
XFILE *f;
X{
X    register struct range *r;
X
X    for (r = rng_base; r; r = r->r_next) {
X	(void) fprintf(f, "define \"%s\" %s%s%s%d",
X			r->r_name,
X			r->r_left.vf & FIX_COL ? "$":"",
X			coltoa(r->r_left.vp->col), 
X			r->r_left.vf & FIX_ROW ? "$":"",
X			r->r_left.vp->row);
X	if (r->r_is_range)
X	    (void) fprintf(f, ":%s%s%s%d\n",
X			    r->r_right.vf & FIX_COL ? "$":"",
X			    coltoa(r->r_right.vp->col), 
X			    r->r_right.vf & FIX_ROW ? "$":"",
X			    r->r_right.vp->row);
X	else
X	    (void) fprintf(f, "\n");
X    }
X}
X
Xvoid
Xlist_range(f)
XFILE *f;
X{
X    register struct range *r;
X
X    (void) fprintf(f, "%-30s %s\n\n","Name","Definition");
X
X    for (r = rng_base; r; r = r->r_next) {
X	(void) fprintf(f, "%-30s %s%s%s%d",
X			    r->r_name,
X			    r->r_left.vf & FIX_COL ? "$":"",
X			    coltoa(r->r_left.vp->col), 
X			    r->r_left.vf & FIX_ROW ? "$":"",
X			    r->r_left.vp->row);
X	if (r->r_is_range)
X	    (void) fprintf(f, ":%s%s%s%d\n",
X			    r->r_right.vf & FIX_COL ? "$":"",
X			    coltoa(r->r_right.vp->col), 
X			    r->r_right.vf & FIX_ROW ? "$":"",
X			    r->r_right.vp->row);
X	else
X	    (void) fprintf(f, "\n");
X    }
X}
X
Xchar *
Xv_name(row, col)
Xint row, col;
X{
X    struct ent *v;
X    struct range *r;
X    static char buf[20];
X
X    v = lookat(row, col);
X    if (r = find_range((char *)0, 0, v, v)) {
X	return(r->r_name);
X    } else {
X        (void) sprintf(buf, "%s%d", coltoa(col), row);
X	return(buf);
X    }
X}
X
Xchar *
Xr_name(r1, c1, r2, c2)
Xint r1, c1, r2, c2;
X{
X    struct ent *v1, *v2;
X    struct range *r;
X    static char buf[100];
X
X    v1 = lookat(r1, c1);
X    v2 = lookat(r2, c2);
X    if (r = find_range((char *)0, 0, v1, v2)) {
X	return(r->r_name);
X    } else {
X        (void) sprintf(buf, "%s", v_name(r1, c1));
X	(void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
X	return(buf);
X    }
X}
X
Xare_ranges()
X{
Xreturn (rng_base != 0);
X}
END_OF_FILE
  if test 5604 -ne `wc -c <'range.c'`; then
    echo shar: \"'range.c'\" unpacked with wrong size!
  fi
  # end of 'range.c'
fi
if test -f 'sc.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sc.h'\"
else
  echo shar: Extracting \"'sc.h'\" \(8426 characters\)
  sed "s/^X//" >'sc.h' <<'END_OF_FILE'
X/*	SC	A Table Calculator
X *		Common definitions
X *
X *		original by James Gosling, September 1982
X *		modified by Mark Weiser and Bruce Israel,
X *			University of Maryland
X *		R. Bond  12/86
X *		More mods by Alan Silverstein, 3-4/88, see list of changes.
X *		$Revision: 6.8 $
X *
X */
X
X#define	ATBL(tbl, row, col)	(*(tbl + row) + (col))
X
X#define MINROWS 40	/* minimum size at startup */
X#define MINCOLS 20
X#define	ABSMAXCOLS 702	/* absolute cols: ZZ (base 26) */
X#define RESCOL 4	/* columns reserved for row numbers */
X#define RESROW 3 /* rows reserved for prompt, error, and column numbers */
X#define DEFWIDTH 10	/* Default column width and precision */
X#define DEFPREC   2
X#define HISTLEN  10	/* Number of history entries for vi emulation */
X#define error (void)move(1,0), (void)clrtoeol(), (void) printw
X#define	FBUFLEN	1024	/* buffer size for a single field */
X#define	PATHLEN	1024	/* maximum path length */
X
X#ifndef A_CHARTEXT	/* Should be defined in curses.h */
X#ifdef INTERNATIONAL
X#define A_CHARTEXT 0xff
X#else
X#define A_CHARTEXT 0x7f
X#endif
X#endif
X
X#if (defined(BSD42) || defined(BSD43)) && !defined(strrchr)
X#define strrchr rindex
X#endif
X
Xstruct ent_ptr {
X    int vf;
X    struct ent *vp;
X};
X
Xstruct range_s {
X	struct ent_ptr left, right;
X};
X
X/*
X * Some not too obvious things about the flags:
X *    is_valid means there is a valid number in v.
X *    label set means it points to a valid constant string.
X *    is_strexpr set means expr yields a string expression.
X *    If is_strexpr is not set, and expr points to an expression tree, the
X *        expression yields a numeric expression.
X *    So, either v or label can be set to a constant. 
X *        Either (but not both at the same time) can be set from an expression.
X */
X
X#define VALID_CELL(p, r, c) ((p = *ATBL(tbl, r, c)) && \
X			     ((p->flags & is_valid) || p->label))
X
Xstruct ent {
X    double v;
X    char *label;
X    struct enode *expr;
X    short flags;
X    short row, col;
X    struct ent *next;		/* next deleted ent */
X    struct ent *evnext;		/* next ent w/ a object to eval */
X    struct ent *evprev;		/* prev ent w/ a object to eval */
X};
X
Xstruct range {
X    struct ent_ptr r_left, r_right;
X    char *r_name;
X    struct range *r_next, *r_prev;
X    int r_is_range;
X};
X
X#define FIX_ROW 1
X#define FIX_COL 2
X
Xstruct enode {
X    int op;
X    union {
X	double k;
X	struct ent_ptr v;
X	struct range_s r;
X	char *s;
X	struct {
X	    struct enode *left, *right;
X	} o;
X    } e;
X};
X
X/* op values */
X#define O_VAR 'v'
X#define O_CONST 'k'
X#define O_SCONST '$'
X#define REDUCE 0200	/* Or'ed into OP if operand is a range */
X
X#define OP_BASE 256
X#define ACOS OP_BASE + 0
X#define ASIN OP_BASE + 1
X#define ATAN OP_BASE + 2
X#define CEIL OP_BASE + 3
X#define COS OP_BASE + 4
X#define EXP OP_BASE + 5 
X#define FABS OP_BASE + 6 
X#define FLOOR OP_BASE + 7
X#define HYPOT OP_BASE + 8
X#define LOG OP_BASE + 9
X#define LOG10 OP_BASE + 10
X#define POW OP_BASE + 11
X#define SIN OP_BASE + 12
X#define SQRT OP_BASE + 13
X#define TAN OP_BASE + 14
X#define DTR OP_BASE + 15
X#define RTD OP_BASE + 16
X#define MIN OP_BASE + 17
X#define MAX OP_BASE + 18
X#define RND OP_BASE + 19
X#define HOUR OP_BASE + 20
X#define MINUTE OP_BASE + 21
X#define SECOND OP_BASE + 22
X#define MONTH OP_BASE + 23
X#define DAY OP_BASE + 24
X#define YEAR OP_BASE + 25
X#define NOW OP_BASE + 26
X#define DATE OP_BASE + 27
X#define FMT OP_BASE + 28
X#define SUBSTR OP_BASE + 29
X#define STON OP_BASE + 30
X#define EQS OP_BASE + 31
X#define EXT OP_BASE + 32
X#define ELIST OP_BASE + 33	/* List of expressions */
X#define LMAX  OP_BASE + 34
X#define LMIN  OP_BASE + 35
X#define NVAL OP_BASE + 36
X#define SVAL OP_BASE + 37
X#define PV OP_BASE + 38
X#define FV OP_BASE + 39
X#define PMT OP_BASE + 40
X#define STINDEX OP_BASE + 41
X#define LOOKUP OP_BASE + 42
X#define ATAN2 OP_BASE + 43
X#define INDEX OP_BASE + 44
X#define DTS OP_BASE + 45
X#define TTS OP_BASE + 46
X#define ABS OP_BASE + 47 
X#define HLOOKUP OP_BASE + 48
X#define VLOOKUP OP_BASE + 49
X#define ROUND OP_BASE + 50
X#define IF OP_BASE + 51
X
X/* flag values */
X#define is_valid     0001
X#define is_changed   0002
X#define is_strexpr   0004
X#define is_leftflush 0010
X#define is_deleted   0020
X
X#define ctl(c) ((c)&037)
X#define ESC 033
X#define DEL 0177
X
X#define BYCOLS 1
X#define BYROWS 2
X#define BYGRAPH 4		/* Future */
X
X#define	TBL	1		/* tblprint style output for 'tbl' */
X#define	LATEX	2		/* tblprint style output for 'LaTeX' */
X#define	TEX	3		/* tblprint style output for 'TeX' */
X
X/* Types for etype() */
X
X#define NUM	1
X#define STR	2
X
X#define	GROWAMT	10	/* default minimum amount to grow */
X
X#define	GROWNEW		1	/* first time table */
X#define	GROWROW		2	/* add rows */
X#define	GROWCOL		3
X#define	GROWBOTH	4
Xextern	struct ent ***tbl;
X
Xextern	char curfile[];
Xextern	int strow, stcol;
Xextern	int currow, curcol;
Xextern	int savedrow, savedcol;
Xextern	int FullUpdate;
Xextern	int maxrow, maxcol;
Xextern	int maxrows, maxcols;	/* # cells currently allocated */
Xextern	int *fwidth;
Xextern	int *precision;
Xextern	char *col_hidden;
Xextern	char *row_hidden;
Xextern	char line[FBUFLEN];
Xextern	int linelim;
Xextern	int changed;
Xextern	struct ent *to_fix;
Xextern	int showsc, showsr;
X
Xextern	FILE *openout();
Xextern	char *coltoa();
Xextern	char *findhome();
Xextern	char *r_name();
Xextern	char *seval();
Xextern	char *strrchr();
Xextern	char *v_name();
Xextern	char *xmalloc();
Xextern	double dolookup();
Xextern	double eval();
Xextern	int RealEvalAll();
Xextern	int are_ranges();
Xextern	int atocol();
Xextern	int constant();
Xextern	int etype();
Xextern	int fork();
Xextern	int get_rcqual();
Xextern	int growtbl();
Xextern	int nmgetch();
Xextern	int writefile();
Xextern	int xfree();
Xextern	int yn_ask();
Xextern	struct enode *copye();
Xextern	struct enode *new();
Xextern	struct enode *new_const();
Xextern	struct enode *new_range();
Xextern	struct enode *new_str();
Xextern	struct enode *new_var();
Xextern	struct ent *lookat();
Xextern	struct range *find_range();
Xextern	void EvalAll();
Xextern	void Evalall();
Xextern	void RealEvalOne();
Xextern	void backcol();
Xextern	void backrow();
Xextern	void checkbounds();
Xextern	void clearent();
Xextern	void closecol();
Xextern	void closeout();
Xextern	void closerow();
Xextern	void colshow_op();
Xextern	void colvalueize();
Xextern	void colvalueize();
Xextern	void copy();
Xextern	void copyent();
Xextern	void copyrtv();
Xextern	void decompile();
Xextern	void deletecol();
Xextern	void deleterow();
Xextern	void deraw();
Xextern	void doend();
Xextern	void doformat();
Xextern	void dupcol();
Xextern	void duprow();
Xextern	void editexp();
Xextern	void edits();
Xextern	void editv();
Xextern	void efree();
Xextern	void erase_area();
Xextern	void erasedb();
Xextern	void eraser();
Xextern	void fill();
Xextern	void flush_saved();
Xextern	void forwcol();
Xextern	void forwrow();
Xextern	void free_ent();
Xextern	void go_last();
Xextern	void goraw();
Xextern	void help();
Xextern	void hide_col();
Xextern	void hide_row();
Xextern	void hidecol();
Xextern	void hiderow();
Xextern	void index_arg();
Xextern	void ins_string();
Xextern	void insert_mode();
Xextern	void insertcol();
Xextern	void insertrow();
Xextern	void kbd_again();
Xextern	void label();
Xextern	void let();
Xextern	void list_arg();
Xextern	void list_range();
Xextern	void moveto();
Xextern	void num_search();
Xextern	void one_arg();
Xextern	void opencol();
Xextern	void openrow();
Xextern	void printfile();
Xextern	void pullcells();
Xextern	void range_arg();
Xextern	void readfile();
Xextern	void repaint();
Xextern	void resetkbd();
Xextern	void rowshow_op();
Xextern	void rowvalueize();
Xextern	void setauto();
Xextern	void setiterations();
Xextern	void setorder();
Xextern	void showcol();
Xextern	void showdr();
Xextern	void showrow();
Xextern	void showstring();
Xextern	void signals();
Xextern	void slet();
Xextern	void startshow();
Xextern	void str_search();
Xextern	void sync_refs();
Xextern	void syncref();
Xextern	void tblprintfile();
Xextern	void three_arg();
Xextern	void two_arg();
Xextern	void two_arg_index();
Xextern	void update();
Xextern	void valueize_area();
Xextern	void write_fd();
Xextern	void write_line();
Xextern	void yyerror();
X#ifdef DOBACKUPS
Xextern	int backup_file();
X#endif
X
Xextern	int modflg;
Xextern	int Crypt;
Xextern	char *mdir;
Xextern	double prescale;
Xextern	int extfunc;
Xextern	int propagation;
Xextern	int calc_order;
Xextern	int autocalc;
Xextern	int numeric;
Xextern	int showcell;
Xextern	int showtop;
Xextern	int loading;
Xextern	int getrcqual;
Xextern	int tbl_style;
Xextern	char *progname;
X
X#if BSD42 || SYSIII
X
X#ifndef cbreak
X#define	cbreak		crmode
X#define	nocbreak	nocrmode
X#endif
X
X#endif
END_OF_FILE
  if test 8426 -ne `wc -c <'sc.h'`; then
    echo shar: \"'sc.h'\" unpacked with wrong size!
  fi
  # end of 'sc.h'
fi
if test -f 'version.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'version.c'\"
else
  echo shar: Extracting \"'version.c'\" \(148 characters\)
  sed "s/^X//" >'version.c' <<'END_OF_FILE'
X/*
X * CODE REVISION NUMBER:
X *
X * The part after the first colon, except the last char, appears on the screen.
X */
X
Xchar *rev = "$Revision: 6.8 $";
END_OF_FILE
  if test 148 -ne `wc -c <'version.c'`; then
    echo shar: \"'version.c'\" unpacked with wrong size!
  fi
  # end of 'version.c'
fi
if test -f 'vi.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vi.c'\"
else
  echo shar: Extracting \"'vi.c'\" \(10584 characters\)
  sed "s/^X//" >'vi.c' <<'END_OF_FILE'
X/*	SC	A Spreadsheet Calculator
X *
X *	One line vi emulation
X *	$Revision: 6.8 $
X */
X
X
X#include <signal.h>
X#include <curses.h>
X
X#ifdef BSD42
X#include <strings.h>
X#else
X#ifndef SYSIII
X#include <string.h>
X#endif
X#endif
X
X#if !defined(strchr) && !defined(UPORT)
X#define strchr index
X#endif
Xextern	char	*strchr();
X
X#include <stdio.h>
X#include <ctype.h>
X#include "sc.h"
X
X#define istext(a) (isalnum(a) || ((a) == '_'))
X
Xextern int showrange;
Xextern char mode_ind;		/* Mode indicator */
X
X/* values for mode below */
X
X#define INSERT_MODE	0	/* Insert mode */
X#define EDIT_MODE       1	/* Edit mode */
X#define REP_MODE        2	/* Replace mode */
X#define SEARCH_MODE	3	/* Get arguments for '/' command */
X 
Xstatic int mode = INSERT_MODE;
Xstatic char *history[HISTLEN];
Xstatic int histp = -1;
Xstatic char *last_search;
Xstatic char *undo_line;
Xstatic int undo_lim;
Xstatic char dotb[100];
Xstatic int doti = 0;
Xstatic int do_dot = 0;
X
Xvoid
Xwrite_line(c)
Xint c;
X{
X    if (mode == EDIT_MODE) {
X	switch(c) {
X	case (ctl('h')):	linelim = back_line();		break;
X	case (ctl('m')):  cr_line();			break;
X	case ESC:	stop_edit();			break;
X	case '+':	for_hist();			break;
X	case '-':	back_hist();			break;
X	case '$':	last_col();			break;
X	case '.':	dotcmd();			break;
X	case '/':	search_mode();			break;
X	case '0':	col_0();			break;
X	case 'D':	u_save(c);del_to_end();		break;
X	case 'I':	u_save(c);col_0();insert_mode();break;
X	case 'R':	replace_mode();			break;
X	case 'X':	u_save(c); back_space();	break;
X	case 'a':	u_save(c); append_line();	break;
X	case 'b':	linelim = back_word();		break;
X	case 'c':	u_save(c); change_cmd();	break;
X	case 'd':	u_save(c); delete_cmd();	break;
X	case 'f':	linelim = find_char();		break;
X	case 'h':	linelim = back_line();		break;
X	case 'i':	u_save(c); insert_mode();	break;
X	case 'j':	for_hist();			break;
X	case 'k':	back_hist();			break;
X	case 'l':	linelim = for_line(0);		break;
X	case 'n':	search_again();			break;
X	case 'q':	stop_edit();			break;
X	case 'r':	u_save(c); rep_char();		break;
X	case 't':	linelim = to_char();		break;
X	case 'u':	restore_it();			break;
X	case 'w':	linelim = for_word(0);		break;
X	case 'x':	u_save(c); del_in_line();	break;
X	default:	break;
X	}
X    } else if (mode == INSERT_MODE) { 
X	savedot(c);
X	switch(c) {
X	case (ctl('h')):	back_space();			break;
X	case (ctl('m')):  cr_line();			break;
X	case ESC:	edit_mode();			break;
X	default:	ins_in_line(c);			break;
X	}
X    } else if (mode == SEARCH_MODE) {
X	switch(c) {
X	case (ctl('h')):	back_space();			break;
X	case (ctl('m')):  search_hist();			break;
X	case ESC:	edit_mode();			break;
X	default:	ins_in_line(c);			break;
X	}
X   } else if (mode == REP_MODE) {
X	savedot(c);
X	switch(c) {
X	case (ctl('h')):	back_space();			break;
X	case (ctl('m')):  cr_line();			break;
X	case ESC:	edit_mode();			break;
X	default:	replace_in_line(c);		break;
X	}
X    }
X}
X
Xedit_mode()
X{
X    mode = EDIT_MODE;
X    mode_ind = 'e';
X    histp = -1;
X    if (line[linelim] == '\0')
X	linelim = back_line();
X}
X
Xvoid
Xinsert_mode()
X{
X    mode_ind = 'i';
X    mode = INSERT_MODE;
X}
X
Xsearch_mode()
X{
X    line[0] = '/';
X    line[1] = 0;
X    linelim = 1;
X    histp = -1;
X    mode_ind = '/';
X    mode = SEARCH_MODE;
X}
X
Xreplace_mode()
X{
X    mode_ind = 'R';
X    mode = REP_MODE;
X}
X
X/* dot command functions.  Saves info so we can redo on a '.' command */
X
Xsavedot(c)
Xint c;
X{
X    if (do_dot)
X	return;
X
X    dotb[doti++] = c;
X    dotb[doti] = 0;
X}
X
Xdotcmd()
X{
X    int c;
X
X    do_dot = 1;
X    doti = 0;
X    while(dotb[doti] != 0) {
X	c = dotb[doti++];
X	write_line(c);
X    }
X    do_dot = 0;
X    doti = 0;
X}
X
Xvigetch()
X{
X    int c;
X
X    if(do_dot) {
X	if (dotb[doti] != 0) {
X	    return(dotb[doti++]);
X	} else {
X	    do_dot = 0;
X	    doti = 0;
X	    return(nmgetch());
X	}
X    }
X    c = nmgetch();
X    savedot(c);
X    return(c);
X}
X
X/* saves the current line for possible use by an undo cmd */
X
Xu_save(c)
Xint c;
X{
X    if (undo_line) {
X	xfree(undo_line);
X	undo_line = 0;
X    }
X    undo_line = strcpy(xmalloc((unsigned)(strlen(line)+1)), line);
X    undo_lim = linelim;
X
X    /* reset dot command if not processing it. */
X
X    if (!do_dot) {
X        doti = 0;
X	savedot(c);
X    }
X}
X
X/* Restores the current line saved by u_save() */
X
Xrestore_it()
X{
X    register char *tempc;
X    register int tempi;
X
X    if (!undo_line)
X	return;
X    tempc = strcpy(xmalloc((unsigned)(strlen(line)+1)), line);
X    tempi = linelim;
X    strcpy(line, undo_line);
X    linelim = undo_lim;
X    xfree(undo_line);
X    undo_line = tempc;
X    undo_lim = tempi;
X}
X
X/* This command stops the editing process. */
X
Xstop_edit()
X{
X    showrange = 0;
X    linelim = -1;
X    (void) move(1, 0);
X    (void) clrtoeol();
X}
X
X/*
X * Motion commands.  Forward motion commands take an argument
X * which, when set, cause the forward motion to continue onto
X * the null at the end of the line instead of stopping at the
X * the last character of the line.
X */
X
Xfor_line(stop_null)
Xint stop_null;
X{
X    if (linelim >= 0 && line[linelim] != 0 && 
X    		        (line[linelim+1] != 0 || stop_null))
X	return(linelim+1);
X    else
X	return(linelim);
X}
X
Xfor_word(stop_null)
Xint stop_null;
X{
X    register int c;
X    register int cpos;
X
X    cpos = linelim;
X
X    if (line[cpos] == ' ') {
X	while (line[cpos] == ' ')
X	    cpos++;
X	if (cpos > 0 && line[cpos] == 0)
X	    --cpos;
X	return(cpos);
X    }
X
X    if (istext(line[cpos])) {
X    	while ((c = line[cpos]) && istext(c)) 
X		cpos++;
X    } else {
X	while ((c = line[cpos]) && !istext(c) && c != ' ')
X		cpos++;
X    }
X
X    while (line[cpos] == ' ')
X        cpos++;
X
X    if (cpos > 0 && line[cpos] == 0 && !stop_null) 
X        --cpos;
X
X    return(cpos);
X}
X
Xback_line()
X{
X    if (linelim)
X        return(linelim-1);
X    else
X	return(0);
X}
X
Xback_word()
X{
X    register int c;
X    register int cpos;
X
X    cpos = linelim;
X
X    if (line[cpos] == ' ') {
X	/* Skip white space */
X        while (cpos > 0 && line[cpos] == ' ')
X	    --cpos;
X    } else if (cpos > 0 && (line[cpos-1] == ' ' 
X		     ||  istext(line[cpos]) && !istext(line[cpos-1])
X		     || !istext(line[cpos]) &&  istext(line[cpos-1]))) {
X	/* Started on the first char of a word - back up to prev. word */
X	--cpos;
X        while (cpos > 0 && line[cpos] == ' ')
X	    --cpos;
X    }
X
X    /* Skip across the word - goes 1 too far */
X    if (istext(line[cpos])) {
X    	while (cpos > 0 && (c = line[cpos]) && istext(c)) 
X		--cpos;
X    } else {
X	while (cpos > 0 && (c = line[cpos]) && !istext(c) && c != ' ')
X		--cpos;
X    }
X
X    /* We are done - fix up the one too far */
X    if (cpos > 0 && line[cpos] && line[cpos+1]) 
X	cpos++;
X
X    return(cpos);
X}
X
X/* Text manipulation commands */
X
Xdel_in_line()
X{
X    register int len, i;
X
X    if (linelim >= 0) {
X	len = strlen(line);
X	if (linelim == len && linelim > 0)
X	    linelim--;
X	for (i = linelim; i < len; i++)
X	    line[i] = line[i+1];
X    }
X    if (linelim > 0 && line[linelim] == 0)
X	--linelim;
X}
X
Xins_in_line(c)
Xint c;
X{
X    register int i, len;
X
X    len = strlen(line);
X    for (i = len; i >= linelim; --i)
X	line[i+1] = line[i];
X    line[linelim++] = c;
X    line[len+1] = 0;
X}
X
Xvoid
Xins_string(s)
Xchar *s;
X{
X    while (*s)
X	ins_in_line(*s++);
X}
X
Xappend_line()
X{
X    register int i;
X
X    i = linelim;
X    if (i >= 0 && line[i])
X	linelim++;
X    insert_mode();
X}
X
Xrep_char()
X{
X    int c;
X
X    c = vigetch();
X    if (line[linelim] != 0) {
X    	line[linelim] = c;
X    } else {
X	line[linelim] = c;
X	line[linelim+1] = 0;
X    }
X}
X
Xreplace_in_line(c)
X{
X    register int len;
X
X    len = strlen(line);
X    line[linelim++] = c;
X    if (linelim > len)
X	line[linelim] = 0;
X}
X    
Xback_space()
X{
X    if (linelim == 0)
X	return;
X
X    if (line[linelim] == 0) {
X	linelim = back_line();
X	del_in_line();
X	linelim = strlen(line);
X    } else {
X	linelim = back_line();
X	del_in_line();
X    }
X}
X
Xget_motion()
X{
X    int c;
X
X    c = vigetch();
X    switch (c) {
X    case 'b':	return(back_word());
X    case 'f':	return(find_char()+1);
X    case 'h':	return(back_line());
X    case 'l':	return(for_line(1));
X    case 't':	return(to_char()+1);
X    case 'w':	return(for_word(1));
X    default:	return(linelim);
X    }
X}
X
Xdelete_cmd()
X{
X    int cpos;
X
X    cpos = get_motion();
X    del_chars(cpos, linelim);
X}
X
Xchange_cmd()
X{
X    delete_cmd();
X    insert_mode();
X}
X
Xdel_chars(first, last)
Xregister int first, last;
X{
X    int temp;
X
X    if (first == last)
X	return;
X
X    if (last < first) {
X	temp = last; last = first; first = temp;
X    }
X
X    linelim = first;
X    while(first < last) {
X	del_in_line();
X	--last;
X    }
X}
X
Xdel_to_end()
X{
X    if (linelim < 0)
X	return;
X    line[linelim] = 0;
X    linelim = back_line();
X}
X
Xcr_line()
X{
X    showrange = 0;
X    insert_mode();
X    save_hist();
X    linelim = 0;
X    (void) yyparse ();
X    linelim = -1;
X}
X
X/* History functions */
X
Xsave_hist()
X{
X    register int i;
X
X    /* free the oldest one */
X    if (history[HISTLEN-1]) {
X	xfree(history[HISTLEN-1]);
X	history[HISTLEN-1] = 0;
X    }
X
X    /* Move the others back */
X    for (i = HISTLEN-1; i > 0; --i)
X	history[i] = history[i-1];
X
X    history[0] = xmalloc((unsigned) strlen(line)+1);
X    strcpy(history[0], line);
X}
X
Xback_hist()
X{
X    if (histp == -1 || histp < HISTLEN-1 && history[histp + 1])
X	histp++;
X
X    if (history[histp]) {
X    	strcpy(line, history[histp]);
X	linelim = 0;
X    } else
X	line[linelim = 0] = 0;
X
X}
X
Xsearch_hist()
X{
X    if (last_search) {
X	xfree(last_search);
X	last_search = 0;
X    }
X
X    if(linelim < 1) {
X	linelim = 0;
X	edit_mode();
X	return;
X    }
X
X    last_search = strcpy(xmalloc((unsigned)(strlen(line+1)+1)), line+1);
X    search_again();
X    mode = EDIT_MODE;
X}
X
Xsearch_again()
X{
X    int found_it;
X    int do_next;
X    int prev_histp;
X    char *look_here;
X
X    prev_histp = histp;
X    if (!last_search)
X	return;
X
X    do {
X	back_hist();
X	if (prev_histp == histp)
X	    break;
X	prev_histp = histp;
X	look_here = line;
X	found_it = do_next = 0;
X	while ((look_here = strchr(look_here, last_search[0])) &&
X						!found_it && !do_next) {
X
X	    if (strncmp(look_here, last_search, strlen(last_search)) == 0)
X		found_it++;
X	    else if (look_here < line + strlen(line) - 1)
X	        look_here++;
X	    else
X		do_next++;
X	}
X    } while (!found_it);
X}
X
Xfor_hist()
X{
X    if (histp > 0)
X        histp--;
X
X    if (histp >= 0 && history[histp]) {
X    	strcpy(line, history[histp]);
X	linelim = 0;
X    } else
X	line[linelim = 0] = 0;
X}
X
Xcol_0()
X{
X    linelim = 0;
X}
X
Xlast_col()
X{
X    linelim = strlen(line);
X    if (linelim > 0)
X	--linelim;
X}
X
Xfind_char()
X{
X    register int c;
X    register int i;
X
X
X    c = vigetch();
X    i = linelim;
X    while(line[i] && line[i] != c)
X	i++;
X    if (!line[i])
X	i = linelim;
X    return(i);
X}
X
Xto_char()
X{
X    register int i;
X
X    i = find_char();
X    if (i > 0 && i != linelim)
X	--i;
X
X    return(i);
X}
END_OF_FILE
  if test 10584 -ne `wc -c <'vi.c'`; then
    echo shar: \"'vi.c'\" unpacked with wrong size!
  fi
  # end of 'vi.c'
fi
if test -f 'vmtbl.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vmtbl.c'\"
else
  echo shar: Extracting \"'vmtbl.c'\" \(4643 characters\)
  sed "s/^X//" >'vmtbl.c' <<'END_OF_FILE'
X#ifdef PSC
X# include <stdio.h>
X# include "sc.h"
X# ifndef FALSE
X#  define	FALSE	0
X#  define	TRUE	1
X# endif /* !FALSE */
X# undef	error
X# define error(msg)	fprintf(stderr, msg);
X#else /* PSC */
X# include <curses.h>
X# include "sc.h"
X#endif /* PSC */
X
Xextern	char	*malloc();
Xextern	char	*realloc();
X
X#if defined(BSD42) || defined(BSD43)
X#define	memcpy(dest, source, len)	bcopy(source, dest, (unsigned int)len);
X#define	memset(dest, zero, len)		bzero((dest), (unsigned int)(len));
X#endif
X
X/*
X * check to see if *rowp && *colp are currently allocated, if not expand the
X * current size if we can.
X */
X#ifndef PSC
Xvoid
Xcheckbounds(rowp, colp)
Xint	*rowp;
Xint	*colp;
X{
X	if (*rowp < 0)
X		*rowp = 0;
X	else if (*rowp >= maxrows)
X	{	if (*colp >= maxcols)
X		{	if (!growtbl(GROWBOTH, *rowp, *colp))
X			{	*rowp = maxrows -1;
X				*colp = maxcols -1;
X			}
X			return;
X		}
X		else
X		{	if (!growtbl(GROWROW, *rowp, 0))
X				*rowp = maxrows-1;
X			return;
X		}
X	}
X	if (*colp < 0) 
X		*colp = 0;
X	else if (*colp >= maxcols)
X	{	if (!growtbl(GROWCOL, 0, *colp));
X			*colp = maxcols-1;
X	}
X}
X#endif /* !PSC */
X	
X
X#define GROWALLOC(newptr, oldptr, nelem, type, msg) \
X	if (oldptr == (type *)NULL) \
X		newptr = (type *)malloc((unsigned)(nelem*sizeof(type))); \
X	else \
X		newptr = (type *)realloc((char *)oldptr, \
X					 (unsigned)(nelem*sizeof(type))); \
X	if (newptr == (type *)NULL) \
X	{   error(msg); \
X	    return(FALSE); \
X	} \
X	oldptr = newptr /* wait incase we can't alloc */
X
Xstatic	char	nolonger[] = "The table can't be any longer";
Xstatic	char	nowider[] = "The table can't be any wider";
X
X/*
X * grow the main && auxiliary tables (reset maxrows/maxcols as needed)
X * toprow &&/|| topcol tell us a better guess of how big to become.
X * we return TRUE if we could grow, FALSE if not....
X */
Xint
Xgrowtbl(rowcol, toprow, topcol)
Xint	rowcol;
Xint	toprow, topcol;
X{
X	struct ent ***tbl2;
X	int	*fwidth2;
X	int	*precision2;
X	char	*col_hidden2;
X	char	*row_hidden2;
X	int	newrows, newcols;
X	int	i;
X
X#ifndef PSC
X	newrows = maxrows;
X#endif /* !PSC */
X
X	newcols = maxcols;
X	if (rowcol == GROWNEW)
X	{
X#ifndef PSC
X		maxrows = toprow = 0;
X		/* when we first start up, fill the screen w/ cells */
X		{	int startval;
X			startval = LINES - RESROW;
X			newrows = startval > MINROWS ? startval : MINROWS;
X			startval = ((COLS) - RESCOL) / DEFWIDTH;
X			newcols = startval > MINCOLS ? startval : MINCOLS;
X		}
X#else
X		newcols = MINCOLS;
X#endif /* !PSC */
X		maxcols = topcol = 0;
X	}
X#ifndef PSC
X	/* set how much to grow */
X	if ((rowcol == GROWROW) || (rowcol == GROWBOTH))
X	{	if (toprow > maxrows)
X			newrows = GROWAMT + toprow;
X		else
X			newrows += GROWAMT;
X	}
X#endif /* !PSC */
X	if ((rowcol == GROWCOL) || (rowcol == GROWBOTH))
X	{	if ((rowcol == GROWCOL) && ((maxcols == ABSMAXCOLS) ||
X					(topcol >= ABSMAXCOLS)))
X		{	error(nowider);
X			return(FALSE);
X		}
X
X		if (topcol > maxcols)
X			newcols = GROWAMT + topcol;
X		else
X			newcols += GROWAMT;
X
X		if (newcols > ABSMAXCOLS)
X			newcols = ABSMAXCOLS;
X	}
X
X#ifndef PSC
X	if ((rowcol == GROWROW) || (rowcol == GROWBOTH) || (rowcol == GROWNEW))
X	{
X		GROWALLOC(row_hidden2, row_hidden, newrows, char, nolonger);
X		memset(row_hidden+maxrows, 0, (newrows-maxrows)*sizeof(char));
X
X		/* alloc tbl row pointers */
X		GROWALLOC(tbl2, tbl, newrows, struct ent **, nolonger);
X		memset(tbl+maxrows, 0, (newrows-maxrows)*(sizeof(struct ent **)));
X	}
X#endif /* !PSC */
X
X	if ((rowcol == GROWCOL) || (rowcol == GROWBOTH) || (rowcol == GROWNEW))
X	{
X		GROWALLOC(fwidth2, fwidth, newcols, int, nowider);
X		GROWALLOC(precision2, precision, newcols, int, nowider);
X#ifdef PSC
X		memset(fwidth+maxcols, 0, (newcols-maxcols)*sizeof(int));
X		memset(precision+maxcols, 0, (newcols-maxcols)*sizeof(int));
X	}
X#else
X		GROWALLOC(col_hidden2, col_hidden, newcols, char, nowider);
X		memset(col_hidden+maxcols, 0, (newcols-maxcols)*sizeof(char));
X		for (i = maxcols; i < newcols; i++) {
X			fwidth[i] = DEFWIDTH;
X			precision[i] = DEFPREC;
X		}
X
X		/* [re]alloc the space for each row */
X		for (i = 0; i < maxrows; i++)
X		{
X		    if ((tbl[i] = (struct ent **)realloc((char *)tbl[i],
X			(unsigned)(newcols * sizeof(struct ent **)))) == (struct ent **)0)
X			{	error(nowider);
X				return(FALSE);
X			}
X		    memset((char *)ATBL(tbl,i, maxcols), 0,
X			   (newcols-maxcols)*sizeof(struct ent **));
X		}
X	}
X	else
X		i = maxrows;
X
X	/* fill in the bottom of the table */
X	for (; i < newrows; i++)
X	{	if ((tbl[i] = (struct ent **)malloc((unsigned)(newcols *
X				sizeof(struct ent **)))) == (struct ent **)0)
X		{	error(nowider);
X			return(FALSE);
X		}
X		memset((char *)tbl[i], 0, newcols*sizeof(struct ent **));
X	}
X
X	FullUpdate++;
X	maxrows = newrows;
X#endif /* PSC */
X
X	maxcols = newcols;
X	return(TRUE);
X}
END_OF_FILE
  if test 4643 -ne `wc -c <'vmtbl.c'`; then
    echo shar: \"'vmtbl.c'\" unpacked with wrong size!
  fi
  # end of 'vmtbl.c'
fi
echo shar: End of archive 5 \(of 6\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list