home *** CD-ROM | disk | FTP | other *** search
- /* 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);
- }
-