home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / calc / part02 / const.c < prev    next >
C/C++ Source or Header  |  1992-05-09  |  3KB  |  109 lines

  1. /*
  2.  * Copyright (c) 1992 David I. Bell
  3.  * Permission is granted to use, distribute, or modify this source,
  4.  * provided that this copyright notice remains intact.
  5.  *
  6.  * Constant number storage module.
  7.  */
  8.  
  9. #include "calc.h"
  10.  
  11. #define CONSTALLOCSIZE 400    /* number of constants to allocate */
  12.  
  13.  
  14. static long constcount;        /* number of constants defined */
  15. static long constavail;        /* number of constants available */
  16. static NUMBER **consttable;    /* table of constants */
  17.  
  18.  
  19. /*
  20.  * Read in a constant number and add it to the table of constant numbers,
  21.  * creating a new entry if necessary.  The incoming number is a string
  22.  * value which must have a correct format, otherwise an undefined number
  23.  * will result.  Returns the index of the number in the constant table.
  24.  * Returns zero if the number could not be saved.
  25.  */
  26. long
  27. addnumber(str)
  28.     char *str;        /* string representation of number */
  29. {
  30.     NUMBER *q;
  31.  
  32.     q = atoq(str);
  33.     if (q == NULL)
  34.         return 0;
  35.     return addqconstant(q);
  36. }
  37.  
  38.  
  39. /*
  40.  * Add a particular number to the constant table.
  41.  * Returns the index of the number in the constant table, or zero
  42.  * if the number could not be saved.  The incoming number if freed
  43.  * if it is already in the table.
  44.  */
  45. long
  46. addqconstant(q)
  47.     register NUMBER *q;    /* number to be added */
  48. {
  49.     register NUMBER **tp;    /* pointer to current number */
  50.     register NUMBER *t;    /* number being tested */
  51.     long index;        /* index into constant table */
  52.     long numlen;        /* numerator length */
  53.     long denlen;        /* denominator length */
  54.     HALF numlow;        /* bottom value of numerator */
  55.     HALF denlow;        /* bottom value of denominator */
  56.  
  57.     numlen = q->num.len;
  58.     denlen = q->den.len;
  59.     numlow = q->num.v[0];
  60.     denlow = q->den.v[0];
  61.     tp = &consttable[1];
  62.     for (index = 1; index <= constcount; index++) {
  63.         t = *tp++;
  64.         if ((numlen != t->num.len) || (numlow != t->num.v[0]))
  65.             continue;
  66.         if ((denlen != t->den.len) || (denlow != t->den.v[0]))
  67.             continue;
  68.         if (q->num.sign != t->num.sign)
  69.             continue;
  70.         if (qcmp(q, t) == 0) {
  71.             qfree(q);
  72.             return index;
  73.         }
  74.     }
  75.     if (constavail <= 0) {
  76.         if (consttable == NULL) {
  77.             tp = (NUMBER **)
  78.                 malloc(sizeof(NUMBER *) * (CONSTALLOCSIZE + 1));
  79.             *tp = NULL;
  80.         } else
  81.             tp = (NUMBER **) realloc((char *) consttable,
  82.             sizeof(NUMBER *) * (constcount+CONSTALLOCSIZE + 1));
  83.         if (tp == NULL)
  84.             return 0;
  85.         consttable = tp;
  86.         constavail = CONSTALLOCSIZE;
  87.     }
  88.     constavail--;
  89.     constcount++;
  90.     consttable[constcount] = q;
  91.     return constcount;
  92. }
  93.  
  94.  
  95. /*
  96.  * Return the value of a constant number given its index.
  97.  * Returns address of the number, or NULL if the index is illegal.
  98.  */
  99. NUMBER *
  100. constvalue(index)
  101.     long index;
  102. {
  103.     if ((index <= 0) || (index > constcount))
  104.         return NULL;
  105.     return consttable[index];
  106. }
  107.  
  108. /* END CODE */
  109.