aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2021-09-15 17:04:21 +0200
committerToni Uhlig <matzeton@googlemail.com>2021-09-15 17:04:21 +0200
commit1fa53c5bf8d0717f784c79abaa5111f88ab00221 (patch)
tree5003411ee362757cb14882bd3d92c98ce8ce3dff /tests
parentc8bf38e5fb717d40635a2a89b22ed71b0de4266b (diff)
Squashed 'dependencies/uthash/' changes from 8e67ced..bf15263
bf15263 Fix a "bug" in the example where option 3 interfered with option 1's counter. b6e24ef Use `malloc(sizeof *s)` in example code. a109c6b Stop using `gets` in example.c. c85c9e1 fix: fix utstack example's compiling error 86e6776 Replace *.github.com urls with *.github.io (#227) e493aa9 Bump version to 2.3.0. ae2ac52 Fix README.md to display the *actual* TravisCI status. 134e241 Silence -Wswitch-default warnings, and add it to the TravisCI config. 62fefa6 Fix some typos in userguide.txt, and re-remove spaces in macro definitions. 37d2021 tests: add whitespaces to example code 524ca1a doc: add whitespaces to documentation 0f6c619 Fix a typo in the documentation for HASH_COUNT. NFC. 388134a Rename uthash_memcmp to HASH_KEYCMP, step 3. 053bed1 Eliminate HASH_FCN; change the handling of HASH_FUNCTION to match HASH_KEYCMP. f0e1bd9 Refactor test93.c to avoid scan-build warnings. 45af88c Remove two dead writes in tests, to silence scan-build warnings. 66e2668 Bump version to 2.2.0. 973bd67 uthash.h: Swap multiplicands to put the widest ones first. 15ad042 Always include <stdint.h>, unless HASH_NO_STDINT is defined by the user. 6b4768b Rename uthash_memcmp to HASH_KEYCMP, step 2. e64c7f0 Update tests/README to describe the most recently added tests. NFC. c62796c HASH_CLEAR after some tests, to eliminate "memory leak" warnings. 7f0aadb Support spaces in $exe path 0831d9a uthash.h: fix compiler warning -Wcast-qual ba2fbfd utarray.h: preserve constness in utarray_str_cpy git-subtree-dir: dependencies/uthash git-subtree-split: bf15263081be6229be31addd48566df93921cb46
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile2
-rw-r--r--tests/README9
-rw-r--r--tests/example.c86
-rw-r--r--tests/hashscan.c2
-rwxr-xr-xtests/keystats4
-rw-r--r--tests/test10.c3
-rw-r--r--tests/test6.c13
-rw-r--r--tests/test65.c2
-rw-r--r--tests/test76.c7
-rw-r--r--tests/test77.c4
-rw-r--r--tests/test88.ans20
-rw-r--r--tests/test88.c8
-rw-r--r--tests/test93.c37
-rw-r--r--tests/test96.ans40
-rw-r--r--tests/test96.c48
15 files changed, 187 insertions, 98 deletions
diff --git a/tests/Makefile b/tests/Makefile
index fcb751984..31f0cc240 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -12,7 +12,7 @@ PROGS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \
test66 test67 test68 test69 test70 test71 test72 test73 \
test74 test75 test76 test77 test78 test79 test80 test81 \
test82 test83 test84 test85 test86 test87 test88 test89 \
- test90 test91 test92 test93 test94 test95
+ test90 test91 test92 test93 test94 test95 test96
CFLAGS += -I$(HASHDIR)
#CFLAGS += -DHASH_BLOOM=16
#CFLAGS += -O2
diff --git a/tests/README b/tests/README
index fc25b9b41..a287de670 100644
--- a/tests/README
+++ b/tests/README
@@ -7,7 +7,7 @@ test2: make 10-item hash, lookup items with even keys, print
test3: make 10-item hash, delete items with even keys, print others
test4: 10 structs have dual hash handles, separate keys
test5: 10 structs have dual hash handles, lookup evens by alt key
-test6: test alt malloc macros (and alt memcmp macro)
+test6: test alt malloc macros (and alt key-comparison macro)
test7: test alt malloc macros with 1000 structs so bucket expansion occurs
test8: test num_items counter in UT_hash_handle
test9: test "find" after bucket expansion
@@ -89,10 +89,15 @@ test84: test HASH_REPLACE_STR with char* key
test85: test HASH_OVERHEAD on null and non null hash
test86: test *_APPEND_ELEM / *_PREPEND_ELEM (Thilo Schulz)
test87: test HASH_ADD_INORDER() macro (Thilo Schulz)
-test88: test alt memcmp and strlen macros
+test88: test alt key-comparison and strlen macros
test89: test code from the tinydtls project
test90: regression-test HASH_ADD_KEYPTR_INORDER (IronBug)
test91: test LL_INSERT_INORDER etc.
+test92: HASH_NONFATAL_OOM
+test93: alt_fatal
+test94: utlist with fields named other than 'next' and 'prev'
+test95: utstack
+test96: HASH_FUNCTION + HASH_KEYCMP
Other Make targets
================================================================================
diff --git a/tests/example.c b/tests/example.c
index a85f422d4..99263027f 100644
--- a/tests/example.c
+++ b/tests/example.c
@@ -1,25 +1,25 @@
-#include <stdio.h> /* gets */
+#include <stdio.h> /* printf */
#include <stdlib.h> /* atoi, malloc */
#include <string.h> /* strcpy */
#include "uthash.h"
struct my_struct {
int id; /* key */
- char name[10];
+ char name[21];
UT_hash_handle hh; /* makes this structure hashable */
};
struct my_struct *users = NULL;
-void add_user(int user_id, char *name)
+void add_user(int user_id, const char *name)
{
struct my_struct *s;
HASH_FIND_INT(users, &user_id, s); /* id already in the hash? */
- if (s==NULL) {
- s = (struct my_struct*)malloc(sizeof(struct my_struct));
+ if (s == NULL) {
+ s = (struct my_struct*)malloc(sizeof *s);
s->id = user_id;
- HASH_ADD_INT( users, id, s ); /* id: name of key field */
+ HASH_ADD_INT(users, id, s); /* id is the key field */
}
strcpy(s->name, name);
}
@@ -28,23 +28,24 @@ struct my_struct *find_user(int user_id)
{
struct my_struct *s;
- HASH_FIND_INT( users, &user_id, s ); /* s: output pointer */
+ HASH_FIND_INT(users, &user_id, s); /* s: output pointer */
return s;
}
void delete_user(struct my_struct *user)
{
- HASH_DEL( users, user); /* user: pointer to deletee */
+ HASH_DEL(users, user); /* user: pointer to deletee */
free(user);
}
void delete_all()
{
- struct my_struct *current_user, *tmp;
+ struct my_struct *current_user;
+ struct my_struct *tmp;
HASH_ITER(hh, users, current_user, tmp) {
- HASH_DEL(users,current_user); /* delete it (users advances to next) */
- free(current_user); /* free it */
+ HASH_DEL(users, current_user); /* delete it (users advances to next) */
+ free(current_user); /* free it */
}
}
@@ -52,41 +53,45 @@ void print_users()
{
struct my_struct *s;
- for(s=users; s != NULL; s=(struct my_struct*)(s->hh.next)) {
+ for (s = users; s != NULL; s = (struct my_struct*)(s->hh.next)) {
printf("user id %d: name %s\n", s->id, s->name);
}
}
-int name_sort(struct my_struct *a, struct my_struct *b)
+int by_name(const struct my_struct *a, const struct my_struct *b)
{
- return strcmp(a->name,b->name);
+ return strcmp(a->name, b->name);
}
-int id_sort(struct my_struct *a, struct my_struct *b)
+int by_id(const struct my_struct *a, const struct my_struct *b)
{
return (a->id - b->id);
}
-void sort_by_name()
+const char *getl(const char *prompt)
{
- HASH_SORT(users, name_sort);
-}
-
-void sort_by_id()
-{
- HASH_SORT(users, id_sort);
+ static char buf[21];
+ char *p;
+ printf("%s? ", prompt); fflush(stdout);
+ p = fgets(buf, sizeof(buf), stdin);
+ if (p == NULL || (p = strchr(buf, '\n')) == NULL) {
+ puts("Invalid input!");
+ exit(EXIT_FAILURE);
+ }
+ *p = '\0';
+ return buf;
}
int main()
{
- char in[10];
- int id=1, running=1;
+ int id = 1;
+ int running = 1;
struct my_struct *s;
- unsigned num_users;
+ int temp;
while (running) {
printf(" 1. add user\n");
- printf(" 2. add/rename user by id\n");
+ printf(" 2. add or rename user by id\n");
printf(" 3. find user\n");
printf(" 4. delete user\n");
printf(" 5. delete all users\n");
@@ -95,27 +100,20 @@ int main()
printf(" 8. print users\n");
printf(" 9. count users\n");
printf("10. quit\n");
- gets(in);
- switch(atoi(in)) {
+ switch (atoi(getl("Command"))) {
case 1:
- printf("name?\n");
- add_user(id++, gets(in));
+ add_user(id++, getl("Name (20 char max)"));
break;
case 2:
- printf("id?\n");
- gets(in);
- id = atoi(in);
- printf("name?\n");
- add_user(id, gets(in));
+ temp = atoi(getl("ID"));
+ add_user(temp, getl("Name (20 char max)"));
break;
case 3:
- printf("id?\n");
- s = find_user(atoi(gets(in)));
+ s = find_user(atoi(getl("ID to find")));
printf("user: %s\n", s ? s->name : "unknown");
break;
case 4:
- printf("id?\n");
- s = find_user(atoi(gets(in)));
+ s = find_user(atoi(getl("ID to delete")));
if (s) {
delete_user(s);
} else {
@@ -126,20 +124,20 @@ int main()
delete_all();
break;
case 6:
- sort_by_name();
+ HASH_SORT(users, by_name);
break;
case 7:
- sort_by_id();
+ HASH_SORT(users, by_id);
break;
case 8:
print_users();
break;
case 9:
- num_users=HASH_COUNT(users);
- printf("there are %u users\n", num_users);
+ temp = HASH_COUNT(users);
+ printf("there are %d users\n", temp);
break;
case 10:
- running=0;
+ running = 0;
break;
}
}
diff --git a/tests/hashscan.c b/tests/hashscan.c
index c487d9cee..d18b364ef 100644
--- a/tests/hashscan.c
+++ b/tests/hashscan.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005-2018, Troy D. Hanson http://troydhanson.github.com/uthash/
+Copyright (c) 2005-2021, Troy D. Hanson http://troydhanson.github.io/uthash/
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/tests/keystats b/tests/keystats
index 9d4076278..9c6bf5b16 100755
--- a/tests/keystats
+++ b/tests/keystats
@@ -12,9 +12,11 @@ sub usage {
usage if ((@ARGV == 0) or ($ARGV[0] eq '-h'));
-my @exes = glob "$FindBin::Bin/keystat.???";
+my @exes = glob "'$FindBin::Bin/keystat.???'";
+
my %stats;
for my $exe (@exes) {
+ $exe =~ s/\ /\\ /g;
$stats{$exe} = `$exe @ARGV`;
delete $stats{$exe} if ($? != 0); # omit hash functions that fail to produce stats (nx)
}
diff --git a/tests/test10.c b/tests/test10.c
index 64f8035e2..edf80d4a1 100644
--- a/tests/test10.c
+++ b/tests/test10.c
@@ -47,5 +47,8 @@ int main()
HASH_FIND(alth,altusers,&i,sizeof(int),tmp);
printf("%d %s in alth\n", i, (tmp != NULL) ? "found" : "not found");
+ HASH_CLEAR(hh, users);
+ HASH_CLEAR(alth, altusers);
+
return 0;
}
diff --git a/tests/test6.c b/tests/test6.c
index 55ce36bfb..919afa8e1 100644
--- a/tests/test6.c
+++ b/tests/test6.c
@@ -7,15 +7,16 @@
/* Set up macros for alternative malloc/free functions */
#undef uthash_malloc
#undef uthash_free
-#undef uthash_memcmp
#undef uthash_strlen
#undef uthash_bzero
#define uthash_malloc(sz) alt_malloc(sz)
#define uthash_free(ptr,sz) alt_free(ptr,sz)
-#define uthash_memcmp(a,b,n) alt_memcmp(a,b,n)
#define uthash_strlen(s) ..fail_to_compile..
#define uthash_bzero(a,n) alt_bzero(a,n)
+#undef HASH_KEYCMP
+#define HASH_KEYCMP(a,b,n) alt_keycmp(a,b,n)
+
typedef struct example_user_t {
int id;
int cookie;
@@ -41,10 +42,10 @@ static void alt_free(void *ptr, size_t sz)
free(ptr);
}
-static int alt_memcmp_count = 0;
-static int alt_memcmp(const void *a, const void *b, size_t n)
+static int alt_keycmp_count = 0;
+static int alt_keycmp(const void *a, const void *b, size_t n)
{
- ++alt_memcmp_count;
+ ++alt_keycmp_count;
return memcmp(a,b,n);
}
@@ -115,7 +116,7 @@ int main()
#else
assert(alt_bzero_count == 2);
#endif
- assert(alt_memcmp_count == 10);
+ assert(alt_keycmp_count == 10);
assert(alt_malloc_balance == 0);
return 0;
}
diff --git a/tests/test65.c b/tests/test65.c
index c863d21db..0584fb1a0 100644
--- a/tests/test65.c
+++ b/tests/test65.c
@@ -3,7 +3,7 @@
#include "uthash.h"
// this is an example of how to do a LRU cache in C using uthash
-// http://troydhanson.github.com/uthash/
+// http://troydhanson.github.io/uthash/
// by Jehiah Czebotar 2011 - jehiah@gmail.com
// this code is in the public domain http://unlicense.org/
diff --git a/tests/test76.c b/tests/test76.c
index a18685cae..ee890f6a2 100644
--- a/tests/test76.c
+++ b/tests/test76.c
@@ -8,8 +8,8 @@ int main()
char V_NeedleStr[] = "needle\0s";
long *V_KMP_Table;
long V_FindPos;
- size_t V_StartPos;
- size_t V_FindCnt;
+ size_t V_StartPos = 0;
+ size_t V_FindCnt = 0;
utstring_new(s);
@@ -24,9 +24,6 @@ int main()
if (V_KMP_Table != NULL) {
_utstring_BuildTable(utstring_body(t), utstring_len(t), V_KMP_Table);
- V_FindCnt = 0;
- V_FindPos = 0;
- V_StartPos = 0;
do {
V_FindPos = _utstring_find(utstring_body(s) + V_StartPos,
utstring_len(s) - V_StartPos,
diff --git a/tests/test77.c b/tests/test77.c
index 7ff97518e..dc55cb244 100644
--- a/tests/test77.c
+++ b/tests/test77.c
@@ -9,7 +9,7 @@ int main()
long *V_KMP_Table;
long V_FindPos;
size_t V_StartPos;
- size_t V_FindCnt;
+ size_t V_FindCnt = 0;
utstring_new(s);
@@ -24,8 +24,6 @@ int main()
if (V_KMP_Table != NULL) {
_utstring_BuildTableR(utstring_body(t), utstring_len(t), V_KMP_Table);
- V_FindCnt = 0;
- V_FindPos = 0;
V_StartPos = utstring_len(s) - 1;
do {
V_FindPos = _utstring_findR(utstring_body(s),
diff --git a/tests/test88.ans b/tests/test88.ans
index 6f35d6e98..7d0129407 100644
--- a/tests/test88.ans
+++ b/tests/test88.ans
@@ -9,22 +9,22 @@ alt_strlen
alt_strlen
alt_strlen
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
alt_strlen
-alt_memcmp
+alt_keycmp
diff --git a/tests/test88.c b/tests/test88.c
index 46f3ee76f..d7a454a0f 100644
--- a/tests/test88.c
+++ b/tests/test88.c
@@ -8,9 +8,9 @@
/* This is mostly a copy of test6.c. */
-#undef uthash_memcmp
+#undef HASH_KEYCMP
#undef uthash_strlen
-#define uthash_memcmp(a,b,n) alt_memcmp(a,b,n)
+#define HASH_KEYCMP(a,b,n) alt_keycmp(a,b,n)
#define uthash_strlen(s) alt_strlen(s)
typedef struct example_user_t {
@@ -19,9 +19,9 @@ typedef struct example_user_t {
UT_hash_handle hh;
} example_user_t;
-static int alt_memcmp(const void *a, const void *b, size_t n)
+static int alt_keycmp(const void *a, const void *b, size_t n)
{
- puts("alt_memcmp");
+ puts("alt_keycmp");
return memcmp(a,b,n);
}
diff --git a/tests/test93.c b/tests/test93.c
index 4afe7d51e..81103a1a7 100644
--- a/tests/test93.c
+++ b/tests/test93.c
@@ -39,43 +39,39 @@ static void alt_fatal(char const * s) {
longjmp(j_buf, 1);
}
-static example_user_t * init_user(int need_malloc_cnt) {
- users = 0;
+static void init_users(int need_malloc_cnt) {
+ users = NULL;
example_user_t * user = (example_user_t*)malloc(sizeof(example_user_t));
user->id = user_id;
is_fatal = 0;
malloc_cnt = need_malloc_cnt;
- /* printf("adding to hash...\n"); */
if (!setjmp(j_buf)) {
HASH_ADD_INT(users, id, user);
+ } else {
+ free(user);
}
- return user;
}
int main()
{
+ example_user_t *user;
-#define init(a) do { \
-} while(0)
-
- example_user_t * user;
-
- user = init_user(3); /* bloom filter must fail */
+ init_users(3); /* bloom filter must fail */
if (!is_fatal) {
printf("fatal not called after bloom failure\n");
}
- user = init_user(2); /* bucket creation must fail */
+ init_users(2); /* bucket creation must fail */
if (!is_fatal) {
printf("fatal not called after bucket creation failure\n");
}
- user = init_user(1); /* table creation must fail */
+ init_users(1); /* table creation must fail */
if (!is_fatal) {
printf("fatal not called after table creation failure\n");
}
- user = init_user(4); /* hash must create OK */
+ init_users(4); /* hash must create OK */
if (is_fatal) {
printf("fatal error when creating hash normally\n");
/* bad idea to continue running */
@@ -83,19 +79,20 @@ int main()
}
/* let's add users until expansion fails */
- users = 0;
+ users = NULL;
malloc_cnt = 4;
while (1) {
- user = (example_user_t*)malloc(sizeof(example_user_t));
- user->id = user_id;
if (user_id++ == 1000) {
printf("there is no way 1000 iterations didn't require realloc\n");
break;
}
+ user = (example_user_t*)malloc(sizeof(example_user_t));
+ user->id = user_id;
if (!setjmp(j_buf)) {
HASH_ADD_INT(users, id, user);
+ } else {
+ free(user);
}
- malloc_cnt = 0;
if (malloc_failed) {
if (!is_fatal) {
@@ -108,12 +105,12 @@ int main()
/* we can't really do anything, the hash is not in consistent
* state, so assume this is a success. */
break;
-
}
+ malloc_cnt = 0;
}
- printf("End\n");
+ HASH_CLEAR(hh, users);
+ printf("End\n");
return 0;
-
}
diff --git a/tests/test96.ans b/tests/test96.ans
new file mode 100644
index 000000000..64556d9f8
--- /dev/null
+++ b/tests/test96.ans
@@ -0,0 +1,40 @@
+time 56 not found, inserting it
+time 7 not found, inserting it
+time 10 not found, inserting it
+time 39 not found, inserting it
+time 82 found with value 10
+time 15 found with value 39
+time 31 found with value 7
+time 26 not found, inserting it
+time 51 found with value 39
+time 83 not found, inserting it
+time 46 found with value 10
+time 92 found with value 56
+time 49 not found, inserting it
+time 25 found with value 49
+time 80 found with value 56
+time 54 not found, inserting it
+time 97 found with value 49
+time 9 not found, inserting it
+time 34 found with value 10
+time 86 found with value 26
+time 87 found with value 39
+time 28 not found, inserting it
+time 13 found with value 49
+time 91 found with value 7
+time 95 found with value 83
+time 63 found with value 39
+time 71 found with value 83
+time 100 found with value 28
+time 44 found with value 56
+time 42 found with value 54
+time 16 found with value 28
+time 32 found with value 56
+time 6 found with value 54
+time 85 found with value 49
+time 40 found with value 28
+time 20 found with value 56
+time 18 found with value 54
+time 99 found with value 39
+time 22 found with value 10
+time 1 found with value 49
diff --git a/tests/test96.c b/tests/test96.c
new file mode 100644
index 000000000..700bdcf30
--- /dev/null
+++ b/tests/test96.c
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define HASH_FUNCTION(a,n,hv) (hv = clockface_hash(*(const int*)(a)))
+#define HASH_KEYCMP(a,b,n) clockface_neq(*(const int*)(a), *(const int*)(b))
+
+#include "uthash.h"
+
+struct clockface {
+ int time;
+ UT_hash_handle hh;
+};
+
+int clockface_hash(int time)
+{
+ return (time % 4);
+}
+
+int clockface_neq(int t1, int t2)
+{
+ return ((t1 % 12) != (t2 % 12));
+}
+
+int main()
+{
+ int random_data[] = {
+ 56, 7, 10, 39, 82, 15, 31, 26, 51, 83,
+ 46, 92, 49, 25, 80, 54, 97, 9, 34, 86,
+ 87, 28, 13, 91, 95, 63, 71, 100, 44, 42,
+ 16, 32, 6, 85, 40, 20, 18, 99, 22, 1
+ };
+
+ struct clockface *times = NULL;
+ for (int i=0; i < 40; ++i) {
+ struct clockface *elt = (struct clockface *)malloc(sizeof(*elt));
+ struct clockface *found = NULL;
+ elt->time = random_data[i];
+ HASH_FIND_INT(times, &elt->time, found);
+ if (found) {
+ printf("time %d found with value %d\n", elt->time, found->time);
+ } else {
+ printf("time %d not found, inserting it\n", elt->time);
+ HASH_ADD_INT(times, time, elt);
+ }
+ }
+
+ return 0;
+}