📄 interp.c
字号:
/* * Evaluate all cells which have expressions and alter their numeric or string * values. Return the number of cells which changed. */int RealEvalAll () { register int i,j; int chgct = 0; register struct ent *p; (void) signal(SIGFPE, eval_fpe);#ifdef EXPRTREE for (p = firstev; p; p = p->evnext) RealEvalOne(p, &chgct);#else if(calc_order == BYROWS ) { for (i=0; i<=maxrow; i++) for (j=0; j<=maxcol; j++) if ((p=tbl[i][j]) && p->expr) RealEvalOne(p,i,j, &chgct); } else if ( calc_order == BYCOLS ) { for (j=0; j<=maxcol; j++) { for (i=0; i<=maxrow; i++) if ((p=tbl[i][j]) && p->expr) RealEvalOne(p,i,j, &chgct); } } else error("Internal error calc_order");#endif (void) signal(SIGFPE, quit); return(chgct);}void#ifdef EXPRTREERealEvalOne(p, chgct)register struct ent *p;int *chgct;#elseRealEvalOne(p, i, j, chgct)register struct ent *p;int i, j, *chgct;#endif{ if (p->flags & is_strexpr) { char *v; if (setjmp(fpe_save)) {#ifdef EXPRTREE error("Floating point exception %s", v_name(p->row, p->col));#else error("Floating point exception %s", v_name(i, j));#endif v = ""; } else { v = seval(p->expr); } if (!v && !p->label) /* Everything's fine */ return; if (!p->label || !v || strcmp(v, p->label) != 0) { (*chgct)++; p->flags |= is_changed; changed++; } if(p->label) xfree(p->label); p->label = v; } else { double v; if (setjmp(fpe_save)) {#ifdef EXPRTREE error("Floating point exception %s", v_name(p->row, p->col));#else error("Floating point exception %s", v_name(i, j));#endif v = (double)0.0; } else { v = eval (p->expr); } if (v != p->v) { p->v = v; (*chgct)++; p->flags |= is_changed|is_valid; changed++; } }}struct enode *new(op, a1, a2)int op;struct enode *a1, *a2;{ register struct enode *p; p = (struct enode *) xmalloc ((unsigned)sizeof (struct enode)); p->op = op; p->e.o.left = a1; p->e.o.right = a2; return p;}struct enode *new_var(op, a1)int op;struct ent_ptr a1;{ register struct enode *p; p = (struct enode *) xmalloc ((unsigned)sizeof (struct enode)); p->op = op; p->e.v = a1; return p;}struct enode *new_range(op, a1)int op;struct range_s a1;{ register struct enode *p; p = (struct enode *) xmalloc ((unsigned)sizeof (struct enode)); p->op = op; p->e.r = a1; return p;}struct enode *new_const(op, a1)int op;double a1;{ register struct enode *p; p = (struct enode *) xmalloc ((unsigned)sizeof (struct enode)); p->op = op; p->e.k = a1; return p;}struct enode *new_str(s)char *s;{ register struct enode *p; p = (struct enode *) xmalloc ((unsigned)sizeof(struct enode)); p->op = O_SCONST; p->e.s = s; return(p);}voidcopy(dv1, dv2, v1, v2)struct ent *dv1, *dv2, *v1, *v2;{ int minsr, minsc; int maxsr, maxsc; int mindr, mindc; int maxdr, maxdc; int vr, vc; int r, c; mindr = dv1->row; mindc = dv1->col; maxdr = dv2->row; maxdc = dv2->col; if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r; if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c; maxsr = v2->row; maxsc = v2->col; minsr = v1->row; minsc = v1->col; if (minsr>maxsr) r = maxsr, maxsr = minsr, minsr = r; if (minsc>maxsc) c = maxsc, maxsc = minsc, minsc = c; checkbounds(&maxdr, &maxdc); erase_area(mindr, mindc, maxdr, maxdc); if (minsr == maxsr && minsc == maxsc) { /* Source is a single cell */ for(vr = mindr; vr <= maxdr; vr++) for (vc = mindc; vc <= maxdc; vc++) copyrtv(vr, vc, minsr, minsc, maxsr, maxsc); } else if (minsr == maxsr) { /* Source is a single row */ for (vr = mindr; vr <= maxdr; vr++) copyrtv(vr, mindc, minsr, minsc, maxsr, maxsc); } else if (minsc == maxsc) { /* Source is a single column */ for (vc = mindc; vc <= maxdc; vc++) copyrtv(mindr, vc, minsr, minsc, maxsr, maxsc); } else { /* Everything else */ copyrtv(mindr, mindc, minsr, minsc, maxsr, maxsc); } sync_refs();}voidcopyrtv(vr, vc, minsr, minsc, maxsr, maxsc)int vr, vc, minsr, minsc, maxsr, maxsc;{ register struct ent *p; register struct ent *n; register int sr, sc; register int dr, dc; for (dr=vr, sr=minsr; sr<=maxsr; sr++, dr++) for (dc=vc, sc=minsc; sc<=maxsc; sc++, dc++) { if (p = *ATBL(tbl, sr, sc)) { n = lookat (dr, dc); (void) clearent(n); copyent( n, p, dr - sr, dc - sc); } else if (n = *ATBL(tbl, dr, dc)) (void) clearent(n); }}voideraser(v1, v2)struct ent *v1, *v2;{ FullUpdate++; flush_saved(); erase_area(v1->row, v1->col, v2->row, v2->col); sync_refs();}/* Goto subroutines */voidg_free(){ switch (gs.g_type) { case G_STR: xfree(gs.g_s); break; default: break; } gs.g_type = G_NONE;}voidgo_last(){ switch (gs.g_type) { case G_NONE: error("Nothing to repeat"); break; case G_NUM: num_search(gs.g_n); break; case G_CELL: moveto(gs.g_row, gs.g_col); break; case G_STR: gs.g_type = G_NONE; /* Don't free the string */ str_search(gs.g_s); break; default: error("go_last: internal error"); }}voidmoveto(row, col)int row, col;{ currow = row; curcol = col; g_free(); gs.g_type = G_CELL; gs.g_row = currow; gs.g_col = curcol;}voidnum_search(n)double n;{ register struct ent *p; register int r,c; int endr, endc; g_free(); gs.g_type = G_NUM; gs.g_n = n; if (currow > maxrow) endr = maxrow ? maxrow-1 : 0; else endr = currow; if (curcol > maxcol) endc = maxcol ? maxcol-1 : 0; else endc = curcol; r = endr; c = endc; do { if (c < maxcol) c++; else { if (r < maxrow) { while(++r < maxrow && row_hidden[r]) /* */; c = 0; } else { r = 0; c = 0; } } if (r == endr && c == endc) { error("Number not found"); return; } p = *ATBL(tbl, r, c); } while(col_hidden[c] || !p || p && (!(p->flags & is_valid) || (p->flags&is_valid) && p->v != n)); currow = r; curcol = c;}voidstr_search(s)char *s;{ register struct ent *p; register int r,c; int endr, endc; char *tmp;#if defined(BSD42) || defined(BSD43) if ((tmp = re_comp(s)) != (char *)0) { xfree(s); error(tmp); return; }#endif#if defined(SYSV2) || defined(SYSV3) if ((tmp = regcmp(s, (char *)0)) == (char *)0) { xfree(s); error("Invalid search string"); return; }#endif g_free(); gs.g_type = G_STR; gs.g_s = s; if (currow > maxrow) endr = maxrow ? maxrow-1 : 0; else endr = currow; if (curcol > maxcol) endc = maxcol ? maxcol-1 : 0; else endc = curcol; r = endr; c = endc; do { if (c < maxcol) c++; else { if (r < maxrow) { while(++r < maxrow && row_hidden[r]) /* */; c = 0; } else { r = 0; c = 0; } } if (r == endr && c == endc) { error("String not found");#if defined(SYSV2) || defined(SYSV3) free(tmp);#endif return; } p = *ATBL(tbl, r, c); } while(col_hidden[c] || !p || p && (!(p->label) #if defined(BSD42) || defined(BSD43) || (re_exec(p->label) == 0)));#else#if defined(SYSV2) || defined(SYSV3) || (regex(tmp, p->label) == (char *)0)));#else || (strcmp(s, p->label) != 0)));#endif#endif currow = r; curcol = c;#if defined(SYSV2) || defined(SYSV3) free(tmp);#endif}voidfill (v1, v2, start, inc)struct ent *v1, *v2;double start, inc;{ 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++; if( calc_order == BYROWS ) { for (r = minr; r<=maxr; r++) for (c = minc; c<=maxc; c++) { n = lookat (r, c); (void) clearent(n); n->v = start; start += inc; n->flags |= (is_changed|is_valid); } } else if ( calc_order == BYCOLS ) { for (c = minc; c<=maxc; c++) for (r = minr; r<=maxr; r++) { n = lookat (r, c); (void) clearent(n); n->v = start; start += inc; n->flags |= (is_changed|is_valid); } } else error(" Internal error calc_order"); changed++;}voidlet (v, e)struct ent *v;struct enode *e;{ double val; exprerr = 0; (void) signal(SIGFPE, eval_fpe); if (setjmp(fpe_save)) { error ("Floating point exception in cell %s", v_name(v->row, v->col)); val = (double)0.0; } else { val = eval(e); } (void) signal(SIGFPE, quit); if (exprerr) { efree((struct ent *)0, e); return; } if (constant(e)) { if (!loading) v->v = val * prescale; else v->v = val; if (!(v->flags & is_strexpr)) { efree(v, v->expr); v->expr = (struct enode *)0; } efree((struct ent *)0, e); v->flags |= (is_changed|is_valid); changed++; modflg++; return; } efree (v, v->expr); v->expr = e; v->flags |= (is_changed|is_valid); v->flags &= ~is_strexpr;#ifdef EXPRTREE totoptree(v);#endif changed++; modflg++;}voidslet (v, se, flushdir)struct ent *v;struct enode *se;int flushdir;{ char *p; exprerr = 0; (void) signal(SIGFPE, eval_fpe); if (setjmp(fpe_save)) { error ("Floating point exception in cell %s", v_name(v->row, v->col)); p = ""; } else { p = seval(se); } (void) signal(SIGFPE, quit); if (exprerr) { efree((struct ent *)0, se); return; } if (constant(se)) { label(v, p, flushdir); if (p) xfree(p); efree((struct ent *)0, se); if (v->flags & is_strexpr) { efree (v, v->expr); v->expr = (struct enode *)0; v->flags &= ~is_strexpr; } return; } efree (v, v->expr); v->expr = se; v->flags |= (is_changed|is_strexpr); if (flushdir<0) v->flags |= is_leftflush; else v->flags &= ~is_leftflush;#ifdef EXPRTREE totoptree();#endif FullUpdate++; changed++; modflg++;}#ifdef EXPRTREE/* * put an expression in the expression tree, only the top of each branch is * in the firstev list */totoptree(v)struct ent *v;{ int right; int left; if (!v->expr) return;#ifdef notdef
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -