⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	SC	A Spreadsheet Calculator *		Main driver * *		original by James Gosling, September 1982 *		modifications by Mark Weiser and Bruce Israel, *			University of Maryland * *              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 $ * */#include <signal.h>#include <curses.h>#include <ctype.h>#ifdef BSD42#include <strings.h>#else#ifndef SYSIII#include <string.h>#endif#endif#include <stdio.h>#include "sc.h"char *getenv();#ifdef SYSV3void exit();#endif#ifndef DFLT_PAGER#define	DFLT_PAGER "more"	/* more is probably more widespread than less */#endif /* DFLT_PAGER */#define MAXCMD 160	/* for ! command below */extern	char	*rev;/* Globals defined in sc.h */struct ent ***tbl;int strow, stcol;int currow, curcol;int savedrow, savedcol;int FullUpdate;int maxrow, maxcol;int maxrows, maxcols;int *fwidth;int *precision;char *col_hidden;char *row_hidden;char line[FBUFLEN];int changed;struct ent *to_fix;int modflg;int numeric;char *mdir;int showsc, showsr;	/* Starting cell for highlighted range */char mode_ind = '.';char curfile[PATHLEN];char    revmsg[80];int  linelim = -1;int  showtop   = 1;	/* Causes current cell value display in top line  */int  showcell  = 1;	/* Causes current cell to be highlighted	  */int  showrange = 0;	/* Causes ranges to be highlighted		  */int  showneed  = 0;	/* Causes cells needing values to be highlighted  */int  showexpr  = 0;	/* Causes cell exprs to be displayed, highlighted */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 */char under_cursor[] = " "; /* Data under the < cursor */#ifdef VMSint VMS_read_raw = 0;#endifint seenerr;voidyyerror(err)char *err; {    if (seenerr) return;    seenerr++;    (void) move(1,0);    (void) clrtoeol();    (void) printw("%s: %.*s<=%s",err,linelim,line,line+linelim);}struct ent *lookat(row,col)int	row, col;{    register struct ent **pp;    checkbounds(&row, &col);    pp = ATBL(tbl, row, col);    if (*pp == (struct ent *)0) {	*pp = (struct ent *) xmalloc((unsigned)sizeof(struct ent));	if (row>maxrow) maxrow = row;	if (col>maxcol) maxcol = col;	(*pp)->label = (char *)0;	(*pp)->row = row;	(*pp)->col = col;	(*pp)->flags = 0;	(*pp)->expr = (struct enode *)0;	(*pp)->v = (double) 0.0;	(*pp)->evnext = (struct ent *)0;    }    return *pp;}/* * This structure is used to keep ent structs around before they * are deleted to allow the sync_refs routine a chance to fix the * variable references. * We also use it as a last-deleted buffer for the 'p' command. */voidfree_ent(p)register struct ent *p;{    p->next = to_fix;    to_fix = p;    p->flags |= is_deleted;}voidflush_saved(){    register struct ent *p;    register struct ent *q;    if (!(p = to_fix))	return;    while (p) {	(void) clearent(p);	q = p->next;	xfree((char *)p);	p = q;    }    to_fix = 0;}/* * standout last time in update()? *	At this point we will let curses do work */int	standlast	= FALSE;voidupdate (anychanged)int	anychanged;	/* did any cell really change in value? */{    register    row,                col;    register struct ent **pp;    int     mxcol;    int     mxrow;    int     rows;    int     cols;    int     minsr, minsc, maxsr, maxsc;    register r;    register i;    while (row_hidden[currow])   /* You can't hide the last row or col */	currow++;    while (col_hidden[curcol])	curcol++;    /* First see if the last display still covers curcol */    if (stcol <= curcol) { 	for (i = stcol, cols = 0, col = RESCOL;			(col + fwidth[i]) < COLS-1 && i < maxcols; i++) {	    cols++;	    if (col_hidden[i])		continue;	    col += fwidth[i];	}    }    while (stcol + cols - 1 < curcol || curcol < stcol) {	FullUpdate++;	if (stcol - 1 == curcol) {    /* How about back one? */	    stcol--;	} else if (stcol + cols == curcol) {   /* Forward one? */	    stcol++;	} else {	    /* Try to put the cursor in the center of the screen */	    col = (COLS - RESCOL - fwidth[curcol]) / 2 + RESCOL; 	    stcol = curcol;	    for (i=curcol-1; i >= 0 && col-fwidth[i] > RESCOL; i--) {		stcol--;		if (col_hidden[i])		    continue;		col -= fwidth[i];	    }	}	/* Now pick up the counts again */	for (i = stcol, cols = 0, col = RESCOL;			(col + fwidth[i]) < COLS-1 && i < maxcols; i++) {	    cols++;	    if (col_hidden[i])		continue;	    col += fwidth[i];	}    }    /* Now - same process on the rows */    if (strow <= currow) { 	for (i = strow, rows = 0, row=RESROW; row<LINES && i<maxrows; i++) {	    rows++;	    if (row_hidden[i])		continue;	    row++;	}    }    while (strow + rows - 1 < currow || currow < strow) {	FullUpdate++;	if (strow - 1 == currow) {    /* How about up one? */	    strow--;	} else if (strow + rows == currow) {   /* Down one? */	    strow++;	} else {	    /* Try to put the cursor in the center of the screen */	    row = (LINES - RESROW) / 2 + RESROW; 	    strow = currow;	    for (i=currow-1; i >= 0 && row-1 > RESROW; i--) {		strow--;		if (row_hidden[i])		    continue;		row--;	    }	}	/* Now pick up the counts again */	for (i = strow, rows = 0, row=RESROW; row<LINES && i<maxrows; i++) {	    rows++;	    if (row_hidden[i])		continue;	    row++;	}    }    mxcol = stcol + cols - 1;    mxrow = strow + rows - 1;    if (FullUpdate || standlast) {	(void) move(2, 0);	(void) clrtobot();	(void) standout();	for (row=RESROW, i=strow; i <= mxrow; i++) {	    if (row_hidden[i]) 		continue;	    (void) move(row,0);	    if (maxrows < 1000)		(void) printw("%-*d", RESCOL-1, i);	    else		(void) printw("%-*d", RESCOL, i);	    row++;	}	(void) move(2,0);	(void) printw("%*s", RESCOL, " ");	for (col=RESCOL, i = stcol; i <= mxcol; i++) {	    register int k;	    if (col_hidden[i])		continue;	    (void) move(2, col);	    k = fwidth[i]/2;	    if (k == 0)		(void) printw("%1s", coltoa(i));	    else	        (void) printw("%*s%-*s", k, " ", fwidth[i]-k, coltoa(i));	    col += fwidth[i];	}	(void) standend();    }    /* Get rid of cursor standout on the cell at previous cursor position */    if (showcell)    {	(void) move(lastmx, lastmy);        repaint(lastmx, lastmy, fwidth[lastcol]);    }    if (showrange) {	minsr = showsr < currow ? showsr : currow;	minsc = showsc < curcol ? showsc : curcol;	maxsr = showsr > currow ? showsr : currow;	maxsc = showsc > curcol ? showsc : curcol;	if (showtop) {	    (void) move(1,0);	    (void) clrtoeol();	    (void) printw("Default range:  %s",			    r_name(minsr, minsc, maxsr, maxsc));	}    }    /* Repaint the visible screen */    if (showrange || anychanged || FullUpdate || standlast)    {	/* may be reset in loop, if not next time we will do a FullUpdate */      if (standlast)      {	FullUpdate = TRUE;	standlast = FALSE;      }      for (row = strow, r = RESROW; row <= mxrow; row++) {	register c = RESCOL;	int do_stand = 0;	int fieldlen;	int nextcol;	if (row_hidden[row])	    continue;	for (pp = ATBL(tbl, row, col = stcol); col <= mxcol;	         pp += nextcol - col,  col = nextcol, c += fieldlen) {	    nextcol = col+1;	    if (col_hidden[col]) {		fieldlen = 0;		continue;	    }	    fieldlen = fwidth[col];	    /*	     * Set standout if:	     *	     * - showing ranges, and not showing cells which need to be filled	     *	 in, and not showing cell expressions, and in a range, OR	     *	     * - if showing cells which need to be filled in and this one is	     *	 of that type (has a value and doesn't have an expression,	     *	 or it is a string expression), OR	     *	     * - if showing cells which have expressions and this one does.	     */	    if ((showrange && (! showneed) && (! showexpr)			   && (row >= minsr) && (row <= maxsr)			   && (col >= minsc) && (col <= maxsc))		    || (showneed && (*pp) && ((*pp) -> flags & is_valid)			&& (((*pp) -> flags & is_strexpr) || !((*pp) -> expr)))		    || (showexpr && (*pp) && ((*pp) -> expr)))	    {		(void) move(r, c);		(void) standout();		standlast++;		if (!*pp)	/* no cell, but standing out */		{	(void) printw("%*s", fwidth[col], " ");			(void) standend();			continue;		}		else			do_stand = 1;	    }	    else		do_stand = 0;	    if ((*pp) && ((*pp) -> flags & is_changed || FullUpdate) || do_stand) {		if (do_stand) {		    (*pp) -> flags |= is_changed; 		} else {		    (void) move(r, c);		    (*pp) -> flags &= ~is_changed;		}		/*		 * Show expression; takes priority over other displays:		 */		if (showexpr && ((*pp) -> expr)) {		    linelim = 0;		    editexp(row, col);		/* set line to expr */		    linelim = -1;		    showstring(line, /* leftflush = */ 1, /* hasvalue = */ 0,				row, col, & nextcol, mxcol, & fieldlen, r, c);		}		else {		    /*		     * Show cell's numeric value:		     */		    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('*');			} else {			    (void)addstr(field);			}		    }		    /*		     * Show cell's label string:		     */		    if ((*pp) -> label) {			showstring((*pp) -> label,				    (*pp) -> flags & is_leftflush,				    (*pp) -> flags & is_valid,				    row, col, & nextcol, mxcol,				    & fieldlen, r, c);		    }		    else	/* repaint a blank cell: */		    if ((do_stand || !FullUpdate) &&				((*pp)->flags & is_changed) &&				!((*pp)->flags & is_valid) && !(*pp)->label) {			(void) printw("%*s", fwidth[col], " ");		    }		} /* else */		if (do_stand) {		    (void) standend();		    do_stand = 0;		}	    }	}	r++;      }    }	        (void) move(lastmy, lastmx+fwidth[lastcol]);    if((inch() & A_CHARTEXT ) == '<')        (void) addstr(under_cursor);    lastmy =  RESROW;    for (row = strow; row < currow; row++)	if (!row_hidden[row])		lastmy += 1;    lastmx = RESCOL;    for (col = stcol; col < curcol; col++)	if (!col_hidden[col])		lastmx += fwidth[col];    lastcol = curcol;    if (showcell && (! showneed) && (! showexpr)) {	(void) move(lastmy, lastmx);        (void) standout();        repaint(lastmx, lastmy, fwidth[lastcol]);        (void) standend();    }    (void) move(lastmy, lastmx+fwidth[lastcol]);    *under_cursor = (inch() & A_CHARTEXT );    (void) addstr("<");    (void) move(0, 0);    (void) clrtoeol();    if (linelim >= 0) {	(void) addch(mode_ind);	(void) addstr("> ");	(void) addstr(line);	(void) move(0, linelim+3);    } else {	if (showtop) {			/* show top line */	    register struct ent *p1;	    int printed = 0;		/* printed something? */            (void) printw("%s%d ", coltoa(curcol), currow);	    if (p1 = *ATBL(tbl, currow, curcol)) {		if (p1 -> expr) {		    /* has expr of some type */		    linelim = 0;		    editexp(currow, curcol);	/* set line to expr */		    linelim = -1;		}		/*		 * Display string part of cell:		 */		if ((p1 -> expr) && (p1 -> flags & is_strexpr)) {		    (void) addstr((p1 -> flags & is_leftflush) ? "<{" : ">{");		    (void) addstr(line);		    (void) addstr("} ");	/* and this '}' is for vi % */		    printed = 1;		} else if (p1 -> label) {		    /* has constant label only */		    (void) addstr ((p1 -> flags & is_leftflush) ? "<\"" : ">\"");		    (void) addstr (p1 -> label);		    (void) addstr ("\" ");		    printed = 1;		}		/*		 * Display value part of cell:		 */		if (p1 -> flags & is_valid) {		    /* has value or num expr */		    if ((! (p1 -> expr)) || (p1 -> flags & is_strexpr))			(void) sprintf (line, "%.15g", p1 -> v);		    (void) addstr ("[");		    (void) addstr (line);		    (void) addstr ("]");		    printed = 1;		}	    }	    if (! printed)		(void) addstr ("[]");	}	(void) move (lastmy, lastmx + fwidth[lastcol]);    }    if (revmsg[0]) {	(void) move(0, 0);	(void) clrtoeol ();	/* get rid of topline display */	(void) printw(revmsg);	revmsg[0] = '\0';	/* don't show it again */	(void) move (lastmy, lastmx + fwidth[lastcol]);    }    FullUpdate = FALSE;}voidrepaint(x, y, len)int x, y, len;{    int c;    while(len-- > 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -