X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/f15300499bce37cd28ea2ace0f2bd1c364fc835e..2e78832ed88bc518b46e0b248d22da061bea46ed:/winhelp.c diff --git a/winhelp.c b/winhelp.c index c41503d..7db4801 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 < (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;