home *** CD-ROM | disk | FTP | other *** search
/ Dr. CD ROM (Annual Premium Edition) / premium.zip / premium / IBMOS2_1 / SC621.ZIP / sc621 / interp.c < prev    next >
C/C++ Source or Header  |  1992-07-10  |  59KB  |  2,502 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Expression interpreter and assorted support routines.
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modified by Mark Weiser and Bruce Israel, 
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        More mods by Alan Silverstein, 3-4/88, see list of changes.
  10.  *        $Revision: 6.21 $
  11.  */
  12.  
  13. #define DEBUGDTS 1        /* REMOVE ME */
  14.      
  15. #include <sys/types.h>
  16. #ifdef aiws
  17. #undef _C_func            /* Fixes for undefined symbols on AIX */
  18. #endif
  19.  
  20. #ifdef IEEE_MATH
  21. #include <ieeefp.h>
  22. #endif /* IEEE_MATH */
  23.  
  24. #include <math.h>
  25. #include <signal.h>
  26. #include <setjmp.h>
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #if !defined(__OS2__)
  31. extern int errno;        /* set by math functions */
  32. #endif
  33.  
  34. #ifdef BSD42
  35. #include <strings.h>
  36. #include <sys/time.h>
  37. #ifndef strchr
  38. #define strchr index
  39. #endif
  40. #else
  41. #include <time.h>
  42. #ifndef SYSIII
  43. #include <string.h>
  44. #endif
  45. #endif
  46.  
  47. #include <curses.h>
  48. #include "sc.h"
  49.  
  50. #if defined(RE_COMP)
  51. char *re_comp();
  52. #endif
  53. #if defined(REGCMP)
  54. char *regcmp();
  55. char *regex();
  56. #endif
  57.  
  58. #ifdef SIGVOID
  59.     void doquit();
  60. #else
  61.     int doquit();
  62. #endif
  63.  
  64. /* Use this structure to save the the last 'g' command */
  65. struct go_save {
  66.     int g_type;
  67.     double g_n;
  68.     char *g_s;
  69.     int  g_row;
  70.     int  g_col;
  71.     int  errsearch;
  72. } gs;
  73.  
  74. /* g_type can be: */
  75. #define G_NONE 0            /* Starting value - must be 0*/
  76. #define G_NUM 1
  77. #define G_STR 2
  78. #define G_CELL 3
  79.  
  80. #define ISVALID(r,c)    ((r)>=0 && (r)<maxrows && (c)>=0 && (c)<maxcols)
  81.  
  82. extern FILE *popen();
  83.  
  84. jmp_buf fpe_save;
  85. int    exprerr;    /* Set by eval() and seval() if expression errors */
  86. double  prescale = 1.0;    /* Prescale for constants in let() */
  87. int    extfunc  = 0;    /* Enable/disable external functions */
  88. int     loading = 0;    /* Set when readfile() is active */
  89. int    gmyrow, gmycol;    /* globals used to implement @myrow, @mycol cmds */
  90.  
  91. /* a linked list of free [struct enodes]'s, uses .e.o.left as the pointer */
  92. struct enode *freeenodes = NULL;
  93.  
  94. char    *seval();
  95. double    dolookup();
  96. double    eval();
  97. double    fn1_eval();
  98. double    fn1_seval();
  99. double    fn2_eval();
  100. int    RealEvalAll();
  101. int    constant();
  102. void    RealEvalOne();
  103. void    copyrtv();
  104. void    decompile();
  105. void    index_arg();
  106. void    list_arg();
  107. void    one_arg();
  108. void    range_arg();
  109. void    three_arg();
  110. void    two_arg();
  111. void    two_arg_index();
  112.  
  113. double    rint();
  114. int    cellerror = CELLOK;    /* is there an error in this cell */
  115.  
  116. #ifndef PI
  117. #define PI (double)3.14159265358979323846
  118. #endif
  119. #define dtr(x) ((x)*(PI/(double)180.0))
  120. #define rtd(x) ((x)*(180.0/(double)PI))
  121.  
  122. double finfunc(fun,v1,v2,v3)
  123. int fun;
  124. double v1,v2,v3;
  125. {
  126.      double answer,p;
  127.  
  128.      p = fn2_eval(pow, 1 + v2, v3);
  129.  
  130.      switch(fun)
  131.      {
  132.      case PV:
  133.         if (v2)
  134.             answer = v1 * (1 - 1/p) / v2;
  135.         else
  136.         {    cellerror = CELLERROR;
  137.             answer = (double)0;
  138.         }
  139.          break;
  140.      case FV:
  141.         if (v2)
  142.             answer = v1 * (p - 1) / v2;
  143.         else
  144.         {    cellerror = CELLERROR;
  145.             answer = (double)0;
  146.         }
  147.          break;
  148.      case PMT:
  149.         /* CHECK IF ~= 1 - 1/1 */
  150.         if (p && p != (double)1)
  151.             answer = v1 * v2 / (1 - 1/p);
  152.         else
  153.         {    cellerror = CELLERROR;
  154.             answer = (double)0;
  155.         }
  156.         
  157.          break;
  158.     default:
  159.         error("Unknown function in finfunc");
  160.         cellerror = CELLERROR;
  161.         return((double)0);
  162.     }
  163.     return(answer);
  164. }
  165.  
  166. char *
  167. dostindex( val, minr, minc, maxr, maxc)
  168. double val;
  169. int minr, minc, maxr, maxc;
  170. {
  171.     register r,c;
  172.     register struct ent *p;
  173.     char *pr;
  174.     int x;
  175.  
  176.     x = (int) val;
  177.     r = minr; c = minc;
  178.     p = (struct ent *)0;
  179.     if ( minr == maxr ) { /* look along the row */
  180.     c = minc + x - 1;
  181.     if (c <= maxc && c >=minc)
  182.         p = *ATBL(tbl, r, c);
  183.     } else if ( minc == maxc ) { /* look down the column */
  184.     r = minr + x - 1;
  185.     if (r <= maxr && r >=minr)
  186.         p = *ATBL(tbl, r, c);
  187.     } else {
  188.     error ("range specified to @stindex");
  189.     cellerror = CELLERROR;
  190.     return((char *)0);
  191.     }
  192.  
  193.     if (p && p->label) {
  194.     pr = scxmalloc((unsigned)(strlen(p->label)+1));
  195.     (void) strcpy(pr, p->label);
  196.     if (p->cellerror)
  197.         cellerror = CELLINVALID;
  198.     return (pr);
  199.      } else
  200.     return((char *)0);
  201. }
  202.  
  203. double
  204. doindex( val, minr, minc, maxr, maxc)
  205. double val;
  206. int minr, minc, maxr, maxc;
  207. {
  208.     double v;
  209.     register r,c;
  210.     register struct ent *p;
  211.     int x;
  212.  
  213.     x = (int) val;
  214.     v = (double)0;
  215.     r = minr; c = minc;
  216.     if ( minr == maxr ) { /* look along the row */
  217.     c = minc + x - 1;
  218.     if (c <= maxc && c >=minc 
  219.         && (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
  220.     {    if (p->cellerror)
  221.             cellerror = CELLINVALID;
  222.         return p->v;
  223.     }
  224.     }
  225.     else if ( minc == maxc ){ /* look down the column */
  226.     r = minr + x - 1;
  227.     if (r <= maxr && r >=minr 
  228.         && (p = *ATBL(tbl, r, c)) && p->flags&is_valid )
  229.     {    if (p->cellerror)
  230.             cellerror = CELLINVALID;
  231.         return p->v;
  232.     }
  233.     }
  234.     else {
  235.     error(" range specified to @index");
  236.     cellerror = CELLERROR;
  237.     }
  238.     return v;
  239. }
  240.  
  241. double
  242. dolookup( val, minr, minc, maxr, maxc, offr, offc)
  243. struct enode * val;
  244. int minr, minc, maxr, maxc, offr, offc;
  245. {
  246.     double v, ret = (double)0;
  247.     register r,c;
  248.     register struct ent *p = (struct ent *)0;
  249.     int incr,incc,fndr,fndc;
  250.     char *s;
  251.  
  252.     incr = (offc != 0); incc = (offr != 0);
  253.     if (etype(val) == NUM) {
  254.     cellerror = CELLOK;
  255.     v = eval(val);
  256.     for (r = minr, c = minc; r <= maxr && c <= maxc; r+=incr, c+=incc) {
  257.         if ( (p = *ATBL(tbl, r, c)) && p->flags&is_valid ) {
  258.         if (p->v <= v) {
  259.             fndr = incc ? (minr + offr) : r;
  260.             fndc = incr ? (minc + offc) : c;
  261.             if (ISVALID(fndr,fndc))
  262.             p = *ATBL(tbl, fndr, fndc);
  263.             else {
  264.             error(" range specified to @[hv]lookup");
  265.             cellerror = CELLERROR;
  266.             }
  267.             if ( p && p->flags&is_valid)
  268.             {    if (p->cellerror)
  269.                 cellerror = CELLINVALID;
  270.             ret = p->v;
  271.             }
  272.         } else break;
  273.         }
  274.     }
  275.     } else {
  276.     cellerror = CELLOK;
  277.     s = seval(val);
  278.     for (r = minr, c = minc; r <= maxr && c <= maxc; r+=incr, c+=incc) {
  279.         if ( (p = *ATBL(tbl, r, c)) && p->label ) {
  280.         if (strcmp(p->label,s) == 0) {
  281.             fndr = incc ? (minr + offr) : r;
  282.             fndc = incr ? (minc + offc) : c;
  283.             if (ISVALID(fndr,fndc))
  284.             {    p = *ATBL(tbl, fndr, fndc);
  285.             if (p->cellerror)
  286.                 cellerror = CELLINVALID;
  287.             }
  288.             else {
  289.             error(" range specified to @[hv]lookup");
  290.             cellerror = CELLERROR;
  291.             }
  292.             break;
  293.         }
  294.         }
  295.     }
  296.     if ( p && p->flags&is_valid)
  297.         ret = p->v;
  298.     scxfree(s);
  299.     }
  300.     return ret;
  301. }
  302.  
  303. double
  304. docount(minr, minc, maxr, maxc)
  305. int minr, minc, maxr, maxc;
  306. {
  307.     int v;
  308.     register r,c;
  309.     register struct ent *p;
  310.  
  311.     v = 0;
  312.     for (r = minr; r<=maxr; r++)
  313.     for (c = minc; c<=maxc; c++)
  314.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  315.         {    if (p->cellerror)
  316.             cellerror = CELLINVALID;
  317.         v++;
  318.         }
  319.     return v;
  320. }
  321.  
  322. double
  323. dosum(minr, minc, maxr, maxc)
  324. int minr, minc, maxr, maxc;
  325. {
  326.     double v;
  327.     register r,c;
  328.     register struct ent *p;
  329.  
  330.     v = (double)0;
  331.     for (r = minr; r<=maxr; r++)
  332.     for (c = minc; c<=maxc; c++)
  333.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  334.         {    if (p->cellerror)
  335.             cellerror = CELLINVALID;
  336.         v += p->v;
  337.         }
  338.     return v;
  339. }
  340.  
  341. double
  342. doprod(minr, minc, maxr, maxc)
  343. int minr, minc, maxr, maxc;
  344. {
  345.     double v;
  346.     register r,c;
  347.     register struct ent *p;
  348.  
  349.     v = 1;
  350.     for (r = minr; r<=maxr; r++)
  351.     for (c = minc; c<=maxc; c++)
  352.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid)
  353.         {    if (p->cellerror)
  354.             cellerror = CELLINVALID;
  355.         v *= p->v;
  356.         }
  357.     return v;
  358. }
  359.  
  360. double
  361. doavg(minr, minc, maxr, maxc)
  362. int minr, minc, maxr, maxc;
  363. {
  364.     double v;
  365.     register r,c,count;
  366.     register struct ent *p;
  367.  
  368.     v = (double)0;
  369.     count = 0;
  370.     for (r = minr; r<=maxr; r++)
  371.     for (c = minc; c<=maxc; c++)
  372.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  373.         if (p->cellerror)
  374.             cellerror = CELLINVALID;
  375.  
  376.         v += p->v;
  377.         count++;
  378.         }
  379.  
  380.     if (count == 0) 
  381.     return ((double) 0);
  382.  
  383.     return (v / (double)count);
  384. }
  385.  
  386. double
  387. dostddev(minr, minc, maxr, maxc)
  388. int minr, minc, maxr, maxc;
  389. {
  390.     double lp, rp, v, nd;
  391.     register r,c,n;
  392.     register struct ent *p;
  393.  
  394.     n = 0;
  395.     lp = 0;
  396.     rp = 0;
  397.     for (r = minr; r<=maxr; r++)
  398.     for (c = minc; c<=maxc; c++)
  399.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  400.         if (p->cellerror)
  401.             cellerror = CELLINVALID;
  402.  
  403.         v = p->v;
  404.         lp += v*v;
  405.         rp += v;
  406.         n++;
  407.         }
  408.  
  409.     if ((n == 0) || (n == 1)) 
  410.     return ((double) 0);
  411.     nd = (double)n;
  412.     return (sqrt((nd*lp-rp*rp)/(nd*(nd-1))));
  413. }
  414.  
  415. double
  416. domax(minr, minc, maxr, maxc)
  417. int minr, minc, maxr, maxc;
  418. {
  419.     double v = (double)0;
  420.     register r,c,count;
  421.     register struct ent *p;
  422.  
  423.     count = 0;
  424.     for (r = minr; r<=maxr; r++)
  425.     for (c = minc; c<=maxc; c++)
  426.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  427.         if (p->cellerror)
  428.             cellerror = CELLINVALID;
  429.  
  430.         if (!count) {
  431.             v = p->v;
  432.             count++;
  433.         } else if (p->v > v)
  434.             v = p->v;
  435.         }
  436.  
  437.     if (count == 0) 
  438.     return ((double) 0);
  439.  
  440.     return (v);
  441. }
  442.  
  443. double
  444. domin(minr, minc, maxr, maxc)
  445. int minr, minc, maxr, maxc;
  446. {
  447.     double v = (double)0;
  448.     register r,c,count;
  449.     register struct ent *p;
  450.  
  451.     count = 0;
  452.     for (r = minr; r<=maxr; r++)
  453.     for (c = minc; c<=maxc; c++)
  454.         if ((p = *ATBL(tbl, r, c)) && p->flags&is_valid) {
  455.         if (p->cellerror)
  456.             cellerror = CELLINVALID;
  457.  
  458.         if (!count) {
  459.             v = p->v;
  460.             count++;
  461.         } else if (p->v < v)
  462.             v = p->v;
  463.         }
  464.  
  465.     if (count == 0) 
  466.     return ((double) 0);
  467.  
  468.     return (v);
  469. }
  470.  
  471. #define sec_min 60
  472. #define sec_hr  3600L
  473. #define sec_day 86400L
  474. #define sec_yr  31471200L     /* 364.25 days/yr */
  475. #define sec_mo  2622600L       /* sec_yr/12: sort of an average */
  476. int mdays[12]={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  477.  
  478. double
  479. dodts(mo, day, yr)
  480. int mo, day, yr;
  481. {
  482.     long trial;
  483.     register struct tm *tp; 
  484.     register int i;
  485.     register long jdate;
  486.  
  487.     mdays[1] = 28 + (yr%4 == 0);
  488.  
  489.     if (mo < 1 || mo > 12 || day < 1 || day > mdays[--mo] ||
  490.         yr > 1999 || yr < 1970) {
  491.     error("@dts: invalid argument");
  492.     cellerror = CELLERROR;
  493.     return(0.0);
  494.     }
  495.  
  496.     jdate = day-1;
  497.     for (i=0; i<mo; i++)
  498.         jdate += mdays[i];
  499.     for (i = 1970; i < yr; i++)
  500.         jdate += 365 + (i%4 == 0);
  501.  
  502.     trial = jdate * sec_day; 
  503.  
  504.     yr -= 1900;
  505.  
  506.     tp = localtime(&trial);
  507.  
  508.     if (tp->tm_year != yr) {
  509.         /*
  510.         * We may fail this test once a year because of time zone
  511.          * and daylight savings time errors.  This bounces the
  512.          * trial time past the boundary.  The error introduced is
  513.          * corrected below.
  514.          */
  515.         trial += sec_day*(yr - tp->tm_year);
  516.         tp = localtime(&trial);
  517.     }
  518.     if (tp->tm_mon != mo) {
  519.         /* We may fail this test once a month.  */
  520.         trial += sec_day*(mo - tp->tm_mon);
  521.         tp = localtime(&trial);
  522.     }
  523.     if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec != day) {
  524.     trial -= (tp->tm_mday - day)*sec_day +  tp->tm_hour*sec_hr
  525.          + tp->tm_min*sec_min + tp->tm_sec;
  526.     }
  527.  
  528. #ifdef DEBUGDTS
  529.     tp = localtime(&trial);
  530.     if (tp->tm_mday + tp->tm_hour + tp->tm_min + tp->tm_sec + 
  531.     tp->tm_year + tp->tm_mon != yr+mo+day)
  532.     {    error("Dts broke down");
  533.         cellerror = CELLERROR;
  534.     }
  535. #endif
  536.  
  537.     return ((double)trial);
  538. }
  539.  
  540. double
  541. dotts(hr, min, sec)
  542. int hr, min, sec;
  543. {
  544.     if (hr < 0 || hr > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) {
  545.     error ("@tts: Invalid argument");
  546.     cellerror = CELLERROR;
  547.     return ((double)0);
  548.     }
  549.     return ((double)(sec+min*60+hr*3600));
  550. }
  551.  
  552. double
  553. dotime(which, when)
  554. int which;
  555. double when;
  556. {
  557. #if !defined(__OS2__)
  558.     long time();
  559. #endif
  560.  
  561.     static long t_cache;
  562.     static struct tm tm_cache;
  563.     struct tm *tp;
  564.     long tloc;
  565.  
  566.     if (which == NOW) 
  567.         return (double)time((long *)0);
  568.  
  569.     tloc = (long)when;
  570.  
  571.     if (tloc != t_cache) {
  572.         tp = localtime(&tloc);
  573.         tm_cache = *tp;
  574.         tm_cache.tm_mon += 1;
  575.         tm_cache.tm_year += 1900;
  576.         t_cache = tloc;
  577.     }
  578.  
  579.     switch (which) {
  580.         case HOUR: return((double)(tm_cache.tm_hour));
  581.         case MINUTE: return((double)(tm_cache.tm_min));
  582.         case SECOND: return((double)(tm_cache.tm_sec));
  583.         case MONTH: return((double)(tm_cache.tm_mon));
  584.         case DAY: return((double)(tm_cache.tm_mday));
  585.         case YEAR: return((double)(tm_cache.tm_year));
  586.     }
  587.     /* Safety net */
  588.     cellerror = CELLERROR;
  589.     return ((double)0);
  590. }
  591.  
  592. double
  593. doston(s)
  594. char *s;
  595. {
  596. #ifndef _AIX
  597.       char *strtof();
  598. #endif
  599.     double v;
  600.  
  601.     if (!s)
  602.     return((double)0);
  603.  
  604.     (void)strtof(s, &v);
  605.     scxfree(s);
  606.     return(v);
  607. }
  608.  
  609. double
  610. doeqs(s1, s2)
  611. char *s1, *s2;
  612. {
  613.     double v;
  614.  
  615.     if (!s1 && !s2)
  616.     return((double)1.0);
  617.  
  618.     if (!s1 || !s2)
  619.     v = 0.0;
  620.     else if (strcmp(s1, s2) == 0)
  621.     v = 1.0;
  622.     else
  623.     v = 0.0;
  624.  
  625.     if (s1)
  626.         scxfree(s1);
  627.  
  628.     if (s2)
  629.         scxfree(s2);
  630.  
  631.     return(v);
  632. }
  633.  
  634.  
  635. /*
  636.  * Given a string representing a column name and a value which is a column
  637.  * number, return a pointer to the selected cell's entry, if any, else NULL.
  638.  * Use only the integer part of the column number.  Always free the string.
  639.  */
  640.  
  641. struct ent *
  642. getent (colstr, rowdoub)
  643.     char *colstr;
  644.     double rowdoub;
  645. {
  646.     int collen;        /* length of string */
  647.     int row, col;    /* integer values   */
  648.     struct ent *p = (struct ent *)0;    /* selected entry   */
  649.  
  650.     if (!colstr)
  651.     {    cellerror = CELLERROR;
  652.     return((struct ent *)0);
  653.     }
  654.  
  655.     if (((row = (int) floor (rowdoub)) >= 0)
  656.      && (row < maxrows)                /* in range */
  657.      && ((collen = strlen (colstr)) <= 2)    /* not too long */
  658.      && ((col = atocol (colstr, collen)) >= 0)
  659.      && (col < maxcols))            /* in range */
  660.     {
  661.     p = *ATBL(tbl, row, col);
  662.     if ((p != NULL) && p->cellerror)
  663.         cellerror = CELLINVALID;
  664.     }
  665.     scxfree (colstr);
  666.     return (p);
  667. }
  668.  
  669.  
  670. /*
  671.  * Given a string representing a column name and a value which is a column
  672.  * number, return the selected cell's numeric value, if any.
  673.  */
  674.  
  675. double
  676. donval (colstr, rowdoub)
  677.     char *colstr;
  678.     double rowdoub;
  679. {
  680.     struct ent *ep;
  681.  
  682.     return (((ep = getent (colstr, rowdoub)) && ((ep -> flags) & is_valid)) ?
  683.         (ep -> v) : (double)0);
  684. }
  685.  
  686.  
  687. /*
  688.  *    The list routines (e.g. dolmax) are called with an LMAX enode.
  689.  *    The left pointer is a chain of ELIST nodes, the right pointer
  690.  *    is a value.
  691.  */
  692. double
  693. dolmax(ep)
  694. struct enode *ep;
  695. {
  696.     register int count = 0;
  697.     register double maxval = 0; /* Assignment to shut up lint */
  698.     register struct enode *p;
  699.     register double v;
  700.  
  701.     cellerror = CELLOK;
  702.     for (p = ep; p; p = p->e.o.left) {
  703.         v = eval(p->e.o.right);
  704.         if (!count || v > maxval) {
  705.             maxval = v; count++;
  706.         }
  707.     }
  708.     if (count) return maxval;
  709.     else return (double)0;
  710. }
  711.  
  712. double
  713. dolmin(ep)
  714. struct enode *ep;
  715. {
  716.     register int count = 0;
  717.     register double minval = 0; /* Assignment to shut up lint */
  718.     register struct enode *p;
  719.     register double v;
  720.  
  721.     cellerror = CELLOK;
  722.     for (p = ep; p; p = p->e.o.left) {
  723.         v = eval(p->e.o.right);
  724.         if (!count || v < minval) {
  725.             minval = v; count++;
  726.         }
  727.     }
  728.     if (count) return minval;
  729.     else return (double)0;
  730. }
  731.  
  732. double 
  733. eval(e)
  734. register struct enode *e;
  735. {
  736.     if (e == (struct enode *)0)
  737.     {    cellerror = CELLINVALID;
  738.     return (double)0;
  739.     }
  740.     switch (e->op) {
  741.     case '+':    return (eval(e->e.o.left) + eval(e->e.o.right));
  742.     case '-':    return (eval(e->e.o.left) - eval(e->e.o.right));
  743.     case '*':    return (eval(e->e.o.left) * eval(e->e.o.right));
  744.     case '/':     { double num, denom;
  745.             num = eval(e->e.o.left);
  746.             denom = eval(e->e.o.right);
  747.             if (denom)
  748. /*            if (1)    /* to test num div 0 */
  749.                 return(num/denom);
  750.             else
  751.             {    cellerror = CELLERROR;
  752.                 return((double) 0);
  753.             }
  754.     }
  755.     case '%':     {    double num, denom;
  756.             num = floor(eval(e->e.o.left));
  757.             denom = floor(eval (e->e.o.right));
  758.             if (denom)
  759.                 return(num - floor(num/denom)*denom);
  760.             else
  761.             {    cellerror = CELLERROR;
  762.                 return((double) 0);
  763.             }
  764.     }
  765.     case '^':    return (fn2_eval(pow,eval(e->e.o.left),eval(e->e.o.right)));
  766.     case '<':    return (eval(e->e.o.left) < eval(e->e.o.right));
  767.     case '=':    return (eval(e->e.o.left) == eval(e->e.o.right));
  768.     case '>':    return (eval(e->e.o.left) > eval(e->e.o.right));
  769.     case '&':    return (eval(e->e.o.left) && eval(e->e.o.right));
  770.     case '|':    return (eval(e->e.o.left) || eval(e->e.o.right));
  771.     case IF:
  772.     case '?':    return eval(e->e.o.left) ? eval(e->e.o.right->e.o.left)
  773.                         : eval(e->e.o.right->e.o.right);
  774.     case 'm':    return (-eval(e->e.o.right));
  775.     case 'f':    return (eval(e->e.o.right));
  776.     case '~':    return (eval(e->e.o.right) == 0.0);
  777.     case O_CONST:    return (e->e.k);
  778.     case O_VAR:    if (e->e.v.vp->cellerror)
  779.                 cellerror = CELLINVALID;
  780.             return (e->e.v.vp->v);
  781.     case INDEX:
  782.     case LOOKUP:
  783.     case HLOOKUP:
  784.     case VLOOKUP:
  785.         {    register r,c;
  786.         register maxr, maxc;
  787.         register minr, minc;
  788.         maxr = e->e.o.right->e.r.right.vp -> row;
  789.         maxc = e->e.o.right->e.r.right.vp -> col;
  790.         minr = e->e.o.right->e.r.left.vp -> row;
  791.         minc = e->e.o.right->e.r.left.vp -> col;
  792.         if (minr>maxr) r = maxr, maxr = minr, minr = r;
  793.         if (minc>maxc) c = maxc, maxc = minc, minc = c;
  794.         switch(e->op){
  795.         case LOOKUP:
  796.             return dolookup(e->e.o.left, minr, minc, maxr, maxc,
  797.                      minr==maxr, minc==maxc);
  798.         case HLOOKUP:
  799.                 return dolookup(e->e.o.left->e.o.left, minr,minc,maxr,maxc,
  800.             (int) eval(e->e.o.left->e.o.right), 0);
  801.         case VLOOKUP:
  802.                 return dolookup(e->e.o.left->e.o.left, minr,minc,maxr,maxc,
  803.             0, (int) eval(e->e.o.left->e.o.right));
  804.         case INDEX:
  805.             return doindex(eval(e->e.o.left), minr, minc, maxr, maxc);
  806.         }
  807.         }
  808.     case REDUCE | '+':
  809.      case REDUCE | '*':
  810.      case REDUCE | 'a':
  811.      case REDUCE | 'c':
  812.      case REDUCE | 's':
  813.     case REDUCE | MAX:
  814.     case REDUCE | MIN:
  815.         {    register r,c;
  816.         register maxr, maxc;
  817.         register minr, minc;
  818.         maxr = e->e.r.right.vp -> row;
  819.         maxc = e->e.r.right.vp -> col;
  820.         minr = e->e.r.left.vp -> row;
  821.         minc = e->e.r.left.vp -> col;
  822.         if (minr>maxr) r = maxr, maxr = minr, minr = r;
  823.         if (minc>maxc) c = maxc, maxc = minc, minc = c;
  824.             switch (e->op) {
  825.                 case REDUCE | '+': return dosum(minr, minc, maxr, maxc);
  826.                  case REDUCE | '*': return doprod(minr, minc, maxr, maxc);
  827.                  case REDUCE | 'a': return doavg(minr, minc, maxr, maxc);
  828.                  case REDUCE | 'c': return docount(minr, minc, maxr, maxc);
  829.                  case REDUCE | 's': return dostddev(minr, minc, maxr, maxc);
  830.                  case REDUCE | MAX: return domax(minr, minc, maxr, maxc);
  831.                  case REDUCE | MIN: return domin(minr, minc, maxr, maxc);
  832.         }
  833.         }
  834.     case ABS:     return (fn1_eval( fabs, eval(e->e.o.right)));
  835.     case ACOS:     return (fn1_eval( acos, eval(e->e.o.right)));
  836.     case ASIN:     return (fn1_eval( asin, eval(e->e.o.right)));
  837.     case ATAN:     return (fn1_eval( atan, eval(e->e.o.right)));
  838.     case ATAN2:     return (fn2_eval( atan2, eval(e->e.o.left), eval(e->e.o.right)));
  839.     case CEIL:     return (fn1_eval( ceil, eval(e->e.o.right)));
  840.     case COS:     return (fn1_eval( cos, eval(e->e.o.right)));
  841.     case EXP:     return (fn1_eval( exp, eval(e->e.o.right)));
  842.     case FABS:     return (fn1_eval( fabs, eval(e->e.o.right)));
  843.     case FLOOR:     return (fn1_eval( floor, eval(e->e.o.right)));
  844.     case HYPOT:     return (fn2_eval( hypot, eval(e->e.o.left), eval(e->e.o.right)));
  845.     case LOG:     return (fn1_eval( log, eval(e->e.o.right)));
  846.     case LOG10:     return (fn1_eval( log10, eval(e->e.o.right)));
  847.     case POW:     return (fn2_eval( pow, eval(e->e.o.left), eval(e->e.o.right)));
  848.     case SIN:     return (fn1_eval( sin, eval(e->e.o.right)));
  849.     case SQRT:     return (fn1_eval( sqrt, eval(e->e.o.right)));
  850.     case TAN:     return (fn1_eval( tan, eval(e->e.o.right)));
  851.     case DTR:     return (dtr(eval(e->e.o.right)));
  852.     case RTD:     return (rtd(eval(e->e.o.right)));
  853.     case RND:
  854.         if (rndinfinity)
  855.         {    double temp = eval(e->e.o.right);
  856.             return(temp-floor(temp) < 0.5 ?
  857.                     floor(temp) : ceil(temp));
  858.         }
  859.         else
  860.             return rint(eval(e->e.o.right));
  861.      case ROUND:
  862.         {    int prec = (int) eval(e->e.o.right);
  863.             double    scal = 1;
  864.             if (0 < prec)
  865.                 do scal *= 10; while (0 < --prec);
  866.             else if (prec < 0)
  867.                 do scal /= 10; while (++prec < 0);
  868.  
  869.             if (rndinfinity)
  870.             {    double temp = eval(e->e.o.left);
  871.                 temp *= scal;
  872.                 temp = ((temp-floor(temp)) < 0.5 ?
  873.                         floor(temp) : ceil(temp));
  874.                 return(temp / scal);
  875.             }
  876.             else
  877.                 return(rint(eval(e->e.o.left) * scal) / scal);
  878.         }
  879.     case FV:
  880.     case PV:
  881.     case PMT:    return(finfunc(e->op,eval(e->e.o.left),
  882.                    eval(e->e.o.right->e.o.left),
  883.                       eval(e->e.o.right->e.o.right)));
  884.     case HOUR:    return (dotime(HOUR, eval(e->e.o.right)));
  885.     case MINUTE:    return (dotime(MINUTE, eval(e->e.o.right)));
  886.     case SECOND:    return (dotime(SECOND, eval(e->e.o.right)));
  887.     case MONTH:    return (dotime(MONTH, eval(e->e.o.right)));
  888.     case DAY:    return (dotime(DAY, eval(e->e.o.right)));
  889.     case YEAR:    return (dotime(YEAR, eval(e->e.o.right)));
  890.     case NOW:    return (dotime(NOW, (double)0.0));
  891.     case DTS:    return (dodts((int)eval(e->e.o.left),
  892.                  (int)eval(e->e.o.right->e.o.left),
  893.                  (int)eval(e->e.o.right->e.o.right)));
  894.     case TTS:    return (dotts((int)eval(e->e.o.left),
  895.                  (int)eval(e->e.o.right->e.o.left),
  896.                  (int)eval(e->e.o.right->e.o.right)));
  897.     case STON:    return (doston(seval(e->e.o.right)));
  898.     case EQS:       return (doeqs(seval(e->e.o.right),seval(e->e.o.left)));
  899.     case LMAX:    return dolmax(e);
  900.     case LMIN:    return dolmin(e);
  901.     case NVAL:      return (donval(seval(e->e.o.left),eval(e->e.o.right)));
  902.     case MYROW:    return ((double) gmyrow);
  903.     case MYCOL:    return ((double) gmycol);
  904.     case NUMITER:    return ((double) repct);
  905.     default:    error ("Illegal numeric expression");
  906.             exprerr = 1;
  907.     }
  908.     cellerror = CELLERROR;
  909.     return((double)0.0);
  910. }
  911.  
  912. #ifdef SIGVOID
  913. void
  914. #else
  915. int
  916. #endif
  917. eval_fpe() /* Trap for FPE errors in eval */
  918. {
  919. #if defined(i386) && !defined(M_XENIX)
  920.     asm("    fnclex");
  921.     asm("    fwait");
  922. #else
  923. #ifdef IEEE_MATH
  924.     (void)fpsetsticky((fp_except)0);    /* Clear exception */
  925. #endif /* IEEE_MATH */
  926. #ifdef PC
  927.     _fpreset();
  928. #endif
  929. #endif
  930.     /* re-establish signal handler for next time */
  931.     (void) signal(SIGFPE, eval_fpe);
  932.     longjmp(fpe_save, 1);
  933. }
  934.  
  935. double fn1_eval(fn, arg)
  936. double (*fn)();
  937. double arg;
  938. {
  939.     double res;
  940.     errno = 0;
  941.     res = (*fn)(arg);
  942.     if(errno)
  943.         cellerror = CELLERROR;
  944.  
  945.     return res;
  946. }
  947.  
  948. double fn2_eval(fn, arg1, arg2)
  949. double (*fn)();
  950. double arg1, arg2;
  951. {
  952.     double res;
  953.     errno = 0;
  954.     res = (*fn)(arg1, arg2);
  955.     if(errno)
  956.         cellerror = CELLERROR;
  957.  
  958.     return res;
  959. }
  960.  
  961. /* 
  962.  * Rules for string functions:
  963.  * Take string arguments which they scxfree.
  964.  * All returned strings are assumed to be xalloced.
  965.  */
  966.  
  967. char *
  968. docat(s1, s2)
  969. register char *s1, *s2;
  970. {
  971.     register char *p;
  972.     char *arg1, *arg2;
  973.  
  974.     if (!s1 && !s2)
  975.     return((char *)0);
  976.     arg1 = s1 ? s1 : "";
  977.     arg2 = s2 ? s2 : "";
  978.     p = scxmalloc((unsigned)(strlen(arg1)+strlen(arg2)+1));
  979.     (void) strcpy(p, arg1);
  980.     (void) strcat(p, arg2);
  981.     if (s1)
  982.         scxfree(s1);
  983.     if (s2)
  984.         scxfree(s2);
  985.     return(p);
  986. }
  987.  
  988. char *
  989. dodate(tloc)
  990. long tloc;
  991. {
  992.     char *tp;
  993.     char *p;
  994.  
  995.     tp = ctime(&tloc);
  996.     tp[24] = '\0';
  997.     p = scxmalloc((unsigned)25);
  998.     (void) strcpy(p, tp);
  999.     return(p);
  1000. }
  1001.  
  1002.  
  1003. char *
  1004. dofmt(fmtstr, v)
  1005. char *fmtstr;
  1006. double v;
  1007. {
  1008.     char buff[FBUFLEN];
  1009.     char *p;
  1010.  
  1011.     if (!fmtstr)
  1012.     return((char *)0);
  1013.     (void) sprintf(buff, fmtstr, v);
  1014.     p = scxmalloc((unsigned)(strlen(buff)+1));
  1015.     (void) strcpy(p, buff);
  1016.     scxfree(fmtstr);
  1017.     return(p);
  1018. }
  1019.  
  1020.  
  1021. /*
  1022.  * Given a command name and a value, run the command with the given value and
  1023.  * read and return its first output line (only) as an allocated string, always
  1024.  * a copy of prevstr, which is set appropriately first unless external
  1025.  * functions are disabled, in which case the previous value is used.  The
  1026.  * handling of prevstr and freeing of command is tricky.  Returning an
  1027.  * allocated string in all cases, even if null, insures cell expressions are
  1028.  * written to files, etc.
  1029.  */
  1030.  
  1031. #if defined(VMS) || defined(MSDOS) || defined(__OS2__)
  1032. char *
  1033. doext(command, value)
  1034. char *command;
  1035. double value;
  1036. {
  1037.     error("Warning: External functions unavailable on VMS");
  1038.     cellerror = CELLERROR;    /* not sure if this should be a cellerror */
  1039.     if (command)
  1040.     scxfree(command);
  1041.     return (strcpy (scxmalloc((unsigned) 1), "\0"));
  1042. }
  1043.  
  1044. #else /* VMS */
  1045.  
  1046. char *
  1047. doext (command, value)
  1048. char   *command;
  1049. double value;
  1050. {
  1051.     static char *prevstr = (char *)0;    /* previous result */
  1052.     static unsigned    prevlen = 0;
  1053.     char buff[FBUFLEN];        /* command line/return, not permanently alloc */
  1054.     extern char *strchr();
  1055.  
  1056.     if (!extfunc)    {
  1057.     error ("Warning: external functions disabled; using %s value",
  1058.         ((prevstr == NULL) || (*prevstr == '\0')) ?
  1059.             "null" : "previous");
  1060.  
  1061.     if (command) scxfree (command);
  1062.     } else {
  1063.     if ((! command) || (! *command)) {
  1064.         error ("Warning: external function given null command name");
  1065.         cellerror = CELLERROR;
  1066.         if (command) scxfree (command);
  1067.     } else {
  1068.         FILE *pp;
  1069.  
  1070.         (void) sprintf (buff, "%s %g", command, value); /* build cmd line */
  1071.         scxfree (command);
  1072.  
  1073.         error ("Running external function...");
  1074.         (void) refresh();
  1075.  
  1076.         if ((pp = popen (buff, "r")) == (FILE *) NULL) {    /* run it */
  1077.         error ("Warning: running \"%s\" failed", buff);
  1078.         cellerror = CELLERROR;
  1079.         }
  1080.         else {
  1081.         if (fgets (buff, sizeof(buff)-1, pp) == NULL)    /* one line */
  1082.             error ("Warning: external function returned nothing");
  1083.         else {
  1084.             char *cp;
  1085.  
  1086.             error ("");                /* erase notice */
  1087.             buff[sizeof(buff)-1] = '\0';
  1088.  
  1089.             if (cp = strchr (buff, '\n'))    /* contains newline */
  1090.             *cp = '\0';            /* end string there */
  1091.  
  1092.             if (strlen(buff) + 1 > prevlen)
  1093.             {    prevlen = strlen(buff) + 40;
  1094.             prevstr = scxrealloc(prevstr, prevlen);
  1095.             }
  1096.             (void) strcpy (prevstr, buff);
  1097.              /* save alloc'd copy */
  1098.         }
  1099.         (void) pclose (pp);
  1100.  
  1101.         } /* else */
  1102.     } /* else */
  1103.     } /* else */
  1104.     if (prevstr)
  1105.     return (strcpy (scxmalloc ((unsigned) (strlen (prevstr) + 1)), prevstr));
  1106.     else
  1107.     return (strcpy(scxmalloc((unsigned)1), ""));
  1108. }
  1109.  
  1110. #endif /* VMS */
  1111.  
  1112.  
  1113. /*
  1114.  * Given a string representing a column name and a value which is a column
  1115.  * number, return the selected cell's string value, if any.  Even if none,
  1116.  * still allocate and return a null string so the cell has a label value so
  1117.  * the expression is saved in a file, etc.
  1118.  */
  1119.  
  1120. char *
  1121. dosval (colstr, rowdoub)
  1122.     char *colstr;
  1123.     double rowdoub;
  1124. {
  1125.     struct ent *ep;
  1126.     char *llabel;
  1127.  
  1128.     llabel = (ep = getent (colstr, rowdoub)) ? (ep -> label) : "";
  1129.     return (strcpy (scxmalloc ((unsigned) (strlen (llabel) + 1)), llabel));
  1130. }
  1131.  
  1132.  
  1133. /*
  1134.  * Substring:  Note that v1 and v2 are one-based to users, but zero-based
  1135.  * when calling this routine.
  1136.  */
  1137.  
  1138. char *
  1139. dosubstr(s, v1, v2)
  1140. char *s;
  1141. register int v1,v2;
  1142. {
  1143.     register char *s1, *s2;
  1144.     char *p;
  1145.  
  1146.     if (!s)
  1147.     return((char *)0);
  1148.  
  1149.     if (v2 >= strlen (s))        /* past end */
  1150.     v2 =  strlen (s) - 1;        /* to end   */
  1151.  
  1152.     if (v1 < 0 || v1 > v2) {        /* out of range, return null string */
  1153.     scxfree(s);
  1154.     p = scxmalloc((unsigned)1);
  1155.     p[0] = '\0';
  1156.     return(p);
  1157.     }
  1158.     s2 = p = scxmalloc((unsigned)(v2-v1+2));
  1159.     s1 = &s[v1];
  1160.     for(; v1 <= v2; s1++, s2++, v1++)
  1161.     *s2 = *s1;
  1162.     *s2 = '\0';
  1163.     scxfree(s);
  1164.     return(p);
  1165. }
  1166.  
  1167. /*
  1168.  * character casing: make upper case, make lower case
  1169.  */
  1170.  
  1171. char *
  1172. docase( acase, s)
  1173. int acase;
  1174. char *s;
  1175. {
  1176.     char *p = s;
  1177.  
  1178.     if (s == NULL)
  1179.     return(NULL);
  1180.  
  1181.     if( acase == UPPER ) {
  1182.         while( *p != '\0' ) {
  1183.            if( islower(*p) )
  1184.         *p = toupper(*p);
  1185.        p++;
  1186.     }
  1187.     }
  1188.     else if ( acase == LOWER ) {
  1189.     while( *p != '\0' ) {
  1190.         if (isupper(*p))
  1191.         *p = tolower(*p);
  1192.         p++;
  1193.     }
  1194.     }
  1195.     return (s);
  1196. }
  1197.  
  1198. /*
  1199.  * make proper capitals of every word in a string
  1200.  * if the string has mixed case we say the string is lower
  1201.  *    and we will upcase only first letters of words
  1202.  * if the string is all upper we will lower rest of words.
  1203.  */
  1204.  
  1205. char *
  1206. docapital( s )
  1207. char *s;
  1208. {
  1209.     char *p;
  1210.     int skip = 1;
  1211.     int AllUpper = 1;
  1212.  
  1213.     if (s == NULL)
  1214.     return(NULL);
  1215.     for( p = s; *p != '\0' && AllUpper != 0; p++ )
  1216.     if( isalpha(*p) && islower(*p) )  AllUpper = 0;
  1217.     for (p = s; *p != '\0'; p++) {
  1218.     if (!isalnum(*p))
  1219.         skip = 1;
  1220.     else
  1221.     if (skip == 1) {
  1222.         skip = 0;
  1223.         if (islower(*p))
  1224.             *p = toupper(*p);
  1225.     }
  1226.     else    /* if the string was all upper before */
  1227.         if (isupper(*p) && AllUpper != 0)
  1228.         *p = tolower(*p);
  1229.     }
  1230.     return(s);
  1231. }
  1232.  
  1233. char *
  1234. seval(se)
  1235. register struct enode *se;
  1236. {
  1237.     register char *p;
  1238.  
  1239.     if (se == (struct enode *)0) return (char *)0;
  1240.     switch (se->op) {
  1241.     case O_SCONST: p = scxmalloc((unsigned)(strlen(se->e.s)+1));
  1242.              (void) strcpy(p, se->e.s);
  1243.              return(p);
  1244.     case O_VAR:    {
  1245.             struct ent *ep;
  1246.             ep = se->e.v.vp;
  1247.  
  1248.             if (!ep->label)
  1249.                 return((char *)0);
  1250.             p = scxmalloc((unsigned)(strlen(ep->label)+1));
  1251.             (void) strcpy(p, ep->label);
  1252.             return(p);
  1253.              }
  1254.     case '#':    return(docat(seval(se->e.o.left), seval(se->e.o.right)));
  1255.     case 'f':    return(seval(se->e.o.right));
  1256.     case IF:
  1257.     case '?':    return(eval(se->e.o.left) ? seval(se->e.o.right->e.o.left)
  1258.                          : seval(se->e.o.right->e.o.right));
  1259.     case DATE:   return(dodate((long)(eval(se->e.o.right))));
  1260.     case FMT:    return(dofmt(seval(se->e.o.left), eval(se->e.o.right)));
  1261.     case UPPER:  return(docase(UPPER, seval(se->e.o.right)));
  1262.     case LOWER:  return(docase(LOWER, seval(se->e.o.right)));
  1263.     case CAPITAL:return(docapital(seval(se->e.o.right)));
  1264.      case STINDEX:
  1265.          {    register r,c;
  1266.          register maxr, maxc;
  1267.          register minr, minc;
  1268.          maxr = se->e.o.right->e.r.right.vp -> row;
  1269.          maxc = se->e.o.right->e.r.right.vp -> col;
  1270.          minr = se->e.o.right->e.r.left.vp -> row;
  1271.          minc = se->e.o.right->e.r.left.vp -> col;
  1272.          if (minr>maxr) r = maxr, maxr = minr, minr = r;
  1273.          if (minc>maxc) c = maxc, maxc = minc, minc = c;
  1274.              return dostindex(eval(se->e.o.left), minr, minc, maxr, maxc);
  1275.         }
  1276.     case EXT:    return(doext(seval(se->e.o.left), eval(se->e.o.right)));
  1277.     case SVAL:   return(dosval(seval(se->e.o.left), eval(se->e.o.right)));
  1278.     case SUBSTR: return(dosubstr(seval(se->e.o.left),
  1279.                 (int)eval(se->e.o.right->e.o.left) - 1,
  1280.                 (int)eval(se->e.o.right->e.o.right) - 1));
  1281.     case COLTOA: return(strcpy(scxmalloc((unsigned)10),
  1282.                    coltoa((int)eval(se->e.o.right)+1)));
  1283.     default:
  1284.              error ("Illegal string expression");
  1285.              exprerr = 1;
  1286.              return(NULL);
  1287.     }
  1288. }
  1289.  
  1290. /*
  1291.  * The graph formed by cell expressions which use other cells's values is not
  1292.  * evaluated "bottom up".  The whole table is merely re-evaluated cell by cell,
  1293.  * top to bottom, left to right, in RealEvalAll().  Each cell's expression uses
  1294.  * constants in other cells.  However, RealEvalAll() notices when a cell gets a
  1295.  * new numeric or string value, and reports if this happens for any cell.
  1296.  * EvalAll() repeats calling RealEvalAll() until there are no changes or the
  1297.  * evaluation count expires.
  1298.  */
  1299.  
  1300. int propagation = 10;    /* max number of times to try calculation */
  1301. int repct = 1;        /* Make repct a global variable so that the 
  1302.                 function @numiter can access it */
  1303.  
  1304. void
  1305. setiterations(i)
  1306. int i;
  1307. {
  1308.     if(i<1) {
  1309.         error("iteration count must be at least 1");
  1310.         propagation = 1;
  1311.         }
  1312.     else propagation = i;
  1313. }
  1314.  
  1315. void
  1316. EvalAll()
  1317. {
  1318.      int lastcnt;
  1319.   
  1320.      repct = 1;
  1321.      (void) signal(SIGFPE, eval_fpe);
  1322.  
  1323.      while ((lastcnt = RealEvalAll()) && (++repct <= propagation));
  1324.      if((propagation>1)&& (lastcnt >0 ))
  1325.          error("Still changing after %d iterations",propagation-1);
  1326.  
  1327.     (void) signal(SIGFPE, doquit);
  1328. }
  1329.  
  1330. /*
  1331.  * Evaluate all cells which have expressions and alter their numeric or string
  1332.  * values.  Return the number of cells which changed.
  1333.  */
  1334.  
  1335. int 
  1336. RealEvalAll()
  1337. {
  1338.     register int i,j;
  1339.     int chgct = 0;
  1340.     register struct ent *p;
  1341.  
  1342.     if(calc_order == BYROWS ) {
  1343.     for (i=0; i<=maxrow; i++)
  1344.         for (j=0; j<=maxcol; j++)
  1345.         if ((p = *ATBL(tbl,i,j)) && !(p->flags&is_locked) && p->expr)
  1346.             RealEvalOne(p,i,j,&chgct);
  1347.     } else if ( calc_order == BYCOLS ) {
  1348.     for (j=0; j<=maxcol; j++) {
  1349.         for (i=0; i<=maxrow; i++)
  1350.         if ((p = *ATBL(tbl,i,j)) && !(p->flags&is_locked) && p->expr)
  1351.             RealEvalOne(p,i,j,&chgct);
  1352.     }
  1353.     } else {
  1354.     error("Internal error calc_order");
  1355.     }
  1356.  
  1357.     return(chgct);
  1358. }
  1359.  
  1360. void
  1361. RealEvalOne(p, i, j, chgct)
  1362. register struct ent *p;
  1363. int i, j, *chgct;
  1364. {
  1365.     if (p->flags & is_strexpr) {
  1366.         char *v;
  1367.         if (setjmp(fpe_save)) {
  1368.         error("Floating point exception %s", v_name(i, j));
  1369.         cellerror = CELLERROR;
  1370.         v = "";
  1371.         } else {
  1372.         cellerror = CELLOK;
  1373.         v = seval(p->expr);
  1374.         }
  1375.         p->cellerror = cellerror;
  1376.         if (!v && !p->label) /* Everything's fine */
  1377.         return;
  1378.         if (!p->label || !v || strcmp(v, p->label) != 0 || cellerror) {
  1379.         (*chgct)++;
  1380.         p->flags |= is_changed;
  1381.         changed++;
  1382.         }
  1383.         if(p->label)
  1384.         scxfree(p->label);
  1385.         p->label = v;
  1386.     } else {
  1387.         double v;
  1388.         if (setjmp(fpe_save)) {
  1389.         error("Floating point exception %s", v_name(i, j));
  1390.         cellerror = CELLERROR;
  1391.         v = (double)0.0;
  1392.         } else {
  1393.         cellerror = CELLOK;
  1394.         gmyrow=i; gmycol=j;
  1395.         v = eval (p->expr);
  1396.         }
  1397.         if ((p->cellerror = cellerror) || (v != p->v)) {
  1398.         p->v = v;
  1399.         if (!cellerror)        /* don't keep eval'ing a error */
  1400.             (*chgct)++;
  1401.         p->flags |= is_changed|is_valid;
  1402.         changed++;
  1403.         }
  1404.     }
  1405. }
  1406.  
  1407. struct enode *
  1408. new(op, a1, a2)
  1409. int    op;
  1410. struct enode *a1, *a2;
  1411. {
  1412.     register struct enode *p;
  1413.     if (freeenodes)
  1414.     {    p = freeenodes;
  1415.     freeenodes = p->e.o.left;
  1416.     }
  1417.     else
  1418.     p = (struct enode *) scxmalloc ((unsigned)sizeof (struct enode));
  1419.     p->op = op;
  1420.     p->e.o.left = a1;
  1421.     p->e.o.right = a2;
  1422.     return p;
  1423. }
  1424.  
  1425. struct enode *
  1426. new_var(op, a1)
  1427. int    op;
  1428. struct ent_ptr a1;
  1429. {
  1430.     register struct enode *p;
  1431.     if (freeenodes)
  1432.     {    p = freeenodes;
  1433.     freeenodes = p->e.o.left;
  1434.     }
  1435.     else
  1436.     p = (struct enode *) scxmalloc ((unsigned)sizeof (struct enode));
  1437.     p->op = op;
  1438.     p->e.v = a1;
  1439.     return p;
  1440. }
  1441.  
  1442. struct enode *
  1443. new_range(op, a1)
  1444. int    op;
  1445. struct range_s a1;
  1446. {
  1447.     register struct enode *p;
  1448.     if (freeenodes)
  1449.     {    p = freeenodes;
  1450.     freeenodes = p->e.o.left;
  1451.     }
  1452.     else
  1453.     p = (struct enode *) scxmalloc ((unsigned)sizeof (struct enode));
  1454.     p->op = op;
  1455.     p->e.r = a1;
  1456.     return p;
  1457. }
  1458.  
  1459. struct enode *
  1460. new_const(op, a1)
  1461. int    op;
  1462. double a1;
  1463. {
  1464.     register struct enode *p;
  1465.     if (freeenodes)    /* reuse an already free'd enode */
  1466.     {    p = freeenodes;
  1467.     freeenodes = p->e.o.left;
  1468.     }
  1469.     else
  1470.     p = (struct enode *) scxmalloc ((unsigned)sizeof (struct enode));
  1471.     p->op = op;
  1472.     p->e.k = a1;
  1473.     return p;
  1474. }
  1475.  
  1476. struct enode *
  1477. new_str(s)
  1478. char *s;
  1479. {
  1480.     register struct enode *p;
  1481.  
  1482.     if (freeenodes)    /* reuse an already free'd enode */
  1483.     {    p = freeenodes;
  1484.     freeenodes = p->e.o.left;
  1485.     }
  1486.     else
  1487.     p = (struct enode *) scxmalloc ((unsigned)sizeof(struct enode));
  1488.     p->op = O_SCONST;
  1489.     p->e.s = s;
  1490.     return(p);
  1491. }
  1492.  
  1493. void
  1494. copy(dv1, dv2, v1, v2)
  1495. struct ent *dv1, *dv2, *v1, *v2;
  1496. {
  1497.     int minsr, minsc;
  1498.     int maxsr, maxsc;
  1499.     int mindr, mindc;
  1500.     int maxdr, maxdc;
  1501.     int vr, vc;
  1502.     int r, c;
  1503.  
  1504.     mindr = dv1->row;
  1505.     mindc = dv1->col;
  1506.     maxdr = dv2->row;
  1507.     maxdc = dv2->col;
  1508.     if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r;
  1509.     if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c;
  1510.     maxsr = v2->row;
  1511.     maxsc = v2->col;
  1512.     minsr = v1->row;
  1513.     minsc = v1->col;
  1514.     if (minsr>maxsr) r = maxsr, maxsr = minsr, minsr = r;
  1515.     if (minsc>maxsc) c = maxsc, maxsc = minsc, minsc = c;
  1516.     checkbounds(&maxdr, &maxdc);
  1517.  
  1518.     erase_area(mindr, mindc, maxdr, maxdc);
  1519.     if (minsr == maxsr && minsc == maxsc) {
  1520.     /* Source is a single cell */
  1521.     for(vr = mindr; vr <= maxdr; vr++)
  1522.         for (vc = mindc; vc <= maxdc; vc++)
  1523.         copyrtv(vr, vc, minsr, minsc, maxsr, maxsc);
  1524.     } else if (minsr == maxsr) {
  1525.     /* Source is a single row */
  1526.     for (vr = mindr; vr <= maxdr; vr++)
  1527.         copyrtv(vr, mindc, minsr, minsc, maxsr, maxsc);
  1528.     } else if (minsc == maxsc) {
  1529.     /* Source is a single column */
  1530.     for (vc = mindc; vc <= maxdc; vc++)
  1531.         copyrtv(mindr, vc, minsr, minsc, maxsr, maxsc);
  1532.     } else {
  1533.     /* Everything else */
  1534.     copyrtv(mindr, mindc, minsr, minsc, maxsr, maxsc);
  1535.     }
  1536.     sync_refs();
  1537. }
  1538.  
  1539. void
  1540. copyrtv(vr, vc, minsr, minsc, maxsr, maxsc)
  1541. int vr, vc, minsr, minsc, maxsr, maxsc;
  1542. {
  1543.     register struct ent *p;
  1544.     register struct ent *n;
  1545.     register int sr, sc;
  1546.     register int dr, dc;
  1547.  
  1548.     for (dr=vr, sr=minsr; sr<=maxsr; sr++, dr++)
  1549.     for (dc=vc, sc=minsc; sc<=maxsc; sc++, dc++) {
  1550.         if (p = *ATBL(tbl, sr, sc))
  1551.         {    n = lookat (dr, dc);
  1552.         if (n->flags&is_locked) continue;
  1553.         (void) clearent(n);
  1554.         copyent( n, p, dr - sr, dc - sc);
  1555.         }
  1556.         else
  1557.         if (n = *ATBL(tbl, dr, dc))
  1558.         (void) clearent(n);
  1559.     }
  1560. }
  1561.  
  1562. /* ERASE a Range of cells */
  1563. void
  1564. eraser(v1, v2)
  1565. struct ent *v1, *v2;
  1566. {
  1567.     FullUpdate++;
  1568.     flush_saved();
  1569.     erase_area(v1->row, v1->col, v2->row, v2->col);
  1570.     sync_refs();
  1571. }
  1572.  
  1573. /* Goto subroutines */
  1574.  
  1575. void
  1576. g_free()
  1577. {
  1578.     switch (gs.g_type) {
  1579.     case G_STR: scxfree(gs.g_s); break;
  1580.     default: break;
  1581.     }
  1582.     gs.g_type = G_NONE;
  1583.     gs.errsearch = 0;
  1584. }
  1585.  
  1586. /* repeat the last goto command */
  1587. void
  1588. go_last()
  1589. {
  1590.     switch (gs.g_type) {
  1591.     case G_NONE:
  1592.         error("Nothing to repeat"); break;
  1593.     case G_NUM:
  1594.         num_search(gs.g_n, gs.errsearch);
  1595.         break;
  1596.     case  G_CELL:
  1597.         moveto(gs.g_row, gs.g_col);
  1598.             break;
  1599.     case  G_STR: 
  1600.         gs.g_type = G_NONE;    /* Don't free the string */
  1601.                str_search(gs.g_s); 
  1602.            break;
  1603.  
  1604.     default: error("go_last: internal error");
  1605.     }
  1606. }
  1607.  
  1608. /* place the cursor on a given cell */
  1609. void
  1610. moveto(row, col)
  1611. int row, col;
  1612. {
  1613.     currow = row;
  1614.     curcol = col;
  1615.     g_free();
  1616.     gs.g_type = G_CELL;
  1617.     gs.g_row = currow;
  1618.     gs.g_col = curcol;
  1619. }
  1620.  
  1621. /*
  1622.  * 'goto' either a given number,'error', or 'invalid' starting at currow,curcol
  1623.  */
  1624. void
  1625. num_search(n, errsearch)
  1626. double n;
  1627. int    errsearch;
  1628. {
  1629.     register struct ent *p;
  1630.     register int r,c;
  1631.     int    endr, endc;
  1632.  
  1633.     g_free();
  1634.     gs.g_type = G_NUM;
  1635.     gs.g_n = n;
  1636.     gs.errsearch = errsearch;
  1637.  
  1638.     if (currow > maxrow)
  1639.     endr = maxrow ? maxrow-1 : 0;
  1640.     else
  1641.     endr = currow;
  1642.     if (curcol > maxcol)
  1643.     endc = maxcol ? maxcol-1 : 0;
  1644.     else
  1645.     endc = curcol;
  1646.     r = endr;
  1647.     c = endc;
  1648.     do {
  1649.     if (c < maxcol)
  1650.         c++;
  1651.     else {
  1652.         if (r < maxrow) {
  1653.         while(++r < maxrow && row_hidden[r]) /* */;
  1654.         c = 0;
  1655.         } else {
  1656.         r = 0;
  1657.         c = 0;
  1658.         }
  1659.     }
  1660.     if (r == endr && c == endc) {
  1661.         if (errsearch)
  1662.         error("no %s cell found", errsearch == CELLERROR ? "ERROR" :
  1663.               "INVALID");
  1664.         else
  1665.         error("Number not found");
  1666.         return;
  1667.     }
  1668.     p = *ATBL(tbl, r, c);
  1669.     } while (col_hidden[c] || !p || !(p->flags & is_valid)
  1670.     || (!errsearch && (p->v != n))
  1671.     || (errsearch && !((p->cellerror == errsearch) ||
  1672.         (p->cellerror == errsearch))));    /* CELLERROR vs CELLINVALID */
  1673.         
  1674.     currow = r;
  1675.     curcol = c;
  1676. }
  1677.  
  1678. /* 'goto' a cell containing a matching string */
  1679. void
  1680. str_search(s)
  1681. char *s;
  1682. {
  1683.     register struct ent *p;
  1684.     register int r,c;
  1685.     int    endr, endc;
  1686.     char *tmp;
  1687.  
  1688. #if defined(RE_COMP)
  1689.     if ((tmp = re_comp(s)) != (char *)0) {
  1690.     scxfree(s);
  1691.     error(tmp);
  1692.     return;
  1693.     }
  1694. #endif
  1695. #if defined(REGCMP)
  1696.     if ((tmp = regcmp(s, (char *)0)) == (char *)0) {
  1697.     scxfree(s);
  1698.     cellerror = CELLERROR;
  1699.     error("Invalid search string");
  1700.     return;
  1701.     }
  1702. #endif
  1703.     g_free();
  1704.     gs.g_type = G_STR;
  1705.     gs.g_s = s;
  1706.     if (currow > maxrow)
  1707.     endr = maxrow ? maxrow-1 : 0;
  1708.     else
  1709.     endr = currow;
  1710.     if (curcol > maxcol)
  1711.     endc = maxcol ? maxcol-1 : 0;
  1712.     else
  1713.     endc = curcol;
  1714.     r = endr;
  1715.     c = endc;
  1716.     do {
  1717.     if (c < maxcol)
  1718.         c++;
  1719.     else {
  1720.         if (r < maxrow) {
  1721.         while(++r < maxrow && row_hidden[r]) /* */;
  1722.         c = 0;
  1723.         } else {
  1724.         r = 0;
  1725.         c = 0;
  1726.         }
  1727.     }
  1728.     if (r == endr && c == endc) {
  1729.         error("String not found");
  1730. #if defined(REGCMP)
  1731.         free(tmp);
  1732. #endif
  1733.         return;
  1734.     }
  1735.     p = *ATBL(tbl, r, c);
  1736.     } while(col_hidden[c] || !p || !(p->label)
  1737. #if defined(RE_COMP)
  1738.                       || (re_exec(p->label) == 0));
  1739. #else
  1740. #if defined(REGCMP)
  1741.                 || (regex(tmp, p->label) == (char *)0));
  1742. #else
  1743.                     || (strcmp(s, p->label) != 0));
  1744. #endif
  1745. #endif
  1746.     currow = r;
  1747.     curcol = c;
  1748. #if defined(REGCMP)
  1749.     free(tmp);
  1750. #endif
  1751. }
  1752.  
  1753. /* fill a range with constants */
  1754. void
  1755. fill (v1, v2, start, inc)
  1756. struct ent *v1, *v2;
  1757. double start, inc;
  1758. {
  1759.     register r,c;
  1760.     register struct ent *n;
  1761.     int maxr, maxc;
  1762.     int minr, minc;
  1763.  
  1764.     maxr = v2->row;
  1765.     maxc = v2->col;
  1766.     minr = v1->row;
  1767.     minc = v1->col;
  1768.     if (minr>maxr) r = maxr, maxr = minr, minr = r;
  1769.     if (minc>maxc) c = maxc, maxc = minc, minc = c;
  1770.     checkbounds(&maxr, &maxc);
  1771.     if (minr < 0) minr = 0;
  1772.     if (minc < 0) minc = 0;
  1773.  
  1774.     FullUpdate++;
  1775.     if( calc_order == BYROWS ) {
  1776.     for (r = minr; r<=maxr; r++)
  1777.     for (c = minc; c<=maxc; c++) {
  1778.         n = lookat (r, c);
  1779.         if (n->flags&is_locked) continue;
  1780.         (void) clearent(n);
  1781.         n->v = start;
  1782.         start += inc;
  1783.         n->flags |= (is_changed|is_valid);
  1784.     }
  1785.     }
  1786.     else if ( calc_order == BYCOLS ) {
  1787.     for (c = minc; c<=maxc; c++)
  1788.     for (r = minr; r<=maxr; r++) {
  1789.         n = lookat (r, c);
  1790.         (void) clearent(n);
  1791.         n->v = start;
  1792.         start += inc;
  1793.         n->flags |= (is_changed|is_valid);
  1794.     }
  1795.     }
  1796.     else error(" Internal error calc_order");
  1797.     changed++;
  1798. }
  1799.  
  1800. /* lock a range of cells */
  1801.  
  1802. void
  1803. lock_cells (v1, v2)
  1804. struct ent *v1, *v2;
  1805. {
  1806.     register r,c;
  1807.     register struct ent *n;
  1808.     int maxr, maxc;
  1809.     int minr, minc;
  1810.  
  1811.     maxr = v2->row;
  1812.     maxc = v2->col;
  1813.     minr = v1->row;
  1814.     minc = v1->col;
  1815.     if (minr>maxr) r = maxr, maxr = minr, minr = r;
  1816.     if (minc>maxc) c = maxc, maxc = minc, minc = c;
  1817.     checkbounds(&maxr, &maxc);
  1818.     if (minr < 0) minr = 0;
  1819.     if (minc < 0) minc = 0;
  1820.  
  1821.     for (r = minr; r<=maxr; r++)
  1822.     for (c = minc; c<=maxc; c++) {
  1823.         n = lookat (r, c);
  1824.         n->flags |= is_locked;
  1825.     }
  1826. }
  1827.  
  1828. /* unlock a range of cells */
  1829.  
  1830. void
  1831. unlock_cells (v1, v2)
  1832. struct ent *v1, *v2;
  1833. {
  1834.     register r,c;
  1835.     register struct ent *n;
  1836.     int maxr, maxc;
  1837.     int minr, minc;
  1838.  
  1839.     maxr = v2->row;
  1840.     maxc = v2->col;
  1841.     minr = v1->row;
  1842.     minc = v1->col;
  1843.     if (minr>maxr) r = maxr, maxr = minr, minr = r;
  1844.     if (minc>maxc) c = maxc, maxc = minc, minc = c;
  1845.     checkbounds(&maxr, &maxc);
  1846.     if (minr < 0) minr = 0;
  1847.     if (minc < 0) minc = 0;
  1848.  
  1849.     for (r = minr; r<=maxr; r++)
  1850.     for (c = minc; c<=maxc; c++) {
  1851.         n = lookat (r, c);
  1852.         n->flags &= ~is_locked;
  1853.     }
  1854. }
  1855.  
  1856. /* set the numeric part of a cell */
  1857. void
  1858. let (v, e)
  1859. struct ent *v;
  1860. struct enode *e;
  1861. {
  1862.     double val;
  1863.     unsigned isconstant = constant(e);
  1864.  
  1865.     if (loading && !isconstant)
  1866.     val = (double)0.0;
  1867.     else
  1868.     {
  1869.     exprerr = 0;
  1870.     (void) signal(SIGFPE, eval_fpe);
  1871.     if (setjmp(fpe_save)) {
  1872.         error ("Floating point exception in cell %s", v_name(v->row, v->col));
  1873.         val = (double)0.0;
  1874.         cellerror = CELLERROR;
  1875.     } else {
  1876.         cellerror = CELLOK;
  1877.         val = eval(e);
  1878.     }
  1879.     if (v->cellerror != cellerror)
  1880.     {    v->flags |= is_changed;
  1881.         changed++;    modflg++;
  1882.         FullUpdate++;
  1883.         v->cellerror = cellerror;
  1884.     }
  1885.     (void) signal(SIGFPE, doquit);
  1886.     if (exprerr) {
  1887.         efree(e);
  1888.         return;
  1889.     }
  1890.     }
  1891.  
  1892.     if (isconstant) {
  1893.     /* prescale input unless it has a decimal */
  1894. #if defined(IEEE_MATH) && !defined(NO_FMOD)
  1895.     if (!loading && (prescale < (double)0.9999999) &&
  1896.                 (fmod(val, (double)1.0) == (double)0))
  1897. #else
  1898.     if (!loading && (prescale < (double)0.9999999) &&
  1899.             ((val - floor(val)) == (double)0))
  1900. #endif
  1901.         val *= prescale;
  1902.  
  1903.     v->v = val;
  1904.  
  1905.     if (!(v->flags & is_strexpr)) {
  1906.             efree(v->expr);
  1907.         v->expr = (struct enode *)0;
  1908.     }
  1909.     efree(e);
  1910.     }
  1911.     else
  1912.     {
  1913.     efree(v->expr);
  1914.     v->expr = e;
  1915.     v->flags &= ~is_strexpr;
  1916.     }
  1917.  
  1918.     changed++; modflg++;
  1919.     v->flags |= (is_changed|is_valid);
  1920. }
  1921.  
  1922. void
  1923. slet (v, se, flushdir)
  1924. struct ent *v;
  1925. struct enode *se;
  1926. int flushdir;
  1927. {
  1928.     char *p;
  1929.  
  1930.     exprerr = 0;
  1931.     (void) signal(SIGFPE, eval_fpe);
  1932.     if (setjmp(fpe_save)) {
  1933.     error ("Floating point exception in cell %s", v_name(v->row, v->col));
  1934.     cellerror = CELLERROR;
  1935.     p = "";
  1936.     } else {
  1937.     cellerror = CELLOK;
  1938.     p = seval(se);
  1939.     }
  1940.     if (v->cellerror != cellerror)
  1941.     {    v->flags |= is_changed;
  1942.     changed++;    modflg++;
  1943.     FullUpdate++;
  1944.     v->cellerror = cellerror;
  1945.     }
  1946.     (void) signal(SIGFPE, doquit);
  1947.     if (exprerr) {
  1948.     efree(se);
  1949.     return;
  1950.     }
  1951.     if (constant(se)) {
  1952.     label(v, p, flushdir);
  1953.     if (p)
  1954.         scxfree(p);
  1955.     efree(se);
  1956.     if (v->flags & is_strexpr) {
  1957.             efree(v->expr);
  1958.         v->expr = (struct enode *)0;
  1959.         v->flags &= ~is_strexpr;
  1960.     }
  1961.     return;
  1962.     }
  1963.     efree(v->expr);
  1964.     v->expr = se;
  1965.     v->flags |= (is_changed|is_strexpr);
  1966.     if (flushdir<0) v->flags |= is_leftflush;
  1967.  
  1968.     if (flushdir==0)
  1969.     v->flags |= is_label;
  1970.     else v->flags &= ~is_label;
  1971.  
  1972.     FullUpdate++;
  1973.     changed++;
  1974.     modflg++;
  1975. }
  1976.  
  1977. void
  1978. format_cell(v1, v2, s)
  1979. struct ent *v1, *v2;
  1980. char *s;
  1981. {
  1982.     register r,c;
  1983.     register struct ent *n;
  1984.     int maxr, maxc;
  1985.     int minr, minc;
  1986.  
  1987.     maxr = v2->row;
  1988.     maxc = v2->col;
  1989.     minr = v1->row;
  1990.     minc = v1->col;
  1991.     if (minr>maxr) r = maxr, maxr = minr, minr = r;
  1992.     if (minc>maxc) c = maxc, maxc = minc, minc = c;
  1993.     checkbounds(&maxr, &maxc);
  1994.     if (minr < 0) minr = 0;
  1995.     if (minc < 0) minc = 0;
  1996.  
  1997.     FullUpdate++;
  1998.     modflg++;
  1999.     for (r = minr; r <= maxr; r++)
  2000.     for (c = minc; c <= maxc; c++) {
  2001.         n = lookat (r, c);
  2002.         if (n->flags&is_locked) {
  2003.         error("Cell %s%d is locked", coltoa(n->col), n->row);
  2004.         continue;
  2005.         }
  2006.         if (n->format)
  2007.         scxfree(n->format);
  2008.         n->format = 0;
  2009.         if (s && *s != '\0')
  2010.         n->format = strcpy(scxmalloc((unsigned)(strlen(s)+1)), s);
  2011.         n->flags |= is_changed;
  2012.        }
  2013. }
  2014.  
  2015. void
  2016. hide_row(arg)
  2017. int arg;
  2018. {
  2019.     if (arg < 0) {
  2020.     error("Invalid Range");
  2021.     return;
  2022.     }
  2023.     if (arg >= maxrows-1)
  2024.     {
  2025.     if (!growtbl(GROWROW, arg+1, 0))
  2026.     {    error("You can't hide the last row");
  2027.         return;
  2028.     }
  2029.     }
  2030.     FullUpdate++;
  2031.     row_hidden[arg] = 1;
  2032. }
  2033.  
  2034. void
  2035. hide_col(arg)
  2036. int arg;
  2037. {
  2038.     if (arg < 0) {
  2039.     error("Invalid Range");
  2040.     return;
  2041.     }
  2042.     if (arg >= maxcols-1)
  2043.     {    if ((arg >= ABSMAXCOLS-1) || !growtbl(GROWCOL, 0, arg+1))
  2044.     {    error("You can't hide the last col");
  2045.         return;
  2046.     }
  2047.     }
  2048.     FullUpdate++;
  2049.     col_hidden[arg] = TRUE;
  2050. }
  2051.  
  2052. void
  2053. clearent (v)
  2054. struct ent *v;
  2055. {
  2056.     if (!v)
  2057.     return;
  2058.     label(v,"",-1);
  2059.     v->v = (double)0;
  2060.     if (v->expr)
  2061.     efree(v->expr);
  2062.     v->expr = (struct enode *)0;
  2063.     if (v->format)
  2064.     scxfree(v->format);
  2065.     v->format = (char *)0;
  2066.     v->flags |= (is_changed);
  2067.     v->flags &= ~(is_valid);
  2068.     changed++;
  2069.     modflg++;
  2070. }
  2071.  
  2072. /*
  2073.  * Say if an expression is a constant (return 1) or not.
  2074.  */
  2075. int
  2076. constant (e)
  2077.     register struct enode *e;
  2078. {
  2079.     return (
  2080.      e == (struct enode *)0
  2081.      || e -> op == O_CONST
  2082.      || e -> op == O_SCONST
  2083.      || (
  2084.          e -> op != O_VAR
  2085.          && (e -> op & REDUCE) != REDUCE
  2086.          && constant (e -> e.o.left)
  2087.          && constant (e -> e.o.right)
  2088.          && e -> op != EXT     /* functions look like constants but aren't */
  2089.          && e -> op != NVAL
  2090.          && e -> op != SVAL
  2091.          && e -> op != NOW
  2092.          && e -> op != MYROW
  2093.          && e -> op != MYCOL
  2094.          && e -> op != NUMITER
  2095.     )
  2096.     );
  2097. }
  2098.  
  2099. void
  2100. efree (e)
  2101. struct enode *e;
  2102. {
  2103.     if (e) {
  2104.     if (e->op != O_VAR && e->op !=O_CONST && e->op != O_SCONST
  2105.         && (e->op & REDUCE) != REDUCE) {
  2106.         efree(e->e.o.left);
  2107.         efree(e->e.o.right);
  2108.     }
  2109.     if (e->op == O_SCONST && e->e.s)
  2110.         scxfree(e->e.s);
  2111.     e->e.o.left = freeenodes;
  2112.     freeenodes = e;
  2113.     }
  2114. }
  2115.  
  2116. void
  2117. label (v, s, flushdir)
  2118. register struct ent *v;
  2119. register char *s;
  2120. int    flushdir;
  2121. {
  2122.     if (v) {
  2123.     if (flushdir==0 && v->flags&is_valid) {
  2124.         register struct ent *tv;
  2125.         if (v->col>0 && ((tv=lookat(v->row,v->col-1))->flags&is_valid)==0)
  2126.         v = tv, flushdir = 1;
  2127.         else if (((tv=lookat (v->row,v->col+1))->flags&is_valid)==0)
  2128.         v = tv, flushdir = -1;
  2129.         else flushdir = -1;
  2130.     }
  2131.     if (v->label) scxfree((char *)(v->label));
  2132.     if (s && s[0]) {
  2133.         v->label = scxmalloc ((unsigned)(strlen(s)+1));
  2134.         (void) strcpy (v->label, s);
  2135.     } else
  2136.         v->label = (char *)0;
  2137.     if (flushdir<0) v->flags |= is_leftflush;
  2138.     else v->flags &= ~is_leftflush;
  2139.     if (flushdir==0) v->flags |= is_label;
  2140.     else v->flags &= ~is_label;
  2141.     FullUpdate++;
  2142.     modflg++;
  2143.     }
  2144. }
  2145.  
  2146. void
  2147. decodev (v)
  2148. struct ent_ptr v; 
  2149. {
  2150.     register struct range *r;
  2151.  
  2152.     if (!v.vp) (void) sprintf (line+linelim,"VAR?");
  2153.     else if ((r = find_range((char *)0, 0, v.vp, v.vp)) && !r->r_is_range)
  2154.         (void) sprintf(line+linelim, "%s", r->r_name);
  2155.     else
  2156.         (void) sprintf (line+linelim, "%s%s%s%d",
  2157.             v.vf & FIX_COL ? "$" : "",
  2158.             coltoa(v.vp->col),
  2159.             v.vf & FIX_ROW ? "$" : "",
  2160.             v.vp->row);
  2161.     linelim += strlen (line+linelim);
  2162. }
  2163.  
  2164. char *
  2165. coltoa(col)
  2166. int col;
  2167. {
  2168.     static char rname[3];
  2169.     register char *p = rname;
  2170.  
  2171.     if (col > 25) {
  2172.     *p++ = col/26 + 'A' - 1;
  2173.     col %= 26;
  2174.     }
  2175.     *p++ = col+'A';
  2176.     *p = '\0';
  2177.     return(rname);
  2178. }
  2179.  
  2180. /*
  2181.  *    To make list elements come out in the same order
  2182.  *    they were entered, we must do a depth-first eval
  2183.  *    of the ELIST tree
  2184.  */
  2185. static void
  2186. decompile_list(p)
  2187. struct enode *p;
  2188. {
  2189.     if (!p) return;
  2190.     decompile_list(p->e.o.left);    /* depth first */
  2191.         decompile(p->e.o.right, 0);
  2192.     line[linelim++] = ',';
  2193. }
  2194.  
  2195. void
  2196. decompile(e, priority)
  2197. register struct enode *e;
  2198. int    priority;
  2199. {
  2200.     register char *s;
  2201.     if (e) {
  2202.     int mypriority;
  2203.     switch (e->op) {
  2204.     default: mypriority = 99; break;
  2205.     case '?': mypriority = 1; break;
  2206.     case ':': mypriority = 2; break;
  2207.     case '|': mypriority = 3; break;
  2208.     case '&': mypriority = 4; break;
  2209.     case '<': case '=': case '>': mypriority = 6; break;
  2210.     case '+': case '-': case '#': mypriority = 8; break;
  2211.     case '*': case '/': case '%': mypriority = 10; break;
  2212.     case '^': mypriority = 12; break;
  2213.     }
  2214.     if (mypriority<priority) line[linelim++] = '(';
  2215.     switch (e->op) {
  2216.     case 'f':    for (s="fixed "; line[linelim++] = *s++;);
  2217.             linelim--;
  2218.             decompile (e->e.o.right, 30);
  2219.             break;
  2220.     case 'm':    line[linelim++] = '-';
  2221.             decompile (e->e.o.right, 30);
  2222.             break;
  2223.     case '~':    line[linelim++] = '~';
  2224.             decompile (e->e.o.right, 30);
  2225.             break;
  2226.     case O_VAR:    decodev (e->e.v);
  2227.             break;
  2228.     case O_CONST:    (void) sprintf (line+linelim,"%.15g",e->e.k);
  2229.             linelim += strlen (line+linelim);
  2230.             break;
  2231.     case O_SCONST:    (void) sprintf (line+linelim, "\"%s\"", e->e.s);
  2232.             linelim += strlen(line+linelim);
  2233.             break;
  2234.  
  2235.     case REDUCE | '+': range_arg( "@sum(", e); break;
  2236.     case REDUCE | '*': range_arg( "@prod(", e); break;
  2237.     case REDUCE | 'a': range_arg( "@avg(", e); break;
  2238.     case REDUCE | 'c': range_arg( "@count(", e); break;
  2239.     case REDUCE | 's': range_arg( "@stddev(", e); break;
  2240.     case REDUCE | MAX: range_arg( "@max(", e); break;
  2241.     case REDUCE | MIN: range_arg( "@min(", e); break;
  2242.  
  2243.     case ABS:        one_arg( "@abs(", e); break;
  2244.     case ACOS:    one_arg( "@acos(", e); break;
  2245.     case ASIN:    one_arg( "@asin(", e); break;
  2246.     case ATAN:    one_arg( "@atan(", e); break;
  2247.     case ATAN2:    two_arg( "@atan2(", e); break;
  2248.     case CEIL:    one_arg( "@ceil(", e); break;
  2249.     case COS:    one_arg( "@cos(", e); break;
  2250.     case EXP:    one_arg( "@exp(", e); break;
  2251.     case FABS:    one_arg( "@fabs(", e); break;
  2252.     case FLOOR:    one_arg( "@floor(", e); break;
  2253.     case HYPOT:    two_arg( "@hypot(", e); break;
  2254.     case LOG:    one_arg( "@ln(", e); break;
  2255.     case LOG10:    one_arg( "@log(", e); break;
  2256.     case POW:    two_arg( "@pow(", e); break;
  2257.     case SIN:    one_arg( "@sin(", e); break;
  2258.     case SQRT:    one_arg( "@sqrt(", e); break;
  2259.     case TAN:    one_arg( "@tan(", e); break;
  2260.     case DTR:    one_arg( "@dtr(", e); break;
  2261.     case RTD:    one_arg( "@rtd(", e); break;
  2262.     case RND:    one_arg( "@rnd(", e); break;
  2263.     case ROUND:    two_arg( "@round(", e); break;
  2264.     case HOUR:    one_arg( "@hour(", e); break;
  2265.     case MINUTE:    one_arg( "@minute(", e); break;
  2266.     case SECOND:    one_arg( "@second(", e); break;
  2267.     case MONTH:    one_arg( "@month(", e); break;
  2268.     case DAY:    one_arg( "@day(", e); break;
  2269.     case YEAR:    one_arg( "@year(", e); break;
  2270.     case DATE:    one_arg( "@date(", e); break;
  2271.     case UPPER:    one_arg( "@upper(", e); break;
  2272.     case LOWER:    one_arg( "@lower(", e); break;
  2273.     case CAPITAL:    one_arg( "@capital(", e); break;
  2274.     case DTS:    three_arg( "@dts(", e); break;
  2275.     case TTS:    three_arg( "@tts(", e); break;
  2276.     case STON:    one_arg( "@ston(", e); break;
  2277.     case FMT:    two_arg( "@fmt(", e); break;
  2278.     case EQS:    two_arg( "@eqs(", e); break;
  2279.     case NOW:    for ( s = "@now"; line[linelim++] = *s++;);
  2280.             linelim--;
  2281.             break;
  2282.     case LMAX:    list_arg("@max(", e); break;
  2283.     case LMIN:     list_arg("@min(", e); break;
  2284.     case FV:    three_arg("@fv(", e); break;
  2285.     case PV:    three_arg("@pv(", e); break;
  2286.     case PMT:    three_arg("@pmt(", e); break;
  2287.     case NVAL:    two_arg("@nval(", e); break;
  2288.     case SVAL:    two_arg("@sval(", e); break;
  2289.     case EXT:    two_arg("@ext(", e); break;
  2290.     case SUBSTR:    three_arg("@substr(", e); break;
  2291.     case STINDEX:    index_arg("@stindex(", e); break;
  2292.     case INDEX:    index_arg("@index(", e); break;
  2293.     case LOOKUP:    index_arg("@lookup(", e); break;
  2294.     case HLOOKUP:    two_arg_index("@hlookup(", e); break;
  2295.     case VLOOKUP:    two_arg_index("@vlookup(", e); break;
  2296.     case IF:    three_arg("@if(", e); break;
  2297.     case MYROW:    for ( s = "@myrow"; line[linelim++] = *s++;);
  2298.             linelim--;
  2299.             break;
  2300.     case MYCOL:    for ( s = "@mycol"; line[linelim++] = *s++;);
  2301.             linelim--;
  2302.             break;
  2303.     case COLTOA:    one_arg( "@coltoa(", e); break;
  2304.     case NUMITER:    for ( s = "@numiter"; line[linelim++] = *s++;);
  2305.                         linelim--;
  2306.                         break;
  2307.     default:    decompile (e->e.o.left, mypriority);
  2308.             line[linelim++] = e->op;
  2309.             decompile (e->e.o.right, mypriority+1);
  2310.             break;
  2311.     }
  2312.     if (mypriority<priority) line[linelim++] = ')';
  2313.     } else line[linelim++] = '?';
  2314. }
  2315.  
  2316. void
  2317. index_arg(s, e)
  2318. char *s;
  2319. struct enode *e;
  2320. {
  2321.     for (; line[linelim++] = *s++;);
  2322.     linelim--;
  2323.     decompile( e-> e.o.left, 0 );
  2324.     range_arg(", ", e->e.o.right);
  2325. }
  2326.  
  2327. void
  2328. two_arg_index(s, e)
  2329. char *s;
  2330. struct enode *e;
  2331. {
  2332.     for (; line[linelim++] = *s++;);
  2333.     linelim--;
  2334.     decompile( e->e.o.left->e.o.left, 0 );
  2335.     range_arg(",", e->e.o.right);
  2336.     linelim--;
  2337.     line[linelim++] = ',';
  2338.     decompile( e->e.o.left->e.o.right, 0 );
  2339.     line[linelim++] = ')';
  2340. }
  2341.  
  2342. void
  2343. list_arg(s, e)
  2344. char *s;
  2345. struct enode *e;
  2346. {
  2347.     for (; line[linelim++] = *s++;);
  2348.     linelim--;
  2349.  
  2350.     decompile (e->e.o.right, 0);
  2351.     line[linelim++] = ',';
  2352.     decompile_list(e->e.o.left);
  2353.     line[linelim - 1] = ')';
  2354. }
  2355.  
  2356. void
  2357. one_arg(s, e)
  2358. char *s;
  2359. struct enode *e;
  2360. {
  2361.     for (; line[linelim++] = *s++;);
  2362.     linelim--;
  2363.     decompile (e->e.o.right, 0);
  2364.     line[linelim++] = ')';
  2365. }
  2366.  
  2367. void
  2368. two_arg(s,e)
  2369. char *s;
  2370. struct enode *e;
  2371. {
  2372.     for (; line[linelim++] = *s++;);
  2373.     linelim--;
  2374.     decompile (e->e.o.left, 0);
  2375.     line[linelim++] = ',';
  2376.     decompile (e->e.o.right, 0);
  2377.     line[linelim++] = ')';
  2378. }
  2379.  
  2380. void
  2381. three_arg(s,e)
  2382. char *s;
  2383. struct enode *e;
  2384. {
  2385.     for (; line[linelim++] = *s++;);
  2386.     linelim--;
  2387.     decompile (e->e.o.left, 0);
  2388.     line[linelim++] = ',';
  2389.     decompile (e->e.o.right->e.o.left, 0);
  2390.     line[linelim++] = ',';
  2391.     decompile (e->e.o.right->e.o.right, 0);
  2392.     line[linelim++] = ')';
  2393. }
  2394.  
  2395. void
  2396. range_arg(s,e)
  2397. char *s;
  2398. struct enode *e;
  2399. {
  2400.     struct range *r;
  2401.  
  2402.     for (; line[linelim++] = *s++;);
  2403.     linelim--;
  2404.     if ((r = find_range((char *)0, 0, e->e.r.left.vp,
  2405.                  e->e.r.right.vp)) && r->r_is_range) {
  2406.     (void) sprintf(line+linelim, "%s", r->r_name);
  2407.     linelim += strlen(line+linelim);
  2408.     } else {
  2409.     decodev (e->e.r.left);
  2410.     line[linelim++] = ':';
  2411.     decodev (e->e.r.right);
  2412.     }
  2413.     line[linelim++] = ')';
  2414. }
  2415.  
  2416. void
  2417. editfmt (row, col)
  2418. int row, col;
  2419. {
  2420.     register struct ent *p;
  2421.  
  2422.     p = lookat (row, col);
  2423.     if (p->format) {
  2424.         (void) sprintf (line, "fmt %s \"%s\"", v_name(row, col), p->format);
  2425.     linelim = strlen(line);
  2426.     }
  2427. }
  2428.  
  2429. void
  2430. editv (row, col)
  2431. int row, col;
  2432. {
  2433.     register struct ent *p;
  2434.  
  2435.     p = lookat (row, col);
  2436.     (void) sprintf (line, "let %s = ", v_name(row, col));
  2437.     linelim = strlen(line);
  2438.     if (p->flags & is_strexpr || p->expr == 0) {
  2439.     (void) sprintf (line+linelim, "%.15g", p->v);
  2440.     linelim += strlen (line+linelim);
  2441.     } else {
  2442.         editexp(row,col);
  2443.     }
  2444. }
  2445.  
  2446. void
  2447. editexp(row,col)
  2448. int row, col;
  2449. {
  2450.     register struct ent *p;
  2451.  
  2452.     p = lookat (row, col);
  2453.     decompile (p->expr, 0);
  2454.     line[linelim] = '\0';
  2455. }
  2456.  
  2457. void
  2458. edits (row, col)
  2459. int row, col;
  2460. {
  2461.     register struct ent *p;
  2462.  
  2463.     p = lookat (row, col);
  2464.     if( p->flags&is_label )
  2465.     (void) sprintf( line, "label %s = ", v_name(row, col));
  2466.     else
  2467.     (void) sprintf (line, "%sstring %s = ",
  2468.             ((p->flags&is_leftflush) ? "left" : "right"),
  2469.             v_name(row, col));
  2470.     linelim = strlen(line);
  2471.     if (p->flags & is_strexpr && p->expr) {
  2472.     editexp(row, col);
  2473.     } else if (p->label) {
  2474.         (void) sprintf (line+linelim, "\"%s\"", p->label);
  2475.         linelim += strlen (line+linelim);
  2476.     } else {
  2477.         (void) sprintf (line+linelim, "\"");
  2478.         linelim += 1;
  2479.     }
  2480. }
  2481.  
  2482. #ifdef RINT
  2483. /*    round-to-even, also known as ``banker's rounding''.
  2484.     With round-to-even, a number exactly halfway between two values is
  2485.     rounded to whichever is even; e.g. rnd(0.5)=0, rnd(1.5)=2,
  2486.     rnd(2.5)=2, rnd(3.5)=4.  This is the default rounding mode for
  2487.     IEEE floating point, for good reason: it has better numeric
  2488.     properties.  For example, if X+Y is an integer,
  2489.     then X+Y = rnd(X)+rnd(Y) with round-to-even,
  2490.     but not always with sc's rounding (which is
  2491.     round-to-positive-infinity).  I ran into this problem when trying to
  2492.     split interest in an account to two people fairly.
  2493. */
  2494. double rint(d) double d;
  2495. {
  2496.     /* as sent */
  2497.     double fl = floor(d),  fr = d-fl;
  2498.     return
  2499.         fr<0.5  ||  fr==0.5 && fl==floor(fl/2)*2   ?   fl   :   ceil(d);
  2500. }
  2501. #endif
  2502.