X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/d7482997dd1ca71b70df43c15dd5956f435a1a7e..b7d319499197dd884b12521ede60ec06b5f52633:/winhelp.c diff --git a/winhelp.c b/winhelp.c index 005409e..7db4801 100644 --- a/winhelp.c +++ b/winhelp.c @@ -83,12 +83,13 @@ #define smalloc malloc #define srealloc realloc #define sfree free -#define mknew(type) ( (type *) smalloc (sizeof (type)) ) -#define mknewa(type, number) ( (type *) smalloc ((number) * sizeof (type)) ) -#define resize(array, len) ( srealloc ((array), (len) * sizeof (*(array))) ) +#define snew(type) ( (type *) smalloc (sizeof (type)) ) +#define snewn(number, type) ( (type *) smalloc ((number) * sizeof (type)) ) +#define sresize(array, len, type) \ + ( (type *) srealloc ((array), (len) * sizeof (type)) ) #define lenof(array) ( sizeof(array) / sizeof(*(array)) ) char *dupstr(char *s) { - char *r = mknewa(char, 1+strlen(s)); strcpy(r,s); return r; + char *r = snewn(1+strlen(s), char); strcpy(r,s); return r; } #endif @@ -375,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 @@ -395,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; @@ -403,7 +431,7 @@ static unsigned long context_hash(char *context) WHLP_TOPIC whlp_register_topic(WHLP h, char *context_name, char **clash) { - context *ctx = mknew(context); + context *ctx = snew(context); context *otherctx; /* @@ -463,7 +491,7 @@ void whlp_prepare(WHLP h) while ( (ctx = index234(h->pre_contexts, 0)) != NULL ) { delpos234(h->pre_contexts, 0); - ctx->name = mknewa(char, 20); + ctx->name = snewn(20, char); do { sprintf(ctx->name, "t%08d", ctx_num++); ctx->hash = context_hash(ctx->name); @@ -485,7 +513,7 @@ char *whlp_topic_id(WHLP_TOPIC topic) void whlp_begin_topic(WHLP h, WHLP_TOPIC topic, char *title, ...) { - struct topiclink *link = mknew(struct topiclink); + struct topiclink *link = snew(struct topiclink); int len, slen; char *macro; va_list ap; @@ -501,7 +529,7 @@ void whlp_begin_topic(WHLP h, WHLP_TOPIC topic, char *title, ...) link->recordtype = 2; /* topic header */ link->len1 = 4*7; /* standard linkdata1 size */ - link->data1 = mknewa(unsigned char, link->len1); + link->data1 = snewn(link->len1, unsigned char); slen = strlen(title); assert(slen+1 <= TOPIC_BLKSIZE); @@ -519,7 +547,7 @@ void whlp_begin_topic(WHLP h, WHLP_TOPIC topic, char *title, ...) len--; /* lose the last \0 on the last macro */ link->len2 = len; - link->data2 = mknewa(unsigned char, link->len2); + link->data2 = snewn(link->len2, unsigned char); memcpy(link->data2, h->linkdata2, link->len2); topic->title = dupstr(title); @@ -552,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; } @@ -643,7 +671,7 @@ void whlp_set_tabstop(WHLP h, int tabstop, int alignment) if (alignment == WHLP_ALIGN_RIGHT) tabstop |= 0x10000; - p = mknew(int); + p = snew(int); *p = tabstop; add234(h->tabstops, p); h->para_flags |= 0x0200; @@ -651,7 +679,7 @@ void whlp_set_tabstop(WHLP h, int tabstop, int alignment) void whlp_begin_para(WHLP h, int para_type) { - struct topiclink *link = mknew(struct topiclink); + struct topiclink *link = snew(struct topiclink); int i; /* @@ -800,10 +828,10 @@ void whlp_end_para(WHLP h) whlp_linkdata_cslong(h, 1, data1cut); whlp_linkdata_cushort(h, 1, h->link->len2); - h->link->data1 = mknewa(unsigned char, h->link->len1); + h->link->data1 = snewn(h->link->len1, unsigned char); memcpy(h->link->data1, h->linkdata1 + data1cut, h->link->len1 - data1cut); memcpy(h->link->data1 + h->link->len1 - data1cut, h->linkdata1, data1cut); - h->link->data2 = mknewa(unsigned char, h->link->len2); + h->link->data2 = snewn(h->link->len2, unsigned char); memcpy(h->link->data2, h->linkdata2, h->link->len2); addpos234(h->text, h->link, count234(h->text)); @@ -870,12 +898,12 @@ static void whlp_topic_layout(WHLP h) /* * Create a final TOPICLINK containing no usable data. */ - link = mknew(struct topiclink); + link = snew(struct topiclink); link->nexttopic = NULL; if (h->prevtopic) h->prevtopic->nexttopic = link; h->prevtopic = link; - link->data1 = mknewa(unsigned char, 0x1c); + link->data1 = snewn(0x1c, unsigned char); link->block_size = 0; link->data2 = NULL; link->len1 = 0x1c; @@ -1043,7 +1071,7 @@ static void whlp_topic_layout(WHLP h) void whlp_index_term(WHLP h, char *index, WHLP_TOPIC topic) { - struct indexrec *idx = mknew(struct indexrec); + struct indexrec *idx = snew(struct indexrec); idx->term = dupstr(index); idx->topic = topic; @@ -1168,7 +1196,7 @@ int whlp_create_font(WHLP h, char *font, int family, int halfpoints, sfree(fontname); } - fontdesc = mknew(struct fontdesc); + fontdesc = snew(struct fontdesc); fontdesc->font = font; fontdesc->family = family; fontdesc->halfpoints = halfpoints; @@ -1247,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; @@ -1302,7 +1330,7 @@ static void whlp_make_btree(struct file *f, int flags, int pagesize, npages_this_level++; if (npages >= pagessize) { pagessize = npages + 32; - page_elements = resize(page_elements, pagessize); + page_elements = sresize(page_elements, pagessize, void *); } page_elements[npages++] = element; @@ -1388,7 +1416,7 @@ static void whlp_make_btree(struct file *f, int flags, int pagesize, npages_this_level++; if (npages >= pagessize) { pagessize = npages + 32; - page_elements = resize(page_elements, pagessize); + page_elements = sresize(page_elements, pagessize, void *); } page_elements[npages++] = page_elements[current]; @@ -1458,7 +1486,7 @@ static void whlp_make_btree(struct file *f, int flags, int pagesize, static struct file *whlp_new_file(WHLP h, char *name) { struct file *f; - f = mknew(struct file); + f = snew(struct file); f->data = NULL; f->pos = f->len = f->size = 0; if (name) { @@ -1481,7 +1509,7 @@ static void whlp_file_add(struct file *f, const void *data, int len) { if (f->pos + len > f->size) { f->size = f->pos + len + 1024; - f->data = resize(f->data, f->size); + f->data = sresize(f->data, f->size, unsigned char); } memcpy(f->data + f->pos, data, len); f->pos += len; @@ -1514,7 +1542,7 @@ static void whlp_file_fill(struct file *f, int len) { if (f->pos + len > f->size) { f->size = f->pos + len + 1024; - f->data = resize(f->data, f->size); + f->data = sresize(f->data, f->size, unsigned char); } memset(f->data + f->pos, 0, len); f->pos += len; @@ -1541,7 +1569,7 @@ WHLP whlp_new(void) WHLP ret; struct file *f; - ret = mknew(struct WHLP_tag); + ret = snew(struct WHLP_tag); /* * Internal B-trees.