home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / OLEO130S.ZIP / oleo130s.tar / oleo-1.3 / io-utils.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  24KB  |  1,329 lines

  1. /*    Copyright (C) 1990, 1992, 1993 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 2, 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 <stdio.h>
  20. #include <ctype.h>
  21. #include <math.h>
  22. #include "sysdef.h"
  23. #include "io-utils.h"
  24. #include "cell.h"
  25. #include "ref.h"
  26. #include "decompile.h"
  27. #include "io-generic.h"
  28. #include "io-abstract.h"
  29. #include "lists.h"
  30. #include "io-term.h"
  31. #include "cmd.h"
  32.  
  33.  
  34. /* Routines for formatting cell values */
  35. #ifdef __STDC__
  36. struct user_fmt;
  37. static char *pr_flt (double, struct user_fmt *, int);
  38. static char *pr_int (long, struct user_fmt *, int);
  39. #else
  40. static char *pr_flt ();
  41. static char *pr_int ();
  42. #endif
  43.  
  44.  
  45. /* Constants */
  46. char *bname[] =
  47. {
  48.   "#FALSE", "#TRUE"
  49. };
  50.  
  51. char numb_oflo[] = "########################################";
  52.  
  53. double __plinf;
  54. double __neinf;
  55. double __nan;
  56.  
  57. char nname[] = "#NOT_A_NUMBER";
  58. char iname[] = "#INFINITY";
  59. char mname[] = "#MINUS_INFINITY";
  60.  
  61. static double
  62. divide (a, b)
  63.      double a;
  64.      double b;
  65. {
  66.   return a / b;
  67. }
  68.  
  69. static RETSIGTYPE
  70. ignore_sig (sig)
  71.      int sig;
  72. {
  73.   (void)signal (SIGFPE, ignore_sig);
  74. }
  75.  
  76. /* It's ok of this fails and generates signals.  In that case, 
  77.  * the same signal will occur when evaluating formulas and a
  78.  * (less informative) error value substituted.  Note that this 
  79.  * should be called before init_eval.
  80.  */
  81. #ifdef __STDC__
  82. void
  83. init_infinity (void)
  84. #else
  85. void
  86. init_infinity ()
  87. #endif
  88. {
  89.   (void)signal (SIGFPE, ignore_sig);
  90.   __plinf = divide (1., 0.);
  91.   (void)signal (SIGFPE, ignore_sig);
  92.   __neinf = divide (-1., 0.);
  93.   (void)signal (SIGFPE, ignore_sig);
  94.   __nan = __plinf + __neinf;
  95. }
  96.  
  97.  
  98.  
  99. /* Slightly larger than the maximum exponent we ever expect to see */
  100. #define BIGFLT 309
  101. #ifdef TEST
  102. char print_buf[1024 * 8];
  103. #else
  104. char print_buf[BIGFLT + 20];
  105. #endif
  106.  
  107.  
  108.  
  109. /* Structures/vars/functions for dealing with formatting floating-point
  110.    numbers, etc */
  111.  
  112. struct user_fmt
  113.   {
  114.     char *p_hdr, *n_hdr;
  115.     char *p_trl, *n_trl;
  116.     char *zero, *comma, *decpt;
  117.     unsigned char prec;
  118.     double scale;
  119.   };
  120.  
  121.  
  122. struct user_fmt dol =
  123. {
  124.   "$", "($", 0, ")", "$0", ",", ".", PRC_FLT, 1};
  125.  
  126. struct user_fmt cma =
  127. {
  128.   0, "(", 0, ")", "0", ",", ".", PRC_FLT, 1};
  129.  
  130. struct user_fmt pct =
  131. {
  132.   0, "-", "%", "%", "0%", 0, ".", PRC_FLT, 100};
  133.  
  134. struct user_fmt fxt =
  135. {
  136.   0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1};
  137.  
  138. /* Variables */
  139.  
  140. struct user_fmt u[16] =
  141. {
  142.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  143.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  144.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  145.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  146.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  147.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  148.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  149.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  150.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  151.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  152.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  153.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  154.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  155.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  156.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  157.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  158. };
  159.  
  160.  
  161. /* Turn a floating-point number into the canonical text form.  This scribbles
  162.    on print_buf */
  163.  
  164. #ifdef __STDC__
  165. char *
  166. flt_to_str (double val)
  167. #else
  168. char *
  169. flt_to_str (val)
  170.      double val;
  171. #endif
  172. {
  173.   double f;
  174.  
  175.   if (val == __plinf)
  176.     return iname;
  177.   if (val == __neinf)
  178.     return mname;
  179.   f = fabs (val);
  180.   if (f >= 1e6 || (f > 0 && f <= 9.9999e-6))
  181.     {
  182.       sprintf (print_buf, "%e", val);
  183.       return print_buf;
  184.     }
  185.   return pr_flt (val, &fxt, PRC_FLT);
  186. }
  187.  
  188.  
  189. #ifdef __STDC__
  190. char *
  191. long_to_str (long val)
  192. #else
  193. char *
  194. long_to_str (val)
  195.      long val;
  196. #endif
  197. {
  198.   sprintf (print_buf, "%ld", val);
  199.   return print_buf;
  200. }
  201.  
  202. /* create the human-readable version of the contents of a cell
  203.    This scribbles on print-buf bigtime */
  204.  
  205. #ifdef __STDC__
  206. char *
  207. print_cell (CELL *cp)
  208. #else
  209. char *
  210. print_cell (cp)
  211.      CELL *cp;
  212. #endif
  213. {
  214.   int j;
  215.   int p;
  216.   long num;
  217.   static char zeroes[] = "000000000000000";
  218.  
  219.   if (!cp)
  220.     return "";
  221.  
  222.   j = GET_FMT (cp);
  223.  
  224.   if (j == FMT_DEF)
  225.     j = default_fmt;
  226.   if (j == FMT_HID || GET_TYP (cp) == 0)
  227.     return "";
  228.  
  229.   if (GET_TYP (cp) == TYP_STR)
  230.     return cp->cell_str;
  231.   if (GET_TYP (cp) == TYP_BOL)
  232.     {
  233. #ifdef TEST
  234.       if (cp->cell_bol < 0 || cp->cell_bol > 1)
  235.     panic ("Bool %d out of range", cp->cell_bol);
  236. #endif
  237.       return bname[cp->cell_bol];
  238.     }
  239.   if (GET_TYP (cp) == TYP_ERR)
  240.     {
  241. #ifdef TEST
  242.       if (cp->cell_err > ERR_MAX || cp->cell_err < 0)
  243.     panic ("Error %d out of range", cp->cell_err);
  244. #endif
  245.       return ename[cp->cell_err];
  246.     }
  247.   if (GET_TYP (cp) == TYP_FLT)
  248.     {
  249.       p = GET_PRC (j);
  250.       switch (j | PRC_FLT)
  251.     {
  252.     case FMT_GPH:
  253.       if (cp->cell_flt < 0)
  254.         {
  255.           j = '-';
  256.           num = -(cp->cell_flt);
  257.         }
  258.       else if (cp->cell_flt >= 1)
  259.         {
  260.           j = '+';
  261.           num = (cp->cell_flt);
  262.         }
  263.       else
  264.         {
  265.           j = '0';
  266.           num = 1;
  267.         }
  268.     graph:
  269.       if (num >= sizeof (print_buf))
  270.         {
  271.           io_error_msg ("Cannot graph %d '%c'", p, j);
  272.           num = sizeof (print_buf) - 1;
  273.         }
  274.       print_buf[num] = '\0';
  275.       while (--num >= 0)
  276.         print_buf[num] = j;
  277.       return print_buf;
  278.  
  279.     case FMT_USR:
  280.       return pr_flt (cp->cell_flt, &u[p], u[p].prec);
  281.  
  282.     case FMT_GEN:
  283.       {
  284.         double f;
  285.  
  286.         f = fabs (cp->cell_flt);
  287.         if (f >= 1e6 || (f > 0 && f <= 9.9999e-6))
  288.           goto handle_exp;
  289.         return pr_flt (cp->cell_flt, &fxt, p);
  290.       }
  291.  
  292.     case FMT_DOL:
  293.       return pr_flt (cp->cell_flt, &dol, p);
  294.  
  295.     case FMT_CMA:
  296.       return pr_flt (cp->cell_flt, &cma, p);
  297.  
  298.     case FMT_PCT:
  299.       return pr_flt (cp->cell_flt, &pct, p);
  300.  
  301.     case FMT_FXT:
  302.       return pr_flt (cp->cell_flt, &fxt, p);
  303.  
  304.     case FMT_EXP:
  305.     handle_exp:
  306.       if (cp->cell_flt == __plinf)
  307.         return iname;
  308.       if (cp->cell_flt == __neinf)
  309.         return mname;
  310.       if (p == PRC_FLT)
  311.         sprintf (print_buf, "%e", cp->cell_flt);
  312.       else
  313.         sprintf (print_buf, "%.*e", p, cp->cell_flt);
  314.       return print_buf;
  315. #ifdef TEST
  316.     default:
  317.       panic ("Unknown format %d", j);
  318.       return 0;
  319. #endif
  320.     }
  321.     }
  322.  
  323.   if (GET_TYP (cp) == TYP_INT)
  324.     {
  325.       p = GET_PRC (j);
  326.       switch (j | PRC_FLT)
  327.     {
  328.     case FMT_GPH:
  329.       if (cp->cell_int < 0)
  330.         {
  331.           j = '-';
  332.           num = -(cp->cell_int);
  333.         }
  334.       else if (cp->cell_int >= 1)
  335.         {
  336.           j = '+';
  337.           num = (cp->cell_int);
  338.         }
  339.       else
  340.         {
  341.           j = '0';
  342.           num = 1;
  343.         }
  344.       goto graph;
  345.  
  346.     case FMT_USR:
  347.       return pr_int (cp->cell_int, &u[p], u[p].prec);
  348.  
  349.     case FMT_GEN:
  350.       sprintf (print_buf, "%ld", cp->cell_int);
  351.       return print_buf;
  352.  
  353.     case FMT_DOL:
  354.       return pr_int (cp->cell_int, &dol, p);
  355.  
  356.     case FMT_CMA:
  357.       return pr_int (cp->cell_int, &cma, p);
  358.  
  359.     case FMT_PCT:
  360.       return pr_int (cp->cell_int, &pct, p);
  361.  
  362.     case FMT_FXT:
  363.       if (p != PRC_FLT && p != 0)
  364.         sprintf (print_buf, "%ld.%.*s", cp->cell_int, p, zeroes);
  365.       else
  366.         sprintf (print_buf, "%ld", cp->cell_int);
  367.       return print_buf;
  368.  
  369.     case FMT_EXP:
  370.       if (p != PRC_FLT)
  371.         sprintf (print_buf, "%.*e", p, (double) (cp->cell_int));
  372.       else
  373.         sprintf (print_buf, "%e", (double) (cp->cell_int));
  374.       return print_buf;
  375. #ifdef TEST
  376.     default:
  377.       panic ("Unknown format %d", j);
  378.       return 0;
  379. #endif
  380.     }
  381.     }
  382. #ifdef TEST
  383.   panic ("Unknown cell type %d", GET_TYP (cp));
  384. #endif
  385.   return 0;
  386. }
  387.  
  388. /* Return the value of ROW,COL in a human-readable fashion
  389.    In paticular, strings have "" around them, and are \\ed
  390.  */
  391. #ifdef __STDC__
  392. char *
  393. cell_value_string (CELLREF row, CELLREF col)
  394. #else
  395. char *
  396. cell_value_string (row, col)
  397.      CELLREF row;
  398.      CELLREF col;
  399. #endif
  400. {
  401.   CELL *cp;
  402.  
  403.   cp = find_cell (row, col);
  404.   if (!cp || !GET_TYP (cp))
  405.     return "";
  406.   switch (GET_TYP (cp))
  407.     {
  408.     case TYP_FLT:
  409.       return flt_to_str (cp->cell_flt);
  410.  
  411.     case TYP_INT:
  412.       sprintf (print_buf, "%ld", cp->cell_int);
  413.       return print_buf;
  414.  
  415.     case TYP_STR:
  416.       return backslash_a_string (cp->cell_str, 1);
  417.  
  418.     case TYP_BOL:
  419.       return bname[cp->cell_bol];
  420.  
  421.     case TYP_ERR:
  422.       return ename[cp->cell_err];
  423. #ifdef TEST
  424.     default:
  425.       panic ("unknown type %d in cell_value_string", GET_TYP (cp));
  426. #endif
  427.     }
  428.   return 0;
  429. }
  430.  
  431. static char *
  432. pr_int (val, fmt, prec)
  433.      long val;
  434.      struct user_fmt *fmt;
  435.      int prec;
  436. {
  437.   char *pf, *pff, *pt;
  438.   long int n;
  439.   int nn = 0;
  440.  
  441.   pt = &print_buf[sizeof (print_buf) - 1];
  442.   *pt = '\0';
  443.  
  444.   n = fmt->scale * ((val < 0) ? -val : val);
  445.   if (n == 0)
  446.     return fmt->zero ? fmt->zero : "";
  447.  
  448.   pf = pff = (val < 0) ? fmt->n_trl : fmt->p_trl;
  449.   if (pf && *pf)
  450.     {
  451.       while (*pf)
  452.     pf++;
  453.       do
  454.     *--pt = *--pf;
  455.       while (pf != pff);
  456.     }
  457.  
  458.   if (prec != PRC_FLT && prec != 0)
  459.     {
  460.       while (prec-- > 0)
  461.     *--pt = '0';
  462.       pf = pff = fmt->decpt;
  463.       if (pf)
  464.     {
  465.       while (*pf)
  466.         pf++;
  467.       do
  468.         *--pt = *--pf;
  469.       while (pf != pff);
  470.     }
  471.       /* *--pt='.'; */
  472.     }
  473.   do
  474.     {
  475.       *--pt = (n % 10) + '0';
  476.       n /= 10;
  477.       if (nn++ == 2 && n > 0)
  478.     {
  479.       if (fmt->comma && *(fmt->comma))
  480.         {
  481.           for (pf = pff = fmt->comma; *pf; pf++)
  482.         ;
  483.           do
  484.         *--pt = *--pf;
  485.           while (pf != pff);
  486.         }
  487.       nn = 0;
  488.     }
  489.     }
  490.   while (n > 0);
  491.  
  492.   pf = pff = (val < 0) ? fmt->n_hdr : fmt->p_hdr;
  493.   if (pf && *pf)
  494.     {
  495.       while (*pf)
  496.     pf++;
  497.       do
  498.     *--pt = *--pf;
  499.       while (pf != pff);
  500.     }
  501.   return pt;
  502. }
  503.  
  504. static char *
  505. pr_flt (val, fmt, prec)
  506.      double val;
  507.      struct user_fmt *fmt;
  508.      int prec;
  509. {
  510.   char *iptr;
  511.   char *fptr;
  512.   char *pptr;
  513.   char *pf, *pff;
  514.   double fract, integer, tmpval;
  515.   int n;
  516.   int isneg;
  517.   int comlen;
  518.  
  519.   val *= fmt->scale;
  520.  
  521.   if (val == __plinf)
  522.     return iname;
  523.   if (val == __neinf)
  524.     return mname;
  525.   if (val != val)
  526.     return nname;
  527.  
  528.   iptr = &print_buf[BIGFLT];
  529.   fptr = &print_buf[BIGFLT];
  530.  
  531.  
  532.   if (val == 0)
  533.     return fmt->zero ? fmt->zero : "";
  534.  
  535.   if (val < 0)
  536.     {
  537.       isneg = 1;
  538.       val = -val;
  539.     }
  540.   else
  541.     isneg = 0;
  542.  
  543.   comlen = 0;
  544.   if (fmt->comma && *(fmt->comma))
  545.     for (pf = fmt->comma; *pf; comlen++, pf++)
  546.       ;
  547.  
  548.   fract = modf (val, &integer);
  549.   n = 0;
  550.   do
  551.     {
  552.       if (iptr < &print_buf[comlen])
  553.     return numb_oflo;
  554.       tmpval = modf (integer / 10, &integer);
  555.       *--iptr = '0' + (int) ((tmpval + .01) * 10);
  556.       if (comlen && n++ == 2 && integer)
  557.     {
  558.       n = 0;
  559.       pff = fmt->comma;
  560.       pf = pff + comlen;
  561.       do
  562.         *--iptr = *--pf;
  563.       while (pf != pff);
  564.     }
  565.     }
  566.   while (integer);
  567.  
  568.   if (prec)
  569.     {
  570.       int p1;
  571.  
  572.       p1 = (prec == PRC_FLT) ? 15 : (prec > 0) ? prec : -prec;
  573.       pf = fmt->decpt;
  574.       while (pf && *pf)
  575.     *fptr++ = *pf++;
  576.       /* *fptr++='.'; */
  577.       if (fract)
  578.     {
  579.       do
  580.         {
  581.           fract = modf (fract * 10, &tmpval);
  582.           *fptr++ = '0' + (int) tmpval;
  583.         }
  584.       while (--p1 && fract);
  585.     }
  586.       if (prec > 0 && prec != PRC_FLT)
  587.     while (p1--)
  588.       *fptr++ = '0';
  589.       else
  590.     {
  591.       fract = 0;
  592.       while (fptr[-1] == '0')
  593.         --fptr;
  594.       while (!isdigit (fptr[-1]))
  595.         --fptr;
  596.       *fptr = '\0';
  597.     }
  598.     }
  599.   if (fract)
  600.     {
  601.       (void) modf (fract * 10, &tmpval);
  602.       if (tmpval > 4)
  603.     {
  604.       iptr[-1] = '0';
  605.       for (pptr = fptr - 1;; --pptr)
  606.         {
  607.           if (!isdigit (*pptr))
  608.         continue;
  609.           else if (*pptr == '9')
  610.         {
  611.           if (pptr == fptr - 1 && pptr > &print_buf[BIGFLT] && (prec < 0 || prec == PRC_FLT))
  612.             {
  613.               --fptr;
  614.               while (!isdigit (pptr[-1]))
  615.             {
  616.               --fptr;
  617.               --pptr;
  618.             }
  619.               *pptr = '\0';
  620.             }
  621.           else
  622.             *pptr = '0';
  623.         }
  624.           else
  625.         {
  626.           (*pptr)++;
  627.           break;
  628.         }
  629.         }
  630.       if (pptr < iptr)
  631.         {
  632.           --iptr;
  633.           if (n == 3)
  634.         {
  635.           char tmpch;
  636.  
  637.           tmpch = *iptr++;
  638.           for (pf = pff = fmt->comma; *pf; pf++)
  639.             ;
  640.           do
  641.             *--iptr = *--pf;
  642.           while (pf != pff);
  643.           *--iptr = tmpch;
  644.         }
  645.         }
  646.     }
  647.     }
  648.   pf = pff = (isneg) ? fmt->n_hdr : fmt->p_hdr;
  649.   if (pf && *pf)
  650.     {
  651.       while (*pf)
  652.     pf++;
  653.       do
  654.     *--iptr = *--pf;
  655.       while (pf != pff);
  656.     }
  657.  
  658.   pf = (isneg) ? fmt->n_trl : fmt->p_trl;
  659.   while (pf && *pf)
  660.     *fptr++ = *pf++;
  661.   *fptr = 0;
  662.   return iptr;
  663. }
  664.  
  665. #ifdef __STDC__
  666. char *
  667. adjust_prc (char *oldp, CELL *cp, int width, int smallwid, int just)
  668. #else
  669. char *
  670. adjust_prc (oldp, cp, width, smallwid, just)
  671.      char *oldp;
  672.      CELL *cp;
  673.      int width;
  674.      int smallwid;
  675.      int just;
  676. #endif
  677. {
  678.   int fmt;
  679.   int prc;
  680.   struct user_fmt *ufmt;
  681.   char *bptr;
  682.   char *eptr;
  683.   int len;
  684.  
  685.   fmt = GET_FMT (cp);
  686.   if (fmt == FMT_DEF)
  687.     fmt = default_fmt;
  688.   prc = GET_PRC (fmt);
  689.   switch (fmt | PRC_FLT)
  690.     {
  691.     case FMT_GPH:
  692.     case FMT_HID:
  693.       return numb_oflo;
  694.     case FMT_DOL:
  695.       ufmt = &dol;
  696.       goto deal_fmt;
  697.  
  698.     case FMT_CMA:
  699.       ufmt = &cma;
  700.       goto deal_fmt;
  701.  
  702.     case FMT_PCT:
  703.       ufmt = &cma;
  704.       goto deal_fmt;
  705.  
  706.     case FMT_FXT:
  707.       ufmt = &fxt;
  708.       goto deal_fmt;
  709.  
  710.     case FMT_USR:
  711.       ufmt = &u[prc];
  712.       prc = ufmt->prec;
  713.       goto deal_fmt;
  714.  
  715.     case FMT_GEN:
  716.       if (prc != PRC_FLT)
  717.     return numb_oflo;
  718.       if (index (oldp, 'e') || !index (oldp, '.'))
  719.     goto handle_exp;
  720.  
  721.       ufmt = &fxt;
  722.       prc = PRC_FLT;
  723.       goto deal_fmt;
  724.  
  725.     deal_fmt:
  726.       if (prc != PRC_FLT)
  727.     return numb_oflo;
  728.       len = strlen (oldp);
  729.       bptr = (char *)strstr (oldp, ufmt->decpt);
  730.       if (!bptr)
  731.     return numb_oflo;
  732.       while (eptr = (char *)strstr (bptr + 1, ufmt->decpt))
  733.     bptr = eptr;
  734.  
  735.       if (width < bptr - oldp)
  736.     return numb_oflo;
  737.       if (bptr - oldp + strlen (ufmt->decpt) >= width)
  738.     prc = 0;
  739.       else
  740.     {
  741.       prc = width - (strlen (ufmt->decpt) + bptr - oldp);
  742.     }
  743.       bptr = pr_flt (cp->cell_flt, ufmt, -prc);
  744.       len = strlen (bptr);
  745.       if (len > width && prc > 0)
  746.     {
  747.       bptr = pr_flt (cp->cell_flt, ufmt, -(prc - 1));
  748.       len = strlen (bptr);
  749.     }
  750.       if (len > width)
  751.     return numb_oflo;
  752.       break;
  753.  
  754.     case FMT_EXP:
  755.     handle_exp:
  756.       {
  757.     double f;
  758.  
  759.     f = fabs (cp->cell_flt);
  760.     if (f > 9.99999e99 || f < 1e-99)
  761.       len = width - 7;
  762.     else            /* if(f>9.9999999e9 || f<1e-9) */
  763.       len = width - 6;
  764.     /* else
  765.                 len=width-5; */
  766.     if (cp->cell_flt < 0)
  767.       --len;
  768.     if (len > 0)
  769.       {
  770.         sprintf (oldp, "%.*e", len, cp->cell_flt);
  771.         len = strlen (oldp);
  772.         if (len <= width)
  773.           {
  774.         bptr = oldp;
  775.         break;
  776.           }
  777.       }
  778.       }
  779.       return numb_oflo;
  780.     default:
  781.       bptr = 0;
  782.       len = 0;
  783. #ifdef TEST
  784.       panic ("Unknown format %d in adjust_prc()", fmt);
  785. #endif
  786.       break;
  787.     }
  788.  
  789.   /* If we get here, bptr points to a a string of len characters
  790.        (len<=width) that we want to output */
  791.   if (len < smallwid)
  792.     {
  793.       if (just == JST_RGT || just == JST_CNT)
  794.     {
  795.       int n;
  796.  
  797.       n = (just == JST_RGT) ? smallwid - len : (1 + smallwid - len) / 2;
  798.       for (;;)
  799.         {
  800.           bptr[len + n] = bptr[len];
  801.           if (len-- == 0)
  802.         break;
  803.         }
  804.       while (n-- >= 0)
  805.         bptr[n] = ' ';
  806.     }
  807.     }
  808.   return bptr;
  809. }
  810.  
  811.  
  812. #ifdef __STDC__
  813. void
  814. set_usr_stats (int usr_n, char **usr_buf)
  815. #else
  816. void
  817. set_usr_stats (usr_n, usr_buf)
  818.      int usr_n;
  819.      char **usr_buf;
  820. #endif
  821. {
  822.   int len;
  823.   int i;
  824.   char *p_in, *p_out;
  825.  
  826.   len = 0;
  827.   for (i = 0; i < 7; i++)
  828.     len += strlen (usr_buf[i]);
  829.   u[usr_n].p_hdr = ck_malloc (len + 7);
  830.   p_out = u[usr_n].p_hdr;
  831.   if (usr_buf[0][0])
  832.     {
  833.       p_in = usr_buf[0];
  834.       while (*p_out++ = *p_in++)
  835.     ;
  836.     }
  837.   else
  838.     *p_out++ = '\0';
  839.  
  840.   if (usr_buf[1][0])
  841.     {
  842.       p_in = usr_buf[1];
  843.       u[usr_n].n_hdr = p_out;
  844.       while (*p_out++ = *p_in++)
  845.     ;
  846.     }
  847.   else
  848.     u[usr_n].n_hdr = 0;
  849.  
  850.   if (usr_buf[2][0])
  851.     {
  852.       p_in = usr_buf[2];
  853.       u[usr_n].p_trl = p_out;
  854.       while (*p_out++ = *p_in++)
  855.     ;
  856.     }
  857.   else
  858.     u[usr_n].p_trl = 0;
  859.  
  860.   if (usr_buf[3][0])
  861.     {
  862.       p_in = usr_buf[3];
  863.       u[usr_n].n_trl = p_out;
  864.       while (*p_out++ = *p_in++)
  865.     ;
  866.     }
  867.   else
  868.     u[usr_n].n_trl = 0;
  869.  
  870.   if (usr_buf[4][0])
  871.     {
  872.       p_in = usr_buf[4];
  873.       u[usr_n].zero = p_out;
  874.       while (*p_out++ = *p_in++)
  875.     ;
  876.     }
  877.   else
  878.     u[usr_n].zero = 0;
  879.  
  880.   if (usr_buf[5][0])
  881.     {
  882.       p_in = usr_buf[5];
  883.       u[usr_n].comma = p_out;
  884.       while (*p_out++ = *p_in++)
  885.     ;
  886.     }
  887.   else
  888.     u[usr_n].comma = 0;
  889.  
  890.   if (usr_buf[6][0])
  891.     {
  892.       p_in = usr_buf[6];
  893.       u[usr_n].decpt = p_out;
  894.       while (*p_out++ = *p_in++)
  895.     ;
  896.     }
  897.   else
  898.     u[usr_n].decpt = 0;
  899.  
  900.   if (!stricmp (usr_buf[7], "float") || !stricmp (usr_buf[7], "f"))
  901.     u[usr_n].prec = 15;
  902.   else
  903.     u[usr_n].prec = astol (&usr_buf[7]);
  904.  
  905.   u[usr_n].scale = astof (&usr_buf[8]);
  906. }
  907.  
  908. #ifdef __STDC__
  909. int
  910. usr_set_fmts (void)
  911. #else
  912. int
  913. usr_set_fmts ()
  914. #endif
  915. {
  916.   int n;
  917.   int ret = 0;
  918.  
  919.   for (n = 0; n < 16; n++)
  920.     if (u[n].p_hdr)
  921.       ret |= 1 << n;
  922.   return ret;
  923. }
  924.  
  925. #ifdef __STDC__
  926. void
  927. get_usr_stats (int usr_num, char **usr_buf)
  928. #else
  929. void
  930. get_usr_stats (usr_num, usr_buf)
  931.      int usr_num;
  932.      char **usr_buf;
  933. #endif
  934. {
  935.   static char buf1[30];
  936.   static char buf2[30];
  937.   static char NullStr[] = "";
  938.  
  939.   usr_buf[0] = u[usr_num].p_hdr ? u[usr_num].p_hdr : NullStr;
  940.   usr_buf[1] = u[usr_num].n_hdr ? u[usr_num].n_hdr : NullStr;
  941.   usr_buf[2] = u[usr_num].p_trl ? u[usr_num].p_trl : NullStr;
  942.   usr_buf[3] = u[usr_num].n_trl ? u[usr_num].n_trl : NullStr;
  943.   usr_buf[4] = u[usr_num].zero ? u[usr_num].zero : NullStr;
  944.   usr_buf[5] = u[usr_num].comma ? u[usr_num].comma : NullStr;
  945.   usr_buf[6] = u[usr_num].decpt ? u[usr_num].decpt : NullStr;
  946.   if (u[usr_num].prec == 15)
  947.     usr_buf[7] = "float";
  948.   else
  949.     {
  950.       sprintf (buf1, "%u", u[usr_num].prec);
  951.       usr_buf[7] = buf1;
  952.     }
  953.   sprintf (buf2, "%.12g", u[usr_num].scale);
  954.   usr_buf[8] = buf2;
  955. }
  956.  
  957. /* Functions for printing out the names of cells and ranges */
  958.  
  959. #ifdef __STDC__
  960. char *
  961. cell_name (CELLREF rr, CELLREF cc)
  962. #else
  963. char *
  964. cell_name (rr, cc)
  965.      CELLREF rr;
  966.      CELLREF cc;
  967. #endif
  968. {
  969.   static char strs[2][20];
  970.   static num = 0;
  971.   char *ptr;
  972.  
  973.   num = num ? 0 : 1;
  974.  
  975.   if (a0)
  976.     {
  977.       ptr = &strs[num][9];
  978.       sprintf (ptr, "%u", rr);
  979.       if (cc < MIN_COL + 26)
  980.     *--ptr = 'A' - MIN_COL + cc;
  981. #if MAX_COL>702
  982.       else if (cc < MIN_COL + 702)
  983.     {
  984.       cc -= MIN_COL + 26;
  985.       *--ptr = 'A' + cc % 26;
  986.       *--ptr = 'A' + cc / 26;
  987.     }
  988.       else if (cc < MIN_COL + 18278)
  989.     {
  990.       cc -= MIN_COL + 702;
  991.       *--ptr = 'A' + cc % 26;
  992.       cc /= 26;
  993.       *--ptr = 'A' + cc % 26;
  994.       *--ptr = 'A' + cc / 26;
  995.     }
  996.       else
  997.     {
  998.       cc -= MIN_COL + 18278;
  999.       *--ptr = 'A' + cc % 26;
  1000.       cc /= 26;
  1001.       *--ptr = 'A' + cc % 26;
  1002.       cc /= 26;
  1003.       *--ptr = 'A' + cc % 26;
  1004.       *--ptr = 'A' + cc / 26;
  1005.     }
  1006. #else
  1007.       else
  1008.     {
  1009.       cc -= MIN_COL + 26;
  1010.       *--ptr = 'A' + cc % 26;
  1011.       *--ptr = 'A' + cc / 26;
  1012.     }
  1013. #endif
  1014.     }
  1015.   else
  1016.     {
  1017.       ptr = &strs[num][0];
  1018.       sprintf (ptr, "r%uc%u", rr, cc);
  1019.     }
  1020.   return ptr;
  1021. }
  1022.  
  1023. #ifdef __STDC__
  1024. char *
  1025. range_name (struct rng *rng)
  1026. #else
  1027. char *
  1028. range_name (rng)
  1029.      struct rng *rng;
  1030. #endif
  1031. {
  1032.   CELLREF lr, lc, hr, hc;
  1033.   static char buf[2][40];
  1034.   static num;
  1035.   char *ptr;
  1036.  
  1037.   ptr = &buf[num][0];
  1038.   num = num ? 0 : 1;
  1039.  
  1040.   lr = rng->lr;
  1041.   lc = rng->lc;
  1042.   hr = rng->hr;
  1043.   hc = rng->hc;
  1044.  
  1045.   if (a0)
  1046.     sprintf (ptr, "%s:%s", cell_name (lr, lc), cell_name (hr, hc));
  1047.   else
  1048.     {
  1049.       if (lr == hr && lc == hc)
  1050.     sprintf (ptr, "r%uc%u", lr, lc);
  1051.       else if (lr == hr && lc != hc)
  1052.     sprintf (ptr, "r%uc%u:%u", lr, lc, hc);
  1053.       else if (lr != hr && lc == hc)
  1054.     sprintf (ptr, "r%u:%uc%u", lr, hr, lc);
  1055.       else
  1056.     sprintf (ptr, "r%u:%uc%u:%u", lr, hr, lc, hc);
  1057.     }
  1058.   return ptr;
  1059. }
  1060.  
  1061.  
  1062. /* Parse a range, allowing variable names.
  1063.  * Return 1 on failure, 0 on succes.
  1064.  */
  1065. #ifdef __STDC__
  1066. int
  1067. get_abs_rng (char **pptr, struct rng *retp)
  1068. #else
  1069. int
  1070. get_abs_rng (pptr, retp)
  1071.      char **pptr;
  1072.      struct rng *retp;
  1073. #endif
  1074. {
  1075.   unsigned char n;
  1076.   struct rng ignored;
  1077.  
  1078.   if (!retp)
  1079.     retp = &ignored;
  1080.  
  1081.   while (**pptr == ' ')
  1082.     (*pptr)++;
  1083.   if (!**pptr)
  1084.     return 1;
  1085.   cur_row = curow;
  1086.   cur_col = cucol;
  1087.   n = parse_cell_or_range (pptr, retp);
  1088.   if (!n)
  1089.     {
  1090.       struct var *v;
  1091.       char *ptr;
  1092.  
  1093.       ptr = *pptr;
  1094.       while (ptr[n] && ptr[n] != ' ')
  1095.     n++;
  1096.       v = find_var (ptr, n);
  1097.       if (!v)
  1098.     return 1;
  1099.       (*pptr) += n;
  1100.       *retp = v->v_rng;
  1101.     }
  1102.   return 0;
  1103. }
  1104.  
  1105.  
  1106. #ifdef __STDC__
  1107. char *
  1108. col_to_str (CELLREF col)
  1109. #else
  1110. char *
  1111. col_to_str (col)
  1112.      CELLREF col;
  1113. #endif
  1114. {
  1115.   static char strs[2][10];
  1116.   static num;
  1117.   char *ptr;
  1118.  
  1119.   ptr = &strs[num][9];
  1120.   num = num ? 0 : 1;
  1121.  
  1122.   if (col < MIN_COL + 26)
  1123.     *--ptr = 'A' - MIN_COL + col;
  1124. #if MAX_COL>702
  1125.   else if (col < MIN_COL + 702)
  1126.     {
  1127.       col -= MIN_COL + 26;
  1128.       *--ptr = 'A' + col % 26;
  1129.       *--ptr = 'A' + col / 26;
  1130.     }
  1131.   else if (col < MIN_COL + 18278)
  1132.     {
  1133.       col -= MIN_COL + 702;
  1134.       *--ptr = 'A' + col % 26;
  1135.       col /= 26;
  1136.       *--ptr = 'A' + col % 26;
  1137.       *--ptr = 'A' + col / 26;
  1138.     }
  1139.   else
  1140.     {
  1141.       col -= MIN_COL + 18278;
  1142.       *--ptr = 'A' + col % 26;
  1143.       col /= 26;
  1144.       *--ptr = 'A' + col % 26;
  1145.       col /= 26;
  1146.       *--ptr = 'A' + col % 26;
  1147.       *--ptr = 'A' + col / 26;
  1148.     }
  1149. #else
  1150.   else
  1151.     {
  1152.       col -= MIN_COL + 26;
  1153.       *--ptr = 'A' + col % 26;
  1154.       *--ptr = 'A' + col / 26;
  1155.     }
  1156. #endif
  1157.   return ptr;
  1158. }
  1159.  
  1160. #ifdef __STDC__
  1161. void
  1162. clear_spreadsheet (void)
  1163. #else
  1164. void
  1165. clear_spreadsheet ()
  1166. #endif
  1167. {
  1168.   int n;
  1169.  
  1170.   flush_everything ();
  1171.   /* flush_widths(); */
  1172.   flush_all_timers ();
  1173.   for (n = 0; n < 16; n++)
  1174.     {
  1175.       if (u[n].p_hdr)
  1176.     {
  1177.       free (u[n].p_hdr);
  1178.       u[n].p_hdr = 0;
  1179.       u[n].prec = PRC_FLT;
  1180.       u[n].scale = 1;
  1181.     }
  1182.     }
  1183.   default_width = saved_default_width;
  1184.   default_height = saved_default_height;
  1185.   default_jst = JST_LFT;
  1186.   default_fmt = FMT_GEN;
  1187.   default_lock = LCK_UNL;
  1188. }
  1189.  
  1190. char *ename[] =
  1191. {
  1192.   "#WHAT?",
  1193.   "#ERROR", "#BAD_INPUT", "#NON_NUMBER", "#NON_STRING",
  1194.   "#NON_BOOL", "#NON_RANGE", "#OUT_OF_RANGE", "#NO_VALUES",
  1195.   "#DIV_BY_ZERO", "#BAD_NAME", "#NOT_AVAIL", "#PARSE_ERROR",
  1196.   "#NEED_OPEN", "#NEED_CLOSE", "#NEED_QUOTE", "#UNK_CHAR",
  1197.   "#UNK_FUNC",
  1198.   0
  1199. };
  1200.  
  1201. char tname[] = "#TRUE";
  1202. char fname[] = "#FALSE";
  1203.  
  1204.  
  1205. #ifdef __STDC__
  1206. int
  1207. words_imatch (char ** ptr, char * key)
  1208. #else
  1209. int
  1210. words_imatch (ptr, key)
  1211.      char ** ptr;
  1212.      char * key;
  1213. #endif
  1214. {
  1215.   char * str = * ptr;
  1216.  
  1217.   while (isspace (*str))
  1218.     ++str;
  1219.   while (isspace (*key))
  1220.     ++key;
  1221.  
  1222.   while (1)
  1223.     {
  1224.       while (*str && *key && (toupper (*str) == toupper (*key)))
  1225.     {
  1226.       ++str;
  1227.       ++key;
  1228.     }
  1229.       /* If we're not at word breaks in both strings... */
  1230.       if (!((!*str || isspace (*str)) && (!*key || isspace (*key))))
  1231.     return 0;
  1232.       else
  1233.     {
  1234.       while (isspace (*key))
  1235.         ++key;
  1236.       while (isspace (*str))
  1237.         ++str;
  1238.       if (!*key)
  1239.         {
  1240.           *ptr = str;
  1241.           return 1;
  1242.         }
  1243.     }
  1244.     }
  1245. }
  1246.  
  1247. #ifdef __STDC__
  1248. int
  1249. parray_len (char ** array)
  1250. #else
  1251. int
  1252. parray_len (array)
  1253.      char ** array;
  1254. #endif
  1255. {
  1256.   int x;
  1257.   for (x = 0; array[x]; ++x) ;
  1258.   return x;
  1259. }
  1260.  
  1261.  
  1262. /* Return the index of CHECK in KEYS or -1.  Case and whitespeace insenstive.
  1263.  */
  1264.  
  1265. #ifdef __STDC__
  1266. int
  1267. words_member (char ** keys, int len, char * check)
  1268. #else
  1269. int
  1270. words_member (keys, len, check)
  1271.      char ** keys;
  1272.      int len;
  1273.      char * check;
  1274. #endif
  1275. {
  1276.   int x;
  1277.   for (x = 0; x < len; ++x)
  1278.     {
  1279.       char * ch = check;
  1280.       if (words_imatch (&ch, keys[x]))
  1281.     if (!*ch)
  1282.       return x;
  1283.     }
  1284.   return -1;
  1285. }
  1286.  
  1287. #ifdef __STDC__
  1288. int
  1289. prompt_len (char * prompt)
  1290. #else
  1291. int
  1292. prompt_len (prompt)
  1293.      char * prompt;
  1294. #endif
  1295. {
  1296.   char * pos;
  1297.   if (!prompt)
  1298.     return 0;
  1299.   for (pos = prompt; *pos && (*pos != '\n'); ++pos)
  1300.     ;
  1301.   return pos - prompt;
  1302. }
  1303.  
  1304.  
  1305. #ifdef __STDC__
  1306. int
  1307. says_default (char * str)
  1308. #else
  1309. int
  1310. says_default (str)
  1311.      char * str;
  1312. #endif
  1313. {
  1314.   char * key = "ault";
  1315.   if (strincmp(str, "def", 3))
  1316.     return 0;
  1317.   str += 3;
  1318.   while (*str && *key)
  1319.     {
  1320.       if (tolower(*str) != *key)
  1321.     return 0;
  1322.       ++key;
  1323.       ++str;
  1324.     }
  1325.   while (isspace(*str))
  1326.     ++str;
  1327.   return !*str;
  1328. }
  1329.