summaryrefslogtreecommitdiff
path: root/winhelp.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2004-07-30 13:21:40 +0000
committerSimon Tatham <anakin@pobox.com>2004-07-30 13:21:40 +0000
commitf7eeb51d4e3e44f5bd46fcd19d5695540f084560 (patch)
treeca5ae678f058939c23129125423235c194591e35 /winhelp.c
parent8aac8532019ac6cee701d48ceb35473280219a0e (diff)
downloadhalibut-f7eeb51d4e3e44f5bd46fcd19d5695540f084560.zip
halibut-f7eeb51d4e3e44f5bd46fcd19d5695540f084560.tar.gz
halibut-f7eeb51d4e3e44f5bd46fcd19d5695540f084560.tar.bz2
halibut-f7eeb51d4e3e44f5bd46fcd19d5695540f084560.tar.xz
More careful context hash calculation which doesn't depend on size
of `unsigned long'. Should help Debian build problems (bug#259504). [originally from svn r4377]
Diffstat (limited to 'winhelp.c')
-rw-r--r--winhelp.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/winhelp.c b/winhelp.c
index c41503d..ec36031 100644
--- a/winhelp.c
+++ b/winhelp.c
@@ -376,10 +376,6 @@ static unsigned long context_hash(char *context)
"\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF";
unsigned long hash;
- /* Sanity check the size of unsigned long */
- enum { assertion = 1 /
- (((unsigned long)0xFFFFFFFF) + 2 == (unsigned long)1) };
-
/*
* The hash algorithm starts the hash at 0 and updates it with
* each character. Therefore, logically, the hash of an empty
@@ -396,7 +392,38 @@ static unsigned long context_hash(char *context)
*/
hash = 0;
while (*context) {
- hash = hash * 43 + bytemapping[(unsigned char)*context];
+ /*
+ * Be careful of overflowing `unsigned long', for maximum
+ * portability.
+ */
+
+ /*
+ * Multiply `hash' by 43.
+ */
+ {
+ unsigned long bottom, top;
+ bottom = (hash & 0xFFFFUL) * 43;
+ top = ((hash >> 16) & 0xFFFFUL) * 43;
+ top += (bottom >> 16);
+ bottom &= 0xFFFFUL;
+ top &= 0xFFFFUL;
+ hash = (top << 16) | bottom;
+ }
+
+ /*
+ * Add the mapping value for this byte to `hash'.
+ */
+ {
+ int val = bytemapping[(unsigned char)*context];
+
+ if (val > 0 && hash > (0xFFFFFFFFUL - val)) {
+ hash -= (0xFFFFFFFFUL - val) + 1;
+ } else if (val < 0 && hash < -val) {
+ hash += (0xFFFFFFFFUL + val) + 1;
+ } else
+ hash += val;
+ }
+
context++;
}
return hash;