home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / oleo_src.lha / src / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-18  |  30.3 KB  |  1,610 lines

  1. /*    Copyright (C) 1990 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with Oleo; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <math.h>
  20. #include <ctype.h>
  21. #include <stdio.h>
  22.  
  23. #ifdef __TURBOC__
  24. #define SMALLEVAL
  25. #else
  26. #include <signal.h>
  27. #ifdef __GNU_LIBRARY__
  28. typedef void SIGTY;
  29. #define SIGRET    return;
  30. #else
  31. typedef int SIGTY;
  32. #define SIGRET return 0;
  33. #ifndef NeXT
  34. #ifndef AMIGA
  35. extern long fseek();
  36. #endif
  37. /* extern fread();
  38. extern fclose(); */
  39. #endif
  40. #endif
  41. #endif
  42.  
  43. #include "funcdef.h"
  44.  
  45. #ifdef NO_RINT
  46. #define rint(x) (((x)<0) ? ceil((x)-.5) : floor((x)+.5))
  47. #else
  48. extern double rint EXT1(double);
  49. #endif
  50.  
  51. #define obstack_chunk_alloc ck_malloc
  52. #define obstack_chunk_free free
  53. #include "obstack.h"
  54.  
  55. #include "sysdef.h"
  56.  
  57. #include "global.h"
  58. #include "cell.h"
  59. #include "eval.h"
  60. #include "errors.h"
  61.  
  62. struct value {
  63.     int    type;
  64.     union vals x;
  65. };
  66.  
  67. #define Float    x.c_d
  68. #define String    x.c_s
  69. #define Int    x.c_l
  70. #define Value    x.c_i
  71. #define Rng    x.c_r
  72.  
  73. #define PI (3.14159265358979326848)
  74.  
  75. double to_int EXT1(double);
  76. static int deal_area EXT3(unsigned char, unsigned char, struct value *);
  77.  
  78. static void add_int EXT1(long);
  79. static void add_flt EXT1(double);
  80. #ifndef __TURBOC__
  81. SIGTY math_sig EXT1(int);
  82. #endif
  83.  
  84. static struct value   *stack;
  85. static int             stackmax;
  86. static int             curstack;
  87.  
  88. unsigned short current_cycle;
  89.  
  90. CELLREF cur_row;
  91. CELLREF cur_col;
  92.  
  93. static double exp10_arr[] = {
  94.     1E0,    1E1,    1E2,    1E3,    1E4,
  95.     1E5,    1E6,    1E7,    1E8,    1E9,
  96.     1E10,    1E11,    1E12,    1E13,    1E14,
  97.     1E15,    1E16,    1E17,    1E18,    1E19,
  98.     1E20,    1E21,    1E22,    1E23,    1E24,
  99.     1E25,    1E26,    1E27,    1E28,    1E29
  100. };
  101.  
  102. /* Various math conversions with error checking */
  103. #define I_ADD(i1,i2) {    itmp=(i1)+(i2);                    \
  104.             if((i1>0)==(i2>0) && (itmp>0)!=(i1>0)) {    \
  105.                 p->Float=(double)(i1)+(double)(i2);    \
  106.                 p->type=TYP_FLT;            \
  107.             } else                        \
  108.                 p->Int=itmp;    }
  109.  
  110. #define I_SUB(i1,i2) {    itmp=(i1)-(i2);                    \
  111.             if(((i1)<0)==((i2)>0) && ((itmp)>0)!=((i2)<0)) {\
  112.                 p->Float=(double)(i1)-(double)(i2);    \
  113.                 p->type=TYP_FLT;            \
  114.             } else                        \
  115.                 p->Int=itmp;    }
  116.  
  117. #define I_DIV(i1,i2) {    ftmp=(double)(i1)/(double)(i2);            \
  118.             /* ... */;                    \
  119.             p->Float=ftmp;                    \
  120.             p->type=TYP_FLT;    }
  121.  
  122. #define I_MOD(i1,i2) {itmp=(i1)%(i2);/* ... */;p->Int=itmp;}
  123.  
  124. int fls EXT1(long);
  125. #define I_MUL(i1,i2) {    if(fls(i1)+fls(i2)>32) {            \
  126.                 p->Float=(double)(i1)*(double)(i2);    \
  127.                 p->type=TYP_FLT;            \
  128.             } else                        \
  129.                 p->Int=(i1)*(i2);    }
  130.  
  131. #define F_ADD(f1,f2) {    ftmp=(f1)+(f2);/* ... */;p->Float=ftmp;    }
  132.  
  133. #define F_SUB(f1,f2) {    ftmp=(f1)-(f2);/* ... */;p->Float=ftmp;}
  134.  
  135. #define F_DIV(f1,f2) {    ftmp=(f1)/(f2);/* ... */;p->Float=ftmp;}
  136.  
  137. #define F_MOD(f1,f2) {    itmp=(long)(f1)%(long)(f2);/* ... */;p->Int=itmp;p->type=TYP_INT;}
  138.  
  139. #define F_MUL(f1,f2) {    ftmp=(f1)*(f2);/* ... */;p->Float=ftmp;}
  140.  
  141. double ftmp;
  142. long itmp;
  143. int overflow;
  144.  
  145. /* You may ask:  Why not jsut put the value in stack[0] and goto break_out
  146.    The answer is that ERROR is a valid input type for several operators, so
  147.    we want to work if we're feeding an error into one of these operators. . .
  148.  */
  149. #define ERROR(cause)        \
  150.     do {            \
  151.         p->type=TYP_ERR;\
  152.         p->Value=cause; \
  153.         goto next_byte; \
  154.     } while(0)
  155.  
  156. #ifdef SMALLEVAL
  157. int __to_flt EXT1(struct value *);
  158. int __to_int EXT1(struct value *);
  159. int __to_num EXT1(struct value *);
  160. int __to_str EXT1(struct value *);
  161. int __to_bol EXT1(struct value *);
  162. int __to_rng EXT1(struct value *);
  163.  
  164. #define TO_FLT(val)            \
  165.     if((tmp=__to_flt(val))!=0)    \
  166.         ERROR(tmp);
  167.  
  168. #define TO_INT(val)            \
  169.     if((tmp=__to_int(val))!=0)    \
  170.         ERROR(tmp);
  171.  
  172. #define TO_NUM(val)            \
  173.     if((tmp=__to_num(val))!=0)    \
  174.         ERROR(tmp);
  175.  
  176. #define TO_STR(val)            \
  177.     if((tmp=__to_str(val))!=0)    \
  178.         ERROR(tmp);
  179.  
  180. #define TO_BOL(val)            \
  181.     if((tmp=__to_bol(val))!=0)    \
  182.         ERROR(tmp);
  183.  
  184. #define TO_RNG(val)            \
  185.     if((tmp=__to_rng(val))!=0)    \
  186.         ERROR(tmp);
  187.  
  188. #else
  189. #define TO_FLT(val)    \
  190.     if((val)->type==TYP_FLT) \
  191.         ; \
  192.     else if((val)->type==TYP_INT) { \
  193.         (val)->type=TYP_FLT; \
  194.         (val)->Float=(double)(val)->Int; \
  195.     } else if((val)->type==TYP_STR) { \
  196.         (val)->type=TYP_FLT; \
  197.         strptr=(val)->String; \
  198.         (val)->Float=astof(&strptr); \
  199.         if(*strptr) \
  200.             ERROR(NON_NUMBER); \
  201.     } else if((val)->type==TYP_ERR) {\
  202.         ERROR((val)->Value); \
  203.     } else if((val)->type==0) { \
  204.         (val)->type=TYP_FLT; \
  205.         (val)->Float=0.0; \
  206.     } else \
  207.         ERROR(NON_NUMBER);
  208.  
  209. #define TO_INT(val)    \
  210.     if((val)->type==TYP_INT) \
  211.         ; \
  212.     else if((val)->type==TYP_FLT) { \
  213.         (val)->type=TYP_INT; \
  214.         (val)->Int=(long)(val)->Float; \
  215.     } else if((val)->type==TYP_STR) { \
  216.         (val)->type=TYP_INT; \
  217.         strptr=(val)->String; \
  218.         (val)->Int=astol(&strptr); \
  219.         if(*strptr) \
  220.             ERROR(NON_NUMBER); \
  221.     } else if((val)->type==TYP_ERR) \
  222.         ERROR((val)->Value); \
  223.     else if((val)->type==0) { \
  224.         (val)->type=TYP_INT; \
  225.         (val)->Int=0; \
  226.     } else \
  227.         ERROR(NON_NUMBER);
  228.  
  229. #define TO_NUM(val)    \
  230.     if((val)->type==TYP_INT || (val)->type==TYP_FLT) \
  231.         ; \
  232.     else if((val)->type==TYP_STR) { \
  233.         (val)->type=TYP_FLT; \
  234.         strptr=(val)->String; \
  235.         (val)->Float=astof(&strptr); \
  236.         if(*strptr) \
  237.             ERROR(NON_NUMBER); \
  238.     } else if((val)->type==TYP_ERR) \
  239.         ERROR((val)->Value); \
  240.     else if((val)->type==0) { \
  241.         (val)->type=TYP_INT; \
  242.         (val)->Int=0; \
  243.     } else \
  244.         ERROR(NON_NUMBER);
  245.  
  246. #define TO_STR(val)    \
  247.     if((val)->type==TYP_STR) \
  248.         ; \
  249.     else if((val)->type==TYP_INT) { \
  250.         char *s; \
  251.         (val)->type=TYP_STR; \
  252.         s=obstack_alloc(&tmp_mem,30); \
  253.         sprintf(s,"%ld",(val)->Int); \
  254.         (val)->String=s; \
  255.     } else if((val)->type==TYP_FLT) {        \
  256.         char *s;                \
  257.         s=flt_to_str((val)->Float);        \
  258.         (void)obstack_grow(&tmp_mem,s,strlen(s)+1); \
  259.         (val)->String=obstack_finish(&tmp_mem);    \
  260.         (val)->type=TYP_STR;            \
  261.     } else if((val)->type==TYP_ERR)            \
  262.         ERROR((val)->Value); \
  263.     else if((val)->type==0) { \
  264.         (val)->type=TYP_STR; \
  265.         (val)->String=obstack_alloc(&tmp_mem,1); \
  266.         (val)->String[0]='\0'; \
  267.     } else \
  268.         ERROR(NON_STRING);
  269.  
  270. #define TO_BOL(val) \
  271.     if((val)->type==TYP_BOL) \
  272.         ; \
  273.     else if((val)->type==TYP_ERR) \
  274.         ERROR((val)->Value); \
  275.     else \
  276.         ERROR(NON_BOOL);
  277.  
  278. #define TO_RNG(val) \
  279.     if((val)->type==TYP_RNG) \
  280.         ; \
  281.     else if((val)->type==TYP_ERR) \
  282.         ERROR((val)->Value); \
  283.     else \
  284.         ERROR(NON_RANGE);
  285.  
  286. #endif
  287.  
  288. #define TO_ANY(val) \
  289.     if((val)->type==TYP_RNG) \
  290.         ERROR(BAD_INPUT); \
  291.  
  292. #define PUSH_ANY(cp)                \
  293.     if(!cp || !GET_TYP(cp)) {        \
  294.         p->type=0;            \
  295.         p->Int=0;            \
  296.     } else {                \
  297.         p->type=GET_TYP(cp);        \
  298.         p->x=cp->c_z;            \
  299.     }
  300.  
  301. void
  302. init_eval FUN0()
  303. {
  304.     stack=(struct value *)ck_malloc(20*sizeof(struct value));
  305.     stackmax=20;
  306.     curstack=0;
  307.     current_cycle++;
  308. #ifndef __TURBOC__
  309.     (void)signal(SIGFPE,math_sig);
  310. #endif
  311. }
  312.  
  313. /* This huge function takes a byte-compiled expression and executes it. */
  314. struct value *
  315. eval_expression FUN1(unsigned char  *,expr)
  316. {
  317.     unsigned char   byte;
  318.     unsigned numarg;
  319.     unsigned jumpto;
  320.     struct function *f;
  321.     struct value    *p;
  322.     char    *strptr;
  323.     int    tmp;
  324.  
  325.     CELLREF    lrow,    hrow,    crow;
  326.     CELLREF    lcol,    hcol,    ccol;
  327.  
  328.     struct cell *cell_ptr;
  329.  
  330.     if(!expr)
  331.         return 0;
  332. #ifdef TEST
  333.     jumpto=0;
  334.     numarg=0;
  335.     p=0;
  336. #endif
  337.     curstack=0;
  338.     while((byte= *expr++)!=ENDCOMP) {
  339.         if(byte<USR1)
  340.             f= &the_funs[byte];
  341.         else if(byte<SKIP) {
  342. #ifdef TEST
  343.             extern int n_usr_funs;
  344.  
  345.             if(byte-USR1>=n_usr_funs)
  346.                 panic("Only have %d usr-function slots, but found byte for slot %d",n_usr_funs,1+byte-USR1);
  347. #endif
  348.             tmp= *expr++;
  349.             f= &usr_funs[byte-USR1][tmp];
  350.         } else
  351.             f= &skip_funs[byte-SKIP];
  352.  
  353.         if(f->fn_argn&X_J)
  354.             jumpto= *expr++;
  355.         else if(f->fn_argn&X_JL) {
  356.             jumpto= expr[0]+((unsigned)(expr[1])<<8);
  357.             expr+=2;
  358.         }
  359.  
  360.         switch(f->fn_argn & X_ARGS) {
  361.             /* A0 is special, since it makes the stack grow, while
  362.                all the others make the stack the same size or
  363.                less. . . */
  364.         case X_A0:
  365.             numarg= 0;
  366.             if(curstack==stackmax) {
  367.                 stackmax*=2;
  368.  
  369.                 stack=(struct value *)ck_realloc(stack,sizeof(struct value)*stackmax);
  370.             }
  371.             p= &stack[curstack];
  372.             curstack++;
  373.             break;
  374.  
  375.         case X_A1:
  376.             numarg=1;
  377.             break;
  378.  
  379.         case X_A2:
  380.             numarg=2;
  381.             break;
  382.         case X_A3:
  383.             numarg=3;
  384.             break;
  385.         case X_A4:
  386.             numarg=4;
  387.             break;
  388.         case X_AN:
  389.             numarg= *expr++;
  390.             break;
  391. #ifdef TEST
  392.         default:
  393.             panic("Unknown arg_num %d",f->fn_argn);
  394.             numarg=0;
  395.             p=0;
  396. #endif
  397.         }
  398.         if(numarg>0) {
  399.             int xt;
  400.  
  401. #ifdef TEST
  402.             if(curstack<numarg)
  403.                 panic("Only %u values on stack, not %u", curstack, numarg);
  404. #endif
  405.             p= &stack[curstack-numarg];
  406.             curstack-=(numarg-1);
  407.             for(xt=0;xt<numarg;xt++) {
  408.                 switch(f->fn_argt[xt<=3 ? xt : 3]) {
  409.                     /* A is for anything */
  410.                     /* Any non-range value */
  411.                 case 'A':
  412.                     TO_ANY(p+xt);
  413.                     break;
  414.                     /* B is for boolean */
  415.                 case 'B':
  416.                     TO_BOL(p+xt);
  417.                     break;
  418.                     /* D is for Don't check */
  419.                 case 'D':
  420.                     break;
  421.                     /* E is for Everything */
  422.                 case 'E':
  423.                     break;
  424.                     /* F is for Float */
  425.                 case 'F':
  426.                     TO_FLT(p+xt);
  427.                     break;
  428.                     /* I is for Int */
  429.                 case 'I':
  430.                     TO_INT(p+xt);
  431.                     break;
  432.                     /* N is for Number (int or float) */
  433.                 case 'N':
  434.                     TO_NUM(p+xt);
  435.                     break;
  436.                     /* R is for Range */
  437.                 case 'R':
  438.                     TO_RNG(p+xt);
  439.                     break;
  440.                     /* S is for String */
  441.                 case 'S':
  442.                     TO_STR(p+xt);
  443.                     break;
  444. #ifdef TEST
  445.                 default:
  446.                     error_msg("YIKE!  Unknown argtype for Fun %u  arg #%u",byte,xt);
  447.                     break;
  448. #endif
  449.                 }
  450.             }
  451.         }
  452.  
  453.         switch (byte) {
  454.         case IF_L:
  455.         case F_IF_L:
  456.         case IF:
  457.         case F_IF:
  458.             if(p->type!=TYP_BOL) {
  459.                 if(p->type!=TYP_ERR) {
  460.                     p->type=TYP_ERR;
  461.                     p->Value=NON_BOOL;
  462.                 }
  463.                 expr+=jumpto;
  464.                 if(expr[-2]!=SKIP)
  465.                     jumpto=expr[-1]+(((unsigned)expr[-2])<<8);
  466.                 else
  467.                     jumpto=expr[-1];
  468.                 expr+=jumpto;    /* Skip both branches of the if */
  469.  
  470.             } else if(p->Value==0) {
  471.                 expr+=jumpto;
  472.                 --curstack;
  473.             } else
  474.                 --curstack;
  475.             break;
  476.         
  477.         case SKIP_L:
  478.         case SKIP:
  479.             --curstack;
  480.             expr+=jumpto;
  481.             break;
  482.  
  483.         case AND_L:
  484.         case AND:
  485.             if(p->type==TYP_ERR)
  486.                 expr+=jumpto;
  487.             else if(p->type!=TYP_BOL) {
  488.                 p->type=TYP_ERR;
  489.                 p->Value=NON_BOOL;
  490.                 expr+=jumpto;
  491.             } else if(p->Value==0)
  492.                 expr+=jumpto;
  493.             else
  494.                 --curstack;
  495.             break;
  496.  
  497.         case OR_L:
  498.         case OR:
  499.             if(p->type==TYP_ERR)
  500.                 expr+=jumpto;
  501.             else if(p->type!=TYP_BOL) {
  502.                 p->type=TYP_ERR;
  503.                 p->Value=NON_BOOL;
  504.                 expr+=jumpto;
  505.             } else if(p->Value)
  506.                 expr+=jumpto;
  507.             else
  508.                 --curstack;
  509.             break;
  510.  
  511.         case CONST_FLT:
  512.             p->type=TYP_FLT;
  513.             bcopy((VOIDSTAR)expr,(VOIDSTAR)(&(p->Float)),sizeof(double));
  514.             expr+=sizeof(double);
  515.             break;
  516.  
  517.         case CONST_INT:
  518.             p->type=TYP_INT;
  519.             bcopy((VOIDSTAR)expr,(VOIDSTAR)(&(p->Int)),sizeof(long));
  520.             expr+=sizeof(long);
  521.             break;
  522.  
  523.         case CONST_STR:
  524.         case CONST_STR_L:
  525.             p->type=TYP_STR;
  526.             p->String=(char *)expr+jumpto;
  527.             break;
  528.  
  529.         case CONST_ERR:
  530.             p->type=TYP_ERR;
  531.             p->Value= *expr++;
  532.             /* expr+=sizeof(char *); */
  533.             break;
  534.  
  535.         case CONST_INF:
  536.         case CONST_NINF:
  537.         case CONST_NAN:
  538.             p->type=TYP_FLT;
  539.             p->Float= (byte==CONST_INF) ? __plinf : ((byte==CONST_NINF) ? __neinf : __nan);
  540.             break;
  541.  
  542.         case VAR:
  543.         {
  544.             struct var *varp;
  545.  
  546.             bcopy((VOIDSTAR)expr,(VOIDSTAR)(&varp),sizeof(struct var *));
  547.             expr+=sizeof(struct var *);
  548.             switch(varp->var_flags) {
  549.             case VAR_UNDEF:
  550.                 p->type=TYP_ERR;
  551.                 p->Value=BAD_NAME;
  552.                 break;
  553.  
  554.             case VAR_CELL:
  555.                 cell_ptr=find_cell(varp->v_rng.lr,varp->v_rng.lc);
  556.                 PUSH_ANY(cell_ptr);
  557.                 break;
  558.  
  559.             case VAR_RANGE:
  560.                 p->type=TYP_RNG;
  561.                 p->Rng=varp->v_rng;
  562.                 break;
  563. #ifdef TEST
  564.             default:
  565.                 panic("Unknown var type %d",varp->var_flags);
  566. #endif
  567.             }
  568.         }
  569.             break;
  570.  
  571.             /* Cell refs */
  572.         case R_CELL:
  573.         case R_CELL|COLREL:
  574.         case R_CELL|ROWREL:
  575.         case R_CELL|ROWREL|COLREL:
  576.         {
  577.             CELLREF torow,tocol;
  578.  
  579.             torow = GET_ROW(expr);
  580.             tocol = GET_COL(expr);
  581.             expr+=EXP_ADD;
  582. #ifdef DONTDEF
  583.             if(byte&ROWREL)
  584.                 torow=(short)torow+cur_row;
  585.             if(byte&COLREL)
  586.                 tocol=(short)tocol+cur_col;
  587. #endif
  588. #ifdef DONTDEF
  589.             if(torow<MIN_ROW || torow>MAX_ROW || tocol<MIN_COL || tocol>MAX_COL) {
  590.                 p->type=TYP_ERR;
  591.                 p->Value=OUT_OF_RANGE;
  592.             } else {
  593. #endif
  594.                 cell_ptr=find_cell((CELLREF)torow,(CELLREF)tocol);
  595.                 PUSH_ANY(cell_ptr);
  596. #ifdef DONTDEF
  597.             }
  598. #endif
  599.         }
  600.             break;
  601.  
  602.         case RANGE:
  603.         case RANGE|LRREL:
  604.         case RANGE|LRREL|LCREL:
  605.         case RANGE|LRREL|LCREL|HCREL:
  606.         case RANGE|LRREL|HCREL:
  607.         case RANGE|LRREL|HRREL:
  608.         case RANGE|LRREL|HRREL|LCREL:
  609.         case RANGE|LRREL|HRREL|LCREL|HCREL:
  610.         case RANGE|LRREL|HRREL|HCREL:
  611.         case RANGE|HRREL:
  612.         case RANGE|HRREL|LCREL:
  613.         case RANGE|HRREL|LCREL|HCREL:
  614.         case RANGE|HRREL|HCREL:
  615.         case RANGE|LCREL:
  616.         case RANGE|LCREL|HCREL:
  617.         case RANGE|HCREL:
  618.             p->type=TYP_RNG;
  619.             GET_RNG(expr,&(p->Rng));
  620.             expr+=EXP_ADD_RNG;
  621.             break;
  622.  
  623.         case F_TRUE:
  624.         case F_FALSE:
  625.             p->type=TYP_BOL;
  626.             p->Value=(byte==F_TRUE);
  627.             break;
  628.  
  629.         case F_PI:
  630.             p->type=TYP_FLT;
  631.             p->Float=PI;
  632.             break;
  633.  
  634.         case F_ROW:
  635.         case F_COL:
  636.             p->type=TYP_INT;
  637.             p->Int= ((byte==F_ROW) ? cur_row : cur_col);
  638.             break;
  639.  
  640.         case F_NOW:
  641.             p->type=TYP_INT;
  642.             p->Int=time((VOIDSTAR)0);
  643.             break;
  644.  
  645.             /* Single operand instrs */
  646.         case F_ABS:
  647.         case F_ACOS:
  648.         case F_ASIN:
  649.         case F_ATAN:
  650.         case F_CEIL:
  651.         case F_COS:
  652.         case F_DTR:
  653.         case F_EXP:
  654.         case F_FLOOR:
  655.         case F_INT:
  656.         case F_LOG:
  657.         case F_LOG10:
  658.         case F_RTD:
  659.         case F_SIN:
  660.         case F_SQRT:
  661.         case F_TAN:
  662.         {
  663.             double (*funp1) EXT1(double);
  664.  
  665.             funp1=(double(*) EXT1(double))(f->fn_fun);
  666.             p->Float=(*funp1)(p->Float);
  667.             if(p->Float!=p->Float)
  668.                 ERROR(OUT_OF_RANGE);
  669.         }
  670.             break;
  671.  
  672.         case F_CTIME:
  673.             p->type=TYP_STR;
  674.             strptr=ctime(&(p->Int));
  675.             p->String=obstack_alloc(&tmp_mem,25);
  676.             strncpy(p->String,strptr,24);
  677.             p->String[24]='\0';
  678.             break;
  679.  
  680.         case NEGATE:
  681.         case F_NEG:
  682.             if(p->type==TYP_ERR)
  683.                 break;
  684.             if(p->type==TYP_INT)
  685.                 p->Int= -(p->Int);
  686.             else if(p->type==TYP_FLT)
  687.                 p->Float= -(p->Float);
  688.             else
  689.                 ERROR(NON_NUMBER);
  690.             break;
  691.  
  692.         case F_RND:
  693.             p->Int=(random()%(p->Int))+1;
  694.             break;
  695.  
  696.         case NOT:
  697.         case F_NOT:
  698.             p->Value= !(p->Value);
  699.             break;
  700.  
  701.         case F_ISERR:
  702.             p->Value= (p->type==TYP_ERR);
  703.             p->type=TYP_BOL;
  704.             break;
  705.  
  706.         case F_ISNUM:
  707.             if(p->type==TYP_FLT || p->type==TYP_INT)
  708.                 p->Value=1;
  709.             else if(p->type==TYP_STR) {
  710.                 strptr=p->String;
  711.                 (void)astof(&strptr);
  712.                 p->Value= (*strptr=='\0');
  713.             } else
  714.                 p->Value=0;
  715.             p->type=TYP_BOL;
  716.             break;
  717.  
  718.         case F_ROWS:
  719.         case F_COLS:
  720.             p->type=TYP_INT;
  721.             p->Int=1+(byte==F_ROWS ? (p->Rng.hr-p->Rng.lr) : (p->Rng.hc-p->Rng.lc));
  722.             break;
  723.  
  724.             /* Two operand cmds */
  725.         case F_ATAN2:
  726.         case F_HYPOT:
  727.         case POW:
  728.         {
  729.             double (*funp2) EXT2(double,double);
  730.  
  731.             funp2=(double(*) EXT2(double,double))(f->fn_fun);
  732.             p->Float=(*funp2)(p->Float,(p+1)->Float);
  733.             if(p->Float!=p->Float)
  734.                 ERROR(OUT_OF_RANGE);
  735.         }
  736.             break;
  737.  
  738.         case DIFF:
  739.         case DIV:
  740.         case MOD:
  741.         case PROD:
  742.         case SUM:
  743.  
  744.             if(p->type!=(p+1)->type) {
  745.                 if(p->type==TYP_INT) {
  746.                     p->type=TYP_FLT;
  747.                     p->Float=(double)p->Int;
  748.                 }
  749.                 if((p+1)->type==TYP_INT) {
  750.                     (p+1)->type=TYP_FLT;
  751.                     (p+1)->Float=(double)((p+1)->Int);
  752.                 }
  753.             }
  754.             if(p->type==TYP_INT) {
  755.                 switch(byte) {
  756.                 case DIFF:
  757.                     I_SUB(p->Int,(p+1)->Int);
  758.                     break;
  759.                 case DIV:
  760.                     if((p+1)->Int==0)
  761.                         ERROR(DIV_ZERO);
  762.                     I_DIV(p->Int,(p+1)->Int);
  763.                     break;
  764.                 case MOD:
  765.                     if((p+1)->Int==0)
  766.                         ERROR(DIV_ZERO);
  767.                     I_MOD(p->Int, (p+1)->Int);
  768.                     break;
  769.                 case PROD:
  770.                     I_MUL(p->Int,(p+1)->Int);
  771.                     break;
  772.                 case SUM:
  773.                     I_ADD(p->Int,(p+1)->Int);
  774.                     break;
  775. #ifdef TEST
  776.                 default:
  777.                     panic("Evaluator confused by byte-value %d",byte);
  778. #endif
  779.                 }
  780.             } else {
  781.                 switch(byte) {
  782.                 case DIFF:
  783.                     F_SUB(p->Float, (p+1)->Float);
  784.                     break;
  785.                 case DIV:
  786.                     if((p+1)->Float==0)
  787.                         ERROR(DIV_ZERO);
  788.                     F_DIV(p->Float, (p+1)->Float);
  789.                     break;
  790.                 case MOD:
  791.                     if((p+1)->Float==0)
  792.                         ERROR(DIV_ZERO);
  793.                     F_MOD(p->Float, (p+1)->Float);
  794.                     break;
  795.                 case PROD:
  796.                     F_MUL(p->Float, (p+1)->Float);
  797.                     break;
  798.                 case SUM:
  799.                     F_ADD(p->Float, (p+1)->Float);
  800.                     break;
  801. #ifdef TEST
  802.                 default:
  803.                     panic("Unknown operation %d",byte);
  804. #endif
  805.                 }
  806.             }
  807.             if(overflow)
  808.                 ERROR(OUT_OF_RANGE);
  809.             break;
  810.  
  811.         case EQUAL:
  812.         case NOTEQUAL:
  813.  
  814.         case GREATEQ:
  815.         case GREATER:
  816.         case LESS:
  817.         case LESSEQ:
  818.             if(p->type==TYP_ERR)
  819.                  break;
  820.             if((p+1)->type==TYP_ERR)
  821.                 ERROR((p+1)->Value);
  822.  
  823.             if(p->type==TYP_BOL || (p+1)->type==TYP_BOL) {
  824.                 if(p->type!=(p+1)->type || (byte!=EQUAL && byte!=NOTEQUAL))
  825.                     ERROR(BAD_INPUT);
  826.                 if(byte==EQUAL)
  827.                     p->Value=p->Value==(p+1)->Value;
  828.                 else
  829.                     p->Value=p->Value!=(p+1)->Value;
  830.                 break;
  831.             }
  832.             if(p->type!=(p+1)->type) {
  833.                 if(p->type==0) {
  834.                     if((p+1)->type==TYP_STR) {
  835.                         p->type=TYP_STR;
  836.                         p->String="";
  837.                     } else if((p+1)->type==TYP_INT) {
  838.                         p->type=TYP_INT;
  839.                         p->Int=0;
  840.                     } else {
  841.                         p->type=TYP_FLT;
  842.                         p->Float=0.0;
  843.                     }
  844.                 } else if((p+1)->type==0) {
  845.                     if(p->type==TYP_STR) {
  846.                         (p+1)->type=TYP_STR;
  847.                         (p+1)->String="";
  848.                     } else if(p->type==TYP_INT) {
  849.                         (p+1)->type=TYP_INT;
  850.                         (p+1)->Int=0;
  851.                     } else {
  852.                         (p+1)->type=TYP_FLT;
  853.                         (p+1)->Float=0.0;
  854.                     }
  855.                 } else if(p->type==TYP_STR) {
  856.                     strptr=p->String;
  857.                     if((p+1)->type==TYP_INT) {
  858.                         p->type=TYP_INT;
  859.                         p->Int=astol(&strptr);
  860.                     } else {
  861.                         p->type=TYP_FLT;
  862.                         p->Float=astof(&strptr);
  863.                     }
  864.                     if(*strptr) {
  865.                         p->type=TYP_BOL;
  866.                         p->Value=(byte==NOTEQUAL);
  867.                         break;
  868.                     }
  869.                 } else if((p+1)->type==TYP_STR) {
  870.                     strptr=(p+1)->String;
  871.                     if(p->type==TYP_INT)
  872.                         (p+1)->Int=astol(&strptr);
  873.                     else
  874.                         (p+1)->Float=astof(&strptr);
  875.                     if(*strptr) {
  876.                         p->type=TYP_BOL;
  877.                         p->Value=(byte==NOTEQUAL);
  878.                         break;
  879.                     }
  880.  
  881.                 /* If we get here, one is INT, and the other
  882.                    is FLT  Make them both FLT */
  883.                 } else if(p->type==TYP_INT) {
  884.                     p->type=TYP_FLT;
  885.                     p->Float=(double)p->Int;
  886.                 } else
  887.                     (p+1)->Float=(double)(p+1)->Int;
  888.             }
  889.             if(p->type==TYP_STR)
  890.                 tmp=strcmp(p->String,(p+1)->String);
  891.             else if(p->type==TYP_FLT)
  892.                 tmp= (p->Float < (p+1)->Float) ? -1 : ((p->Float>(p+1)->Float) ? 1 : 0);
  893.             else if(p->type==TYP_INT)
  894.                 tmp= (p->Int < (p+1)->Int ? -1 : ((p->Int>(p+1)->Int) ? 1 : 0));
  895.             else if(p->type==0)
  896.                 tmp = 0;
  897.             else {
  898.                 tmp=0;
  899.                 panic("Bad type value %d",p->type);
  900.             }
  901.             p->type=TYP_BOL;
  902.             if(tmp<0)
  903.                 p->Value=(byte==NOTEQUAL || byte==LESS || byte==LESSEQ);
  904.             else if(tmp==0)
  905.                 p->Value=(byte==EQUAL || byte==GREATEQ || byte==LESSEQ);
  906.             else
  907.                 p->Value=(byte==NOTEQUAL || byte==GREATER || byte==GREATEQ);
  908.             break;
  909.  
  910.         case F_FIXED:
  911.             tmp=(p+1)->Int;
  912.             if(tmp<-29 || tmp>29)
  913.                 ERROR(OUT_OF_RANGE);
  914.             if(tmp<0)
  915.                 p->Float=rint((p->Float)/exp10_arr[-tmp])*exp10_arr[-tmp];
  916.             else
  917.                 p->Float=rint((p->Float)*exp10_arr[tmp])/exp10_arr[tmp];
  918.             break;
  919.  
  920.         case F_IFERR:
  921.             if(p->type==TYP_ERR)
  922.                 *p= *(p+1);
  923.             break;
  924.  
  925.         case F_INDEX:
  926.             tmp=(p+1)->Int - 1;
  927.             if(tmp<0)
  928.                 ERROR(OUT_OF_RANGE);
  929.             lrow=p->Rng.lr;
  930.             lcol=p->Rng.lc;
  931.             hrow=p->Rng.hr;
  932.             hcol=p->Rng.hc;
  933.             if(lrow!=hrow && lcol!=hcol) {
  934.                 int dex;
  935.  
  936.                 dex=1+hrow-lrow;
  937.                 if(tmp>=dex*(1+hcol-lcol))
  938.                     ERROR(OUT_OF_RANGE);
  939.                 crow=tmp%dex;
  940.                 ccol=tmp/dex;
  941.                 lrow+=crow;
  942.                 lcol+=ccol;
  943.             } else if(lrow!=hrow) {
  944.                 if(tmp>(hrow-lrow))
  945.                     ERROR(OUT_OF_RANGE);
  946.                 lrow+=tmp;
  947.             } else {
  948.                 if(tmp>(hcol-lcol))
  949.                     ERROR(OUT_OF_RANGE);
  950.                 lcol+=tmp;
  951.             }
  952.             cell_ptr=find_cell(lrow,lcol);
  953.             PUSH_ANY(cell_ptr);
  954.             break;
  955.  
  956.         case F_INDEX2:
  957.             crow=(p+1)->Int - 1;
  958.             ccol=(p+2)->Int - 1;
  959.             lrow=p->Rng.lr;
  960.             lcol=p->Rng.lc;
  961.             hrow=p->Rng.hr;
  962.             hcol=p->Rng.hc;
  963.             if(crow<0 || ccol<0 || crow>(hrow-lrow) || ccol>(hcol-lcol))
  964.                 ERROR(OUT_OF_RANGE);
  965.             cell_ptr=find_cell(lrow+crow,lcol+ccol);
  966.             PUSH_ANY(cell_ptr);
  967.             break;
  968.  
  969.         /* case F_PRINTF:
  970.             panic("no printf yet");
  971.             break; */
  972.  
  973.         case CONCAT:
  974.             strptr=(char *)obstack_alloc(&tmp_mem,strlen(p->String)+strlen((p+1)->String)+1);
  975.             strcpy(strptr,p->String);
  976.             strcat(strptr,(p+1)->String);
  977.             p->String=strptr;
  978.             break;
  979.  
  980.         case F_ONEOF:
  981.             if(numarg<2)
  982.                 ERROR(NO_VALUES);
  983.             --numarg;
  984.             tmp=p->Int;
  985.             if(tmp<1 || tmp>numarg)
  986.                 ERROR(OUT_OF_RANGE);
  987.             /* Can never happen? */
  988.             TO_ANY(p+tmp);
  989.             p[0]= p[tmp];
  990.             break;
  991.  
  992.         case F_FILE:
  993.         {
  994.             FILE *fp;
  995.             char buf[128];
  996.             int num;
  997.             extern size_t fread();
  998.  
  999.             if(numarg<1)
  1000.                 ERROR(NO_VALUES);
  1001.             fp=fopen(p->String,"r");
  1002.             if(!fp)
  1003.                 ERROR(BAD_INPUT);
  1004.             switch(numarg) {
  1005.             case 2:
  1006.                 fseek(fp,(p+1)->Int,0);
  1007.                 /* Fallthrough */
  1008.  
  1009.             case 1:
  1010.                 while((num=fread(buf,sizeof(char),sizeof(buf),fp))>0)
  1011.                     (void)obstack_grow(&tmp_mem,buf,num);
  1012.                 break;
  1013.  
  1014.             case 3:
  1015.                 fseek(fp,(p+1)->Int,0);
  1016.                 for(;;) {
  1017.                     num=((p+2)->Int<sizeof(buf)) ? (p+2)->Int : sizeof(buf);
  1018.                     (p+2)->Int-=num;
  1019.                     num=fread(buf,sizeof(char),num,fp);
  1020.                     (void)obstack_grow(&tmp_mem,buf,num);
  1021.                     if(num==0 || (p+2)->Int==0)
  1022.                         break;
  1023.                 }
  1024.                 break;
  1025.  
  1026.             default:
  1027.                 ERROR(BAD_INPUT);
  1028.             }
  1029.             fclose(fp);
  1030.             (void)obstack_1grow(&tmp_mem,0);
  1031.             p->String=obstack_finish(&tmp_mem);
  1032.             break;
  1033.         }
  1034.  
  1035.         case AREA_SUM:
  1036.         case AREA_PROD:
  1037.         case AREA_AVG:
  1038.         case AREA_STD:
  1039.         case AREA_MAX:
  1040.         case AREA_MIN:
  1041.         case AREA_CNT:
  1042.         case AREA_VAR:
  1043.             tmp=deal_area(byte,numarg,p);
  1044.             if(tmp)
  1045.                 ERROR(tmp);
  1046.             break;
  1047.  
  1048.             /* This is now a fallthrough for all the USRmumble codes */
  1049.         case USR1:
  1050.         default:
  1051.             if((f->fn_argn&X_ARGS)==X_AN) {
  1052.                 void (*funp) EXT2(int, struct value *);
  1053.  
  1054.                 funp=(void (*) EXT2(int, struct value *))f->fn_fun;
  1055.                 (*funp)(numarg,p);
  1056.             } else {
  1057.                 void (*funp) EXT1(struct value *);
  1058.                 funp=(void(*)EXT1(struct value *))f->fn_fun;
  1059.                 (*funp)(p);
  1060.             }
  1061.             break;
  1062.  
  1063. /* #ifdef TEST
  1064.         default:
  1065.             panic("Unknown byte-value %d",byte);
  1066.             break; 
  1067. #endif */
  1068.         }
  1069.         /* Goto next-byte is the equiv of a multi-level break, which
  1070.            C doesn't allow. */
  1071.     next_byte:
  1072.         ;
  1073.     }
  1074. #ifdef TEST
  1075.     if (curstack != 1)
  1076.         error_msg("%d values on stack", curstack);
  1077. #endif
  1078.     return stack;
  1079. }
  1080.  
  1081. /* These helper functions were split out so that eval_expression would compile
  1082.    under Turbo C 2.0 on my PC.
  1083.  */
  1084.  
  1085.  
  1086. static int    cnt_flt;
  1087. static int    cnt_int;
  1088.  
  1089. static long    int_tmp;
  1090. static double    flt_tmp;
  1091.  
  1092. static long    sqr_int_tmp;    /* for AREA_STD */
  1093. static double    sqr_flt_tmp;
  1094.  
  1095. static unsigned char area_cmd;
  1096.  
  1097. static int
  1098. deal_area FUN3(unsigned char, cmd, unsigned char,num_args, struct value *,p)
  1099. {
  1100.     double flt_cnt_flt;
  1101.     CELL *cell_ptr;
  1102.     char *strptr;
  1103.  
  1104.     area_cmd=cmd;
  1105.     cnt_flt = 0;
  1106.     cnt_int = 0;
  1107.     for(;num_args--;) {
  1108.         switch(p[num_args].type) {
  1109.         case TYP_INT:
  1110.             add_int(p[num_args].Int);
  1111.             break;
  1112.  
  1113.         case TYP_FLT:
  1114.             add_flt(p[num_args].Float);
  1115.             break;
  1116.  
  1117.         case TYP_STR:
  1118.             strptr=p[num_args].String;
  1119.             flt_cnt_flt=astof(&strptr);
  1120.             if(*strptr)
  1121.                 return NON_NUMBER;
  1122.             add_flt(flt_cnt_flt);
  1123.             break;
  1124.  
  1125.         case TYP_RNG:
  1126.             find_cells_in_range(&(p[num_args].Rng));
  1127.             while(cell_ptr=next_cell_in_range()) {
  1128.                 if(GET_TYP(cell_ptr)==TYP_FLT)
  1129.                     add_flt(cell_ptr->cell_flt);
  1130.                 else if(GET_TYP(cell_ptr)==TYP_INT)
  1131.                     add_int(cell_ptr->cell_int);
  1132.                 else if(GET_TYP(cell_ptr)==TYP_STR) {
  1133.                     strptr=cell_ptr->cell_str;
  1134.                     flt_cnt_flt=astof(&strptr);
  1135.                     if(!*strptr)
  1136.                         add_flt(flt_cnt_flt);
  1137.                 }
  1138.             }
  1139.             break;
  1140.  
  1141.         case 0:
  1142.             break;
  1143.  
  1144.         case TYP_ERR:
  1145.             return p[num_args].Value;
  1146.  
  1147.         default:
  1148.             return NON_NUMBER;
  1149.         }
  1150.     }
  1151.     if(!cnt_flt && !cnt_int && area_cmd!=AREA_CNT)
  1152.         return NO_VALUES;
  1153.  
  1154.     switch(area_cmd) {
  1155.     case AREA_SUM:
  1156.         if(cnt_flt && cnt_int) {
  1157.             flt_tmp+=(double)int_tmp;
  1158.             cnt_int=0;
  1159.         }
  1160.         break;
  1161.     case AREA_PROD:
  1162.         if(cnt_flt && cnt_int) {
  1163.             flt_tmp*=(double)int_tmp;
  1164.             cnt_int=0;
  1165.         }
  1166.         break;
  1167.     case AREA_AVG:
  1168.         if(cnt_flt && cnt_int) {
  1169.             flt_tmp+=(double)int_tmp;
  1170.             flt_tmp/=(double)((cnt_flt+cnt_int));
  1171.             cnt_int=0;
  1172.         } else if(cnt_flt)
  1173.             flt_tmp/=(double)cnt_flt;
  1174.         else {
  1175.             flt_tmp=(double)int_tmp/(double)cnt_int;
  1176.             cnt_int=0;
  1177.         }
  1178.         break;
  1179.     case AREA_STD:
  1180.         if(cnt_int && cnt_flt) {
  1181.             flt_tmp+=(double)int_tmp;
  1182.             sqr_flt_tmp+=(double)sqr_int_tmp;
  1183.             cnt_flt+=cnt_int;
  1184.             cnt_int=0;
  1185.         } else if(cnt_int) {
  1186.             flt_tmp=(double)int_tmp;
  1187.             sqr_flt_tmp=(double)sqr_int_tmp;
  1188.             cnt_flt=cnt_int;
  1189.             cnt_int=0;
  1190.         }
  1191.         flt_cnt_flt=(double)cnt_flt;
  1192.         flt_tmp=sqrt( ( (flt_cnt_flt*sqr_flt_tmp) -
  1193.                 (flt_tmp*flt_tmp) )         /
  1194.                 (flt_cnt_flt * (flt_cnt_flt-1)));
  1195.         break;
  1196.     case AREA_VAR:
  1197.         if(cnt_int && cnt_flt) {
  1198.             flt_tmp+=(double)int_tmp;
  1199.             sqr_flt_tmp+=(double)sqr_int_tmp;
  1200.             cnt_flt+=cnt_int;
  1201.             cnt_int=0;
  1202.         } else if(cnt_int) {
  1203.             flt_tmp=(double)int_tmp;
  1204.             sqr_flt_tmp=(double)sqr_int_tmp;
  1205.             cnt_flt=cnt_int;
  1206.             cnt_int=0;
  1207.         }
  1208.         flt_cnt_flt=(double)cnt_flt;
  1209.         flt_tmp=( (flt_cnt_flt*sqr_flt_tmp) -
  1210.                 (flt_tmp*flt_tmp) )         /
  1211.                 (flt_cnt_flt * flt_cnt_flt);
  1212.         break;
  1213.  
  1214.     case AREA_MAX:
  1215.         if(cnt_flt && cnt_int && flt_tmp>(double)int_tmp)
  1216.             cnt_int=0;
  1217.         break;
  1218.  
  1219.     case AREA_MIN:
  1220.         if(cnt_flt && cnt_int && flt_tmp<(double)int_tmp)
  1221.             cnt_int=0;
  1222.         break;
  1223.  
  1224.     case AREA_CNT:
  1225.         int_tmp=cnt_int+cnt_flt;
  1226.         cnt_int=1;
  1227.         break;
  1228.  
  1229. #ifdef TEST
  1230.     default:
  1231.         panic("Unknown AREA command %d",area_cmd);
  1232. #endif
  1233.     }
  1234.     if(cnt_int) {
  1235.         p->type=TYP_INT;
  1236.         p->Int=int_tmp;
  1237.     } else {
  1238.         p->type=TYP_FLT;
  1239.         p->Float=flt_tmp;
  1240.     }
  1241.     return 0;
  1242. }
  1243.  
  1244. static void
  1245. add_flt FUN1(double, value)
  1246. {
  1247.     if(cnt_flt++==0) {
  1248.         flt_tmp = value;
  1249.         sqr_flt_tmp=value*value;
  1250.         return;
  1251.     }
  1252.  
  1253.     switch(area_cmd) {
  1254.     case AREA_STD:
  1255.     case AREA_VAR:
  1256.         sqr_flt_tmp+=value*value;
  1257.         /* Fall through */
  1258.     case AREA_SUM:
  1259.     case AREA_AVG:
  1260.         flt_tmp +=value;
  1261.         return;
  1262.     case AREA_PROD:
  1263.         flt_tmp *=value;
  1264.         return;
  1265.     case AREA_MAX:
  1266.         if(flt_tmp<value)
  1267.             flt_tmp=value;
  1268.         return;
  1269.     case AREA_MIN:
  1270.         if(flt_tmp>value)
  1271.             flt_tmp=value;
  1272.         return;
  1273.     case AREA_CNT:
  1274.         return;
  1275. #ifdef TEST
  1276.     default:
  1277.         panic("Unknown area command %d in add_flt(%g)",area_cmd,value);
  1278. #endif
  1279.     }
  1280. }
  1281.  
  1282. static void
  1283. add_int FUN1(long, value)
  1284. {
  1285.     if(cnt_int++==0) {
  1286.         int_tmp=value;
  1287.         sqr_int_tmp=value*value;
  1288.         return;
  1289.     }
  1290.  
  1291.     switch(area_cmd) {
  1292.     case AREA_STD:
  1293.     case AREA_VAR:
  1294.         sqr_int_tmp+=value*value;
  1295.         /* Fall through */
  1296.     case AREA_SUM:
  1297.     case AREA_AVG:
  1298.         int_tmp+=value;
  1299.         return;
  1300.     case AREA_PROD:
  1301.         int_tmp*=value;
  1302.         return;
  1303.     case AREA_MAX:
  1304.         if(int_tmp<value)
  1305.             int_tmp=value;
  1306.         return;
  1307.     case AREA_MIN:
  1308.         if(int_tmp>value)
  1309.             int_tmp=value;
  1310.         return;
  1311.     case AREA_CNT:
  1312.         return;
  1313. #ifdef TEST
  1314.     default:
  1315.         panic("Unknown Area command %d in add_int(%ld)",area_cmd,value);
  1316. #endif
  1317.     }
  1318. }
  1319.  
  1320. double
  1321. dtr FUN1(double, x)
  1322. {
  1323.     return x * (PI / (double)180.0);
  1324. }
  1325.  
  1326. double
  1327. rtd FUN1(double, x)
  1328. {
  1329.     return x * (180.0 / (double)PI);
  1330. }
  1331.  
  1332. double
  1333. to_int FUN1(double, x)
  1334. {
  1335.     return (x<0 ? ceil(x) : floor(x));
  1336. }
  1337.  
  1338. /* Various methods of dealing with arithmatic overflow.  They don't work well.
  1339.    Someone should really convince this thing to properly deal with it.
  1340.  */
  1341. #ifdef __TURBOC__
  1342. int
  1343. matherr FUN1(struct exception *, exc)
  1344. {
  1345.     stack[curstack].type=TYP_ERR;
  1346.     stack[curstack].Value=BAD_INPUT;
  1347.     write(2,"MATHERR\n",8);
  1348.     return 1;
  1349. }
  1350. #endif
  1351.  
  1352. #ifndef __TURBOC__
  1353. SIGTY
  1354. math_sig FUN1(int, sig)
  1355. {
  1356.     stack[curstack].type=TYP_ERR;
  1357.     stack[curstack].Value=BAD_INPUT;
  1358.     (void)write(2,"MATH_SIG\n",9);
  1359.     SIGRET;
  1360. }
  1361. #endif
  1362.  
  1363. /* Here's the entry point for this module. */
  1364. void
  1365. update_cell FUN1(CELL *,cell)
  1366. {
  1367.     struct value *new;
  1368.     int new_val;
  1369.  
  1370. #ifdef TEST
  1371.     extern int debug;
  1372.  
  1373.     if(cell->cell_cycle==current_cycle && (debug&01)) {
  1374.         error_msg("Cycle detected at %s (%d)",cell_name(cur_row,cur_col),current_cycle);
  1375.         /* return; */
  1376.     } else if(debug&02)
  1377.         error_msg("Update %s",cell_name(cur_row,cur_col));
  1378. #endif
  1379.     new=eval_expression(cell->cell_formula);
  1380.     if(!new) {
  1381.         push_refs(cell->cell_refs_from);
  1382.         return;
  1383.     }
  1384.     cell->cell_cycle=current_cycle;
  1385.  
  1386.     if(new->type!=GET_TYP(cell)) {
  1387.         if(GET_TYP(cell)==TYP_STR)
  1388.             free(cell->cell_str);
  1389.         SET_TYP(cell,new->type);
  1390.         new_val=1;
  1391.         if(new->type==TYP_STR)
  1392.             new->String=strdup(new->String);
  1393.     } else switch(new->type) {
  1394.     case 0:
  1395.         new_val=0;
  1396.         break;
  1397.     case TYP_FLT:
  1398.         new_val=new->Float!=cell->cell_flt;
  1399.         break;
  1400.     case TYP_INT:
  1401.         new_val=new->Int!=cell->cell_int;
  1402.         break;
  1403.     case TYP_STR:
  1404.         new_val= strcmp(new->String,cell->cell_str);
  1405.         if(new_val) {
  1406.             free(cell->cell_str);
  1407.             new->String=strdup(new->String);
  1408.         }
  1409.         break;
  1410.     case TYP_BOL:
  1411.         new_val= new->Value!=cell->cell_bol;
  1412.         break;
  1413.     case TYP_ERR:
  1414.         new_val=new->Value!=cell->cell_err;
  1415.         break;
  1416. #ifdef TEST
  1417.     default:
  1418.         new_val=0;
  1419.         panic("Unknown type %d in update_cell",new->type);
  1420. #endif
  1421.     }
  1422.     if(new_val) {
  1423.         cell->c_z=new->x;
  1424.         push_refs(cell->cell_refs_from);
  1425.     }
  1426.     (void)obstack_free(&tmp_mem,tmp_mem_start);
  1427. }
  1428.  
  1429. int
  1430. fls FUN1(long, num)
  1431. {
  1432.     int ret=1;
  1433.  
  1434.     if(!num)
  1435.         return 0;
  1436.     if(num<0)
  1437.         num= -num;
  1438.     if(num&0xffff0000) {
  1439.         ret+=16;
  1440.         num= (num>>16)&0xffff;
  1441.     }
  1442.     if(num&0xff00) {
  1443.         ret+=8;
  1444.         num>>=8;
  1445.     }
  1446.     if(num&0xf0){
  1447.         ret+=4;
  1448.         num>>=4;
  1449.     }
  1450.     if(num&0x0c) {
  1451.         ret+=2;
  1452.         num>>=2;
  1453.     }
  1454.     if(num&2)
  1455.         ret++;
  1456.     return ret;
  1457. }
  1458.  
  1459. #ifdef SMALLEVAL
  1460. int
  1461. __to_flt FUN1(struct value *,p)
  1462. {
  1463.     char *strptr;
  1464.  
  1465.     switch(p->type) {
  1466.     case 0:
  1467.         p->type=TYP_FLT;
  1468.         p->Float=0;
  1469.         /* Fallthrough */
  1470.     case TYP_FLT:
  1471.         return 0;
  1472.     case TYP_INT:
  1473.         p->Float=(double)p->Int;
  1474.         p->type=TYP_FLT;
  1475.         return 0;
  1476.     case TYP_STR:
  1477.         p->type=TYP_FLT;
  1478.         strptr=p->String;
  1479.         p->Float=astof(&strptr);
  1480.         if(*strptr)
  1481.             return NON_NUMBER;
  1482.         return 0;
  1483.     case TYP_ERR:
  1484.         return p->Value;
  1485.     default:
  1486.         return NON_NUMBER;
  1487.     }
  1488. }
  1489.  
  1490. int
  1491. __to_int FUN1(struct value *,p)
  1492. {
  1493.     char *strptr;
  1494.  
  1495.     switch(p->type) {
  1496.     case 0:
  1497.         p->type=TYP_INT;
  1498.         p->Int=0;
  1499.     case TYP_INT:
  1500.         return 0;
  1501.     case TYP_FLT:
  1502.         p->type=TYP_INT;
  1503.         p->Int=(long)p->Float;
  1504.         return 0;
  1505.     case TYP_STR:
  1506.         p->type=TYP_INT;
  1507.         strptr=p->String;
  1508.         p->Int=astol(&strptr);
  1509.         if(*strptr)
  1510.             return NON_NUMBER;
  1511.         return 0;
  1512.     case TYP_ERR:
  1513.         return p->Value;
  1514.     default:
  1515.         return NON_NUMBER;
  1516.     }
  1517. }
  1518.  
  1519. int
  1520. __to_num FUN1(struct value *,p)
  1521. {
  1522.     char *strptr;
  1523.  
  1524.     switch(p->type) {
  1525.     case 0:
  1526.         p->type=TYP_INT;
  1527.         p->Int=0;
  1528.         return 0;
  1529.     case TYP_FLT:
  1530.     case TYP_INT:
  1531.         return 0;
  1532.     case TYP_STR:
  1533.         p->type=TYP_FLT;
  1534.         strptr=p->String;
  1535.         p->Float=astof(&strptr);
  1536.         if(*strptr)
  1537.             return NON_NUMBER;
  1538.         return 0;
  1539.     case TYP_ERR:
  1540.         return p->Value;
  1541.     default:
  1542.         return NON_NUMBER;
  1543.     }
  1544. }
  1545.  
  1546. int
  1547. __to_str FUN1(struct value *,p)
  1548. {
  1549.     char *strptr;
  1550.  
  1551.     switch(p->type) {
  1552.     case 0:
  1553.         p->type=TYP_STR;
  1554.         p->String=obstack_alloc(&tmp_mem,1);
  1555.         p->String[0]='\0';
  1556.         return 0;
  1557.  
  1558.     case TYP_STR:
  1559.         return 0;
  1560.  
  1561.     case TYP_INT:
  1562.         p->type=TYP_STR;
  1563.         strptr=obstack_alloc(&tmp_mem,30);
  1564.         sprintf(strptr,"%ld",p->Int);
  1565.         p->String=strptr;
  1566.         return 0;
  1567.  
  1568.     case TYP_FLT:
  1569.         p->type=TYP_STR;
  1570.         strptr=flt_to_str(p->Float);
  1571.         (void)obstack_grow(&tmp_mem,strptr,strlen(strptr)+1);
  1572.         p->String=obstack_finish(&tmp_mem);
  1573.         return 0;
  1574.  
  1575.     case TYP_ERR:
  1576.         return p->Value;
  1577.  
  1578.     default:
  1579.         return NON_STRING;
  1580.     }
  1581. }
  1582.  
  1583. int
  1584. __to_bol FUN1(struct value *,p)
  1585. {
  1586.     switch(p->type) {
  1587.     case TYP_BOL:
  1588.         return 0;
  1589.     case TYP_ERR:
  1590.         return p->Value;
  1591.     default:
  1592.         return NON_BOOL;
  1593.     }
  1594. }
  1595.  
  1596. int
  1597. __to_rng FUN1(struct value *,p)
  1598. {
  1599.     switch(p->type) {
  1600.     case TYP_RNG:
  1601.         return 0;
  1602.     case TYP_ERR:
  1603.         return p->Value;
  1604.     default:
  1605.         return NON_BOOL;
  1606.     }
  1607. }
  1608.  
  1609. #endif
  1610.