mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
114 lines
2.7 KiB
C
114 lines
2.7 KiB
C
/*
|
|
* Copyright (c) 1993 David I. Bell
|
|
* Permission is granted to use, distribute, or modify this source,
|
|
* provided that this copyright notice remains intact.
|
|
*
|
|
* Constant number storage module.
|
|
*/
|
|
|
|
#include "calc.h"
|
|
|
|
#define CONSTALLOCSIZE 400 /* number of constants to allocate */
|
|
|
|
|
|
static long constcount; /* number of constants defined */
|
|
static long constavail; /* number of constants available */
|
|
static NUMBER **consttable; /* table of constants */
|
|
|
|
|
|
/*
|
|
* Read in a constant number and add it to the table of constant numbers,
|
|
* creating a new entry if necessary. The incoming number is a string
|
|
* value which must have a correct format, otherwise an undefined number
|
|
* will result. Returns the index of the number in the constant table.
|
|
* Returns zero if the number could not be saved.
|
|
*
|
|
* given:
|
|
* str string representation of number
|
|
*/
|
|
long
|
|
addnumber(char *str)
|
|
{
|
|
NUMBER *q;
|
|
|
|
q = str2q(str);
|
|
if (q == NULL)
|
|
return 0;
|
|
return addqconstant(q);
|
|
}
|
|
|
|
|
|
/*
|
|
* Add a particular number to the constant table.
|
|
* Returns the index of the number in the constant table, or zero
|
|
* if the number could not be saved. The incoming number if freed
|
|
* if it is already in the table.
|
|
*
|
|
* XXX - we should hash the constant table
|
|
*
|
|
* given:
|
|
* q number to be added
|
|
*/
|
|
long
|
|
addqconstant(NUMBER *q)
|
|
{
|
|
register NUMBER **tp; /* pointer to current number */
|
|
register NUMBER *t; /* number being tested */
|
|
long index; /* index into constant table */
|
|
long numlen; /* numerator length */
|
|
long denlen; /* denominator length */
|
|
HALF numlow; /* bottom value of numerator */
|
|
HALF denlow; /* bottom value of denominator */
|
|
|
|
numlen = q->num.len;
|
|
denlen = q->den.len;
|
|
numlow = q->num.v[0];
|
|
denlow = q->den.v[0];
|
|
tp = &consttable[1];
|
|
for (index = 1; index <= constcount; index++) {
|
|
t = *tp++;
|
|
if ((numlen != t->num.len) || (numlow != t->num.v[0]))
|
|
continue;
|
|
if ((denlen != t->den.len) || (denlow != t->den.v[0]))
|
|
continue;
|
|
if (q->num.sign != t->num.sign)
|
|
continue;
|
|
if (qcmp(q, t) == 0) {
|
|
qfree(q);
|
|
return index;
|
|
}
|
|
}
|
|
if (constavail <= 0) {
|
|
if (consttable == NULL) {
|
|
tp = (NUMBER **)
|
|
malloc(sizeof(NUMBER *) * (CONSTALLOCSIZE + 1));
|
|
*tp = NULL;
|
|
} else
|
|
tp = (NUMBER **) realloc((char *) consttable,
|
|
sizeof(NUMBER *) * (constcount+CONSTALLOCSIZE + 1));
|
|
if (tp == NULL)
|
|
return 0;
|
|
consttable = tp;
|
|
constavail = CONSTALLOCSIZE;
|
|
}
|
|
constavail--;
|
|
constcount++;
|
|
consttable[constcount] = q;
|
|
return constcount;
|
|
}
|
|
|
|
|
|
/*
|
|
* Return the value of a constant number given its index.
|
|
* Returns address of the number, or NULL if the index is illegal.
|
|
*/
|
|
NUMBER *
|
|
constvalue(unsigned long index)
|
|
{
|
|
if ((index <= 0) || (index > constcount))
|
|
return NULL;
|
|
return consttable[index];
|
|
}
|
|
|
|
/* END CODE */
|