home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d01xx / d0172.lha / Spiff / tol.c < prev    next >
C/C++ Source or Header  |  1988-11-22  |  6KB  |  362 lines

  1. /*                        Copyright (c) 1988 Bellcore
  2. **                            All Rights Reserved
  3. **       Permission is granted to copy or use this program, EXCEPT that it
  4. **       may not be sold for profit, the copyright notice must be reproduced
  5. **       on copies, and credit should be given to Bellcore where it is due.
  6. **       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7. */
  8.  
  9.  
  10. #ifndef lint
  11. static char rcsid[]= "$Header: tol.c,v 1.1 88/09/15 11:33:59 daniel Rel $";
  12. #endif
  13.  
  14. #include "misc.h"
  15. #include "float.h"
  16. #include "tol.h"
  17. #include "token.h"
  18.  
  19. /*
  20. **    storage for the default tolerances
  21. */
  22. T_tol _T_gtol = _T_null;
  23.  
  24. /*
  25. **    tolerances that can be set in the command script and attached to floating
  26. **        point numbers at parse time
  27. */
  28. static T_tol _T_tols[_T_TOLMAX];
  29.  
  30. /*
  31. **    initialize the global tolerance
  32. **    should be called only once at the beginning of the program
  33. */
  34. void
  35. T_initdefault()
  36. {
  37.     static int called_before = 0;
  38.  
  39.     if (called_before)
  40.     {
  41.         Z_fatal("T_initdefault called more than once\n");
  42.     }
  43.  
  44.     /*
  45.     **    if the default tolerance was set somewhere else
  46.     **    don't set it here
  47.     */
  48.     if (T_isnull(_T_gtol))
  49.     {
  50.         T_defatol(_T_ADEF);
  51.         T_defrtol(_T_RDEF);
  52.     }
  53.     called_before = 1;
  54. }
  55.  
  56. static void
  57. _T_tolclear(addr)
  58. T_tol *addr;
  59. {
  60.     *addr = _T_null;
  61. }
  62.  
  63. /*
  64. **    clear the parse time tolerances
  65. */
  66. void
  67. T_clear_tols()
  68. {
  69.     int i;
  70.     for(i=0;i<_T_TOLMAX;i++)
  71.     {
  72.         _T_tolclear(&_T_tols[i]);
  73.     }
  74. }
  75.  
  76. static void
  77. _T_defclear()
  78. {
  79.     _T_tolclear(&_T_gtol);
  80. }
  81.  
  82. /*
  83. **    take a series of specifiers and add them to the tolerance
  84. */
  85. static void
  86. _T_settol(toladdr,str)
  87. T_tol *toladdr;
  88. char *str;
  89. {
  90.     char typechar;
  91.     while ('\0' != *str)
  92.     {
  93.         /*
  94.         **    find the first non-whitespace character
  95.         */
  96.         S_skipspace(&str);
  97.         /*
  98.         **    snarf up the type specifier
  99.         */
  100.         typechar = *str;
  101.         /*
  102.         **    now skip the first char
  103.         */
  104.         str++;
  105.         /*
  106.         **    skip any possibly intervening whitespace
  107.         */
  108.         S_skipspace(&str);
  109.         switch (typechar)
  110.         {
  111.             case 'a':
  112.                 _T_addtol(toladdr,T_ABSOLUTE,str);
  113.                 break;
  114.             case 'r':
  115.                 _T_addtol(toladdr,T_RELATIVE,str);
  116.                 break;
  117.             case 'i':
  118.                 _T_addtol(toladdr,T_IGNORE,(char*)0);
  119.                 break;
  120.             case 'd':
  121.                 _T_appendtols(toladdr,_T_gtol);
  122.                 break;
  123.             default:
  124.                 (void) sprintf(Z_err_buf,
  125.                   "don't understand tolerance type '%c'\n",typechar);
  126.                 Z_fatal(Z_err_buf);
  127.         }
  128.         /*
  129.         **    and skip to next tolerance
  130.         */
  131.         S_nextword(&str);
  132.     }
  133. }
  134.  
  135. /*
  136. **    set the default tolerance 
  137. */
  138. void
  139. T_setdef(str)
  140. char *str;
  141. {
  142.     _T_defclear();
  143.     _T_settol(&_T_gtol,str);
  144. }
  145.  
  146.  
  147. static char*
  148. _T_nextspec(ptr)
  149. char *ptr;
  150. {
  151.     /*
  152.     **    find the end of the current spec
  153.     */
  154.     for(;(_T_SEPCHAR != *ptr) && ('\0' != *ptr);ptr++)
  155.     {
  156.     }
  157.  
  158.     /*
  159.     **    and step over the seperator if necessary
  160.     */
  161.     if (_T_SEPCHAR == *ptr)
  162.         ptr++;
  163.  
  164.     return(ptr);
  165. }
  166.  
  167. /*
  168. **    return just the next set of specs
  169. **        ie the string up to end of line or
  170. **            the first _T_SEPCHAR
  171. **    returned string does not include the _T_SEPCHAR
  172. */
  173. static char *
  174. _T_getspec(from)
  175. char *from;
  176. {
  177.     static char retval[Z_LINELEN];
  178.     char *ptr = retval;
  179.  
  180.     while((_T_SEPCHAR != *from) && ('\0' != *from))
  181.     {
  182.         *ptr++ = *from++;
  183.     }
  184.     *ptr = '\0';    /* terminate the line */
  185.     return(retval);
  186. }
  187.  
  188. /*
  189. **    parse a series of _T_SEPCHAR separated tolerance specifications
  190. */
  191. void
  192. T_tolline(str)
  193. char *str;
  194. {
  195.     int nexttol;
  196.  
  197.     T_clear_tols();
  198.  
  199.     for(nexttol=0;'\0' != *str;nexttol++,str = _T_nextspec(str))
  200.     {
  201.         /*
  202.         **    make sure we haven't run off the end
  203.         */
  204.         if (nexttol >= _T_TOLMAX)
  205.         {
  206.             Z_fatal("too many tolerances per line");
  207.         }
  208.  
  209.         /*
  210.         **    and set the tolerance
  211.         */
  212.         _T_settol(&_T_tols[nexttol],_T_getspec(str));
  213.     }
  214. }
  215.  
  216. T_moretols(next_tol)
  217. {
  218.     return((next_tol >= 0) &&
  219.         (_T_TOLMAX-1 > next_tol) &&
  220.         (!T_isnull( _T_tols[next_tol+1])));
  221. }
  222.  
  223. T_tol
  224. T_gettol(index)
  225. int index;
  226. {
  227.     return(_T_tols[index]);
  228. }
  229.  
  230. /*
  231. **    chose which tolerance to use
  232. **         precidence is
  233. **            first tolerance
  234. **            second tolerance
  235. **            default tolerance
  236. */
  237. T_tol
  238. T_picktol(p1,p2)
  239. T_tol p1, p2;
  240. {
  241.     if (!(T_isnull(p1)))
  242.         return(p1);
  243.  
  244.     if (!(T_isnull(p2)))
  245.         return(p2);
  246.  
  247.     return(_T_gtol);
  248. }
  249.  
  250. void
  251. _T_appendtols(to,from)
  252. T_tol *to,from;
  253. {
  254.  
  255.     T_tol last;
  256.  
  257.     /*
  258.     **    are there any elements on the list yet
  259.     */
  260.     if (T_isnull(*to))
  261.     {
  262.         /*
  263.         **    it's a null list, so allocat space for the
  264.         **        first element and set pointer to it.
  265.         */
  266.  
  267.         *to = from;
  268.     }
  269.     else
  270.     {
  271.         /*
  272.         **    find the last element on the list
  273.         */
  274.         for(last= *to;!T_isnull(T_getnext(last));last = T_getnext(last))
  275.         {
  276.         }
  277.         /*
  278.         **    add an element on the end
  279.         */
  280.         T_setnext(last,from);
  281.     }
  282. }
  283.  
  284. /*
  285. **    add a tolerance to a list
  286. */
  287. void
  288. _T_addtol(listptr,type,str)
  289. T_tol *listptr;
  290. int type;
  291. char *str;
  292. {
  293.     T_tol last;
  294.  
  295.     /*
  296.     **    are there any elements on the list yet
  297.     */
  298.     if (T_isnull(*listptr))
  299.     {
  300.         /*
  301.         **    it's a null list, so allocat space for the
  302.         **        first element and set pointer to it.
  303.         */
  304.  
  305.         last = *listptr = Z_ALLOC(1,_T_struct);
  306.     }
  307.     else
  308.     {
  309.         /*
  310.         **    find the last element on the list
  311.         */
  312.         for(last= *listptr;!T_isnull(T_getnext(last));last = T_getnext(last))
  313.         {
  314.         }
  315.         /*
  316.         **    add an element on the end
  317.         */
  318.         T_setnext(last,Z_ALLOC(1,_T_struct));
  319.  
  320.         /*
  321.         **    and point to the new element
  322.         */
  323.         last = T_getnext(last);
  324.     }
  325.  
  326.     T_settype(last,type);
  327.     T_setnext(last,_T_null);
  328.  
  329.     /*
  330.     **    set the float value only if necessary
  331.     */
  332.     if (T_IGNORE == type)
  333.     {
  334.         T_setfloat(last,F_null);
  335.     }
  336.     else
  337.     {
  338.         T_setfloat(last,F_atof(str,NO_USE_ALL));
  339.  
  340.         /*
  341.         **    test new tolerance for sanity
  342.         */
  343.         if (F_getsign(T_getfloat(last)))
  344.         {
  345.             (void) sprintf(Z_err_buf,
  346.             "%s : negative tolerances don't make any sense\n",str);
  347.             Z_fatal(Z_err_buf);
  348.         }
  349.         /*
  350.         **    check for excessively large relative tolerances
  351.         */
  352.         if ((T_RELATIVE == type) &&
  353.              (F_floatcmp(T_getfloat(last),
  354.                      F_atof("2.0",USE_ALL)) > 0))
  355.         {
  356.             (void) sprintf(Z_err_buf,
  357.     "%s : relative tolerances greater than 2 don't make any sense\n",str);
  358.             Z_fatal(Z_err_buf);
  359.         }
  360.     }
  361. }
  362.