Merge commit '9a14454d3c5589373253571cee7428c593adefd9'

This commit is contained in:
Toni Uhlig
2024-10-17 12:16:20 +02:00
21 changed files with 198 additions and 71 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,6 @@
[![Build status](https://api.travis-ci.org/troydhanson/uthash.svg?branch=master)](https://travis-ci.org/troydhanson/uthash)
[![GitHub CI status](https://github.com/troydhanson/uthash/actions/workflows/build.yml/badge.svg)](https://github.com/troydhanson/uthash/actions/workflows/build.yml)
Documentation for uthash is available at:

View File

@@ -13,8 +13,8 @@
</div> <!-- banner -->
<div id="topnav">
<a href="http://github.com/troydhanson/uthash">GitHub page</a> &gt;
uthash home <!-- http://troydhanson.github.io/uthash/ -->
<a href="https://github.com/troydhanson/uthash">GitHub page</a> &gt;
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>

View File

@@ -13,7 +13,7 @@
</div> <!-- banner -->
<div id="topnav">
<a href="http://troydhanson.github.io/uthash/">uthash home</a> &gt;
<a href="https://troydhanson.github.io/uthash/">uthash home</a> &gt;
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

View File

@@ -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)'.
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.
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
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
~~~~~~~~~~~~~~~~~~~

View File

@@ -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

View File

@@ -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;

View File

@@ -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; \

View File

@@ -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 { \

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
================================================================================

View File

@@ -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

View File

@@ -1 +0,0 @@
found

View File

@@ -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");
}
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);
/* release memory */
HASH_DEL(hash,e);
free(e);
return 0;
}

View File

@@ -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/

0
dependencies/uthash/tests/test97.ans vendored Normal file
View File

57
dependencies/uthash/tests/test97.c vendored Normal file
View File

@@ -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;
}