Sc6.8->Sc6.9 patches (REPOST)
Jeffery A Buhrt
buhrt at sawmill.uucp
Wed Oct 31 15:08:40 AEST 1990
Rich Salz posted these for me almost a month ago to comp.source.bugs
when we didn't have outbound news.
-Jeff Buhrt
317-477-6000
sequent!sawmill!buhrt
*** posted/CHANGES Mon Sep 24 09:33:48 1990
--- CHANGES Mon Sep 24 09:44:14 1990
***************
*** 1,3
CHANGES BETWEEN 6.1 and 6.7
Dave Lewis -
--- 1,114 -----
+
+ CHANGES BETWEEN 6.9 and 6.8
+
+ Jim Richardson
+ - pointed out vi mode was not documented in sc.doc
+ - found a nasty buffer limit bug in savedot()
+ - a side effect was ^D could cause a core dump (-Jeff)
+ Tim Wilson
+ - Hints on compiling on Ultrix
+ Eric Putz
+ -patch for printfile() (sc died on huge # of columns in a W)
+ Jeffrey C Honig
+ -patch for lex.c which bombed on SunOS 4.1 if $TERM was not set
+ Tom Kloos
+ -psc now calls [+-.] strings vs numbers.
+ -also pointed out a format reversal problem
+ Jack Goral
+ -changes to Makefile to compile under SCO Unix V rel 3.2.0
+ Mark Nagel
+ -changes to allow arbitrarily complex formatting of cells
+ Kim Sanders
+ -^W generated an incorrect equation (line was not started at beginning)
+ Mike Schwartz
+ -a put command will use the same encryption key as when the
+ file was read.
+ >I have a suggestion for making the encyrption option of "sc" more
+ >usable: Right now, if you use the -x option when you start up sc, it
+ >prompts you for the key (just like "vi -x" does). But when you try to
+ >write the file out using the Put command, it asks for the key again
+ >each time. Why not make it use the same key you used before (as "vi
+ >-x" does)? That would really help, because as it is, each time you try
+ >to save the file you run the risk of mistyping the key.
+ >
+ >You might think this causes a security problem, since the key is then
+ >an argument to crypt, and hence is visible from ps. But when crypt
+ >runs, the first thing it does is to copy the key to an internal buffer
+ >and then zero out the argv copy, so the window of vulnerability is
+ >vanishingly small.
+ Adri Verhoef
+ - pointed out a ^D caused a core dump (fixed)
+ Gene H. Olson
+ - format now grows the spreadsheet before setting the column format.
+ - removed an extra ';' that caused a possible column number trashing
+ Paul Eggert
+ -sc now also has round-to-even, also known as ``banker's rounding''.
+ >With round-to-even, a number exactly halfway between two values is
+ >rounded to whichever is even; e.g. rnd(0.5)=0, rnd(1.5)=2,
+ >rnd(2.5)=2, rnd(3.5)=4. This is the default rounding mode for
+ >IEEE floating point, for good reason: it has better numeric
+ >properties. For example, if X+Y is an integer,
+ >then X+Y = rnd(X)+rnd(Y) with round-to-even,
+ >but not always with sc's rounding (which is
+ >round-to-positive-infinity). I ran into this problem when trying to
+ >split interest in an account to two people fairly.
+ -While we're on the subject, @round(X,Y) should also work when Y
+ >is negative. For example, @round(123,-2) should yield 100.
+
+
+ CHANGES BETWEEN 6.8 and 6.7
+
+ Jeff Buhrt (with help from some beta testers-Thank you)
+ 1) added a per row memory allocation
+ -runs in about 1/2 run time and 1/3 the space of 6.6vm.1
+ -insert/delete row now just moves pointers (# == maxrow+1-currow)
+ and blanks one row (of columns (maxcol))
+ -as the number of cells grows the size is more linear
+ (no more ##Meg images except for 100,000's of rows....)
+ -row to column pointer translation is done by a macro (ATBL)
+ that returns a pointer to the cell pointer.
+ *ATBL would be a pointer to a *ent (cell).
+ -the maximum # of columns is limited by ABSMAXCOLS or
+ sizeof(struct ent *)*maxcols (whichever is smaller)
+ (702 * 4 = 2808 is no real limit even for 286 large model)
+ -the maximum # of rows is limited by the virtual memory limit or
+ sizeof(struct ent **)*maxrows (whichever is smaller)
+ (4*X=64k, X=16384 rows (excluding malloc overhead) on
+ a '286 large model. Even w/ 3.25Meg and 10Mhz)
+ (plus of course any memory used for cells)
+ 2) dolookup (int vs double)
+ 3) dolookup calling eval w/ ent * not enode *
+ (dolookup called w/ ent * not enode *)
+ 4) cleaned up a lot of .... *x = 0 to (.... *)0 (cmds, interp)
+ 5) psc: fwidth/precision were reversed on the output
+ 6) Backup copy (on save) using same mode to [path/]#file~
+ (will prompt if a backup fails)
+ 7) put y/n prompt function into yn_ask(mesg)
+ 8) found a move(x,y) in sc -> move(y,x) and only move when needed
+ 9) we use FullUpdate || changed (to see if ANY cells changed)
+ before trying to redraw the screen in update
+ (now we don't try to redraw every time a key is hit)
+ -if we are stand[ing]out we do not create a cell just to force a
+ standout inside the repaint section of update()
+ -only draw blank cells if we cleared it or it is standing out
+ reason: the less work (what to update) curses has to do, the faster
+ a screen update will be (less cpu required)
+ 14) {insert, delete}col replaced w/ {open,close}col(currow, numcol_to_insert)
+ (limits looping)
+ 6.7.1.1
+ 15) goto nonexistant cell may loop
+ 16) make sure that startup size will at least fill the screen w/ cells.
+ 17) added version.c
+ 6.7.1.2
+ 18) When we would normally die w/o saving (SIGQUIT, etc), we now ask
+ if people would like to save the current spreadsheet.
+ If 'y', saves to the current file name, otherwise ~/SC.SAVE,
+ then /tmp/SC.SAVE if all else fails.
+ 6.7.1.3
+ 19) don't use malloc.c for production code
+ 20) progname is now truncated to just the basename (systems w/ long paths
+ caused problems)
+
CHANGES BETWEEN 6.1 and 6.7
Dave Lewis -
*** posted/Makefile Mon Sep 24 09:33:59 1990
--- Makefile Mon Sep 24 09:48:25 1990
***************
*** 5,11
NAME=SC
# This is where the install step puts it.
! #EXDIR=/v/rgb/bin/psx
EXDIR=/usr/local/bin
# This is where the man page goes.
--- 5,11 -----
NAME=SC
# This is where the install step puts it.
! #EXDIR=/site/bin
EXDIR=/usr/local/bin
# This is where the man page goes.
***************
*** 9,15
EXDIR=/usr/local/bin
# This is where the man page goes.
! #MANDIR=/usr/man/man1
MANDIR=/usr/man/manl
# Set SIMPLE for lex.c if you don't want arrow keys or lex.c blows up
--- 9,15 -----
EXDIR=/usr/local/bin
# This is where the man page goes.
! #MANDIR=/site/man/man1
MANDIR=/usr/man/manl
# This is where the library file (tutorial) goes.
***************
*** 12,17
#MANDIR=/usr/man/man1
MANDIR=/usr/man/manl
# Set SIMPLE for lex.c if you don't want arrow keys or lex.c blows up
#SIMPLE=-DSIMPLE
--- 12,21 -----
#MANDIR=/site/man/man1
MANDIR=/usr/man/manl
+ # This is where the library file (tutorial) goes.
+ #LIBDIR=/site/lib/sc
+ LIBDIR=/usr/local/lib/sc
+
# Set SIMPLE for lex.c if you don't want arrow keys or lex.c blows up
#SIMPLE=-DSIMPLE
***************
*** 29,34
#
#IEEE_MATH=-DIEEE_MATH
# This is the name of a pager like "more" If the line is commented out
# then "more" will be used. "pg" may be appropriate for SYSV
PAGER=-DDFLT_PAGER=\"less\"
--- 33,41 -----
#
#IEEE_MATH=-DIEEE_MATH
+ # Set RINT if you do not have rint() in math.h
+ RINT=-DRINT
+
# This is the name of a pager like "more" If the line is commented out
# then "more" will be used. "pg" may be appropriate for SYSV
PAGER=-DDFLT_PAGER=\"less\"
***************
*** 33,38
# then "more" will be used. "pg" may be appropriate for SYSV
PAGER=-DDFLT_PAGER=\"less\"
# Use this for system V.2
#CFLAGS= -O -DSYSV2
#LDFLAGS=
--- 40,48 -----
# then "more" will be used. "pg" may be appropriate for SYSV
PAGER=-DDFLT_PAGER=\"less\"
+ # For ULTRIX: define the BSD4.2 section and SIGVOID above
+ # tdw at cl.cam.ac.uk tested on Ultrix 3.1C-0
+
# Use this for system V.2
#CFLAGS= -O -DSYSV2
#LDFLAGS=
***************
*** 56,62
# Use this for Sequent boxes
CC=atscc
CFLAGS=-O -DBSD42
! LDFLAGS= -s
LIB=-lm -lcurses -ltermcap
PSCLIB=-lseq
--- 66,72 -----
# Use this for Sequent boxes
CC=atscc
CFLAGS=-O -DBSD42
! #LDFLAGS= -s
LIB=-lm -lcurses -ltermcap
PSCLIB=-lseq
***************
*** 75,80
#LDFLAGS= -z -i
#LIB=-lm -lcurses -ltermcap
# All of the source files
SRC=sc.h sc.c lex.c gram.y interp.c crypt.c xmalloc.c cmds.c range.c help.c \
vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c
--- 85,101 -----
#LDFLAGS= -z -i
#LIB=-lm -lcurses -ltermcap
+ # For SCO Unix V rel. 3.2.0
+ # -compile using rcc, cc does not cope with gram.c
+ # -edit /usr/include/curses.h, rcc does not understand #error
+ # -link: make CC=cc, rcc's loader gets unresolved __cclass, __range
+ # (rather strange,?)
+ #CC=rcc
+ #SIGVOID=-DSIGVOID
+ #CFLAGS= -O -DSYSV3
+ #LDFLAGS=
+ #LIB=-lm -lcurses -ltinfo -lPW
+
# All of the source files
SRC=sc.h sc.c lex.c gram.y interp.c crypt.c xmalloc.c cmds.c range.c help.c \
vi.c eres.sed sres.sed Makefile psc.c vmtbl.c version.c
***************
*** 81,87
# The objects
OBJS=sc.o interp.o cmds.o crypt.o xmalloc.o range.o help.o vi.o lex.o gram.o \
! vmtbl.o version.o
# The documents in the Archive
DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES BSD_BUGS
--- 102,108 -----
# The objects
OBJS=sc.o interp.o cmds.o crypt.o xmalloc.o range.o help.o vi.o lex.o gram.o \
! vmtbl.o format.o version.o
# The documents in the Archive
DOCS=README CHANGES sc.doc psc.doc tutorial.sc VMS_NOTES BSD_BUGS
***************
*** 107,113
$(CC) ${CFLAGS} ${INTERNATIONAL} ${PAGER} ${SIGVOID} -c sc.c
interp.o: interp.c sc.h
! $(CC) ${CFLAGS} ${IEEE_MATH} ${SIGVOID} -c interp.c
gram.o: sc.h y.tab.h
--- 128,134 -----
$(CC) ${CFLAGS} ${INTERNATIONAL} ${PAGER} ${SIGVOID} -c sc.c
interp.o: interp.c sc.h
! $(CC) ${CFLAGS} ${IEEE_MATH} ${SIGVOID} ${RINT} -c interp.c
gram.o: sc.h y.tab.h
***************
*** 121,126
help.o: help.c sc.h
vi.o: vi.c sc.h
y.tab.h: gram.y
--- 142,149 -----
help.o: help.c sc.h
+ format.o: format.c
+
vi.o: vi.c sc.h
y.tab.h: gram.y
***************
*** 154,160
prc sc.h gram.y sc.c lex.c interp.c cmds.c crypt.c | lpr
$(name).1: sc.doc
! sed -e s/pname/$(name)/g -e s/PNAME/$(NAME)/g sc.doc > $(name).1
$(name).man: $(name).1
nroff -man $(name).1 > $(name).man
--- 177,184 -----
prc sc.h gram.y sc.c lex.c interp.c cmds.c crypt.c | lpr
$(name).1: sc.doc
! sed -e s/pname/$(name)/g -e s/PNAME/$(NAME)/g \
! -e s%#LIBDIR#%$(LIBDIR)%g sc.doc > $(name).1
$(name).man: $(name).1
nroff -man $(name).1 > $(name).man
***************
*** 168,174
p$(name).man: p$(name).1
nroff -man p$(name).1 > p$(name).man
! install: $(EXDIR)/$(name)
inst-man: $(MANDIR)/$(name).1
--- 192,198 -----
p$(name).man: p$(name).1
nroff -man p$(name).1 > p$(name).man
! install: $(EXDIR)/$(name) $(LIBDIR)/tutorial
inst-man: $(MANDIR)/$(name).1
***************
*** 176,181
-mv $(EXDIR)/$(name) $(EXDIR)/$(name).old
cp $(name) $(EXDIR)
strip $(EXDIR)/$(name)
$(MANDIR)/$(name).1: $(name).1
cp $(name).1 $(MANDIR)
--- 200,209 -----
-mv $(EXDIR)/$(name) $(EXDIR)/$(name).old
cp $(name) $(EXDIR)
strip $(EXDIR)/$(name)
+
+ $(LIBDIR)/tutorial: tutorial.sc
+ -mkdir $(LIBDIR)
+ cp tutorial.sc $(LIBDIR)
$(MANDIR)/$(name).1: $(name).1
cp $(name).1 $(MANDIR)
*** posted/TODO Mon Sep 24 09:34:09 1990
--- TODO Wed Sep 5 15:19:17 1990
***************
*** 1,54
- done/tested: (Jeff Buhrt)
- 6.7
- 1) added a per row memory allocation
- -runs in about 1/2 run time and 1/3 the space of 6.6vm.1
- -insert/delete row now just moves pointers (# == maxrow+1-currow)
- and blanks one row (of columns (maxcol))
- -as the number of cells grows the size is more linear
- (no more ##Meg images except for 100,000's of rows....)
- -row to column pointer translation is done by a macro (ATBL)
- that returns a pointer to the cell pointer.
- *ATBL would be a pointer to a *ent (cell).
- -the maximum # of columns is limited by ABSMAXCOLS or
- sizeof(struct ent *)*maxcols (whichever is smaller)
- (702 * 4 = 2808 is no real limit even for 286 large model)
- -the maximum # of rows is limited by the virtual memory limit or
- sizeof(struct ent **)*maxrows (whichever is smaller)
- (4*X=64k, X=16384 rows (excluding malloc overhead) on
- a '286 large model. Even w/ 3.25Meg and 10Mhz)
- (plus of course any memory used for cells)
- 2) dolookup (int vs double)
- 3) dolookup calling eval w/ ent * not enode *
- (dolookup called w/ ent * not enode *)
- 4) cleaned up a lot of .... *x = 0 to (.... *)0 (cmds, interp)
- 5) psc: fwidth/precision were reversed on the output
- 6) Backup copy (on save) using same mode to [path/]#file~
- (will prompt if a backup fails)
- 7) put y/n prompt function into yn_ask(mesg)
- 8) found a move(x,y) in sc -> move(y,x) and only move when needed
- 9) we use FullUpdate || changed (to see if ANY cells changed)
- before trying to redraw the screen in update
- (now we don't try to redraw every time a key is hit)
- -if we are stand[ing]out we do not create a cell just to force a
- standout inside the repaint section of update()
- -only draw blank cells if we cleared it or it is standing out
- reason: the less work (what to update) curses has to do, the faster
- a screen update will be (less cpu required)
- 14) {insert, delete}col replaced w/ {open,close}col(currow, numcol_to_insert)
- (limits looping)
- 6.7.1.1
- 15) goto nonexistant cell may loop
- 16) make sure that startup size will at least fill the screen w/ cells.
- 17) added version.c
- 6.7.1.2
- 18) When we would normally die w/o saving (SIGQUIT, etc), we now ask
- if people would like to save the current spreadsheet.
- If 'y', saves to the current file name, otherwise ~/SC.SAVE,
- then /tmp/SC.SAVE if all else fails.
- 6.7.1.3
- 19) don't use malloc.c for production code
- 20) progname is now truncated to just the basename (systems w/ long paths
- caused problems)
todo:
1) autobackup of things typed in.
--- 1,3 -----
todo:
1) autobackup of things typed in.
*** posted/cmds.c Mon Sep 24 09:34:48 1990
--- cmds.c Mon Sep 24 09:41:56 1990
***************
*** 7,13
*
* More mods Robert Bond, 12/86
*
! * $Revision: 6.8 $
*/
#include <curses.h>
--- 7,13 -----
*
* More mods Robert Bond, 12/86
*
! * $Revision: 6.9 $
*/
#include <curses.h>
***************
*** 583,588
{
register int i;
if (w > COLS - RESCOL - 2) {
error("Format too large - Maximum = %d", COLS - RESCOL - 2);
w = COLS-RESCOL-2;
--- 583,591 -----
{
register int i;
+ if (c1 >= maxcols && !growtbl(GROWCOL, 0, c1)) c1 = maxcols-1 ;
+ if (c2 >= maxcols && !growtbl(GROWCOL, 0, c2)) c2 = maxcols-1 ;
+
if (w > COLS - RESCOL - 2) {
error("Format too large - Maximum = %d", COLS - RESCOL - 2);
w = COLS-RESCOL-2;
***************
*** 647,653
int r0, c0, rn, cn;
{
FILE *f;
! char pline[FBUFLEN];
int plinelim;
int pid;
int fieldlen, nextcol;
--- 650,656 -----
int r0, c0, rn, cn;
{
FILE *f;
! char *pline;
int plinelim;
int fbufs_allocated = 0;
int pid;
***************
*** 649,654
FILE *f;
char pline[FBUFLEN];
int plinelim;
int pid;
int fieldlen, nextcol;
register row, col;
--- 652,658 -----
FILE *f;
char *pline;
int plinelim;
+ int fbufs_allocated = 0;
int pid;
int fieldlen, nextcol;
register row, col;
***************
*** 654,659
register row, col;
register struct ent **pp;
if ((strcmp(fname, curfile) == 0) &&
!yn_ask("Confirm that you want to destroy the data base: (y,n)"))
return;
--- 658,668 -----
register row, col;
register struct ent **pp;
+ if((pline = (char *)malloc(FBUFLEN * ++fbufs_allocated)) == (char *)NULL) {
+ error("Malloc failed in printfile()");
+ return;
+ }
+
if ((strcmp(fname, curfile) == 0) &&
!yn_ask("Confirm that you want to destroy the data base: (y,n)")) {
free((char *)pline);
***************
*** 655,661
register struct ent **pp;
if ((strcmp(fname, curfile) == 0) &&
! !yn_ask("Confirm that you want to destroy the data base: (y,n)"))
return;
if ((f = openout(fname, &pid)) == (FILE *)0)
--- 664,671 -----
}
if ((strcmp(fname, curfile) == 0) &&
! !yn_ask("Confirm that you want to destroy the data base: (y,n)")) {
! free((char *)pline);
return;
}
***************
*** 657,662
if ((strcmp(fname, curfile) == 0) &&
!yn_ask("Confirm that you want to destroy the data base: (y,n)"))
return;
if ((f = openout(fname, &pid)) == (FILE *)0)
{ error ("Can't create file \"%s\"", fname);
--- 667,673 -----
!yn_ask("Confirm that you want to destroy the data base: (y,n)")) {
free((char *)pline);
return;
+ }
if ((f = openout(fname, &pid)) == (FILE *)0)
{ error ("Can't create file \"%s\"", fname);
***************
*** 660,665
if ((f = openout(fname, &pid)) == (FILE *)0)
{ error ("Can't create file \"%s\"", fname);
return;
}
for (row=r0;row<=rn; row++) {
--- 671,677 -----
if ((f = openout(fname, &pid)) == (FILE *)0)
{ error ("Can't create file \"%s\"", fname);
+ free((char *)pline);
return;
}
for (row=r0;row<=rn; row++) {
***************
*** 682,687
if (*pp) {
char *s;
while (plinelim<c) pline[plinelim++] = ' ';
plinelim = c;
if ((*pp)->flags&is_valid) {
--- 694,713 -----
if (*pp) {
char *s;
+ /*
+ * dynamically allocate pline, making sure we are not
+ * attempting to write 'out of bounds'.
+ */
+ while(c > (fbufs_allocated * FBUFLEN)) {
+ if((pline = ((char *)realloc
+ ((char *)pline,
+ (unsigned)(FBUFLEN * ++fbufs_allocated))))
+ == NULL) {
+ error ("Realloc failed in printfile()");
+ free((char *)pline);
+ return;
+ }
+ }
while (plinelim<c) pline[plinelim++] = ' ';
plinelim = c;
if ((*pp)->flags&is_valid) {
***************
*** 685,692
while (plinelim<c) pline[plinelim++] = ' ';
plinelim = c;
if ((*pp)->flags&is_valid) {
! (void)sprintf (pline+plinelim,"%*.*f",fwidth[col],
! precision[col], (*pp)->v);
plinelim += strlen (pline+plinelim);
}
if (s = (*pp)->label) {
--- 711,738 -----
while (plinelim<c) pline[plinelim++] = ' ';
plinelim = c;
if ((*pp)->flags&is_valid) {
! while(plinelim + fwidth[col] >
! (fbufs_allocated * FBUFLEN)) {
! if((pline = ((char *)realloc
! ((char *)pline,
! (unsigned)(FBUFLEN * ++fbufs_allocated))))
! == NULL) {
! error ("Realloc failed in printfile()");
! free((char *)pline);
! return;
! }
! }
! if ((*pp)->format) {
! char field[FBUFLEN];
!
! (void) format ((*pp)->format, (*pp)->v, field,
! sizeof(field));
! (void) sprintf (pline+plinelim, "%*s", fwidth[col],
! field);
! } else {
! (void)sprintf (pline+plinelim,"%*.*f",fwidth[col],
! precision[col], (*pp)->v);
! }
plinelim += strlen (pline+plinelim);
}
if (s = (*pp)->label) {
***************
*** 709,714
if (slen > fieldlen)
slen = fieldlen;
/* Now justify and print */
start = (*pp)->flags & is_leftflush ? pline + c
: pline + c + fieldlen - slen;
--- 755,771 -----
if (slen > fieldlen)
slen = fieldlen;
+ while(c + fieldlen + 2 > (fbufs_allocated * FBUFLEN)) {
+ if((pline = ((char *)realloc
+ ((char *)pline,
+ (unsigned)(FBUFLEN * ++fbufs_allocated))))
+ == NULL) {
+ error ("Realloc failed in printfile()");
+ free((char *)pline);
+ return;
+ }
+ }
+
/* Now justify and print */
start = (*pp)->flags & is_leftflush ? pline + c
: pline + c + fieldlen - slen;
***************
*** 731,736
(void) fputs (pline, f);
}
closeout(f, pid);
}
--- 788,795 -----
(void) fputs (pline, f);
}
+ free((char *)pline);
+
closeout(f, pid);
}
***************
*** 780,787
if (*pp) {
char *s;
if ((*pp)->flags&is_valid) {
! (void) fprintf (f,"%.*f",precision[col],
! (*pp)->v);
}
if (s = (*pp)->label) {
(void) fprintf (f,"%s",s);
--- 839,854 -----
if (*pp) {
char *s;
if ((*pp)->flags&is_valid) {
! if ((*pp)->format) {
! char field[FBUFLEN];
!
! (void) format ((*pp)->format, (*pp)->v, field,
! sizeof(field));
! (void) fprintf (f, "%s", field);
! } else {
! (void) fprintf (f,"%.*f",precision[col],
! (*pp)->v);
! }
}
if (s = (*pp)->label) {
(void) fprintf (f,"%s",s);
***************
*** 1090,1096
n -> label = (char *)0;
if (p -> label) {
n -> label = (char *)
! xmalloc ((unsigned) (strlen (p -> label) + 1));
(void) strcpy (n -> label, p -> label);
}
}
--- 1157,1163 -----
n -> label = (char *)0;
if (p -> label) {
n -> label = (char *)
! xmalloc ((unsigned) (strlen (p -> label) + 1));
(void) strcpy (n -> label, p -> label);
}
n -> format = 0;
***************
*** 1093,1098
xmalloc ((unsigned) (strlen (p -> label) + 1));
(void) strcpy (n -> label, p -> label);
}
}
void
--- 1160,1171 -----
xmalloc ((unsigned) (strlen (p -> label) + 1));
(void) strcpy (n -> label, p -> label);
}
+ n -> format = 0;
+ if (p -> format) {
+ n -> format = (char *)
+ xmalloc ((unsigned) (strlen (p -> format) + 1));
+ (void) strcpy (n -> format, p -> format);
+ }
}
void
***************
*** 1137,1142
editv (r, c);
(void) fprintf (f, "%s\n",line);
}
}
}
}
--- 1210,1219 -----
editv (r, c);
(void) fprintf (f, "%s\n",line);
}
+ if ((*pp)->format) {
+ editfmt (r, c);
+ (void) fprintf (f, "%s\n",line);
+ }
}
}
if (rndinfinity)
***************
*** 1139,1144
}
}
}
}
int
--- 1216,1223 -----
}
}
}
+ if (rndinfinity)
+ fprintf(f, "set rndinfinity\n");
}
int
*** posted/crypt.c Mon Sep 24 09:34:53 1990
--- crypt.c Mon Sep 24 09:41:59 1990
***************
*** 2,8
* Encryption utilites
* Bradley Williams
* {allegra,ihnp4,uiucdcs,ctvax}!convex!williams
! * $Revision: 6.8 $
*/
#include <stdio.h>
--- 2,8 -----
* Encryption utilites
* Bradley Williams
* {allegra,ihnp4,uiucdcs,ctvax}!convex!williams
! * $Revision: 6.9 $
*/
#include <stdio.h>
***************
*** 23,28
#endif
int Crypt = 0;
creadfile (save, eraseflg)
char *save;
--- 23,30 -----
#endif
int Crypt = 0;
+ #define MAXKEYWORDSIZE 30
+ char KeyWord[MAXKEYWORDSIZE] = NULL;
creadfile (save, eraseflg)
char *save;
***************
*** 49,54
}
deraw();
if ((pid=fork()) == 0) /* if child */
{
(void) close (0); /* close stdin */
--- 51,59 -----
}
deraw();
+ strcpy(KeyWord, getpass("Enter key:"));
+ goraw();
+
if ((pid=fork()) == 0) /* if child */
{
(void) close (0); /* close stdin */
***************
*** 57,63
(void) dup (fildes); /* standard in from file */
(void) dup (pipefd[1]); /* connect to pipe */
(void) fprintf (stderr, " ");
! (void) execl ("/bin/sh", "sh", "-c", "crypt", (char *)0);
exit (-127);
}
else /* else parent */
--- 62,69 -----
(void) dup (fildes); /* standard in from file */
(void) dup (pipefd[1]); /* connect to pipe */
(void) fprintf (stderr, " ");
! (void) execl ("/bin/crypt", "crypt", KeyWord, 0);
!
exit (-127);
}
else /* else parent */
***************
*** 82,88
(void) fclose (f);
(void) close (pipefd[0]);
while (pid != wait(&fildes)) /**/;
- goraw();
linelim = -1;
modflg++;
if (eraseflg) {
--- 88,93 -----
(void) fclose (f);
(void) close (pipefd[0]);
while (pid != wait(&fildes)) /**/;
linelim = -1;
modflg++;
if (eraseflg) {
***************
*** 134,140
return(-1);
}
! deraw();
if ((pid=fork()) == 0) /* if child */
{
(void) close (0); /* close stdin */
--- 139,150 -----
return(-1);
}
! if (KeyWord[0] == NULL) {
! deraw();
! strcpy(KeyWord, getpass("Enter key:"));
! goraw();
! }
!
if ((pid=fork()) == 0) /* if child */
{
(void) close (0); /* close stdin */
***************
*** 143,149
(void) dup (pipefd[0]); /* connect to pipe input */
(void) dup (fildes); /* standard out to file */
(void) fprintf (stderr, " ");
! (void) execl ("/bin/sh", "sh", "-c", "crypt", 0);
exit (-127);
}
else /* else parent */
--- 153,159 -----
(void) dup (pipefd[0]); /* connect to pipe input */
(void) dup (fildes); /* standard out to file */
(void) fprintf (stderr, " ");
! (void) execl ("/bin/crypt", "crypt", KeyWord, 0);
exit (-127);
}
else /* else parent */
***************
*** 168,175
(void) strcpy(curfile,save);
modflg = 0;
! error ("File \"%s\" written", curfile);
! goraw();
return(0);
}
--- 178,184 -----
(void) strcpy(curfile,save);
modflg = 0;
! error ("File \"%s\" written (encrypted).", curfile);
return(0);
}
*** posted/format.c Mon Sep 24 09:54:28 1990
--- format.c Mon Sep 24 09:42:10 1990
***************
*** 0
--- 1,461 -----
+ /*****************************************************************************
+ *
+ * Mark Nagel <nagel at ics.uci.edu>
+ * 20 July 1989
+ *
+ * $Revision: 6.9 $
+ *
+ * bool
+ * format(fmt, num, buf, buflen)
+ * char *fmt;
+ * double num;
+ * char buf[];
+ * int buflen;
+ *
+ * The format function will produce a string representation of a number
+ * given a _format_ (described below) and a double value. The result is
+ * written into the passed buffer -- if the resulting string is too
+ * long to fit into the passed buffer, the function returns false.
+ * Otherwise the function returns true.
+ *
+ * The fmt parameter contains the format to use to convert the number.
+ *
+ * # Digit placeholder. If the number has fewer digits on either
+ * side of the decimal point than there are '#' characters in
+ * the format, the extra '#' characters are ignored. The number
+ * is rounded to the number of digit placeholders as there are
+ * to the right of the decimal point. If there are more digits
+ * in the number than there are digit placeholders on the left
+ * side of the decimal point, then those digits are displayed.
+ *
+ * 0 Digit placeholder. Same as for '#' except that the number
+ * is padded with zeroes on either side of the decimal point.
+ * The number of zeroes used in padding is determined by the
+ * number of digit placeholders after the '0' for digits on
+ * the left side of the decimal point and by the number of
+ * digit placeholders before the '0' for digits on the right
+ * side of the decimal point.
+ *
+ * . Decimal point. Determines how many digits are placed on
+ * the right and left sides of the decimal point in the number.
+ * Note that numbers smaller than 1 will begin with a decimal
+ * point if the left side of the decimal point contains only
+ * a '#' digit placeholder. Use a '0' placeholder to get a
+ * leading zero in decimal formats.
+ *
+ * % Percentage. For each '%' character in the format, the actual
+ * number gets multiplied by 100 (only for purposes of formatting
+ * -- the original number is left unmodified) and the '%' character
+ * is placed in the same position as it is in the format.
+ *
+ * , 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.
+ *
+ * \ Quote. This character causes the next character to be
+ * inserted into the formatted string directly with no
+ * special interpretation.
+ *
+ * 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
+ * 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 '-'.
+ *
+ * ; Format selector. Use this character to separate the format
+ * into two distinct formats. The format to the left of the
+ * ';' character will be used if the number given is zero or
+ * positive. The format to the right of the ';' character is
+ * used if the number given is negative.
+ *
+ * Any
+ * Self insert. Any other character will be inserted directly
+ * into the formatted number with no change made to the actual
+ * number.
+ *
+ *****************************************************************************/
+
+ /*****************************************************************************/
+
+ #include <stdio.h>
+
+ #define bool int
+ #define true 1
+ #define false 0
+ #define EOS '\0'
+ #define MAXBUF 256
+
+ extern char
+ *strcpy();
+
+ static char
+ *fmt_int(),
+ *fmt_frac(),
+ *fmt_exp();
+
+ static void
+ reverse();
+
+ /*****************************************************************************/
+
+ bool
+ format(fmt, val, buf, buflen)
+ char *fmt;
+ double val;
+ char *buf;
+ int buflen;
+ {
+ register char *cp;
+ char *tmp, *tp, *tmpfmt;
+ bool comma = false, negative = false;
+ char *integer = NULL, *decimal = NULL;
+ char *exponent = NULL;
+ int exp_val, width;
+ char prtfmt[32];
+ char *mantissa;
+ char *fraction = NULL;
+ int zero_pad = 0;
+
+ if (fmt == NULL)
+ return;
+
+ fmt = tmpfmt = strcpy((char *) xmalloc(strlen(fmt) + 1), fmt);
+ mantissa = (char *) xmalloc(buflen + 1);
+
+ /*
+ * select positive or negative format if necessary
+ */
+ for (cp = fmt; *cp != ';' && *cp != EOS; cp++)
+ {
+ if (*cp == '\\')
+ cp++;
+ }
+ if (*cp == ';')
+ {
+ if (val < 0.0)
+ {
+ val = -val; /* format should provide sign if desired */
+ fmt = cp + 1;
+ }
+ else
+ {
+ *cp = EOS;
+ }
+ }
+
+ /*
+ * extract other information from format and produce new
+ * malloc'ed format string
+ */
+ tmp = (char *) xmalloc(strlen(fmt) + 1);
+ for (cp = fmt, tp = tmp; *cp != EOS; cp++)
+ {
+ switch (*cp)
+ {
+ case '\\':
+ *tp++ = *cp++;
+ *tp++ = *cp;
+ break;
+
+ case ',':
+ comma = true;
+ break;
+
+ case '.':
+ if (decimal == NULL)
+ decimal = tp;
+ *tp++ = *cp;
+ break;
+
+ case '%':
+ val *= 100.0;
+ *tp++ = *cp;
+ break;
+
+ default:
+ *tp++ = *cp;
+ break;
+ }
+ }
+ *tp = EOS;
+ xfree(tmpfmt);
+ fmt = tmp;
+
+ /*
+ * extract the exponent from the format if present
+ */
+ for (cp = fmt; *cp != EOS; cp++)
+ {
+ if (*cp == '\\')
+ {
+ cp++;
+ }
+ else if (*cp == 'e' || *cp == 'E')
+ {
+ if (cp[1] == '+' || cp[1] == '-')
+ {
+ tmp = (char *) xmalloc(strlen(cp) + 1);
+ exponent = strcpy(tmp, cp);
+ *cp = EOS;
+ exp_val = 0;
+ while (val < 1.0)
+ {
+ val *= 10.0;
+ exp_val--;
+ }
+ while (val >= 10.0)
+ {
+ val /= 10.0;
+ exp_val++;
+ }
+ break;
+ }
+ }
+ }
+
+ /*
+ * determine maximum decimal places and use sprintf
+ * to build initial character form of formatted value.
+ */
+ width = 0;
+ if (decimal)
+ {
+ *decimal++ = EOS;
+ for (cp = decimal; *cp != EOS; cp++)
+ {
+ switch (*cp)
+ {
+ case '\\':
+ cp++;
+ break;
+
+ case '#':
+ width++;
+ break;
+
+ case '0':
+ zero_pad = ++width;
+ break;
+ }
+ }
+ zero_pad = strlen(decimal) - zero_pad;
+ }
+ if (val < 0.0)
+ {
+ negative = true;
+ val = -val;
+ }
+ sprintf(prtfmt, "%%.%dlf", width);
+ sprintf(mantissa, prtfmt, val);
+ for (cp = integer = mantissa; *cp != '.' && *cp != EOS; cp++)
+ {
+ if (*integer == '0')
+ integer++;
+ }
+ if (*cp == '.')
+ {
+ fraction = cp + 1;
+ *cp = EOS;
+ cp = fraction + strlen(fraction) - 1;
+ for (; zero_pad > 0; zero_pad--, cp--)
+ {
+ if (*cp == '0')
+ *cp = EOS;
+ }
+ }
+
+ /*
+ * format the puppy
+ */
+ {
+ char *ci, *cf, *ce;
+ int len_ci, len_cf, len_ce;
+ bool ret = false;
+
+ ci = fmt_int(integer, fmt, comma, negative);
+ ci = strcpy((char *)xmalloc((len_ci = strlen(ci)) + 1), ci);
+ cf = (fraction) ? fmt_frac(fraction, decimal) : "";
+ cf = strcpy((char *)xmalloc((len_cf = strlen(cf)) + 1), cf);
+ ce = (exponent) ? fmt_exp(exp_val, exponent) : "";
+ ce = strcpy((char *)xmalloc((len_ce = strlen(ce)) + 1), ce);
+ if (len_ci + len_cf + len_ce < buflen)
+ {
+ sprintf(buf, "%s%s%s", ci, cf, ce);
+ ret = true;
+ }
+
+ /*
+ * free up malloc'ed memory
+ */
+ xfree(mantissa);
+ xfree(fmt);
+ if (exponent) xfree(exponent);
+ xfree(ci);
+ xfree(cf);
+ xfree(ce);
+
+ return (ret);
+ }
+ }
+
+ /*****************************************************************************/
+
+ static char *
+ fmt_int(val, fmt, comma, negative)
+ char *val; /* integer part of the value to be formatted */
+ char *fmt; /* integer part of the format */
+ bool comma; /* true if we should comma-ify the value */
+ bool negative; /* true if the value is actually negative */
+ {
+ int digit, f, v;
+ int thousands = 0;
+ char *cp;
+ static char buf[MAXBUF];
+ char *bufptr = buf;
+
+ /*
+ * locate the leftmost digit placeholder
+ */
+ for (cp = fmt; *cp != EOS; cp++)
+ {
+ if (*cp == '\\')
+ cp++;
+ else if (*cp == '#' || *cp == '0')
+ break;
+ }
+ digit = (*cp == EOS) ? -1 : cp - fmt;
+
+ /*
+ * format the value
+ */
+ f = strlen(fmt) - 1;
+ v = (digit >= 0) ? strlen(val) - 1 : -1;
+ while (f >= 0 || v >= 0)
+ {
+ if (f > 0 && fmt[f-1] == '\\')
+ {
+ *bufptr++ = fmt[f--];
+ }
+ else if (f >= 0 && (fmt[f] == '#' || fmt[f] == '0'))
+ {
+ if (v >= 0 || fmt[f] == '0')
+ {
+ *bufptr++ = v < 0 ? '0' : val[v];
+ if (comma && (thousands = (thousands + 1) % 3) == 0 && v > 0)
+ {
+ *bufptr++ = ',';
+ }
+ v--;
+ }
+ }
+ else if (f >= 0)
+ {
+ *bufptr++ = fmt[f];
+ }
+ if (v >= 0 && f == digit)
+ {
+ continue;
+ }
+ f--;
+ }
+
+ if (negative && digit >= 0)
+ *bufptr++ = '-';
+ *bufptr = EOS;
+ reverse(buf);
+
+ return (buf);
+ }
+
+ /*****************************************************************************/
+
+ static char *
+ fmt_frac(val, fmt)
+ char *val; /* fractional part of the value to be formatted */
+ char *fmt; /* fractional portion of format */
+ {
+ static char buf[MAXBUF];
+ register char *bufptr = buf;
+ register char *fmtptr = fmt, *valptr = val;
+
+ *bufptr++ = '.';
+ while (*fmtptr != EOS)
+ {
+ if (*fmtptr == '\\')
+ {
+ *bufptr++ = *++fmtptr;
+ }
+ else if (*fmtptr == '#' || *fmtptr == '0')
+ {
+ if (*valptr != EOS || *fmtptr == '0')
+ {
+ *bufptr++ = (*valptr != EOS) ? *valptr++ : *fmtptr;
+ }
+ }
+ else
+ {
+ *bufptr++ = *fmtptr;
+ }
+ fmtptr++;
+ }
+ *bufptr = EOS;
+
+ return (buf);
+ }
+
+ /*****************************************************************************/
+
+ static char *
+ fmt_exp(val, fmt)
+ int val; /* value of the exponent */
+ char *fmt; /* exponent part of the format */
+ {
+ static char buf[MAXBUF];
+ register char *bufptr = buf;
+ char valbuf[64];
+ bool negative = false;
+
+ *bufptr++ = *fmt++;
+ if (*fmt++ == '+')
+ *bufptr++ = (val < 0) ? '-' : '+';
+ else if (val < 0)
+ *bufptr++ = '-';
+ *bufptr = EOS;
+
+ if (val < 0)
+ {
+ val = -val;
+ negative = true;
+ }
+ sprintf(valbuf, "%d", val);
+
+ strcat(buf, fmt_int(valbuf, fmt, false, negative));
+ return (buf);
+ }
+
+ /*****************************************************************************/
+
+ static void
+ reverse(buf)
+ register char *buf;
+ {
+ register char *cp = buf + strlen(buf) - 1;
+ register char tmp;
+
+ while (buf < cp)
+ {
+ tmp = *cp;
+ *cp-- = *buf;
+ *buf++ = tmp;
+ }
+ }
+
+ /*****************************************************************************/
+
*** posted/gram.y Mon Sep 24 09:35:10 1990
--- gram.y Mon Sep 24 09:42:13 1990
***************
*** 9,15
*
* More mods by Alan Silverstein, 3/88, see list of changes.
*
! * $Revision: 6.8 $
*/
--- 9,15 -----
*
* More mods by Alan Silverstein, 3/88, see list of changes.
*
! * $Revision: 6.9 $
*/
***************
*** 46,51
%token <sval> WORD
%token <ival> COL
%token S_FORMAT
%token S_LABEL
%token S_LEFTSTRING
%token S_RIGHTSTRING
--- 46,52 -----
%token <sval> WORD
%token <ival> COL
%token S_FORMAT
+ %token S_FMT
%token S_LABEL
%token S_LEFTSTRING
%token S_RIGHTSTRING
***************
*** 140,145
%token K_TBL
%token K_LATEX
%token K_TEX
%left '?' ':'
%left '|'
--- 141,147 -----
%token K_TBL
%token K_LATEX
%token K_TEX
+ %token K_RNDINFINITY
%left '?' ':'
%left '|'
***************
*** 223,228
lookat(currow, curcol), $2, $3); }
| S_FILL var_or_range num num
{ fill($2.left.vp, $2.right.vp, $3, $4); }
| S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
| S_GOTO num {num_search($2);}
| S_GOTO STRING {str_search($2);}
--- 225,232 -----
lookat(currow, curcol), $2, $3); }
| S_FILL var_or_range num num
{ fill($2.left.vp, $2.right.vp, $3, $4); }
+ | S_FMT var_or_range STRING
+ { format_cell($2.left.vp, $2.right.vp, $3); }
| S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
| S_GOTO num {num_search($2);}
| S_GOTO STRING {str_search($2);}
***************
*** 418,421
| K_TBLSTYLE '=' K_TBL { tbl_style = TBL; }
| K_TBLSTYLE '=' K_LATEX { tbl_style = LATEX; }
| K_TBLSTYLE '=' K_TEX { tbl_style = TEX; }
;
--- 422,427 -----
| K_TBLSTYLE '=' K_TBL { tbl_style = TBL; }
| K_TBLSTYLE '=' K_LATEX { tbl_style = LATEX; }
| K_TBLSTYLE '=' K_TEX { tbl_style = TEX; }
+ | K_RNDINFINITY { rndinfinity = 1; FullUpdate++;}
+ | '!' K_RNDINFINITY { rndinfinity = 0; FullUpdate++;}
;
*** posted/help.c Mon Sep 24 09:35:31 1990
--- help.c Mon Sep 24 09:42:17 1990
***************
*** 1,7
/*
* Help functions for sc
* R. Bond, 1988
! * $Revision: 6.8 $
*/
#include <curses.h>
--- 1,7 -----
/*
* Help functions for sc
* R. Bond, 1988
! * $Revision: 6.9 $
*/
#include <curses.h>
***************
*** 53,58
" iterations=n Set the number of iterations allowed. (10)",
" tblstyle=xx Set ``T'' output style to:",
" 0 (none), tex, latex, or tbl.",
(char *)0
};
--- 53,59 -----
" iterations=n Set the number of iterations allowed. (10)",
" tblstyle=xx Set ``T'' output style to:",
" 0 (none), tex, latex, or tbl.",
+ " rndinfinity Round to infinity (round .5 up vs to nearest even).",
(char *)0
};
***************
*** 91,96
" \",> Enter a right justified string or string expression.",
" e Edit the current cell's numeric value.",
" E Edit the current cell's string part.",
" x Clear the current cell.",
" c Copy the last marked cell to the current cell.",
" m Mark a cell to be used as the source for ``c''",
--- 92,98 -----
" \",> Enter a right justified string or string expression.",
" e Edit the current cell's numeric value.",
" E Edit the current cell's string part.",
+ " F Assign a format to the current cell's numeric value.",
" x Clear the current cell.",
" c Copy the last marked cell to the current cell.",
" m Mark a cell to be used as the source for ``c''",
***************
*** 192,199
" as ``A10'' or a range such as ``a1:b20''.",
" /s Shows the currently defined range names. Pipe output to",
" sort, then to less.",
! " /u Use this command to undefine a previously defined range",
! " name.",
" ",
" Range operations affect a rectangular region on the screen",
" defined by the upper left and lower right cells in the region.",
--- 194,201 -----
" as ``A10'' or a range such as ``a1:b20''.",
" /s Shows the currently defined range names. Pipe output to",
" sort, then to less.",
! " /u Use this command to undefine a previously defined range name.",
! " /F Assign a format string to a range of cells.",
" ",
" Range operations affect a rectangular region on the screen",
" defined by the upper left and lower right cells in the region.",
*** posted/interp.c Mon Sep 24 09:36:32 1990
--- interp.c Mon Sep 24 09:42:28 1990
***************
*** 7,13
*
* More mods Robert Bond, 12/86
* More mods by Alan Silverstein, 3-4/88, see list of changes.
! * $Revision: 6.8 $
*/
#define DEBUGDTS 1 /* REMOVE ME */
--- 7,13 -----
*
* More mods Robert Bond, 12/86
* More mods by Alan Silverstein, 3-4/88, see list of changes.
! * $Revision: 6.9 $
*/
#define DEBUGDTS 1 /* REMOVE ME */
***************
*** 86,91
double fn1_eval();
double fn2_eval();
struct ent *firstev = (struct ent *)0; /* first expr in the eval list */
#define PI (double)3.14159265358979323846
#define dtr(x) ((x)*(PI/(double)180.0))
--- 86,92 -----
double fn1_eval();
double fn2_eval();
struct ent *firstev = (struct ent *)0; /* first expr in the eval list */
+ double rint();
#define PI (double)3.14159265358979323846
#define dtr(x) ((x)*(PI/(double)180.0))
***************
*** 719,729
case TAN: return (fn1_eval( tan, eval(e->e.o.right)));
case DTR: return (dtr(eval(e->e.o.right)));
case RTD: return (rtd(eval(e->e.o.right)));
! case RND: {
! double temp;
! temp = eval(e->e.o.right);
! return(temp-floor(temp) < 0.5 ?
! floor(temp) : ceil(temp));
}
case ROUND: {
double temp = eval(e->e.o.left);
--- 720,747 -----
case TAN: return (fn1_eval( tan, eval(e->e.o.right)));
case DTR: return (dtr(eval(e->e.o.right)));
case RTD: return (rtd(eval(e->e.o.right)));
! case RND:
! if (rndinfinity)
! { double temp = eval(e->e.o.right);
! return(temp-floor(temp) < 0.5 ?
! floor(temp) : ceil(temp));
! }
! else
! return rint(eval(e->e.o.right));
! case ROUND:
! { int prec = (int) eval(e->e.o.right);
! double scal = 1;
! if (0 < prec)
! do scal *= 10; while (0 < --prec);
! else if (prec < 0)
! do scal /= 10; while (++prec < 0);
!
! if (rndinfinity)
! { double temp = eval(e->e.o.left);
! temp *= scal;
! temp = ((temp-floor(temp)) < 0.5 ?
! floor(temp) : ceil(temp));
! return(temp / scal);
}
else
return(rint(eval(e->e.o.left) * scal) / scal);
***************
*** 725,739
return(temp-floor(temp) < 0.5 ?
floor(temp) : ceil(temp));
}
! case ROUND: {
! double temp = eval(e->e.o.left);
! int prec = (int) eval(e->e.o.right), scal = 1;
! while (prec-- > 0) scal *= 10;
! temp *= scal;
! temp = ((temp-floor(temp)) < 0.5 ?
! floor(temp) : ceil(temp));
! return(temp / scal);
! }
case FV:
case PV:
case PMT: return(finfunc(e->op,eval(e->e.o.left),
--- 743,751 -----
floor(temp) : ceil(temp));
return(temp / scal);
}
! else
! return(rint(eval(e->e.o.left) * scal) / scal);
! }
case FV:
case PV:
case PMT: return(finfunc(e->op,eval(e->e.o.left),
***************
*** 1732,1737
}
#endif /* EXPRTREE*/
void
hide_row(arg)
int arg;
--- 1744,1781 -----
}
#endif /* EXPRTREE*/
+ format_cell(v1, v2, s)
+ struct ent *v1, *v2;
+ char *s;
+ {
+ register r,c;
+ register struct ent *n;
+ int maxr, maxc;
+ int minr, minc;
+
+ maxr = v2->row;
+ maxc = v2->col;
+ minr = v1->row;
+ minc = v1->col;
+ if (minr>maxr) r = maxr, maxr = minr, minr = r;
+ if (minc>maxc) c = maxc, maxc = minc, minc = c;
+ checkbounds(&maxr, &maxc);
+ if (minr < 0) minr = 0;
+ if (minr < 0) minr = 0;
+
+ FullUpdate++;
+ for (r = minr; r <= maxr; r++)
+ for (c = minc; c <= maxc; c++) {
+ n = lookat (r, c);
+ if (n->format)
+ xfree(n->format);
+ n->format = 0;
+ if (s && *s != '\0')
+ n->format = strcpy((char *)xmalloc(strlen(s)+1), s);
+ n->flags |= is_changed;
+ }
+ }
+
void
hide_row(arg)
int arg;
***************
*** 1780,1785
if (v->expr)
efree(v, v->expr);
v->expr = (struct enode *)0;
v->flags |= (is_changed);
v->flags &= ~(is_valid);
changed++;
--- 1824,1832 -----
if (v->expr)
efree(v, v->expr);
v->expr = (struct enode *)0;
+ if (v->format)
+ xfree(v->format);
+ v->format = (char *)0;
v->flags |= (is_changed);
v->flags &= ~(is_valid);
changed++;
***************
*** 2118,2123
line[linelim++] = ')';
}
void
editv (row, col)
int row, col;
--- 2165,2182 -----
line[linelim++] = ')';
}
+ editfmt (row, col)
+ int row, col;
+ {
+ register struct ent *p;
+
+ p = lookat (row, col);
+ if (p->format) {
+ (void)sprintf (line, "fmt %s \"%s\"", v_name(row, col), p->format);
+ linelim = strlen(line);
+ }
+ }
+
void
editv (row, col)
int row, col;
***************
*** 2167,2169
linelim += 1;
}
}
--- 2226,2242 -----
linelim += 1;
}
}
+
+ #ifdef RINT
+ double rint(d) double d;
+ {
+ /* as sent */
+ double fl = floor(d), fr = d-fl;
+ return
+ fr<0.5 || fr==0.5 && fl==floor(fl/2)*2 ? fl : ceil(d);
+ /**/
+ /* double fl = floor(d), fr = d-fl;
+ return((fr<0.5) || ((fr==0.5) && (fl==floor(fl/2)*2)) ? fl : ceil(d));
+ */
+ }
+ #endif
*** posted/lex.c Mon Sep 24 09:36:49 1990
--- lex.c Mon Sep 24 09:42:31 1990
***************
*** 7,13
*
* More mods Robert Bond, 12/86
* More mods by Alan Silverstein, 3/88, see list of changes.
! * $Revision: 6.8 $
*
*/
--- 7,13 -----
*
* More mods Robert Bond, 12/86
* More mods by Alan Silverstein, 3/88, see list of changes.
! * $Revision: 6.9 $
*
*/
***************
*** 340,346
char *ktmp;
static char buf[1024]; /* Why do I have to do this again? */
! if (tgetent(buf, getenv("TERM")) <= 0)
return;
km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b');
--- 340,350 -----
char *ktmp;
static char buf[1024]; /* Why do I have to do this again? */
! if (!(ktmp = getenv("TERM"))) {
! (void) fprintf(stderr, "TERM environment variable not set\n");
! exit (1);
! }
! if (tgetent(buf, ktmp) <= 0)
return;
km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b');
*** posted/psc.c Mon Sep 24 09:37:00 1990
--- psc.c Wed Sep 12 10:32:18 1990
***************
*** 13,19
* -f suppress 'format' lines in output
*
* Author: Robert Bond
! * $Revision: 6.8 $
*/
#include <ctype.h>
--- 13,20 -----
* -f suppress 'format' lines in output
*
* Author: Robert Bond
! * Adjustments: Jeff Buhrt and Eric Putz
! * $Revision: 6.10 $
*/
#include <ctype.h>
***************
*** 128,134
case END:
if(drop_format) exit(0);
for (i = 0; i<maxcols; i++) {
! if (precision[i])
(void) printf("format %s %d %d\n", coltoa(i),
fwidth[i], precision[i]+1);
}
--- 129,135 -----
case END:
if(drop_format) exit(0);
for (i = 0; i<maxcols; i++) {
! if (fwidth[i])
(void) printf("format %s %d %d\n", coltoa(i),
fwidth[i]+1, precision[i]);
}
***************
*** 130,136
for (i = 0; i<maxcols; i++) {
if (precision[i])
(void) printf("format %s %d %d\n", coltoa(i),
! fwidth[i], precision[i]+1);
}
exit(0);
case NUM:
--- 131,137 -----
for (i = 0; i<maxcols; i++) {
if (fwidth[i])
(void) printf("format %s %d %d\n", coltoa(i),
! fwidth[i]+1, precision[i]);
}
exit(0);
case NUM:
***************
*** 154,163
while (*p) {
p++; i++; j++;
}
! if (precision[effc] < j)
! precision[effc] = j;
! if (fwidth[effc] < i)
! fwidth[effc] = i;
break;
case ALPHA:
first = 0;
--- 155,178 -----
while (*p) {
p++; i++; j++;
}
! { int ow, nw;
!
! ow = fwidth[effc] - precision[effc];
! if (precision[effc] < j)
! precision[effc] = j;
!
! if (fwidth[effc] < i)
! fwidth[effc] = i;
!
! /* now make sure:
! * 1234.567890 (format 11 6)
! * 1234567.890 (format 11 3)
! * both show (format 14 6)
! * (really it uses 15 6 to separate columns)
! */
! if ((nw = i - j) > ow)
! fwidth[effc] += nw - (fwidth[effc] - precision[effc]);
! }
break;
case ALPHA:
first = 0;
***************
*** 172,179
}
}
i = strlen(token);
! if (i > precision[effc])
! precision[effc] = i;
break;
case SPACE:
if (first && strip_delim)
--- 187,194 -----
}
}
i = strlen(token);
! if (i > fwidth[effc])
! fwidth[effc] = i;
break;
case SPACE:
if (first && strip_delim)
***************
*** 214,219
{
register int c;
register char *p;
p = token;
c = getchar();
--- 229,235 -----
{
register int c;
register char *p;
+ register int founddigit;
p = token;
c = getchar();
***************
*** 251,256
p = token;
c = *p;
if (isdigit(c) || c == '.' || c == '-' || c == '+') {
while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
|| c == 'E') {
--- 267,273 -----
p = token;
c = *p;
+ founddigit = 0;
if (isdigit(c) || c == '.' || c == '-' || c == '+') {
while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
|| c == 'E') {
***************
*** 254,259
if (isdigit(c) || c == '.' || c == '-' || c == '+') {
while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
|| c == 'E') {
c = *p++;
}
if (c == 0)
--- 271,278 -----
if (isdigit(c) || c == '.' || c == '-' || c == '+') {
while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
|| c == 'E') {
+ if (isdigit(c))
+ founddigit = 1;
c = *p++;
}
if (c == 0 && founddigit)
***************
*** 256,262
|| c == 'E') {
c = *p++;
}
! if (c == 0)
return(NUM);
else
return(ALPHA);
--- 275,281 -----
founddigit = 1;
c = *p++;
}
! if (c == 0 && founddigit)
return(NUM);
else
return(ALPHA);
*** posted/sc.c Mon Sep 24 09:37:52 1990
--- sc.c Mon Sep 24 09:42:47 1990
***************
*** 8,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.8 $
*
*/
--- 8,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 $
*
*/
***************
*** 78,83
int autocalc = 1 ; /* 1 to calculate after each update */
int calc_order = BYROWS;
int tbl_style = 0; /* headers for T command output */
int lastmx, lastmy; /* Screen address of the cursor */
int lastcol; /* Spreadsheet Column the cursor was in last */
--- 78,84 -----
int autocalc = 1 ; /* 1 to calculate after each update */
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 */
***************
*** 117,122
(*pp)->flags = 0;
(*pp)->expr = (struct enode *)0;
(*pp)->v = (double) 0.0;
(*pp)->evnext = (struct ent *)0;
}
return *pp;
--- 118,124 -----
(*pp)->flags = 0;
(*pp)->expr = (struct enode *)0;
(*pp)->v = (double) 0.0;
+ (*pp)->format = (char *)0;
(*pp)->evnext = (struct ent *)0;
}
return *pp;
***************
*** 392,398
if ((*pp) -> flags & is_valid) {
char field[FBUFLEN];
! (void)sprintf(field,"%*.*f", fwidth[col], precision[col], (*pp)->v);
if(strlen(field) > fwidth[col]) {
for(i = 0; i<fwidth[col]; i++)
(void)addch('*');
--- 394,406 -----
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);
! }
if(strlen(field) > fwidth[col]) {
for(i = 0; i<fwidth[col]; i++)
(void)addch('*');
***************
*** 397,402
for(i = 0; i<fwidth[col]; i++)
(void)addch('*');
} else {
(void)addstr(field);
}
}
--- 405,412 -----
for(i = 0; i<fwidth[col]; i++)
(void)addch('*');
} else {
+ for(i = 0; i < fwidth[col] - strlen(field); i++)
+ (void)addch(' ');
(void)addstr(field);
}
}
***************
*** 803,809
case ctl('t'):
error(
! "Toggle: a:auto c:cell e:ext funcs n:numeric t:top x:encrypt $:pre-scale");
(void) refresh();
switch (nmgetch()) {
--- 813,819 -----
case ctl('t'):
error(
! "Toggle: a:auto c:cell e:ext funcs n:numeric t:top x:encrypt $:pre-scale");
(void) refresh();
switch (nmgetch()) {
***************
*** 876,881
temp = strcpy(xmalloc((unsigned)(strlen(line)+1)),line);
templim = linelim;
editexp(currow,curcol);
temp1= strcpy(xmalloc((unsigned)(strlen(line)+1)),line);
strcpy(line, temp);
--- 886,892 -----
temp = strcpy(xmalloc((unsigned)(strlen(line)+1)),line);
templim = linelim;
+ linelim = 0; /* reset line to empty */
editexp(currow,curcol);
temp1= strcpy(xmalloc((unsigned)(strlen(line)+1)),line);
strcpy(line, temp);
***************
*** 1033,1039
case '/':
error (
! "Range: x:erase v:value c:copy f:fill d:define s:show u:undefine");
(void) refresh();
switch (nmgetch()) {
--- 1044,1050 -----
case '/':
error (
! "Range: x:erase v:value c:copy f:fill d:define s:show u:undefine F:fmt");
(void) refresh();
switch (nmgetch()) {
***************
*** 1096,1101
}
else error("No ranges defined");
break;
case ESC:
case ctl('g'):
--- 1107,1118 -----
}
else error("No ranges defined");
break;
+ case 'F':
+ (void) sprintf(line, "fmt [range \"format\"] ");
+ linelim = strlen(line);
+ startshow();
+ insert_mode();
+ break;
case ESC:
case ctl('g'):
***************
*** 1283,1288
linelim = strlen (line);
insert_mode();
break;
case 'g':
(void) sprintf (line, "goto [v] ");
linelim = strlen (line);
--- 1300,1311 -----
linelim = strlen (line);
insert_mode();
break;
+ case 'F':
+ (void) sprintf(line, "fmt [format] %s \"",
+ v_name(currow, curcol));
+ linelim = strlen(line);
+ insert_mode();
+ break;
case 'g':
(void) sprintf (line, "goto [v] ");
linelim = strlen (line);
***************
*** 1327,1333
break;
case 'S': /* set options */
(void) sprintf (line, "set ");
! error("Options: byrows, bycols, iterations=n, tblstyle=(0|tbl|latex|tex)");
linelim = strlen (line);
insert_mode();
break;
--- 1350,1356 -----
break;
case 'S': /* set options */
(void) sprintf (line, "set ");
! error("Options: byrows, bycols, iterations=n, tblstyle=(0|tbl|latex|tex), rndinfinity");
linelim = strlen (line);
insert_mode();
break;
*** posted/sc.doc Mon Sep 24 09:38:48 1990
--- sc.doc Mon Sep 24 09:48:12 1990
***************
*** 15,21
.\" - TPs use default indent except for function names, then 18.
.\" - Smallify uppercase strings.
.\" - Avoid passive voice and third person.
! .\" $Revision: 6.8 $
.\"
.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.9 $
.\"
.TH PNAME 1
.SH NAME
***************
*** 61,66
and/or an expression (formula)
which evaluates to a numeric value or label string,
often based on other cell values.
.\" ----------
.PP
Options are:
--- 61,70 -----
and/or an expression (formula)
which evaluates to a numeric value or label string,
often based on other cell values.
+ .LP
+ For a on-line tutorial, type the command:
+ .IP
+ pname #LIBDIR#/tutorial.sc
.\" ----------
.SH OPTIONS
.\" ----------
***************
*** 62,69
which evaluates to a numeric value or label string,
often based on other cell values.
.\" ----------
! .PP
! Options are:
.\" ----------
.TP
.B \-c
--- 66,72 -----
.IP
pname #LIBDIR#/tutorial.sc
.\" ----------
! .SH OPTIONS
.\" ----------
.TP
.B \-c
***************
*** 324,329
.TP
.BR toprow / !toprow
Set/clear top row display mode.
.RE
.\" ==========
.SS "Cursor Control Commands"
--- 327,337 -----
.TP
.BR toprow / !toprow
Set/clear top row display mode.
+ .TP
+ .BR rndinfinity / !rndinfinity
+ default: round-to-even (banker's round), *.5 will round to the closest even
+ number; doing a 'set rndinfinity' will round *.5 up to the next integer
+ (rounding to infinity).
.RE
.\" ==========
.SS "Cursor Control Commands"
***************
*** 504,509
.B >
Enter a label string into the current cell
to be flushed right against the right edge of the cell.
.PD
.\" ----------
.PP
--- 512,518 -----
.B >
Enter a label string into the current cell
to be flushed right against the right edge of the cell.
+ .\" ----------
.PD
.TP
.B F
***************
*** 505,510
Enter a label string into the current cell
to be flushed right against the right edge of the cell.
.PD
.\" ----------
.PP
Strings you enter must start with ".
--- 514,601 -----
to be flushed right against the right edge of the cell.
.\" ----------
.PD
+ .TP
+ .B F
+ Enter a format string into the current cell. This format string
+ overrides the precision specified with the ``f'' command.
+ The format only applies to numeric values. The following
+ characters can be used to build a format string:
+ .RS
+ .TP
+ .BR #
+ Digit placeholder. If the number has fewer digits on either
+ side of the decimal point than there are `#' characters in
+ the format, the extra `#' characters are ignored. The number
+ is rounded to the number of digit placeholders as there are
+ to the right of the decimal point. If there are more digits
+ in the number than there are digit placeholders on the left
+ side of the decimal point, then those digits are displayed.
+ .TP
+ .BR 0
+ Digit placeholder.
+ Same as for `#' except that the number
+ is padded with zeroes on either side of the decimal point.
+ The number of zeroes used in padding is determined by the
+ number of digit placeholders after the `0' for digits on
+ the left side of the decimal point and by the number of
+ digit placeholders before the `0' for digits on the right
+ side of the decimal point.
+ .TP
+ .BR .
+ Decimal point.
+ Determines how many digits are placed on
+ the right and left sides of the decimal point in the number.
+ Note that numbers smaller than 1 will begin with a decimal
+ point if the left side of the decimal point contains only
+ a `#' digit placeholder. Use a `0' placeholder to get a
+ leading zero in decimal formats.
+ .TP
+ .BR %
+ Percentage.
+ For each `%' character in the format, the actual
+ number gets multiplied by 100 (only for purposes of formatting
+ -- the original number is left unmodified) and the `%' character
+ is placed in the same position as it is in the format.
+ .TP
+ .BR ,
+ 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
+ .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+
+ 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
+ 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
+ .BR ;
+ Format selector.
+ Use this character to separate the format
+ into two distinct formats. The format to the left of the
+ `;' character will be used if the number given is zero or
+ positive. The format to the right of the `;' character is
+ used if the number given is negative.
+ .RE
+ .IP
+ Some example formats are integer (``0'' or ``#''),
+ fixed (``0.00''), percentage (``0%'' or ``0.00%''),
+ scientific (``0.00E+00''),
+ and currency (``$#,0.00;($#,0.00)'').
.\" ----------
.PP
Strings you enter must start with ".
***************
*** 520,525
This is identical to ``=''
except that the command line starts out containing
the old numeric value or expression associated with the cell.
.\" ----------
.TP
.B E
--- 611,662 -----
This is identical to ``=''
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
***************
*** 527,532
This is identical to ``<'', ``"'', or ``>''
except that the command line starts out containing
the old string value or expression associated with the cell.
.\" ----------
.PP
To enter and edit a cell's number part, use the ``='' and
--- 664,672 -----
This is identical to ``<'', ``"'', or ``>''
except that the command line starts out containing
the old string value or expression associated with the cell.
+ SEE
+ .B e
+ ABOVE.
.\" ----------
.PP
To enter and edit a cell's number part, use the ``='' and
***************
*** 909,914
.TP
.B /u
Use this command to undefine a previously defined range name.
.\" ==========
.SS "Miscellaneous Commands"
.\" ----------
--- 1049,1058 -----
.TP
.B /u
Use this command to undefine a previously defined range name.
+ .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"
.\" ----------
***************
*** 1378,1383
Round
.I e
to the nearest integer.
.TP 18
.BR @round (e,n)
Round
--- 1522,1529 -----
Round
.I e
to the nearest integer.
+ default: round-to-even (banker's round), *.5 will round to the closest even
+ number; 'set rndinfinity' will round *.5 up to the next integer.
.TP 18
.BR @round (e,n)
Round
***************
*** 1385,1390
to
.I n
decimal places.
.\" ----------
.TP 18
.BR @abs (e)
--- 1531,1539 -----
to
.I n
decimal places.
+ n may be positive to round off the right side of the decimal,
+ and negative to round off the left side. See @rnd(e) above for rounding
+ types.
.\" ----------
.TP 18
.BR @abs (e)
***************
*** 1778,1794
with (perhaps) recourse to relaxation should be implemented.
.\" ----------
.PP
- Editing is crude.
- All you can do is backspace over and retype text to be altered.
- There is no easy way to switch a leftstring to a rightstring or vice versa.
- Of course, you can always write the spreadsheet to a file with
- .IR Put ,
- edit it by calling an editor on the file with ``!'',
- and read it back with
- .I Get
- -- if you are comfortable editing spreadsheet files.
- .\" ----------
- .PP
Only one previous value is saved from any call of
.IR @ext ().
If it is used more than once in a spreadsheet
--- 1927,1932 -----
with (perhaps) recourse to relaxation should be implemented.
.\" ----------
.PP
Only one previous value is saved from any call of
.IR @ext ().
If it is used more than once in a spreadsheet
***************
*** 1808,1810
.PP
Many commands give no indication (a message or beep) if they have null effect.
Some should give confirmation of their action, but they don't.
--- 1946,1983 -----
.PP
Many commands give no indication (a message or beep) if they have null effect.
Some should give confirmation of their action, but they don't.
+ .SH AUTHORS
+ This is a much modified version of a public domain spread sheet
+ originally authored by James Gosling,
+ and subsequently modified and posted to USENET by Mark Weiser under the name
+ .IR vc .
+ The program was subsequently renamed
+ .IR sc ,
+ 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:
+ Gregory Bond,
+ Peter Brower,
+ John Campbell,
+ Lawrence Cipriani,
+ Chris Cole,
+ Glen Ditchfield
+ Sam Drake,
+ Kurt Horton,
+ Peter King,
+ Dave Lewis,
+ Rick Linck,
+ Soren Lundsgaard,
+ Tad Mannes,
+ Rob McMahon,
+ Marius Olafsson,
+ Rick Perry,
+ R. P. C. Rodgers,
+ Alan Silverstein,
+ and
+ Andy Valencia.
+ .\" end of man page
*** posted/sc.h Mon Sep 24 09:38:59 1990
--- sc.h Mon Sep 24 09:42:50 1990
***************
*** 6,12
* University of Maryland
* R. Bond 12/86
* More mods by Alan Silverstein, 3-4/88, see list of changes.
! * $Revision: 6.8 $
*
*/
--- 6,12 -----
* University of Maryland
* R. Bond 12/86
* More mods by Alan Silverstein, 3-4/88, see list of changes.
! * $Revision: 6.9 $
*
*/
***************
*** 68,73
struct ent *next; /* next deleted ent */
struct ent *evnext; /* next ent w/ a object to eval */
struct ent *evprev; /* prev ent w/ a object to eval */
};
struct range {
--- 68,74 -----
struct ent *next; /* next deleted ent */
struct ent *evnext; /* next ent w/ a object to eval */
struct ent *evprev; /* prev ent w/ a object to eval */
+ char *format;
};
struct range {
***************
*** 338,343
extern int loading;
extern int getrcqual;
extern int tbl_style;
extern char *progname;
#if BSD42 || SYSIII
--- 339,345 -----
extern int loading;
extern int getrcqual;
extern int tbl_style;
+ extern int rndinfinity;
extern char *progname;
#if BSD42 || SYSIII
*** posted/version.c Mon Sep 24 09:39:08 1990
--- version.c Mon Sep 24 09:45:54 1990
***************
*** 4,7
* The part after the first colon, except the last char, appears on the screen.
*/
! char *rev = "$Revision: 6.8 $";
--- 4,7 -----
* The part after the first colon, except the last char, appears on the screen.
*/
! char *rev = "$Revision: 6.9 $";
*** posted/vi.c Mon Sep 24 09:39:19 1990
--- vi.c Mon Sep 24 09:42:58 1990
***************
*** 1,7
/* SC A Spreadsheet Calculator
*
* One line vi emulation
! * $Revision: 6.8 $
*/
--- 1,7 -----
/* SC A Spreadsheet Calculator
*
* One line vi emulation
! * $Revision: 6.9 $
*/
***************
*** 36,42
#define EDIT_MODE 1 /* Edit mode */
#define REP_MODE 2 /* Replace mode */
#define SEARCH_MODE 3 /* Get arguments for '/' command */
!
static int mode = INSERT_MODE;
static char *history[HISTLEN];
static int histp = -1;
--- 36,44 -----
#define EDIT_MODE 1 /* Edit mode */
#define REP_MODE 2 /* Replace mode */
#define SEARCH_MODE 3 /* Get arguments for '/' command */
!
! #define DOTLEN 200
!
static int mode = INSERT_MODE;
static char *history[HISTLEN];
static int histp = -1;
***************
*** 43,49
static char *last_search;
static char *undo_line;
static int undo_lim;
! static char dotb[100];
static int doti = 0;
static int do_dot = 0;
--- 45,51 -----
static char *last_search;
static char *undo_line;
static int undo_lim;
! static char dotb[DOTLEN];
static int doti = 0;
static int do_dot = 0;
***************
*** 47,52
static int doti = 0;
static int do_dot = 0;
void
write_line(c)
int c;
--- 49,55 -----
static int doti = 0;
static int do_dot = 0;
+
void
write_line(c)
int c;
***************
*** 116,121
mode = EDIT_MODE;
mode_ind = 'e';
histp = -1;
if (line[linelim] == '\0')
linelim = back_line();
}
--- 119,126 -----
mode = EDIT_MODE;
mode_ind = 'e';
histp = -1;
+ if (linelim < 0) /* -1 says stop editing, ...so we still aren't */
+ return;
if (line[linelim] == '\0')
linelim = back_line();
}
***************
*** 151,158
if (do_dot)
return;
! dotb[doti++] = c;
! dotb[doti] = 0;
}
dotcmd()
--- 156,166 -----
if (do_dot)
return;
! if (doti < DOTLEN-1)
! {
! dotb[doti++] = c;
! dotb[doti] = NULL;
! }
}
static int dotcalled = 0;
***************
*** 155,160
dotb[doti] = 0;
}
dotcmd()
{
int c;
--- 163,170 -----
}
}
+ static int dotcalled = 0;
+
dotcmd()
{
int c;
***************
*** 159,164
{
int c;
do_dot = 1;
doti = 0;
while(dotb[doti] != 0) {
--- 169,176 -----
{
int c;
+ if (dotcalled) /* stop recursive calling of dotcmd() */
+ return;
do_dot = 1;
doti = 0;
while(dotb[doti] != 0) {
***************
*** 163,168
doti = 0;
while(dotb[doti] != 0) {
c = dotb[doti++];
write_line(c);
}
do_dot = 0;
--- 175,181 -----
doti = 0;
while(dotb[doti] != 0) {
c = dotb[doti++];
+ dotcalled = 1;
write_line(c);
}
do_dot = 0;
***************
*** 167,172
}
do_dot = 0;
doti = 0;
}
vigetch()
--- 180,186 -----
}
do_dot = 0;
doti = 0;
+ dotcalled = 0;
}
vigetch()
***************
*** 351,356
{
register int i, len;
len = strlen(line);
for (i = len; i >= linelim; --i)
line[i+1] = line[i];
--- 365,374 -----
{
register int i, len;
+ if (linelim < 0)
+ { *line = 0;
+ linelim = 0;
+ }
len = strlen(line);
for (i = len; i >= linelim; --i)
line[i+1] = line[i];
***************
*** 380,385
{
int c;
c = vigetch();
if (line[linelim] != 0) {
line[linelim] = c;
--- 398,407 -----
{
int c;
+ if (linelim < 0)
+ { linelim = 0;
+ *line = 0;
+ }
c = vigetch();
if (line[linelim] != 0) {
line[linelim] = c;
***************
*** 393,398
{
register int len;
len = strlen(line);
line[linelim++] = c;
if (linelim > len)
--- 415,424 -----
{
register int len;
+ if (linelim < 0)
+ { linelim = 0;
+ *line = 0;
+ }
len = strlen(line);
line[linelim++] = c;
if (linelim > len)
*** posted/vmtbl.c Mon Sep 24 09:39:25 1990
--- vmtbl.c Mon Sep 24 09:43:00 1990
***************
*** 49,55
if (*colp < 0)
*colp = 0;
else if (*colp >= maxcols)
! { if (!growtbl(GROWCOL, 0, *colp));
*colp = maxcols-1;
}
}
--- 49,55 -----
if (*colp < 0)
*colp = 0;
else if (*colp >= maxcols)
! { if (!growtbl(GROWCOL, 0, *colp))
*colp = maxcols-1;
}
}
More information about the Comp.sources.bugs
mailing list