📄 cmds.c
字号:
/* SC A Spreadsheet Calculator * Command routines * * original by James Gosling, September 1982 * modifications by Mark Weiser and Bruce Israel, * University of Maryland * * More mods Robert Bond, 12/86 * * $Revision: 6.8 $ */#include <curses.h>#if defined(BSD42) || defined(BSD43)#include <sys/file.h>#else#include <fcntl.h>#endif#include "sc.h"#include <signal.h>#include <errno.h>#ifdef BSD42#include <strings.h>#else#ifndef SYSIII#include <string.h>#endif#endif#ifdef SYSV3extern void exit();#elseextern int exit();#endifextern int errno;#define DEFCOLDELIM ':'voidduprow(){ if (currow >= maxrows - 1 || maxrow >= maxrows - 1) { if (!growtbl(GROWROW, 0, 0)) return; } modflg++; currow++; openrow (currow); for (curcol = 0; curcol <= maxcol; curcol++) { register struct ent *p = *ATBL(tbl, currow - 1, curcol); if (p) { register struct ent *n; n = lookat (currow, curcol); (void)copyent ( n, p, 1, 0); } } for (curcol = 0; curcol <= maxcol; curcol++) { register struct ent *p = *ATBL(tbl, currow, curcol); if (p && (p -> flags & is_valid) && !p -> expr) break; } if (curcol > maxcol) curcol = 0;}voiddupcol() { if (curcol >= maxcols - 1 || maxcol >= maxcols - 1) { if (!growtbl(GROWCOL, 0, 0)) return; } modflg++; curcol++; opencol (curcol, 1); for (currow = 0; currow <= maxrow; currow++) { register struct ent *p = *ATBL(tbl, currow, curcol - 1); if (p) { register struct ent *n; n = lookat (currow, curcol); copyent ( n, p, 0, 1); } } for (currow = 0; currow <= maxrow; currow++) { register struct ent *p = *ATBL(tbl, currow, curcol); if (p && (p -> flags & is_valid) && !p -> expr) break; } if (currow > maxrow) currow = 0;}voidinsertrow(arg)register int arg;{ while (--arg>=0) openrow (currow);}voiddeleterow(arg)register int arg;{ flush_saved(); erase_area(currow, 0, currow + arg - 1, maxcol); currow += arg; while (--arg>=0) closerow (--currow); sync_refs();}voidrowvalueize(arg)register int arg;{ valueize_area(currow, 0, currow + arg - 1, maxcol);}voidcolvalueize(arg)register int arg;{ valueize_area(0, curcol, maxrow, curcol + arg - 1);}voiderase_area(sr, sc, er, ec)int sr, sc, er, ec;{ register int r, c; register struct ent **pp; if (sr > er) { r = sr; sr = er; er= r; } if (sc > ec) { c = sc; sc = ec; ec= c; } if (sr < 0) sr = 0; if (sc < 0) sc = 0; checkbounds(&er, &ec); for (r = sr; r <= er; r++) { for (c = sc; c <= ec; c++) { pp = ATBL(tbl, r, c); if (*pp) { free_ent(*pp); *pp = (struct ent *)0; } } }}voidvalueize_area(sr, sc, er, ec)int sr, sc, er, ec;{ register int r, c; register struct ent *p; if (sr > er) { r = sr; sr = er; er= r; } if (sc > ec) { c = sc; sc = ec; ec= c; } if (sr < 0) sr = 0; if (sc < 0) sc = 0; checkbounds(&er, &ec); for (r = sr; r <= er; r++) { for (c = sc; c <= ec; c++) { p = *ATBL(tbl, r, c); if (p && p->expr) { efree(p, p->expr); p->expr = (struct enode *)0; p->flags &= ~is_strexpr; } } }}voidpullcells(to_insert)int to_insert;{ register struct ent *p, *n; register int deltar, deltac; int minrow, mincol; int mxrow, mxcol; int numrows, numcols; if (! to_fix) { error ("No data to pull"); return; } minrow = maxrows; mincol = maxcols; mxrow = 0; mxcol = 0; for (p = to_fix; p; p = p->next) { if (p->row < minrow) minrow = p->row; if (p->row > mxrow) mxrow = p->row; if (p->col < mincol) mincol = p->col; if (p->col > mxcol) mxcol = p->col; } numrows = mxrow - minrow + 1; numcols = mxcol - mincol + 1; deltar = currow - minrow; deltac = curcol - mincol; if (to_insert == 'r') { insertrow(numrows); deltac = 0; } else if (to_insert == 'c') { opencol(curcol, numcols); deltar = 0; } FullUpdate++; modflg++; for (p = to_fix; p; p = p->next) { n = lookat (p->row + deltar, p->col + deltac); (void) clearent(n); copyent( n, p, deltar, deltac); n -> flags = p -> flags & ~is_deleted; }}voidcolshow_op(){ register int i,j; for (i=0; i<maxcols; i++) if (col_hidden[i]) break; for(j=i; j<maxcols; j++) if (!col_hidden[j]) break; j--; if (i>=maxcols) error ("No hidden columns to show"); else { (void) sprintf(line,"show %s:", coltoa(i)); (void) sprintf(line + strlen(line),"%s",coltoa(j)); linelim = strlen (line); }}voidrowshow_op(){ register int i,j; for (i=0; i<maxrows; i++) if (row_hidden[i]) break; for(j=i; j<maxrows; j++) if (!row_hidden[j]) { break; } j--; if (i>=maxrows) error ("No hidden rows to show"); else { (void) sprintf(line,"show %d:%d", i, j); linelim = strlen (line); }}/* * Given a row/column command letter, emit a small menu, then read a qualifier * character for a row/column command and convert it to 'r' (row), 'c' * (column), or 0 (unknown). If ch is 'p', an extra qualifier 'm' is allowed. */intget_rcqual (ch) int ch;{ error ("%sow/column: r: row c: column%s", (ch == 'i') ? "Insert r" : (ch == 'a') ? "Append r" : (ch == 'd') ? "Delete r" : (ch == 'p') ? "Pull r" : (ch == 'v') ? "Values r" : (ch == 'z') ? "Zap r" : (ch == 's') ? "Show r" : "R", (ch == 'p') ? " m: merge" : ""); (void) refresh(); switch (nmgetch()) { case 'r': case 'l': case 'h': case ctl('f'): case ctl('b'): return ('r'); case 'c': case 'j': case 'k': case ctl('p'): case ctl('n'): return ('c'); case 'm': return ((ch == 'p') ? 'm' : 0); case ESC: case ctl('g'): return (ESC); default: return (0); } /*NOTREACHED*/}voidopenrow (rs)int rs;{ register r, c; struct ent **tmprow, **pp; if (rs > maxrow) maxrow = rs; if (maxrow >= maxrows - 1 || rs > maxrows - 1) { if (!growtbl(GROWROW, rs, 0)) return; } /* * save the last active row+1, shift the rows downward, put the last * row in place of the first */ tmprow = tbl[++maxrow]; for (r = maxrow; r > rs; r--) { row_hidden[r] = row_hidden[r-1]; tbl[r] = tbl[r-1]; pp = ATBL(tbl, r, 0); for (c = 0; c < maxcols; c++, pp++) if (*pp) (*pp)->row = r; } tbl[r] = tmprow; /* the last row was never used.... */ FullUpdate++; modflg++;}voidcloserow (r)register r;{ register struct ent **pp; register c; struct ent **tmprow; if (r > maxrow) return; /* save the row and empty it out */ tmprow = tbl[r]; pp = ATBL(tbl, r, 0); for (c=maxcol+1; --c>=0; pp++) { if (*pp) { free_ent(*pp); *pp = (struct ent *)0; } } /* move the rows, put the deleted row at the end */ for (; r < maxrows - 1; r++) { row_hidden[r] = row_hidden[r+1]; tbl[r] = tbl[r+1]; pp = ATBL(tbl, r, 0); for (c = 0; c < maxcols; c++, pp++) if (*pp) (*pp)->row = r; } tbl[r] = tmprow; maxrow--; FullUpdate++; modflg++;}voidopencol (cs, numcol)int cs;int numcol;{ register r; register struct ent **pp; register c; register lim = maxcol-cs+1; int i; if (cs > maxcol) maxcol = cs; maxcol += numcol; if ((maxcol >= maxcols - 1) && !growtbl(GROWCOL, 0, maxcol)) return; for (i = maxcol; i > cs; i--) { fwidth[i] = fwidth[i-numcol]; precision[i] = precision[i-numcol]; col_hidden[i] = col_hidden[i-numcol]; } for (c = cs; c - cs < numcol; c++) { fwidth[c] = DEFWIDTH; precision[c] = DEFPREC; } for (r=0; r<=maxrow; r++) { pp = ATBL(tbl, r, maxcol); for (c=lim; --c>=0; pp--) if (pp[0] = pp[-numcol]) pp[0]->col += numcol; pp = ATBL(tbl, r, cs); for (c = cs; c - cs < numcol; c++, pp++) *pp = (struct ent *)0; } FullUpdate++; modflg++;}voidclosecol (cs, numcol)int cs;int numcol;{ register r; register struct ent **pp; register struct ent *q; register c; register lim = maxcol-cs; int i; char buf[50]; if (lim - numcol < -1) { sprintf(buf, "Can't delete %d column%s %d columns left", numcol, (numcol > 1 ? "s," : ","), lim+1); error(buf); return; } flush_saved(); erase_area(0, curcol, maxrow, curcol + numcol - 1); sync_refs(); /* clear then copy the block left */ lim = maxcols - numcol - 1; for (r=0; r<=maxrow; r++) { for (c = cs; c - cs < numcol; c++) if (q = *ATBL(tbl, r, c)) free_ent(q); pp = ATBL(tbl, r, cs); for (c=cs; c <= lim; c++, pp++) { if (c > lim) *pp = (struct ent *)0; else if (pp[0] = pp[numcol]) pp[0]->col -= numcol; } c = numcol; for (; --c >= 0; pp++) *pp = (struct ent *)0; } for (i = cs; i < maxcols - numcol - 1; i++) { fwidth[i] = fwidth[i+numcol]; precision[i] = precision[i+numcol]; col_hidden[i] = col_hidden[i+numcol]; } for (; i < maxcols - 1; i++) { fwidth[i] = DEFWIDTH; precision[i] = DEFPREC; col_hidden[i] = 0; } maxcol -= numcol; FullUpdate++; modflg++;}voiddoend(rowinc, colinc)int rowinc, colinc;{ register struct ent *p; int r, c; if (VALID_CELL(p, currow, curcol)) { r = currow + rowinc; c = curcol + colinc; if (r >= 0 && r < maxrows && c >= 0 && c < maxcols && !VALID_CELL(p, r, c)) { currow = r; curcol = c;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -