+ if (strcmp(list->token, token) == 0)
+ {
+ checked_free(list->value);
+
+ list->value = getStringCopy(value);
+
+ return list;
+ }
+ else if (list->next == NULL)
+ return (list->next = newSetupFileList(token, value));
+ else
+ return setListEntry(list->next, token, value);
+}
+
+SetupFileList *addListEntry(SetupFileList *list, char *token, char *value)
+{
+ if (list == NULL)
+ return NULL;
+
+ if (list->next == NULL)
+ return (list->next = newSetupFileList(token, value));
+ else
+ return addListEntry(list->next, token, value);
+}
+
+#ifdef DEBUG
+static void printSetupFileList(SetupFileList *list)
+{
+ if (!list)
+ return;
+
+ printf("token: '%s'\n", list->token);
+ printf("value: '%s'\n", list->value);
+
+ printSetupFileList(list->next);
+}
+#endif
+
+#ifdef DEBUG
+DEFINE_HASHTABLE_INSERT(insert_hash_entry, char, char);
+DEFINE_HASHTABLE_SEARCH(search_hash_entry, char, char);
+DEFINE_HASHTABLE_CHANGE(change_hash_entry, char, char);
+DEFINE_HASHTABLE_REMOVE(remove_hash_entry, char, char);
+#else
+#define insert_hash_entry hashtable_insert
+#define search_hash_entry hashtable_search
+#define change_hash_entry hashtable_change
+#define remove_hash_entry hashtable_remove
+#endif
+
+static unsigned int get_hash_from_key(void *key)
+{
+ /*
+ djb2
+
+ This algorithm (k=33) was first reported by Dan Bernstein many years ago in
+ 'comp.lang.c'. Another version of this algorithm (now favored by Bernstein)
+ uses XOR: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic of number 33 (why
+ it works better than many other constants, prime or not) has never been
+ adequately explained.
+
+ If you just want to have a good hash function, and cannot wait, djb2
+ is one of the best string hash functions i know. It has excellent
+ distribution and speed on many different sets of keys and table sizes.
+ You are not likely to do better with one of the "well known" functions
+ such as PJW, K&R, etc.
+
+ Ozan (oz) Yigit [http://www.cs.yorku.ca/~oz/hash.html]
+ */
+
+ char *str = (char *)key;
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
+}
+
+static int keys_are_equal(void *key1, void *key2)
+{
+ return (strcmp((char *)key1, (char *)key2) == 0);
+}
+
+SetupFileHash *newSetupFileHash()
+{
+ SetupFileHash *new_hash =
+ create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal);
+
+ if (new_hash == NULL)
+ Error(ERR_EXIT, "create_hashtable() failed -- out of memory");
+
+ return new_hash;
+}
+
+void freeSetupFileHash(SetupFileHash *hash)
+{
+ if (hash == NULL)
+ return;
+
+ hashtable_destroy(hash, 1); /* 1 == also free values stored in hash */