diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2024-10-17 12:16:20 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2024-10-17 12:16:20 +0200 |
commit | 9a14454d3c5589373253571cee7428c593adefd9 (patch) | |
tree | 2ebd3c81ca4594ed2c9b1267a7af31d8cd1646e9 | |
parent | 1fa53c5bf8d0717f784c79abaa5111f88ab00221 (diff) |
Squashed 'dependencies/uthash/' changes from bf152630..f69112c0
f69112c0 utarray: Fix typo in docs
619fe95c Fix MSVC warning C4127 in HASH_BLOOM_TEST (#261)
eeba1961 uthash: Improve the docs for HASH_ADD_INORDER
ca98384c HASH_DEL should be able to delete a const-qualified node
095425f7 utlist: Add one more assertion in DL_DELETE2
399bf74b utarray: Stop making `oom` a synonym for `utarray_oom`
85bf75ab utarray_str_cpy: Remove strdup; utarray_oom() if strdup fails.
1a53f304 GitHub CI: Also test building the docs (#248)
4d01591e The MCST Elbrus C Compiler supports __typeof. (#247)
1e0baf06 CI: Add GitHub Actions CI
8844b529 Update test57.c per a suggestion by @mark-summerfield
44a66fe8 Update http:// URLs to https://, and copyright dates to 2022. NFC.
git-subtree-dir: dependencies/uthash
git-subtree-split: f69112c04f1b6e059b8071cb391a1fcc83791a00
-rw-r--r-- | .github/workflows/build.yml | 41 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | doc/index.html | 6 | ||||
-rw-r--r-- | doc/license.html | 4 | ||||
-rw-r--r-- | doc/userguide.txt | 46 | ||||
-rw-r--r-- | doc/utarray.txt | 2 | ||||
-rw-r--r-- | src/utarray.h | 18 | ||||
-rw-r--r-- | src/uthash.h | 16 | ||||
-rw-r--r-- | src/utlist.h | 7 | ||||
-rw-r--r-- | src/utringbuffer.h | 2 | ||||
-rw-r--r-- | src/utstack.h | 2 | ||||
-rw-r--r-- | src/utstring.h | 2 | ||||
-rw-r--r-- | tests/Makefile | 2 | ||||
-rw-r--r-- | tests/README | 1 | ||||
-rw-r--r-- | tests/hashscan.c | 2 | ||||
-rw-r--r-- | tests/test57.ans | 1 | ||||
-rw-r--r-- | tests/test57.c | 59 | ||||
-rw-r--r-- | tests/test65.c | 2 | ||||
-rw-r--r-- | tests/test97.ans | 0 | ||||
-rw-r--r-- | tests/test97.c | 57 |
21 files changed, 200 insertions, 73 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..3438b0797 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: build # This name shows up in badge.svg + +on: + push: # any branch + pull_request: + branches: [ "master" ] + +jobs: + build-gcc: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - run: make -C tests EXTRA_CFLAGS="-W -Wall -Wextra -Wswitch-default" + - run: make -C tests clean ; make -C tests pedantic + - run: make -C tests clean ; make -C tests pedantic EXTRA_CFLAGS=-DNO_DECLTYPE + - run: make -C tests clean ; make -C tests cplusplus + - run: make -C tests clean ; make -C tests cplusplus EXTRA_CFLAGS=-DNO_DECLTYPE + build-clang: + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + env: + CC: clang + CXX: clang++ + steps: + - uses: actions/checkout@v3 + - run: make -C tests EXTRA_CFLAGS="-W -Wall -Wextra -Wswitch-default" + - run: make -C tests clean ; make -C tests pedantic + - run: make -C tests clean ; make -C tests pedantic EXTRA_CFLAGS=-DNO_DECLTYPE + - run: make -C tests clean ; make -C tests cplusplus + - run: make -C tests clean ; make -C tests cplusplus EXTRA_CFLAGS=-DNO_DECLTYPE + build-asciidoc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: sudo apt-get update && sudo apt-get install asciidoc -y + - run: make -C doc @@ -1,4 +1,4 @@ -Copyright (c) 2005-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2005-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1,5 +1,6 @@ [](https://travis-ci.org/troydhanson/uthash) +[](https://github.com/troydhanson/uthash/actions/workflows/build.yml) Documentation for uthash is available at: diff --git a/doc/index.html b/doc/index.html index 2f86ba1dc..fe00bd845 100644 --- a/doc/index.html +++ b/doc/index.html @@ -13,8 +13,8 @@ </div> <!-- banner --> <div id="topnav"> - <a href="http://github.com/troydhanson/uthash">GitHub page</a> > - uthash home <!-- http://troydhanson.github.io/uthash/ --> + <a href="https://github.com/troydhanson/uthash">GitHub page</a> > + uthash home <!-- https://troydhanson.github.io/uthash/ --> <a href="https://twitter.com/share" class="twitter-share-button" data-via="troydhanson">Tweet</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> @@ -43,7 +43,7 @@ <h2>developer</h2> - <div><a href="http://troydhanson.github.io/">Troy D. Hanson</a></div> + <div><a href="https://troydhanson.github.io/">Troy D. Hanson</a></div> <h2>maintainer</h2> <div><a href="https://github.com/Quuxplusone">Arthur O'Dwyer</a></div> diff --git a/doc/license.html b/doc/license.html index 9a4b9ef35..a179d19a7 100644 --- a/doc/license.html +++ b/doc/license.html @@ -13,7 +13,7 @@ </div> <!-- banner --> <div id="topnav"> - <a href="http://troydhanson.github.io/uthash/">uthash home</a> > + <a href="https://troydhanson.github.io/uthash/">uthash home</a> > BSD license </div> @@ -21,7 +21,7 @@ <div id="mid"> <div id="main"> <pre> -Copyright (c) 2005-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2005-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/doc/userguide.txt b/doc/userguide.txt index 39fa7d1ed..09970d932 100644 --- a/doc/userguide.txt +++ b/doc/userguide.txt @@ -5,7 +5,7 @@ v2.3.0, February 2021 To download uthash, follow this link back to the https://github.com/troydhanson/uthash[GitHub project page]. -Back to my http://troydhanson.github.io/[other projects]. +Back to my https://troydhanson.github.io/[other projects]. A hash in C ----------- @@ -805,7 +805,7 @@ Here is a simple example where a structure has a pointer member, called `key`. .A pointer key ---------------------------------------------------------------------- -#include <stdio.h> +#include <assert.h> #include <stdlib.h> #include "uthash.h" @@ -816,17 +816,16 @@ typedef struct { } el_t; el_t *hash = NULL; -char *someaddr = NULL; +void *someaddr = &hash; int main() { el_t *d; el_t *e = (el_t *)malloc(sizeof *e); - if (!e) return -1; - e->key = (void*)someaddr; + e->key = someaddr; e->i = 1; HASH_ADD_PTR(hash, key, e); HASH_FIND_PTR(hash, &someaddr, d); - if (d) printf("found\n"); + assert(d == e); /* release memory */ HASH_DEL(hash, e); @@ -835,9 +834,7 @@ int main() { } ---------------------------------------------------------------------- -This example is included in `tests/test57.c`. Note that the end of the program -deletes the element out of the hash, (and since no more elements remain in the -hash), uthash releases its internal memory. +This example is included in `tests/test57.c`. Structure keys ~~~~~~~~~~~~~~ @@ -893,7 +890,7 @@ int main(int argc, char *argv[]) { ---------------------------------------------------------------------- -This usage is nearly the same as use of a compound key explained below. +This usage is nearly the same as the usage of a compound key explained below. Note that the general macros require the name of the `UT_hash_handle` to be passed as the first argument (here, this is `hh`). The general macros are @@ -1153,17 +1150,16 @@ always used with the `users_by_name` hash table). Sorted insertion of new items ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you would like to maintain a sorted hash you have two options. The first -option is to use the HASH_SRT() macro, which will sort any unordered list in +To maintain a sorted hash, you have two options. Your first +option is to use the `HASH_SRT` macro, which will sort any unordered list in 'O(n log(n))'. This is the best strategy if you're just filling up a hash -table with items in random order with a single final HASH_SRT() operation -when all is done. Obviously, this won't do what you want if you need -the list to be in an ordered state at times between insertion of -items. You can use HASH_SRT() after every insertion operation, but that will -yield a computational complexity of 'O(n^2 log n)'. - -The second route you can take is via the in-order add and replace macros. -The `HASH_ADD_INORDER*` macros work just like their `HASH_ADD*` counterparts, but +table with items in random order with a single final `HASH_SRT` operation +when all is done. If you need the table to remain sorted as you add and remove +items, you can use `HASH_SRT` after every insertion operation, but that gives +a computational complexity of 'O(n^2 log n)' to insert 'n' items. + +Your second option is to use the in-order add and replace macros. +The `HASH_ADD_*_INORDER` macros work just like their `HASH_ADD_*` counterparts, but with an additional comparison-function argument: int name_sort(struct my_struct *a, struct my_struct *b) { @@ -1172,11 +1168,11 @@ with an additional comparison-function argument: HASH_ADD_KEYPTR_INORDER(hh, items, &item->name, strlen(item->name), item, name_sort); -New items are sorted at insertion time in 'O(n)', thus resulting in a -total computational complexity of 'O(n^2)' for the creation of the hash -table with all items. -For in-order add to work, the list must be in an ordered state before -insertion of the new item. +These macros assume that the hash is already sorted according to the +comparison function, and insert the new item in its proper place. +A single insertion takes 'O(n)', resulting in a total computational +complexity of 'O(n^2)' to insert all 'n' items: slower than a single +`HASH_SRT`, but faster than doing a `HASH_SRT` after every insertion. Several sort orders ~~~~~~~~~~~~~~~~~~~ diff --git a/doc/utarray.txt b/doc/utarray.txt index 8ef940b53..22470a272 100644 --- a/doc/utarray.txt +++ b/doc/utarray.txt @@ -139,7 +139,7 @@ a copy of the source string and pushes that copy into the array. About UT_icd ~~~~~~~~~~~~ -Arrays be made of any type of element, not just integers and strings. The +Arrays can be made of any type of element, not just integers and strings. The elements can be basic types or structures. Unless you're dealing with integers and strings (which use pre-defined `ut_int_icd` and `ut_str_icd`), you'll need to define a `UT_icd` helper structure. This structure contains everything that diff --git a/src/utarray.h b/src/utarray.h index 3a5106666..1fe8bc1c7 100644 --- a/src/utarray.h +++ b/src/utarray.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2008-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -38,11 +38,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define UTARRAY_UNUSED #endif -#ifdef oom -#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code." -#define utarray_oom() oom() -#endif - #ifndef utarray_oom #define utarray_oom() exit(-1) #endif @@ -234,7 +229,16 @@ typedef struct { static void utarray_str_cpy(void *dst, const void *src) { char *const *srcc = (char *const *)src; char **dstc = (char**)dst; - *dstc = (*srcc == NULL) ? NULL : strdup(*srcc); + if (*srcc == NULL) { + *dstc = NULL; + } else { + *dstc = (char*)malloc(strlen(*srcc) + 1); + if (*dstc == NULL) { + utarray_oom(); + } else { + strcpy(*dstc, *srcc); + } + } } static void utarray_str_dtor(void *elt) { char **eltc = (char**)elt; diff --git a/src/uthash.h b/src/uthash.h index 9a396b617..57c9eac9e 100644 --- a/src/uthash.h +++ b/src/uthash.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2003-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -51,6 +51,8 @@ typedef unsigned char uint8_t; #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #endif +#elif defined(__MCST__) /* Elbrus C Compiler */ +#define DECLTYPE(x) (__typeof(x)) #elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) #define NO_DECLTYPE #else /* GNU, Sun and other compilers */ @@ -157,7 +159,7 @@ do { if (head) { \ unsigned _hf_bkt; \ HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ - if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ + if (HASH_BLOOM_TEST((head)->hh.tbl, hashval)) { \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ } \ } \ @@ -194,7 +196,7 @@ do { } while (0) #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) +#define HASH_BLOOM_BITTEST(bv,idx) ((bv[(idx)/8U] & (1U << ((idx)%8U))) != 0) #define HASH_BLOOM_ADD(tbl,hashv) \ HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) @@ -206,7 +208,7 @@ do { #define HASH_BLOOM_MAKE(tbl,oomed) #define HASH_BLOOM_FREE(tbl) #define HASH_BLOOM_ADD(tbl,hashv) -#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_TEST(tbl,hashv) 1 #define HASH_BLOOM_BYTELEN 0U #endif @@ -450,7 +452,7 @@ do { #define HASH_DELETE_HH(hh,head,delptrhh) \ do { \ - struct UT_hash_handle *_hd_hh_del = (delptrhh); \ + const struct UT_hash_handle *_hd_hh_del = (delptrhh); \ if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl->buckets, \ @@ -593,7 +595,9 @@ do { /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx + * (archive link: https://archive.is/Ivcan ) + */ #define HASH_SAX(key,keylen,hashv) \ do { \ unsigned _sx_i; \ diff --git a/src/utlist.h b/src/utlist.h index 1979448a7..08fc59ae6 100644 --- a/src/utlist.h +++ b/src/utlist.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2007-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2007-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without @@ -70,6 +70,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #endif +#elif defined(__MCST__) /* Elbrus C Compiler */ +#define LDECLTYPE(x) __typeof(x) #elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) #define NO_DECLTYPE #else /* GNU, Sun and other compilers */ @@ -709,7 +711,8 @@ do { assert((del)->prev != NULL); \ if ((del)->prev == (del)) { \ (head)=NULL; \ - } else if ((del)==(head)) { \ + } else if ((del) == (head)) { \ + assert((del)->next != NULL); \ (del)->next->prev = (del)->prev; \ (head) = (del)->next; \ } else { \ diff --git a/src/utringbuffer.h b/src/utringbuffer.h index c2b2e673c..603411798 100644 --- a/src/utringbuffer.h +++ b/src/utringbuffer.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2015-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2015-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/utstack.h b/src/utstack.h index fc390de10..94b8c5133 100644 --- a/src/utstack.h +++ b/src/utstack.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2018-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2018-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/utstring.h b/src/utstring.h index f6a33af3e..f0270fb63 100644 --- a/src/utstring.h +++ b/src/utstring.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2008-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/tests/Makefile b/tests/Makefile index 31f0cc240..ff3504ead 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 test96 + test90 test91 test92 test93 test94 test95 test96 test97 CFLAGS += -I$(HASHDIR) #CFLAGS += -DHASH_BLOOM=16 #CFLAGS += -O2 diff --git a/tests/README b/tests/README index a287de670..747661dd0 100644 --- a/tests/README +++ b/tests/README @@ -98,6 +98,7 @@ test93: alt_fatal test94: utlist with fields named other than 'next' and 'prev' test95: utstack test96: HASH_FUNCTION + HASH_KEYCMP +test97: deleting a const-qualified node from a hash Other Make targets ================================================================================ diff --git a/tests/hashscan.c b/tests/hashscan.c index d18b364ef..dc581f2dd 100644 --- a/tests/hashscan.c +++ b/tests/hashscan.c @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2021, Troy D. Hanson http://troydhanson.github.io/uthash/ +Copyright (c) 2005-2022, Troy D. Hanson https://troydhanson.github.io/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/tests/test57.ans b/tests/test57.ans index 4d3bb1d0b..e69de29bb 100644 --- a/tests/test57.ans +++ b/tests/test57.ans @@ -1 +0,0 @@ -found diff --git a/tests/test57.c b/tests/test57.c index 3b89fb52d..7ba3b81ae 100644 --- a/tests/test57.c +++ b/tests/test57.c @@ -1,5 +1,5 @@ -#include <stdio.h> -#include <stdlib.h> +#include <assert.h> +#include <stddef.h> #include "uthash.h" typedef struct { @@ -8,25 +8,46 @@ typedef struct { UT_hash_handle hh; } el_t; +el_t *findit(el_t *hash, void *keytofind) +{ + el_t *found; + HASH_FIND_PTR(hash, &keytofind, found); + return found; +} + int main() { - el_t *d; el_t *hash = NULL; - char *someaddr = NULL; - el_t *e = (el_t*)malloc(sizeof(el_t)); - if (!e) { - return -1; - } - e->key = (void*)someaddr; - e->i = 1; - HASH_ADD_PTR(hash,key,e); - HASH_FIND_PTR(hash, &someaddr, d); - if (d != NULL) { - printf("found\n"); - } - - /* release memory */ - HASH_DEL(hash,e); - free(e); + el_t e1; + el_t e2; + + e1.key = NULL; + e1.i = 1; + + e2.key = &e2; + e2.i = 2; + + assert(findit(hash, NULL) == NULL); + assert(findit(hash, &e1) == NULL); + assert(findit(hash, &e2) == NULL); + + HASH_ADD_PTR(hash, key, &e1); + assert(findit(hash, NULL) == &e1); + assert(findit(hash, &e1) == NULL); + assert(findit(hash, &e2) == NULL); + + HASH_ADD_PTR(hash, key, &e2); + assert(findit(hash, NULL) == &e1); + assert(findit(hash, &e1) == NULL); + assert(findit(hash, &e2) == &e2); + + HASH_DEL(hash, &e1); + assert(findit(hash, NULL) == NULL); + assert(findit(hash, &e1) == NULL); + assert(findit(hash, &e2) == &e2); + + HASH_CLEAR(hh, hash); + assert(hash == NULL); + return 0; } diff --git a/tests/test65.c b/tests/test65.c index 0584fb1a0..5820a4552 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.io/uthash/ +// https://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/test97.ans b/tests/test97.ans new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/test97.ans diff --git a/tests/test97.c b/tests/test97.c new file mode 100644 index 000000000..d59008bac --- /dev/null +++ b/tests/test97.c @@ -0,0 +1,57 @@ +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include "uthash.h" + +struct item { + int payload; + UT_hash_handle hh; +}; + +void delete_without_modifying(struct item *head, const struct item *p) +{ + struct item old; + memcpy(&old, p, sizeof(struct item)); // also copy the padding bits + assert(memcmp(&old, p, sizeof(struct item)) == 0); + assert(p->hh.tbl == head->hh.tbl); // class invariant + HASH_DEL(head, p); + assert(memcmp(&old, p, sizeof(struct item)) == 0); // unmodified by HASH_DEL +} + +int main() +{ + struct item *items = NULL; + struct item *found = NULL; + int fortytwo = 42; + int i; + + for (i=0; i < 100; i++) { + struct item *p = (struct item *)malloc(sizeof *p); + p->payload = i; + HASH_ADD_INT(items, payload, p); + } + assert(HASH_COUNT(items) == 100); + + // Delete item "42" from the hash, wherever it is. + HASH_FIND_INT(items, &fortytwo, found); + assert(found != NULL); + assert(found->payload == 42); + delete_without_modifying(items, found); + + assert(HASH_COUNT(items) == 99); + HASH_FIND_INT(items, &fortytwo, found); + assert(found == NULL); + + // Delete the very first item in the hash. + assert(items != NULL); + i = items->payload; + delete_without_modifying(items, items); + + assert(HASH_COUNT(items) == 98); + HASH_FIND_INT(items, &i, found); + assert(found == NULL); + + // leak the items, we don't care + + return 0; +} |