home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum7.lzh
/
C
/
VC
/
sc.c
< prev
next >
Wrap
Text File
|
1988-09-23
|
17KB
|
892 lines
/* SC A Spreadsheet Calculator
* Main driver
*
* original by James Gosling, September 1982
* modifications by Mark Weiser and Bruce Israel,
* University of Maryland
*
* Adapted to Os-9 August 1988 by Uwe Simon West-Germany
*/
#include <signal.h>
#include "vc.h"
#include <stdio.h>
/* default column width */
#define DEFWIDTH 10
#define DEFPREC 2
extern int lines;
extern int colms;
char curfile[1024];
char field[1024];
char hilf[80]; /* merker bei insertmodus */
int ins =0; /* insertmode */
int batch;
error (fmt,a,b,c,d,e) {
if (batch) fprintf(stderr,fmt,a,b,c,d,e);
else
{
gotoXY (0,1);
printf (fmt,a,b,c,d,e);
cleoln ();
}
}
int seenerr;
yyerror (err)
char *err; {
char h[80];
if (seenerr)
return;
seenerr++;
gotoXY (0,1);
sprintf (h, "%%s: %%.%ds<=%%s",linelim);
printf (h, err, line, line+linelim);
cleoln ();
}
struct ent *lookat(row,col){
register struct ent **p;
p = &tbl[row][col];
if (*p==0) {
*p = (struct ent *) malloc (sizeof (struct ent));
if (row>maxrow)
maxrow = row;
if (col>maxcol)
maxcol = col;
(*p)->label = 0;
(*p)->flags = 0;
(*p)->row = row;
(*p)->col = col;
(*p)->expr = 0;
}
return *p;
}
update_field(p,r,c,row,col,opt)
struct ent *p;
int r;
int c;
int row;
int col;
int opt;
{
char *s;
char h[30];
gotoXY (c, r);
if(p)
{
p-> flags &= ~is_changed;
if (p -> flags & is_valid)
{
sprintf(h,"%%%d.%df",fwidth[col],precision[col]);
printf (h, p -> v);
fflush(stdout);
}
else
if (s = p -> label)
{
strncpy(field,s,fwidth[col]);
field[fwidth[col]] = 0;
if(p->flags & is_leftflush)
sprintf(h,"%%%ds",fwidth[col]);
else
sprintf(h,"%-%%ds",fwidth[col]);
printf(h,field);
fflush(stdout);
}
else
{
sprintf(h,"%-%%ds",fwidth[col]);
printf(h," ");
fflush(stdout);
}
return;
}
if(opt || (p == 0))
{
sprintf(h,"%%%ds",fwidth[col]);
printf(h," ");
fflush(stdout);
}
}
select_field(mode)
int mode;
{
int col;
int lastmx;
int lastmy;
lastmy = currow - strow + 3;
lastmx = 4;
for (col = stcol; col <= curcol;)
lastmx += fwidth[col++];
if(mode)
sout_on();
update_field(tbl[currow][curcol],lastmy, lastmx - fwidth[curcol], currow, curcol,1);
if(mode)
mvaddstr (lastmy, lastmx, "<");
else
mvaddstr (lastmy, lastmx, " ");
sout_off();
gotoXY(lastmx, lastmy);
}
update () {
register row,
col;
register struct ent **p;
int maxcol;
int rows;
int cols;
rows = lines -3;
if (curcol < stcol)
stcol = curcol, FullUpdate++;
if (currow < strow)
strow = currow, FullUpdate++;
while (1) {
register i;
for (i = stcol, cols = 0, col = 4;
(col + fwidth[i]) < colms && i < MAXCOLS;
i++)
col += fwidth[i], cols++;
if (curcol >= stcol + cols)
stcol++, FullUpdate++;
else
break;
}
if (currow >= strow + rows)
strow = currow - rows + 2, FullUpdate++;
maxcol = stcol + cols - 1;
if (FullUpdate)
{
int i,h;
gotoXY (0,2);
cleop();
unsc_on();
printf("r\\c| ");
for( i=stcol;i<=maxcol; i++)
{
char h[80];
sprintf(h,"%%%dd|",fwidth[i]-1);
printf(h,i);
}
fflush(stdout);
unsc_off();
}
for (row = strow + rows - 1; row >= strow; row--) {
register c = 4;
register int r;
r = row - strow + 3;
if(FullUpdate)
{
gotoXY(0,r);
printf("%3d|",row);
fflush(stdout);
}
for (p = &tbl[row][col = stcol]; col <= maxcol; col++, p++) {
if (*p && ((*p) -> flags & is_changed || FullUpdate)) {
update_field(*p,r,c,row,col,0);
}
c += fwidth[col];
}
}
select_field(1);
gotoXY (0, 0);
if (line[0])
{
printf("%s %s ", ins?">>":"->", line);
}
FullUpdate = 0;
fflush(stdout);
}
#define ctl(c) ('c' & 0x1f)
/* non-meta getchar */
#define nmgetch() (getchar() & 0x7f)
main (argc, argv)
char **argv; {
int inloop;
register int c;
int edistate;
int arg;
int narg;
int nedistate;
int running;
char h[80];
inloop = 1; edistate = -1; nedistate = -1; running =1; arg = 1;
linelim = -1; changed = 0;
{
register i;
batch = 0;
for (i = 0; i < MAXCOLS; i++) {
fwidth[i] = DEFWIDTH;
precision[i] = DEFPREC;
}
}
curfile[0]=0;
stdin->_flag |= _UNBUF;
set_up("TERM");
if (argc > 1 && (! strcmp(argv[1],"-b"))) {
argc--, argv++;
batch = 1;
}
if (! batch) {
clscr();
/* initscr();
clear ();
raw (); */
filter_off ();
}
if (argc > 1) {
strcpy(curfile,argv[1]);
readfile (argv[1],0); }
modflg = 0;
FullUpdate =1;
if (batch) exit(0);
error ("Welcome to the Spreadsheet Calculator, type '?' for help.");
while (inloop) { running = 1;
while (running) {
nedistate = -1;
narg = 1; if (edistate < 0 && linelim < 0 && (changed || FullUpdate))
EvalAll (), changed = 0;
if(ins)
{
line[linelim] =0;
strcat(line,hilf);
}
else
hilf[0]=0;
update ();
/* refresh (); */
if(linelim>=0)
gotoXY(linelim+3,0);
else
gotoXY(0,0);
c = nmgetch ();
if(seenerr)
{
gotoXY(0,1);
cleoln();
}
seenerr = 0;
if(ins)
{
if(linelim >=0)
strcpy(hilf, &line[linelim]);
else
hilf[0]=0;
}
if (c < ' ')
{
if((c!= ctl(v)) && (c != ctl(e)) && (c!= ctl(h)))
select_field(0);
switch (c) {
case ctl (z):
/* noraw (); */
filter_on ();
/* kill(getpid(),SIGTSTP); */
/* the pc stops here */
clscr();
exit(0);
/* raw (); */
filter_off ();
break;
case ctl (r):
FullUpdate++;
/* clearok(stdscr,1); */
break;
default:
error ("No such command (^%c)", c + 0100);
break;
case ctl (b):
while (--arg>=0) if (curcol)
curcol--;
break;
case ctl (c):
running = 0;
break;
case ctl (f):
while (--arg>=0) if (curcol < MAXCOLS - 1)
curcol++;
break;
case ctl (d):
if(linelim >= 0)
{
if(line[linelim])
strcpy(&line[linelim], &line[linelim+1]);
else
linelim--;
}
break;
case ctl ([):
ins =0;
linelim = -1;
gotoXY (0,0);
cleoln ();
gotoXY (0,1);
cleoln ();
break;
case ctl (k):
if((linelim >= 0) &&line[linelim])
linelim++;
break;
case ctl (h):
if (linelim > 0)
linelim--;
break;
case ctl(i):
ins = 1-ins;
if(ins)
{
if(linelim >=0)
strcpy(hilf, &line[linelim]);
else
hilf[0]=0;
}
break;
case ctl (j):
if (currow >= MAXCOLS - 1 || maxcol >= MAXCOLS - 1)
{
error ("The table can't be any bigger");
break;
}
modflg++;
currow++;
openrow (currow);
for (curcol = 0; curcol <= maxcol; curcol++)
{
register struct ent *p;
p = tbl[currow - 1][curcol];
if (p)
{
register struct ent *n;
n = lookat (currow, curcol);
n -> v = p -> v;
n -> flags = p -> flags;
n -> expr = copye (p -> expr, 1, 0);
n -> label = 0;
if (p -> label)
{
n -> label = (char *)
malloc (strlen (p -> label) + 1);
strcpy (n -> label, p -> label);
}
}
}
for (curcol = 0; curcol <= maxcol; curcol++)
{
register struct ent *p = tbl[currow][curcol];
if (p && (p -> flags & is_valid) && !p -> expr)
break;
}
if (curcol > maxcol)
curcol = 0;
break;
case ctl (l):
FullUpdate++;
break;
case ctl (m):
ins =0;
if (linelim < 0)
line[linelim = 0] = 0;
else
{
int h;
h = linelim;
linelim = 0;
yyparse ();
if(seenerr)
linelim = h;
else
{
gotoXY(0,0);
cleoln();
linelim = -1;
}
}
break;
case ctl (n):
while (--arg>=0) if (currow < MAXROWS - 1)
currow++;
break;
case ctl (p):
while (--arg>=0) if (currow)
currow--;
break;
case ctl (q):
break; /* ignore flow control */
case ctl (s):
break; /* ignore flow control */
case ctl (u):
narg = arg * 4;
nedistate = 1;
break;
case ctl (v): /* insert variable name */
if (linelim > 0) {
sprintf (line + linelim, "r%dc%d", currow, curcol);
linelim = strlen (line);
}
break;
case ctl (e): /* insert variable expression */
if (linelim > 0) editexp(currow,curcol);
break;
case ctl (a): /* insert variable value */
if (linelim > 0) {
struct ent *p = tbl[currow][curcol];
if (p && p -> flags & is_valid) {
sprintf(h,"%%.%df",precision[curcol]);
sprintf (line + linelim, h, p -> v);
linelim = strlen (line);
}
}
break;
}
}
else
if ('0' <= c && c <= '9' && (linelim < 0 || edistate >= 0))
{
if (edistate != 0)
arg = 0;
nedistate = 0;
narg = arg * 10 + (c - '0');
}
else
{
if (linelim >= 0)
{
if(line[linelim] == 0)
{
line[linelim++] = c;
line[linelim] = 0;
}
else
line[linelim++] = c;
}
else
{
gotoXY(0,0);
cleoln();
switch (c)
{
case '.':
nedistate = 1;
break;
case '=':
sprintf (line, "let r%dc%d = ", currow, curcol);
linelim = strlen (line);
break;
case '?':
help ();
break;
case '"':
sprintf (line, "label r%dc%d = \"", currow, curcol);
linelim = strlen (line);
break;
case '<':
sprintf (line, "leftstring r%dc%d = \"", currow, curcol);
linelim = strlen (line);
break;
case '>':
sprintf (line, "rightstring r%dc%d = \"", currow, curcol);
linelim = strlen (line);
break;
case 'e':
editv (currow, curcol);
break;
case 'E':
edits (currow, curcol);
break;
case 'f':
sprintf (line, "format [for column] %d [is] ", curcol);
error("Current format is %d %d", fwidth[curcol],precision[curcol]);
linelim = strlen (line);
break;
case 'p':
sprintf (line, "put [database into] \"");
if (*curfile)
error("default file is '%s'",curfile);
linelim = strlen (line);
break;
case 'M':
sprintf (line, "merge [database from] \"");
linelim = strlen (line);
break;
case 'g':
sprintf (line, "get [database from] \"");
if (*curfile)
error("default file is '%s'",curfile);
linelim = strlen (line);
break;
case 'w':
sprintf (line, "write [listing to] \"");
linelim = strlen (line);
break;
case 'T': /* tbl output */
sprintf (line, "tbl [listing to] \"");
linelim = strlen (line);
break;
case 'r':
while (--arg>=0) openrow (currow);
break;
case 'd':
while (--arg>=0) closerow (currow);
break;
case 'c':
while (--arg>=0) opencol (curcol);
break;
case 'D':
while (--arg>=0) closecol (curcol);
break;
case 'C':
clearent(lookat(currow,curcol));
FullUpdate++;
break;
case 'Q':
running = 0;
break;
default:
if ((c & 0177) != c)
error("Weird character, decimal '%d'.\n", (int) c);
else
error ("No such command (%c)", c);
break;
}
}
}
edistate = nedistate;
arg = narg;
} /* while (running) */
inloop = modcheck(" before exiting");
} /* while (inloop) */
gotoXY (0, lines - 1);
/* refresh ();
noraw (); */
clscr();
filter_on ();
/* endwin (); */
}
modcheck(endstr) char *endstr; {
if (modflg && curfile[0]) {
char ch, lin[100];
gotoXY (0, 0);
cleoln ();
sprintf (lin,"File '%s' is modified, save%s? ",curfile,endstr);
addstr (lin);
/* refresh(); */
ch = nmgetch();
if (ch == 'y' || ch == 'Y') writefile(curfile);
else if (ch == ctl (g)) return(1);
}
return(0);
}
writefile (fname)
char *fname; {
register FILE *f;
register struct ent **p;
register r, c;
char save[1024];
if (*fname == 0) fname = &curfile[0];
strcpy(save,fname);
f = fopen (fname, "w");
if (f==0) {
error ("Can't create %s", fname);
return;
}
fprintf (f, "# This data file was generated by the Spreadsheet ");
fprintf (f, "Calculator.\n");
fprintf (f, "# You almost certainly shouldn't edit it.\n\n");
for (c=0; c<MAXCOLS; c++)
if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC)
fprintf (f, "format %d %d %d\n",c,fwidth[c],precision[c]);
for (r=0; r<=maxrow; r++) {
p = &tbl[r][0];
for (c=0; c<=maxcol; c++, p++)
if (*p) {
if ((*p)->label)
fprintf (f, "%sstring r%dc%d = \"%s\"\n",
(*p)->flags&is_leftflush ? "left" : "right",
r,c,(*p)->label);
if ((*p)->flags&is_valid) {
editv (r, c);
fprintf (f, "%s\n",line);
}
}
}
fclose (f);
strcpy(curfile,save);
modflg = 0;
error("File '%s' written.",curfile);
}
readfile (fname,eraseflg)
char *fname; int eraseflg; {
register FILE *f;
char save[1024];
if (*fname == 0) fname = &curfile[0];
strcpy(save,fname);
if (eraseflg && strcmp(fname,curfile) && modcheck(" first")) return;
f = fopen (save, "r");
if (f==0) {
error ("Can't read %s", save);
return;
}
if (eraseflg) erasedb ();
while (fgets(line,sizeof line,f)) {
linelim = 0;
if (line[0] != '#') yyparse ();
}
fclose (f);
linelim = -1;
modflg++;
if (eraseflg) {
strcpy(curfile,save);
modflg = 0;
}
EvalAll();
}
erasedb () {
register r, c;
for (c = 0; c<maxcol; c++) {
fwidth[c] = DEFWIDTH;
precision[c] = DEFPREC;
}
for (r = 0; r<=maxrow; r++) {
register struct ent **p = &tbl[r][0];
for (c=0; c++<=maxcol; p++)
if (*p) {
if ((*p)->expr) efree ((*p) -> expr);
if ((*p)->label) free ((*p) -> label);
free (*p);
*p = 0;
}
}
maxrow = 0;
maxcol = 0;
FullUpdate++;
}
openrow (rs) {
register r;
register struct ent **p;
register c;
if (maxcol >= MAXCOLS - 1) {
error ("The table can't be any bigger");
return;
}
for (r = ++maxrow; r > rs; r--)
for (c = maxcol + 1, p = &tbl[r][0]; --c >= 0; p++)
if (p[0] = p[-MAXCOLS])
p[0] -> row++;
p = &tbl[rs][0];
for (c = maxcol + 1; --c >= 0;)
*p++ = 0;
FullUpdate++;
modflg++;
}
closerow (r)
register r; {
register struct ent **p;
register c;
if (r > maxrow) return;
while (r<maxrow) {
for (c = maxcol+1, p = &tbl[r][0]; --c>=0; p++)
if (p[0] = p[MAXCOLS])
p[0]->row--;
r++;
}
p = &tbl[maxrow][0];
for (c=maxcol+1; --c>=0; ) *p++ = 0;
maxrow--;
FullUpdate++;
modflg++;
}
opencol (cs) {
register r;
register struct ent **p;
register c;
register lim;
int i;
lim = maxcol-cs+1;
for (i = MAXCOLS - 1; i > cs; i--) {
fwidth[i] = fwidth[i-1];
precision[i] = precision[i-1];
}
/* fwidth[cs] = DEFWIDTH;
precision[i] = DEFPREC; */
for (r=0; r<=maxrow; r++) {
p = &tbl[r][maxcol+1];
for (c=lim; --c>=0; p--)
if (p[0] = p[-1])
p[0]->col++;
p[0] = 0;
}
maxcol++;
FullUpdate++;
modflg++;
}
closecol (cs) {
register r;
register struct ent **p;
register c;
register lim;
int i;
lim = maxcol-cs;
if (lim < 0) return;
for (r=0; r<=maxrow; r++) {
p = &tbl[r][cs];
for (c=lim; --c>=0; p++)
if (p[0] = p[1])
p[0]->col++;
p[0] = 0;
}
for (i = cs; i < MAXCOLS - 1; i++) {
fwidth[i] = fwidth[i+1];
precision[i] = precision[i+1];
}
maxcol--;
FullUpdate++;
modflg++;
}
debugout(g,fmt,args) FILE *g; char *fmt; {
int i,op;
if (g == 0) g = fopen("debug","a"),op = 1;
if (g == 0) return;
fprintf(g, fmt, &args);
fflush(g);
if (op) fclose(g);
}
mvaddstr(row, col, s)
int row, col;
char *s;
{
gotoXY(col, row);
addstr(s);
}
addstr(s)
char *s;
{
printf("%s",s);
fflush(stdout);
}