mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
Compare commits
2 Commits
2.11.0t8.2
...
2.11.0t8.4
Author | SHA1 | Date | |
---|---|---|---|
|
8db10967e8 | ||
|
49be672338 |
17
BUGS
17
BUGS
@@ -68,9 +68,20 @@ importantly, fixes (in the form of a context diff patch) to:
|
|||||||
|
|
||||||
Known bugs:
|
Known bugs:
|
||||||
|
|
||||||
None reported. We are sure some bugs exist. When you find them,
|
* calc -i ignores quit binding or EOF input in some cases. For example:
|
||||||
please let us know! See the above for details on how to report and
|
|
||||||
were to EMail your bug reports and hopefully patches to fix them.
|
echo 'define f(x) { ' > myfile
|
||||||
|
calc -i read myfile
|
||||||
|
"./myfile", line 2: End-of-file in function body
|
||||||
|
Error in commands
|
||||||
|
>
|
||||||
|
|
||||||
|
At this point, calc will re-prompt if you give it an EOF, or
|
||||||
|
type ^D while using lib/altbind or while ^D is bound to quit.
|
||||||
|
|
||||||
|
We are sure some more bugs exist. When you find them, please let
|
||||||
|
us know! See the above for details on how to report and were to
|
||||||
|
EMail your bug reports and hopefully patches to fix them.
|
||||||
|
|
||||||
=-=
|
=-=
|
||||||
|
|
||||||
|
27
CHANGES
27
CHANGES
@@ -44,6 +44,33 @@ Following is the change from calc version 2.11.0t8 to date:
|
|||||||
|
|
||||||
Misc source file cleanup for things such as } else { style consistency.
|
Misc source file cleanup for things such as } else { style consistency.
|
||||||
|
|
||||||
|
Fixed the basis for FNV-1 hashes. Piror to this fix, the hash()
|
||||||
|
builtin produced FNV hash values that did not match the FNV-1
|
||||||
|
algorithm as specified in:
|
||||||
|
|
||||||
|
http://reality.sgi.com/chongo/tech/comp/fnv/index.html
|
||||||
|
|
||||||
|
Removed an unused argument in the function getbody() in codegen.c.
|
||||||
|
|
||||||
|
Encountering of EOF in getbody() will cause a scanerror rather then
|
||||||
|
stop activity. This will now result in a scanerror:
|
||||||
|
|
||||||
|
echo 'define f(x) { ' > myfile
|
||||||
|
calc -i read myfile
|
||||||
|
|
||||||
|
A '{' at the start of a command and a later matching '}' surrounding zero
|
||||||
|
or more statements (and possibly newlines) results in a function body to
|
||||||
|
be "evaluated". This permits another command to follow on the same
|
||||||
|
line as the '}' as in:
|
||||||
|
|
||||||
|
{display(5)} read something;
|
||||||
|
and:
|
||||||
|
{static a = 5} define f(x) = a + x;
|
||||||
|
|
||||||
|
String constants can now be concatenated. For exmaple:
|
||||||
|
|
||||||
|
s = "curds" ' and ' "whey";
|
||||||
|
|
||||||
|
|
||||||
Following is the change from calc version 2.11.0t7 to 2.11.0t7.5:
|
Following is the change from calc version 2.11.0t7 to 2.11.0t7.5:
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
|||||||
* so that we can first select the correct hash chain, and
|
* so that we can first select the correct hash chain, and
|
||||||
* also so we can quickly compare each element for a match.
|
* also so we can quickly compare each element for a match.
|
||||||
*/
|
*/
|
||||||
hash = (QCKHASH)0;
|
hash = FNV1_32_BASIS;
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
hash = hashvalue(&indices[i], hash);
|
hash = hashvalue(&indices[i], hash);
|
||||||
|
|
||||||
|
30
codegen.c
30
codegen.c
@@ -31,7 +31,7 @@ static void getshowstatement(void);
|
|||||||
static void getfunction(void);
|
static void getfunction(void);
|
||||||
static void ungetfunction(void);
|
static void ungetfunction(void);
|
||||||
static void getbody(LABEL *contlabel, LABEL *breaklabel,
|
static void getbody(LABEL *contlabel, LABEL *breaklabel,
|
||||||
LABEL *nextcaselabel, LABEL *defaultlabel, BOOL toplevel);
|
LABEL *nextcaselabel, LABEL *defaultlabel);
|
||||||
static void getdeclarations(int symtype);
|
static void getdeclarations(int symtype);
|
||||||
static void getsimpledeclaration (int symtype);
|
static void getsimpledeclaration (int symtype);
|
||||||
static int getonevariable (int symtype);
|
static int getonevariable (int symtype);
|
||||||
@@ -190,13 +190,16 @@ evaluate(BOOL nestflag)
|
|||||||
|
|
||||||
funcname = (nestflag ? "**" : "*");
|
funcname = (nestflag ? "**" : "*");
|
||||||
beginfunc(funcname, nestflag);
|
beginfunc(funcname, nestflag);
|
||||||
|
if (gettoken() == T_LEFTBRACE) {
|
||||||
|
getbody(NULL_LABEL, NULL_LABEL, NULL_LABEL, NULL_LABEL);
|
||||||
|
} else {
|
||||||
if (nestflag)
|
if (nestflag)
|
||||||
(void) tokenmode(TM_DEFAULT);
|
(void) tokenmode(TM_DEFAULT);
|
||||||
|
rescantoken();
|
||||||
while (loop) {
|
while (loop) {
|
||||||
switch (gettoken()) {
|
switch (gettoken()) {
|
||||||
case T_SEMICOLON:
|
case T_SEMICOLON:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_NEWLINE:
|
case T_NEWLINE:
|
||||||
case T_EOF:
|
case T_EOF:
|
||||||
loop = 0;
|
loop = 0;
|
||||||
@@ -208,6 +211,7 @@ evaluate(BOOL nestflag)
|
|||||||
NULL_LABEL, NULL_LABEL);
|
NULL_LABEL, NULL_LABEL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
addop(OP_UNDEF);
|
addop(OP_UNDEF);
|
||||||
addop(OP_RETURN);
|
addop(OP_RETURN);
|
||||||
checklabels();
|
checklabels();
|
||||||
@@ -322,13 +326,11 @@ getfunction(void)
|
|||||||
}
|
}
|
||||||
switch (gettoken()) {
|
switch (gettoken()) {
|
||||||
case T_ASSIGN:
|
case T_ASSIGN:
|
||||||
rescantoken();
|
|
||||||
getsimplebody();
|
getsimplebody();
|
||||||
break;
|
break;
|
||||||
case T_LEFTBRACE:
|
case T_LEFTBRACE:
|
||||||
rescantoken();
|
|
||||||
getbody(NULL_LABEL, NULL_LABEL, NULL_LABEL,
|
getbody(NULL_LABEL, NULL_LABEL, NULL_LABEL,
|
||||||
NULL_LABEL, TRUE);
|
NULL_LABEL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scanerror(T_NULL,
|
scanerror(T_NULL,
|
||||||
@@ -347,11 +349,6 @@ getfunction(void)
|
|||||||
static void
|
static void
|
||||||
getsimplebody(void)
|
getsimplebody(void)
|
||||||
{
|
{
|
||||||
if (gettoken() != T_ASSIGN) {
|
|
||||||
scanerror(T_SEMICOLON,
|
|
||||||
"Missing equals for simple function body");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(void) tokenmode(TM_NEWLINES);
|
(void) tokenmode(TM_NEWLINES);
|
||||||
(void) getexprlist();
|
(void) getexprlist();
|
||||||
addop(OP_RETURN);
|
addop(OP_RETURN);
|
||||||
@@ -365,14 +362,10 @@ getsimplebody(void)
|
|||||||
*/
|
*/
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
getbody(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *defaultlabel, BOOL toplevel)
|
getbody(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *defaultlabel)
|
||||||
{
|
{
|
||||||
int oldmode;
|
int oldmode;
|
||||||
|
|
||||||
if (gettoken() != T_LEFTBRACE) {
|
|
||||||
scanerror(T_SEMICOLON, "Missing left brace for function body");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
oldmode = tokenmode(TM_DEFAULT);
|
oldmode = tokenmode(TM_DEFAULT);
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
switch (gettoken()) {
|
switch (gettoken()) {
|
||||||
@@ -380,6 +373,10 @@ getbody(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *defaul
|
|||||||
(void) tokenmode(oldmode);
|
(void) tokenmode(oldmode);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case T_EOF:
|
||||||
|
scanerror(T_SEMICOLON, "End-of-file in function body");
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rescantoken();
|
rescantoken();
|
||||||
getstatement(contlabel, breaklabel, nextcaselabel, defaultlabel);
|
getstatement(contlabel, breaklabel, nextcaselabel, defaultlabel);
|
||||||
@@ -595,8 +592,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_LEFTBRACE:
|
case T_LEFTBRACE:
|
||||||
rescantoken();
|
getbody(contlabel, breaklabel, nextcaselabel, defaultlabel);
|
||||||
getbody(contlabel, breaklabel, nextcaselabel, defaultlabel, FALSE);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case T_IF:
|
case T_IF:
|
||||||
|
2
func.c
2
func.c
@@ -1527,7 +1527,7 @@ f_hash(int count, VALUE **vals)
|
|||||||
long lhash;
|
long lhash;
|
||||||
VALUE result;
|
VALUE result;
|
||||||
|
|
||||||
hash = (QCKHASH)0;
|
hash = FNV1_32_BASIS;
|
||||||
while (count-- > 0)
|
while (count-- > 0)
|
||||||
hash = hashvalue(*vals++, hash);
|
hash = hashvalue(*vals++, hash);
|
||||||
lhash = (long) hash;
|
lhash = (long) hash;
|
||||||
|
15
help/hash
15
help/hash
@@ -12,10 +12,23 @@ TYPES
|
|||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Returns a hash value for one or more values of arbitrary types.
|
Returns a hash value for one or more values of arbitrary types.
|
||||||
|
|
||||||
|
This function implements the Fowler/Noll/Vo hash-1 (FNV-1 hash).
|
||||||
|
The basis of the hash algorithm was taken from an idea sent
|
||||||
|
by Email to the IEEE POSIX P1003.2 mailing list from Phong Vo
|
||||||
|
(kpv@research.att.com) and Glenn Fowler (gsf@research.att.com).
|
||||||
|
Landon Curt Noll (http://reality.sgi.com/chongo) later improved on
|
||||||
|
their algorithm to come up with Fowler/Noll/Vo hash.
|
||||||
|
|
||||||
|
See:
|
||||||
|
|
||||||
|
http://reality.sgi.com/chongo/tech/comp/fnv/index.html
|
||||||
|
|
||||||
|
for more information in this hash.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
> a = isqrt(2e1000); s = "xyz";
|
> a = isqrt(2e1000); s = "xyz";
|
||||||
> hash(a,s)
|
> hash(a,s)
|
||||||
870000771
|
1916476840
|
||||||
|
|
||||||
LIMITS
|
LIMITS
|
||||||
The number of arguments is not to exceed 100.
|
The number of arguments is not to exceed 100.
|
||||||
|
@@ -6861,7 +6861,7 @@ print '181: parsed test_ptr()';
|
|||||||
*/
|
*/
|
||||||
define test_newstring()
|
define test_newstring()
|
||||||
{
|
{
|
||||||
local A, B, C, D, S, p;
|
local A, B, C, D, S, p, q;
|
||||||
|
|
||||||
print '7700: Beginning test_newstring';
|
print '7700: Beginning test_newstring';
|
||||||
|
|
||||||
@@ -6953,7 +6953,14 @@ define test_newstring()
|
|||||||
print '7762: setbit(A, 16, 0);';
|
print '7762: setbit(A, 16, 0);';
|
||||||
vrfy(A == "A\255fdef", '7763: A == "A\255fdef"');
|
vrfy(A == "A\255fdef", '7763: A == "A\255fdef"');
|
||||||
|
|
||||||
print '7764: Ending test_newstring';
|
q = "curds" " and " "whey";
|
||||||
|
print '7764: q = "curds" " and " "whey"';
|
||||||
|
vrfy(q == "curds and whey", '7765: q == "curds and whey"');
|
||||||
|
q = "chongo" ' was ' "here";
|
||||||
|
print '7766: q = "chongo" \' was \' "here"';
|
||||||
|
vrfy(q == "chongo was here", '7767: q == "chongo was here"');
|
||||||
|
|
||||||
|
print '7768: Ending test_newstring';
|
||||||
}
|
}
|
||||||
print '182: parsed test_newstring()';
|
print '182: parsed test_newstring()';
|
||||||
|
|
||||||
@@ -7115,6 +7122,8 @@ print '188: parsed test_natnumset()';
|
|||||||
*/
|
*/
|
||||||
define test_somenew()
|
define test_somenew()
|
||||||
{
|
{
|
||||||
|
local a, s;
|
||||||
|
|
||||||
print '8200: Starting test_somenew';
|
print '8200: Starting test_somenew';
|
||||||
|
|
||||||
vrfy(char(-1) == char(255), '8201: char(-1) == char(255)');
|
vrfy(char(-1) == char(255), '8201: char(-1) == char(255)');
|
||||||
@@ -7139,7 +7148,11 @@ define test_somenew()
|
|||||||
vrfy(1/(1/0) == 0, '8215: 1/(1/0) == 0');
|
vrfy(1/(1/0) == 0, '8215: 1/(1/0) == 0');
|
||||||
vrfy(inverse(1/0) == 0, '8216: inverse(1/0) == 0');
|
vrfy(inverse(1/0) == 0, '8216: inverse(1/0) == 0');
|
||||||
|
|
||||||
print '8217: Ending test_somenew';
|
a = isqrt(2e1000); s = "xyz";
|
||||||
|
print '8217: a = isqrt(2e1000); s = "xyz";';
|
||||||
|
vrfy(hash(a,s) == 1916476840, '8218: hash(a,s) == 1916476840');
|
||||||
|
|
||||||
|
print '8219: Ending test_somenew';
|
||||||
}
|
}
|
||||||
print '189: parsed test_somenew()';
|
print '189: parsed test_somenew()';
|
||||||
|
|
||||||
@@ -7195,16 +7208,27 @@ print '1700: Beginning read test';
|
|||||||
value = 0;
|
value = 0;
|
||||||
vrfy(value == 0, '1701: value == 0');
|
vrfy(value == 0, '1701: value == 0');
|
||||||
read "test1700";
|
read "test1700";
|
||||||
vrfy(value == 1, '1702: value == 1');
|
print '1702: read "test1700";';
|
||||||
read -once "test1700";
|
|
||||||
vrfy(value == 1, '1703: value == 1');
|
vrfy(value == 1, '1703: value == 1');
|
||||||
|
read -once "test1700";
|
||||||
|
print '1704: read -once "test1700";';
|
||||||
|
vrfy(value == 1, '1705: value == 1');
|
||||||
read "test1700.cal";
|
read "test1700.cal";
|
||||||
vrfy(value == 2, '1704: value == 2');
|
print '1706: read "test1700.cal";';
|
||||||
|
vrfy(value == 2, '1707: value == 2');
|
||||||
read -once "test1700.cal";
|
read -once "test1700.cal";
|
||||||
vrfy(value == 2, '1705: value == 2');
|
print '1708: read -once "test1700.cal";';
|
||||||
|
vrfy(value == 2, '1709: value == 2');
|
||||||
read "test1700.cal";
|
read "test1700.cal";
|
||||||
vrfy(value == 3, '1706: value == 3');
|
print '1710: read "test1700.cal";';
|
||||||
print '1707: Ending read test';
|
vrfy(value == 3, '1711: value == 3');
|
||||||
|
{++value;} read "test1700.cal";
|
||||||
|
print '1712: {++value;} read "test1700.cal";';
|
||||||
|
vrfy(value == 5, '1713: value == 5');
|
||||||
|
{++value;} read -once "test1700.cal";
|
||||||
|
print '1714: {++value;} read -once "test1700.cal";';
|
||||||
|
vrfy(value == 6, '1715: value == 6');
|
||||||
|
print '1716: Ending read test';
|
||||||
|
|
||||||
print;
|
print;
|
||||||
return test_obj();
|
return test_obj();
|
||||||
@@ -7279,6 +7303,9 @@ print;
|
|||||||
return test_size();
|
return test_size();
|
||||||
print;
|
print;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5800 assignment tests
|
||||||
|
*/
|
||||||
return test_assign(5800, 1);
|
return test_assign(5800, 1);
|
||||||
define xy5800_assign(a,b) { };
|
define xy5800_assign(a,b) { };
|
||||||
print '5812: define xy5800_assign(a,b) { }';
|
print '5812: define xy5800_assign(a,b) { }';
|
||||||
@@ -7323,7 +7350,7 @@ X5800 = obj xy5800 = {1,2};
|
|||||||
print '5864: X5800 = obj xy5800 = {1,2}';
|
print '5864: X5800 = obj xy5800 = {1,2}';
|
||||||
vrfy(X5800 == (obj xy5800 = {1,2}),
|
vrfy(X5800 == (obj xy5800 = {1,2}),
|
||||||
'5865: X5800 == (obj xy5800 = {1,2})');
|
'5865: X5800 == (obj xy5800 = {1,2})');
|
||||||
print '5899: End of 5800 sequence';
|
print '5866: End of 5800 sequence';
|
||||||
|
|
||||||
print;
|
print;
|
||||||
return test_is();
|
return test_is();
|
||||||
@@ -7407,7 +7434,10 @@ print '8304: define h8300(x)=x^3;define i8300(x)=x-1;define j8300(x)=x+1;';
|
|||||||
vrfy(h8300(10) == 1000, '8305: h8300(10) == 1000');
|
vrfy(h8300(10) == 1000, '8305: h8300(10) == 1000');
|
||||||
vrfy(i8300(10) == 9, '8306: i8300(10) == 9');
|
vrfy(i8300(10) == 9, '8306: i8300(10) == 9');
|
||||||
vrfy(j8300(10) == 11, '8307: j8300(10) == 11');
|
vrfy(j8300(10) == 11, '8307: j8300(10) == 11');
|
||||||
print '8308: Ending define tests';
|
{static k8300 = 5} define l8300(x) = k8300 + x;
|
||||||
|
print '8308: {static k8300 = 5} define l8300(x) = k8300 + x;';
|
||||||
|
vrfy(l8300(10) == 15, '8309: l8300(10) == 15');
|
||||||
|
print '8310: Ending define tests';
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
64
seed.c
64
seed.c
@@ -86,6 +86,50 @@ typedef struct s_hash64 hash64;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FNV-1 basis
|
||||||
|
*
|
||||||
|
* We start the hash at a non-zero value at the beginning so that
|
||||||
|
* hashing blocks of data with all 0 bits do not map onto the same
|
||||||
|
* 0 hash value. The virgin value that we use below is the hash value
|
||||||
|
* that we would get from following 32 ASCII characters:
|
||||||
|
*
|
||||||
|
* chongo <Landon Curt Noll> /\../\
|
||||||
|
*
|
||||||
|
* Note that the \'s above are not back-slashing escape characters.
|
||||||
|
* They are literal ASCII backslash 0x5c characters.
|
||||||
|
*
|
||||||
|
* The effect of this virgin initial value is the same as starting
|
||||||
|
* with 0 and pre-pending those 32 characters onto the data being
|
||||||
|
* hashed.
|
||||||
|
*
|
||||||
|
* Yes, even with this non-zero virgin value there is a set of data
|
||||||
|
* that will result in a zero hash value. Worse, appending any
|
||||||
|
* about of zero bytes will continue to produce a zero hash value.
|
||||||
|
* But that would happen with any initial value so long as the
|
||||||
|
* hash of the initial was the `inverse' of the virgin prefix string.
|
||||||
|
*
|
||||||
|
* But then again for any hash function, there exists sets of data
|
||||||
|
* which that the hash of every member is the same value. That is
|
||||||
|
* life with many to few mapping functions. All we do here is to
|
||||||
|
* prevent sets whose members consist of 0 or more bytes of 0's from
|
||||||
|
* being such an awkward set.
|
||||||
|
*
|
||||||
|
* And yes, someone can figure out what the magic 'inverse' of the
|
||||||
|
* 32 ASCII character are ... but this hash function is NOT intended
|
||||||
|
* to be a cryptographic hash function, just a fast and reasonably
|
||||||
|
* good hash function.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_B64)
|
||||||
|
# define FNV1_64_BASIS ((hash64)(0xcbf29ce484222325ULL))
|
||||||
|
#else
|
||||||
|
# define FNV1_64_BASIS_0 ((USB32)0x2325)
|
||||||
|
# define FNV1_64_BASIS_1 ((USB32)0x8422)
|
||||||
|
# define FNV1_64_BASIS_2 ((USB32)0x9ce4)
|
||||||
|
# define FNV1_64_BASIS_3 ((USB32)0xcbf2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hash_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer
|
* hash_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer
|
||||||
*
|
*
|
||||||
@@ -116,24 +160,16 @@ hash_buf(char *buf, unsigned len)
|
|||||||
* (gsf@research.att.com).
|
* (gsf@research.att.com).
|
||||||
*
|
*
|
||||||
* See:
|
* See:
|
||||||
* http://reality.sgi.com/chongo/src/fnv/fnv_hash.tar.gz
|
* http://reality.sgi.com/chongo/tech/comp/fnv/index.html
|
||||||
* http://reality.sgi.com/chongo/src/fnv/h32.c
|
|
||||||
* http://reality.sgi.com/chongo/src/fnv/h64.c
|
|
||||||
*
|
*
|
||||||
* for information on 32bit and 64bit Fowler/Noll/Vo hashes.
|
* for information on 32bit and 64bit Fowler/Noll/Vo hashes.
|
||||||
*
|
*
|
||||||
* Landon Curt Noll (http://reality.sgi.com/chongo) later improved
|
* Landon Curt Noll (http://reality.sgi.com/chongo) later improved
|
||||||
* on their algorithm to come up with Fowler/Noll/Vo hash.
|
* on their algorithm to come up with Fowler/Noll/Vo hash.
|
||||||
*
|
|
||||||
* The 32 hash was able to process 234936 words from the web2 dictionary
|
|
||||||
* without any 32 bit collisions using a constant of
|
|
||||||
* 16777619 = 0x1000193.
|
|
||||||
*
|
|
||||||
* The 64 bit hash uses 1099511628211 = 0x100000001b3 instead.
|
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_B64)
|
#if defined(HAVE_B64)
|
||||||
/* hash each octet of the buffer */
|
/* hash each octet of the buffer */
|
||||||
for (hval = (hash64)0ULL; buf < buf_end; ++buf) {
|
for (hval = FNV1_64_BASIS; buf < buf_end; ++buf) {
|
||||||
|
|
||||||
/* multiply by 1099511628211ULL mod 2^64 using 64 bit longs */
|
/* multiply by 1099511628211ULL mod 2^64 using 64 bit longs */
|
||||||
hval *= (hash64)1099511628211ULL;
|
hval *= (hash64)1099511628211ULL;
|
||||||
@@ -145,7 +181,11 @@ hash_buf(char *buf, unsigned len)
|
|||||||
#else /* HAVE_B64 */
|
#else /* HAVE_B64 */
|
||||||
|
|
||||||
/* hash each octet of the buffer */
|
/* hash each octet of the buffer */
|
||||||
for (val[0]=val[1]=val[2]=val[3]=0; buf < buf_end; ++buf) {
|
val[0] = FNV1_64_BASIS_0;
|
||||||
|
val[1] = FNV1_64_BASIS_1;
|
||||||
|
val[2] = FNV1_64_BASIS_2;
|
||||||
|
val[3] = FNV1_64_BASIS_3;
|
||||||
|
for (; buf < buf_end; ++buf) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* multiply by 1099511628211 mod 2^64 using 32 bit longs
|
* multiply by 1099511628211 mod 2^64 using 32 bit longs
|
||||||
@@ -167,7 +207,7 @@ hash_buf(char *buf, unsigned len)
|
|||||||
val[0] = tmp[0] & 0xffff;
|
val[0] = tmp[0] & 0xffff;
|
||||||
tmp[2] += (tmp[1] >> 16);
|
tmp[2] += (tmp[1] >> 16);
|
||||||
val[1] = tmp[1] & 0xffff;
|
val[1] = tmp[1] & 0xffff;
|
||||||
val[3] += (tmp[2] >> 16);
|
val[3] = tmp[3] + (tmp[2] >> 16);
|
||||||
val[2] = tmp[2] & 0xffff;
|
val[2] = tmp[2] & 0xffff;
|
||||||
/*
|
/*
|
||||||
* Doing a val[3] &= 0xffff; is not really needed since it simply
|
* Doing a val[3] &= 0xffff; is not really needed since it simply
|
||||||
|
12
token.c
12
token.c
@@ -438,6 +438,18 @@ eatstring(int quotechar)
|
|||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
if (ch == quotechar) {
|
if (ch == quotechar) {
|
||||||
|
for (;;) {
|
||||||
|
ch = nextchar();
|
||||||
|
if (ch != ' ' && ch != '\t' &&
|
||||||
|
(ch != '\n' ||
|
||||||
|
newlines))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == '"' || ch == '\'') {
|
||||||
|
quotechar = ch;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
reread();
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
ch = '\0';
|
ch = '\0';
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#define MAJOR_VER 2 /* major version */
|
#define MAJOR_VER 2 /* major version */
|
||||||
#define MINOR_VER 11 /* minor version */
|
#define MINOR_VER 11 /* minor version */
|
||||||
#define MAJOR_PATCH 0 /* patch level or 0 if no patch */
|
#define MAJOR_PATCH 0 /* patch level or 0 if no patch */
|
||||||
#define MINOR_PATCH "8.2" /* test number or empty string if no patch */
|
#define MINOR_PATCH "8.4" /* test number or empty string if no patch */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calc version constants
|
* calc version constants
|
||||||
|
37
zmath.h
37
zmath.h
@@ -144,6 +144,43 @@ typedef SB32 LEN; /* unit of length storage */
|
|||||||
#endif /* LONG_BITS == 64 */
|
#endif /* LONG_BITS == 64 */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FNV-1 basis
|
||||||
|
*
|
||||||
|
* We start the hash at a non-zero value at the beginning so that
|
||||||
|
* hashing blocks of data with all 0 bits do not map onto the same
|
||||||
|
* 0 hash value. The virgin value that we use below is the hash value
|
||||||
|
* that we would get from following 32 ASCII characters:
|
||||||
|
*
|
||||||
|
* chongo <Landon Curt Noll> /\../\
|
||||||
|
*
|
||||||
|
* Note that the \'s above are not back-slashing escape characters.
|
||||||
|
* They are literal ASCII backslash 0x5c characters.
|
||||||
|
*
|
||||||
|
* The effect of this virgin initial value is the same as starting
|
||||||
|
* with 0 and pre-pending those 32 characters onto the data being
|
||||||
|
* hashed.
|
||||||
|
*
|
||||||
|
* Yes, even with this non-zero virgin value there is a set of data
|
||||||
|
* that will result in a zero hash value. Worse, appending any
|
||||||
|
* about of zero bytes will continue to produce a zero hash value.
|
||||||
|
* But that would happen with any initial value so long as the
|
||||||
|
* hash of the initial was the `inverse' of the virgin prefix string.
|
||||||
|
*
|
||||||
|
* But then again for any hash function, there exists sets of data
|
||||||
|
* which that the hash of every member is the same value. That is
|
||||||
|
* life with many to few mapping functions. All we do here is to
|
||||||
|
* prevent sets whose members consist of 0 or more bytes of 0's from
|
||||||
|
* being such an awkward set.
|
||||||
|
*
|
||||||
|
* And yes, someone can figure out what the magic 'inverse' of the
|
||||||
|
* 32 ASCII character are ... but this hash function is NOT intended
|
||||||
|
* to be a cryptographic hash function, just a fast and reasonably
|
||||||
|
* good hash function.
|
||||||
|
*/
|
||||||
|
#define FNV1_32_BASIS ((QCKHASH)(0x811c9dc5))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The largest power of 10 we will compute for our decimal conversion
|
* The largest power of 10 we will compute for our decimal conversion
|
||||||
* internal constants is: 10^(2^TEN_MAX).
|
* internal constants is: 10^(2^TEN_MAX).
|
||||||
|
Reference in New Issue
Block a user