This somehow got missed in my "put PDF before PostScript" sweep.
[sgt/halibut] / winhelp.c
index c41503d..7db4801 100644 (file)
--- 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 < (unsigned long)-val) {
+                hash += (0xFFFFFFFFUL + val) + 1;
+            } else
+                hash += val;
+        }
+
        context++;
     }
     return hash;
@@ -553,7 +580,7 @@ void whlp_browse_link(WHLP h, WHLP_TOPIC before, WHLP_TOPIC after)
 static void whlp_linkdata(WHLP h, int which, int c)
 {
     int *len = (which == 1 ? &h->link->len1 : &h->link->len2);
-    char *data = (which == 1 ? h->linkdata1 : h->linkdata2);
+    unsigned char *data = (which == 1 ? h->linkdata1 : h->linkdata2);
     assert(*len < TOPIC_BLKSIZE);
     data[(*len)++] = c;
 }
@@ -1248,7 +1275,7 @@ static void whlp_make_btree(struct file *f, int flags, int pagesize,
     int npages = 0, pagessize = 0;
     int npages_this_level, nentries, nlevels;
     int total_leaf_entries;
-    char btdata[MAX_PAGE_SIZE];
+    unsigned char btdata[MAX_PAGE_SIZE];
     int btlen;
     int page_start, fixups_offset, unused_bytes;
     void *element;