file, but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version. */
+/* With -DSTANDALONE, this file can be compiled outside Wget source
+ tree. To test, also use -DTEST. */
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <string.h>
+#include <limits.h>
-#include "wget.h"
-#include "utils.h"
-
-#include "hash.h"
-
-#ifdef STANDALONE
-# undef xmalloc
-# undef xrealloc
-# undef xfree
-
-# define xmalloc malloc
-# define xrealloc realloc
+#ifndef STANDALONE
+/* Get Wget's utility headers. */
+# include "wget.h"
+# include "utils.h"
+#else
+/* Make do without them. */
+# define xnew(x) xmalloc (sizeof (x))
+# define xnew_array(type, x) xmalloc (sizeof (type) * (x))
+# define xmalloc malloc /* or something that exits
+ if not enough memory */
# define xfree free
-
-# undef TOLOWER
+# define countof(x) (sizeof (x) / sizeof ((x)[0]))
# define TOLOWER(x) ('A' <= (x) && (x) <= 'Z' ? (x) - 32 : (x))
#endif
+#include "hash.h"
+
/* INTERFACE:
Hash tables are a technique used to implement mapping between
void *value;
};
-typedef unsigned long (*hashfun_t) PARAMS ((const void *));
-typedef int (*testfun_t) PARAMS ((const void *, const void *));
+typedef unsigned long (*hashfun_t) (const void *);
+typedef int (*testfun_t) (const void *, const void *);
struct hash_table {
hashfun_t hash_function;
-1. This is acceptable because it still allows the use of
nonnegative integer keys. */
-#define INVALID_PTR ((void *) ~(unsigned long)0)
+#define INVALID_PTR ((void *) ~0UL)
#ifndef UCHAR_MAX
# define UCHAR_MAX 0xff
#endif
static int
prime_size (int size, int *prime_offset)
{
- static const unsigned long primes [] = {
+ static const int primes[] = {
13, 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
- 1174703521, 1527114613, 1985248999,
- (unsigned long)0x99d43ea5, (unsigned long)0xc7fa5177
+ 1174703521, 1527114613, 1837299131, 2147483647
};
int i;
}
abort ();
- return 0;
}
-static unsigned long ptrhash PARAMS ((const void *));
-static int ptrcmp PARAMS ((const void *, const void *));
+static int cmp_pointer (const void *, const void *);
/* Create a hash table with hash function HASH_FUNCTION and test
function TEST_FUNCTION. The table is empty (its count is 0), but
int size;
struct hash_table *ht = xnew (struct hash_table);
- ht->hash_function = hash_function ? hash_function : ptrhash;
- ht->test_function = test_function ? test_function : ptrcmp;
+ ht->hash_function = hash_function ? hash_function : hash_pointer;
+ ht->test_function = test_function ? test_function : cmp_pointer;
/* If the size of struct hash_table ever becomes a concern, this
field can go. (Wget doesn't create many hashes.) */
/*assert (ht->resize_threshold >= items);*/
ht->mappings = xnew_array (struct mapping, ht->size);
+
/* Mark mappings as empty. We use 0xff rather than 0 to mark empty
keys because it allows us to use NULL/0 as keys. */
memset (ht->mappings, INVALID_PTR_BYTE, size * sizeof (struct mapping));
don't strictly belong to this file. However, this is as good a
place for them as any. */
-/* Rules for creating custom hash and test functions:
+/* Guidelines for creating custom hash and test functions:
- The test function returns non-zero for keys that are considered
"equal", zero otherwise.
We used to use the popular hash function from the Dragon Book, but
this one seems to perform much better. */
-unsigned long
-string_hash (const void *key)
+static unsigned long
+hash_string (const void *key)
{
const char *p = key;
unsigned int h = *p;
/* Frontend for strcmp usable for hash tables. */
-int
-string_cmp (const void *s1, const void *s2)
+static int
+cmp_string (const void *s1, const void *s2)
{
return !strcmp ((const char *)s1, (const char *)s2);
}
struct hash_table *
make_string_hash_table (int items)
{
- return hash_table_new (items, string_hash, string_cmp);
+ return hash_table_new (items, hash_string, cmp_string);
}
/*
*
*/
-/* Like string_hash, but produce the same hash regardless of the case. */
+/* Like hash_string, but produce the same hash regardless of the case. */
static unsigned long
-string_hash_nocase (const void *key)
+hash_string_nocase (const void *key)
{
const char *p = key;
unsigned int h = TOLOWER (*p);
struct hash_table *
make_nocase_string_hash_table (int items)
{
- return hash_table_new (items, string_hash_nocase, string_cmp_nocase);
+ return hash_table_new (items, hash_string_nocase, string_cmp_nocase);
}
/* Hashing of numeric values, such as pointers and integers.
spreading of values and doesn't need to know the hash table size to
work (unlike the very popular Knuth's multiplication hash). */
-static unsigned long
-ptrhash (const void *ptr)
+unsigned long
+hash_pointer (const void *ptr)
{
unsigned long key = (unsigned long)ptr;
key += (key << 12);
}
static int
-ptrcmp (const void *ptr1, const void *ptr2)
+cmp_pointer (const void *ptr1, const void *ptr2)
{
return ptr1 == ptr2;
}
\f
-#ifdef STANDALONE
+#ifdef TEST
#include <stdio.h>
#include <string.h>
#endif
return 0;
}
-#endif
+#endif /* TEST */