cmdtree

A trie command launcher for X11
git clone git://jb55.com/cmdtree
Log | Files | Refs | README | LICENSE

commit 9593fc545950782ed75f12f53238b07885559b2b
parent bd8c223756d2f912526ecef53bae0cc8e0c63442
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  9 Jul 2018 22:28:25 -0700

remove ccan for now

Diffstat:
MMakefile | 5+----
Dccan/alignof/LICENSE | 2--
Dccan/alignof/_info | 51---------------------------------------------------
Dccan/alignof/alignof.h | 20--------------------
Dccan/alignof/test/run.c | 61-------------------------------------------------------------
Dccan/build_assert/LICENSE | 2--
Dccan/build_assert/_info | 49-------------------------------------------------
Dccan/build_assert/build_assert.h | 40----------------------------------------
Dccan/build_assert/test/compile_fail-expr.c | 10----------
Dccan/build_assert/test/compile_fail.c | 9---------
Dccan/build_assert/test/compile_ok.c | 7-------
Dccan/build_assert/test/run-BUILD_ASSERT_OR_ZERO.c | 9---------
Dccan/check_type/LICENSE | 2--
Dccan/check_type/_info | 33---------------------------------
Dccan/check_type/check_type.h | 64----------------------------------------------------------------
Dccan/check_type/test/compile_fail-check_type.c | 11-----------
Dccan/check_type/test/compile_fail-check_type_unsigned.c | 16----------------
Dccan/check_type/test/compile_fail-check_types_match.c | 11-----------
Dccan/check_type/test/run.c | 23-----------------------
Dccan/compiler/LICENSE | 2--
Dccan/compiler/_info | 64----------------------------------------------------------------
Dccan/compiler/compiler.h | 231-------------------------------------------------------------------------------
Dccan/compiler/test/compile_fail-printf.c | 24------------------------
Dccan/compiler/test/run-is_compile_constant.c | 17-----------------
Dccan/container_of/LICENSE | 2--
Dccan/container_of/_info | 65-----------------------------------------------------------------
Dccan/container_of/container_of.h | 145-------------------------------------------------------------------------------
Dccan/container_of/test/compile_fail-bad-type.c | 22----------------------
Dccan/container_of/test/compile_fail-types.c | 22----------------------
Dccan/container_of/test/compile_fail-var-types.c | 25-------------------------
Dccan/container_of/test/run.c | 30------------------------------
Dccan/hash/LICENSE | 2--
Dccan/hash/_info | 32--------------------------------
Dccan/hash/hash.c | 926-------------------------------------------------------------------------------
Dccan/hash/hash.h | 313-------------------------------------------------------------------------------
Dccan/hash/test/api-hash_stable.c | 300-------------------------------------------------------------------------------
Dccan/hash/test/run.c | 149-------------------------------------------------------------------------------
Dccan/htable/LICENSE | 2--
Dccan/htable/_info | 117-------------------------------------------------------------------------------
Dccan/htable/htable.c | 325-------------------------------------------------------------------------------
Dccan/htable/htable.h | 226-------------------------------------------------------------------------------
Dccan/htable/htable_type.h | 166-------------------------------------------------------------------------------
Dccan/htable/test/run-copy.c | 44--------------------------------------------
Dccan/htable/test/run-size.c | 36------------------------------------
Dccan/htable/test/run-type-int.c | 215-------------------------------------------------------------------------------
Dccan/htable/test/run-type.c | 210-------------------------------------------------------------------------------
Dccan/htable/test/run-zero-hash-first-entry.c | 61-------------------------------------------------------------
Dccan/htable/test/run.c | 212-------------------------------------------------------------------------------
Dccan/htable/tools/Makefile | 40----------------------------------------
Dccan/htable/tools/hsearchspeed.c | 95-------------------------------------------------------------------------------
Dccan/htable/tools/speed.c | 370-------------------------------------------------------------------------------
Dccan/htable/tools/stringspeed.c | 240-------------------------------------------------------------------------------
Dccan/licenses/BSD-MIT | 17-----------------
Dccan/licenses/CC0 | 28----------------------------
Dccan/licenses/LGPL-2.1 | 510-------------------------------------------------------------------------------
Dccan/likely/LICENSE | 2--
Dccan/likely/_info | 57---------------------------------------------------------
Dccan/likely/likely.c | 136-------------------------------------------------------------------------------
Dccan/likely/likely.h | 111-------------------------------------------------------------------------------
Dccan/likely/test/run-debug.c | 105-------------------------------------------------------------------------------
Dccan/likely/test/run.c | 30------------------------------
Dccan/list/LICENSE | 2--
Dccan/list/_info | 72------------------------------------------------------------------------
Dccan/list/list.c | 43-------------------------------------------
Dccan/list/list.h | 842-------------------------------------------------------------------------------
Dccan/list/test/compile_ok-constant.c | 49-------------------------------------------------
Dccan/list/test/helper.c | 56--------------------------------------------------------
Dccan/list/test/helper.h | 9---------
Dccan/list/test/run-CCAN_LIST_DEBUG.c | 60------------------------------------------------------------
Dccan/list/test/run-check-corrupt.c | 90-------------------------------------------------------------------------------
Dccan/list/test/run-check-nonconst.c | 27---------------------------
Dccan/list/test/run-list_del_from-assert.c | 36------------------------------------
Dccan/list/test/run-list_prev-list_next.c | 65-----------------------------------------------------------------
Dccan/list/test/run-prepend_list.c | 111-------------------------------------------------------------------------------
Dccan/list/test/run-single-eval.c | 168-------------------------------------------------------------------------------
Dccan/list/test/run-with-debug.c | 3---
Dccan/list/test/run.c | 305------------------------------------------------------------------------------
Dccan/str/LICENSE | 2--
Dccan/str/_info | 52----------------------------------------------------
Dccan/str/debug.c | 108-------------------------------------------------------------------------------
Dccan/str/str.c | 13-------------
Dccan/str/str.h | 228-------------------------------------------------------------------------------
Dccan/str/str_debug.h | 30------------------------------
Dccan/str/test/compile_fail-STR_MAX_CHARS.c | 23-----------------------
Dccan/str/test/compile_fail-isalnum.c | 23-----------------------
Dccan/str/test/compile_fail-isalpha.c | 23-----------------------
Dccan/str/test/compile_fail-isascii.c | 23-----------------------
Dccan/str/test/compile_fail-isblank.c | 27---------------------------
Dccan/str/test/compile_fail-iscntrl.c | 23-----------------------
Dccan/str/test/compile_fail-isdigit.c | 23-----------------------
Dccan/str/test/compile_fail-islower.c | 23-----------------------
Dccan/str/test/compile_fail-isprint.c | 23-----------------------
Dccan/str/test/compile_fail-ispunct.c | 23-----------------------
Dccan/str/test/compile_fail-isspace.c | 23-----------------------
Dccan/str/test/compile_fail-isupper.c | 23-----------------------
Dccan/str/test/compile_fail-isxdigit.c | 23-----------------------
Dccan/str/test/compile_fail-strchr.c | 18------------------
Dccan/str/test/compile_fail-strrchr.c | 18------------------
Dccan/str/test/compile_fail-strstr.c | 18------------------
Dccan/str/test/compile_ok-STR_MAX_CHARS-static.c | 8--------
Dccan/str/test/debug.c | 5-----
Dccan/str/test/run-STR_MAX_CHARS.c | 59-----------------------------------------------------------
Dccan/str/test/run.c | 106-------------------------------------------------------------------------------
Dccan/take/LICENSE | 2--
Dccan/take/_info | 61-------------------------------------------------------------
Dccan/take/take.c | 115-------------------------------------------------------------------------------
Dccan/take/take.h | 136-------------------------------------------------------------------------------
Dccan/take/test/run-debug.c | 34----------------------------------
Dccan/take/test/run.c | 102-------------------------------------------------------------------------------
Dccan/tal/LICENSE | 2--
Dccan/tal/_info | 108-------------------------------------------------------------------------------
Dccan/tal/benchmark/Makefile | 26--------------------------
Dccan/tal/benchmark/samba-allocs.c | 381-------------------------------------------------------------------------------
Dccan/tal/benchmark/speed.c | 125-------------------------------------------------------------------------------
Dccan/tal/benchmark/talloc.dump | 26137-------------------------------------------------------------------------------
Dccan/tal/str/LICENSE | 2--
Dccan/tal/str/_info | 59-----------------------------------------------------------
Dccan/tal/str/str.c | 309-------------------------------------------------------------------------------
Dccan/tal/str/str.h | 192-------------------------------------------------------------------------------
Dccan/tal/str/test/helper.h | 22----------------------
Dccan/tal/str/test/run-fmt-terminate.c | 22----------------------
Dccan/tal/str/test/run-string.c | 90-------------------------------------------------------------------------------
Dccan/tal/str/test/run-strndup.c | 22----------------------
Dccan/tal/str/test/run-strreg.c | 124-------------------------------------------------------------------------------
Dccan/tal/str/test/run-take.c | 48------------------------------------------------
Dccan/tal/str/test/run.c | 158-------------------------------------------------------------------------------
Dccan/tal/tal.c | 1026-------------------------------------------------------------------------------
Dccan/tal/tal.h | 514-------------------------------------------------------------------------------
Dccan/tal/test/run-allocfail.c | 153-------------------------------------------------------------------------------
Dccan/tal/test/run-array.c | 48------------------------------------------------
Dccan/tal/test/run-count.c | 92-------------------------------------------------------------------------------
Dccan/tal/test/run-destructor.c | 68--------------------------------------------------------------------
Dccan/tal/test/run-destructor2.c | 38--------------------------------------
Dccan/tal/test/run-expand.c | 33---------------------------------
Dccan/tal/test/run-free.c | 29-----------------------------
Dccan/tal/test/run-groups-grow.c | 48------------------------------------------------
Dccan/tal/test/run-iter.c | 53-----------------------------------------------------
Dccan/tal/test/run-named-debug.c | 35-----------------------------------
Dccan/tal/test/run-named-nolabels.c | 31-------------------------------
Dccan/tal/test/run-named.c | 34----------------------------------
Dccan/tal/test/run-notifier.c | 133-------------------------------------------------------------------------------
Dccan/tal/test/run-overflow.c | 99-------------------------------------------------------------------------------
Dccan/tal/test/run-resizez.c | 27---------------------------
Dccan/tal/test/run-steal.c | 41-----------------------------------------
Dccan/tal/test/run-take.c | 57---------------------------------------------------------
Dccan/tal/test/run-test-backend.c | 80-------------------------------------------------------------------------------
Dccan/tal/test/run.c | 61-------------------------------------------------------------
Dccan/typesafe_cb/LICENSE | 2--
Dccan/typesafe_cb/_info | 151------------------------------------------------------------------------------
Dccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c | 24------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c | 28----------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb.c | 37-------------------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c | 44--------------------------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c | 26--------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c | 31-------------------------------
Dccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c | 32--------------------------------
Dccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c | 19-------------------
Dccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c | 60------------------------------------------------------------
Dccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c | 63---------------------------------------------------------------
Dccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c | 42------------------------------------------
Dccan/typesafe_cb/test/run.c | 109-------------------------------------------------------------------------------
Dccan/typesafe_cb/typesafe_cb.h | 134-------------------------------------------------------------------------------
Mcommand.c | 24+++---------------------
Mcommand.h | 4----
Dconfig.h | 75---------------------------------------------------------------------------
165 files changed, 4 insertions(+), 40935 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,9 +4,6 @@ LDFLAGS=-lXft -lfontconfig BIN=cmdtree -DEPS = $(wildcard ccan/*/*.c) -DEPS += $(wildcard ccan/tal/str/*.c) - OBJS += drw.o OBJS += util.o OBJS += cmdtree.o @@ -34,7 +31,7 @@ $(BIN): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ clean: fake - rm -f $(OBJS) $(BIN) + rm -f $(OBJS) $(BIN) *.d TAGS: fake etags *.c diff --git a/ccan/alignof/LICENSE b/ccan/alignof/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/alignof/_info b/ccan/alignof/_info @@ -1,51 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * alignof - ALIGNOF() macro to determine alignment of a type. - * - * Many platforms have requirements that certain types must be aligned - * to certain address boundaries, such as ints needing to be on 4-byte - * boundaries. Attempting to access variables with incorrect - * alignment may cause performance loss or even program failure (eg. a - * bus signal). - * - * There are times which it's useful to be able to programatically - * access these requirements, such as for dynamic allocators. - * - * Example: - * #include <stdio.h> - * #include <stdlib.h> - * #include <ccan/alignof/alignof.h> - * - * // Output contains "ALIGNOF(char) == 1" - * // Will also print out whether an onstack char array can hold a long. - * int main(void) - * { - * char arr[sizeof(int)]; - * - * printf("ALIGNOF(char) == %zu\n", ALIGNOF(char)); - * if ((unsigned long)arr % ALIGNOF(int)) { - * printf("arr %p CANNOT hold an int\n", arr); - * exit(1); - * } else { - * printf("arr %p CAN hold an int\n", arr); - * exit(0); - * } - * } - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - return 0; - } - - return 1; -} diff --git a/ccan/alignof/alignof.h b/ccan/alignof/alignof.h @@ -1,20 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_ALIGNOF_H -#define CCAN_ALIGNOF_H -#include "config.h" - -/** - * ALIGNOF - get the alignment of a type - * @t: the type to test - * - * This returns a safe alignment for the given type. - */ -#if HAVE_ALIGNOF -/* A GCC extension. */ -#define ALIGNOF(t) __alignof__(t) -#else -/* Alignment by measuring structure padding. */ -#define ALIGNOF(t) ((char *)(&((struct { char c; t _h; } *)0)->_h) - (char *)0) -#endif - -#endif /* CCAN_ALIGNOF_H */ diff --git a/ccan/alignof/test/run.c b/ccan/alignof/test/run.c @@ -1,61 +0,0 @@ -#include <ccan/alignof/alignof.h> -#include <stdlib.h> -#include <stddef.h> -#include <ccan/tap/tap.h> - -/* Alignment is remarkably difficult to test. The rules may be more - * complex than ALIGNOF() can know: eg. on i386 __alignof__(double) == 8, but - * __alignof__(struct containing double) == 4. - * - * Technically, we can only test that we give *at least* the alignment which - * naturally occurs, and that accesses work. - * - * For the moment, we work around double. */ -struct lots_of_types -{ - char c; - short s; - char c2; - int i; - char c3; - float f; - char c4; - double d; - char c5; -}; - -int main(void) -{ - struct lots_of_types lots_of_types, *lp = malloc(sizeof(*lp)); - char c; - short s; - char c2; - int i; - char c3; - float f; - char c4; - double d; - - /* Make sure we use all the variables. */ - c = c2 = c3 = c4 = 0; - - plan_tests(15); - ok1((unsigned long)&c % ALIGNOF(char) == 0); - ok1((unsigned long)&s % ALIGNOF(short) == 0); - ok1((unsigned long)&i % ALIGNOF(int) == 0); - ok1((unsigned long)&f % ALIGNOF(float) == 0); - ok1((unsigned long)&d % ALIGNOF(double) == 0); - - ok1((unsigned long)&lots_of_types.c % ALIGNOF(char) == 0); - ok1((unsigned long)&lots_of_types.s % ALIGNOF(short) == 0); - ok1((unsigned long)&lots_of_types.i % ALIGNOF(int) == 0); - ok1((unsigned long)&lots_of_types.f % ALIGNOF(float) == 0); - ok1(offsetof(struct lots_of_types, d) % ALIGNOF(double) == 0); - - ok1((unsigned long)&lp->c % ALIGNOF(char) == 0); - ok1((unsigned long)&lp->s % ALIGNOF(short) == 0); - ok1((unsigned long)&lp->i % ALIGNOF(int) == 0); - ok1((unsigned long)&lp->f % ALIGNOF(float) == 0); - ok1((unsigned long)&lp->d % ALIGNOF(double) == 0); - exit(exit_status()); -} diff --git a/ccan/build_assert/LICENSE b/ccan/build_assert/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/build_assert/_info b/ccan/build_assert/_info @@ -1,49 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * build_assert - routines for build-time assertions - * - * This code provides routines which will cause compilation to fail should some - * assertion be untrue: such failures are preferable to run-time assertions, - * but much more limited since they can only depends on compile-time constants. - * - * These assertions are most useful when two parts of the code must be kept in - * sync: it is better to avoid such cases if possible, but seconds best is to - * detect invalid changes at build time. - * - * For example, a tricky piece of code might rely on a certain element being at - * the start of the structure. To ensure that future changes don't break it, - * you would catch such changes in your code like so: - * - * Example: - * #include <stddef.h> - * #include <ccan/build_assert/build_assert.h> - * - * struct foo { - * char string[5]; - * int x; - * }; - * - * static char *foo_string(struct foo *foo) - * { - * // This trick requires that the string be first in the structure - * BUILD_ASSERT(offsetof(struct foo, string) == 0); - * return (char *)foo; - * } - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) - /* Nothing. */ - return 0; - - return 1; -} diff --git a/ccan/build_assert/build_assert.h b/ccan/build_assert/build_assert.h @@ -1,40 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_BUILD_ASSERT_H -#define CCAN_BUILD_ASSERT_H - -/** - * BUILD_ASSERT - assert a build-time dependency. - * @cond: the compile-time condition which must be true. - * - * Your compile will fail if the condition isn't true, or can't be evaluated - * by the compiler. This can only be used within a function. - * - * Example: - * #include <stddef.h> - * ... - * static char *foo_to_char(struct foo *foo) - * { - * // This code needs string to be at start of foo. - * BUILD_ASSERT(offsetof(struct foo, string) == 0); - * return (char *)foo; - * } - */ -#define BUILD_ASSERT(cond) \ - do { (void) sizeof(char [1 - 2*!(cond)]); } while(0) - -/** - * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression. - * @cond: the compile-time condition which must be true. - * - * Your compile will fail if the condition isn't true, or can't be evaluated - * by the compiler. This can be used in an expression: its value is "0". - * - * Example: - * #define foo_to_char(foo) \ - * ((char *)(foo) \ - * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0)) - */ -#define BUILD_ASSERT_OR_ZERO(cond) \ - (sizeof(char [1 - 2*!(cond)]) - 1) - -#endif /* CCAN_BUILD_ASSERT_H */ diff --git a/ccan/build_assert/test/compile_fail-expr.c b/ccan/build_assert/test/compile_fail-expr.c @@ -1,10 +0,0 @@ -#include <ccan/build_assert/build_assert.h> - -int main(void) -{ -#ifdef FAIL - return BUILD_ASSERT_OR_ZERO(1 == 0); -#else - return 0; -#endif -} diff --git a/ccan/build_assert/test/compile_fail.c b/ccan/build_assert/test/compile_fail.c @@ -1,9 +0,0 @@ -#include <ccan/build_assert/build_assert.h> - -int main(void) -{ -#ifdef FAIL - BUILD_ASSERT(1 == 0); -#endif - return 0; -} diff --git a/ccan/build_assert/test/compile_ok.c b/ccan/build_assert/test/compile_ok.c @@ -1,7 +0,0 @@ -#include <ccan/build_assert/build_assert.h> - -int main(void) -{ - BUILD_ASSERT(1 == 1); - return 0; -} diff --git a/ccan/build_assert/test/run-BUILD_ASSERT_OR_ZERO.c b/ccan/build_assert/test/run-BUILD_ASSERT_OR_ZERO.c @@ -1,9 +0,0 @@ -#include <ccan/build_assert/build_assert.h> -#include <ccan/tap/tap.h> - -int main(void) -{ - plan_tests(1); - ok1(BUILD_ASSERT_OR_ZERO(1 == 1) == 0); - return exit_status(); -} diff --git a/ccan/check_type/LICENSE b/ccan/check_type/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/check_type/_info b/ccan/check_type/_info @@ -1,33 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * check_type - routines for compile time type checking - * - * C has fairly weak typing: ints get automatically converted to longs, signed - * to unsigned, etc. There are some cases where this is best avoided, and - * these macros provide methods for evoking warnings (or build errors) when - * a precise type isn't used. - * - * On compilers which don't support typeof() these routines are less effective, - * since they have to use sizeof() which can only distiguish between types of - * different size. - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { -#if !HAVE_TYPEOF - printf("ccan/build_assert\n"); -#endif - return 0; - } - - return 1; -} diff --git a/ccan/check_type/check_type.h b/ccan/check_type/check_type.h @@ -1,64 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_CHECK_TYPE_H -#define CCAN_CHECK_TYPE_H -#include "config.h" - -/** - * check_type - issue a warning or build failure if type is not correct. - * @expr: the expression whose type we should check (not evaluated). - * @type: the exact type we expect the expression to be. - * - * This macro is usually used within other macros to try to ensure that a macro - * argument is of the expected type. No type promotion of the expression is - * done: an unsigned int is not the same as an int! - * - * check_type() always evaluates to 0. - * - * If your compiler does not support typeof, then the best we can do is fail - * to compile if the sizes of the types are unequal (a less complete check). - * - * Example: - * // They should always pass a 64-bit value to _set_some_value! - * #define set_some_value(expr) \ - * _set_some_value((check_type((expr), uint64_t), (expr))) - */ - -/** - * check_types_match - issue a warning or build failure if types are not same. - * @expr1: the first expression (not evaluated). - * @expr2: the second expression (not evaluated). - * - * This macro is usually used within other macros to try to ensure that - * arguments are of identical types. No type promotion of the expressions is - * done: an unsigned int is not the same as an int! - * - * check_types_match() always evaluates to 0. - * - * If your compiler does not support typeof, then the best we can do is fail - * to compile if the sizes of the types are unequal (a less complete check). - * - * Example: - * // Do subtraction to get to enclosing type, but make sure that - * // pointer is of correct type for that member. - * #define container_of(mbr_ptr, encl_type, mbr) \ - * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \ - * ((encl_type *) \ - * ((char *)(mbr_ptr) - offsetof(encl_type, mbr)))) - */ -#if HAVE_TYPEOF -#define check_type(expr, type) \ - ((typeof(expr) *)0 != (type *)0) - -#define check_types_match(expr1, expr2) \ - ((typeof(expr1) *)0 != (typeof(expr2) *)0) -#else -#include <ccan/build_assert/build_assert.h> -/* Without typeof, we can only test the sizes. */ -#define check_type(expr, type) \ - BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type)) - -#define check_types_match(expr1, expr2) \ - BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2)) -#endif /* HAVE_TYPEOF */ - -#endif /* CCAN_CHECK_TYPE_H */ diff --git a/ccan/check_type/test/compile_fail-check_type.c b/ccan/check_type/test/compile_fail-check_type.c @@ -1,11 +0,0 @@ -#include <ccan/check_type/check_type.h> - -int main(int argc, char *argv[]) -{ - (void)argc; - (void)argv; -#ifdef FAIL - check_type(argc, char); -#endif - return 0; -} diff --git a/ccan/check_type/test/compile_fail-check_type_unsigned.c b/ccan/check_type/test/compile_fail-check_type_unsigned.c @@ -1,16 +0,0 @@ -#include <ccan/check_type/check_type.h> - -int main(int argc, char *argv[]) -{ - (void)argc; - (void)argv; -#ifdef FAIL -#if HAVE_TYPEOF - check_type(argc, unsigned int); -#else - /* This doesn't work without typeof, so just fail */ -#error "Fail without typeof" -#endif -#endif - return 0; -} diff --git a/ccan/check_type/test/compile_fail-check_types_match.c b/ccan/check_type/test/compile_fail-check_types_match.c @@ -1,11 +0,0 @@ -#include <ccan/check_type/check_type.h> - -int main(int argc, char *argv[]) -{ - unsigned char x = argc; - (void)argv; -#ifdef FAIL - check_types_match(argc, x); -#endif - return x; -} diff --git a/ccan/check_type/test/run.c b/ccan/check_type/test/run.c @@ -1,23 +0,0 @@ -#include <ccan/check_type/check_type.h> -#include <ccan/tap/tap.h> - -int main(int argc, char *argv[]) -{ - int x = 0, y = 0; - - (void)argv; - plan_tests(9); - - ok1(check_type(argc, int) == 0); - ok1(check_type(&argc, int *) == 0); - ok1(check_types_match(argc, argc) == 0); - ok1(check_types_match(argc, x) == 0); - ok1(check_types_match(&argc, &x) == 0); - - ok1(check_type(x++, int) == 0); - ok(x == 0, "check_type does not evaluate expression"); - ok1(check_types_match(x++, y++) == 0); - ok(x == 0 && y == 0, "check_types_match does not evaluate expressions"); - - return exit_status(); -} diff --git a/ccan/compiler/LICENSE b/ccan/compiler/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/compiler/_info b/ccan/compiler/_info @@ -1,64 +0,0 @@ -#include "config.h" -#include <string.h> -#include <stdio.h> - -/** - * compiler - macros for common compiler extensions - * - * Abstracts away some compiler hints. Currently these include: - * - COLD - * For functions not called in fast paths (aka. cold functions) - * - PRINTF_FMT - * For functions which take printf-style parameters. - * - CONST_FUNCTION - * For functions which return the same value for same parameters. - * - NEEDED - * For functions and variables which must be emitted even if unused. - * - UNNEEDED - * For functions and variables which need not be emitted if unused. - * - UNUSED - * For parameters which are not used. - * - IS_COMPILE_CONSTANT() - * For using different tradeoffs for compiletime vs runtime evaluation. - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - * - * Example: - * #include <ccan/compiler/compiler.h> - * #include <stdio.h> - * #include <stdarg.h> - * - * // Example of a (slow-path) logging function. - * static int log_threshold = 2; - * static void COLD PRINTF_FMT(2,3) - * logger(int level, const char *fmt, ...) - * { - * va_list ap; - * va_start(ap, fmt); - * if (level >= log_threshold) - * vfprintf(stderr, fmt, ap); - * va_end(ap); - * } - * - * int main(int argc, char *argv[] UNNEEDED) - * { - * if (argc != 1) { - * logger(3, "Don't want %i arguments!\n", argc-1); - * return 1; - * } - * return 0; - * } - */ -int main(int argc, char *argv[]) -{ - /* Expect exactly one argument */ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - return 0; - } - - return 1; -} diff --git a/ccan/compiler/compiler.h b/ccan/compiler/compiler.h @@ -1,231 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_COMPILER_H -#define CCAN_COMPILER_H -#include "config.h" - -#ifndef COLD -#if HAVE_ATTRIBUTE_COLD -/** - * COLD - a function is unlikely to be called. - * - * Used to mark an unlikely code path and optimize appropriately. - * It is usually used on logging or error routines. - * - * Example: - * static void COLD moan(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * } - */ -#define COLD __attribute__((__cold__)) -#else -#define COLD -#endif -#endif - -#ifndef NORETURN -#if HAVE_ATTRIBUTE_NORETURN -/** - * NORETURN - a function does not return - * - * Used to mark a function which exits; useful for suppressing warnings. - * - * Example: - * static void NORETURN fail(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * exit(1); - * } - */ -#define NORETURN __attribute__((__noreturn__)) -#else -#define NORETURN -#endif -#endif - -#ifndef PRINTF_FMT -#if HAVE_ATTRIBUTE_PRINTF -/** - * PRINTF_FMT - a function takes printf-style arguments - * @nfmt: the 1-based number of the function's format argument. - * @narg: the 1-based number of the function's first variable argument. - * - * This allows the compiler to check your parameters as it does for printf(). - * - * Example: - * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...); - */ -#define PRINTF_FMT(nfmt, narg) \ - __attribute__((format(__printf__, nfmt, narg))) -#else -#define PRINTF_FMT(nfmt, narg) -#endif -#endif - -#ifndef CONST_FUNCTION -#if HAVE_ATTRIBUTE_CONST -/** - * CONST_FUNCTION - a function's return depends only on its argument - * - * This allows the compiler to assume that the function will return the exact - * same value for the exact same arguments. This implies that the function - * must not use global variables, or dereference pointer arguments. - */ -#define CONST_FUNCTION __attribute__((__const__)) -#else -#define CONST_FUNCTION -#endif - -#ifndef PURE_FUNCTION -#if HAVE_ATTRIBUTE_PURE -/** - * PURE_FUNCTION - a function is pure - * - * A pure function is one that has no side effects other than it's return value - * and uses no inputs other than it's arguments and global variables. - */ -#define PURE_FUNCTION __attribute__((__pure__)) -#else -#define PURE_FUNCTION -#endif -#endif -#endif - -#if HAVE_ATTRIBUTE_UNUSED -#ifndef UNNEEDED -/** - * UNNEEDED - a variable/function may not be needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that if it is unused it need not emit it into the source code. - * - * Example: - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED int counter; - * - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED void add_to_counter(int add) - * { - * counter += add; - * } - */ -#define UNNEEDED __attribute__((__unused__)) -#endif - -#ifndef NEEDED -#if HAVE_ATTRIBUTE_USED -/** - * NEEDED - a variable/function is needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that it must exist even if it (seems) unused. - * - * Example: - * // Even if this is unused, these are vital for debugging. - * static NEEDED int counter; - * static NEEDED void dump_counter(void) - * { - * printf("Counter is %i\n", counter); - * } - */ -#define NEEDED __attribute__((__used__)) -#else -/* Before used, unused functions and vars were always emitted. */ -#define NEEDED __attribute__((__unused__)) -#endif -#endif - -#ifndef UNUSED -/** - * UNUSED - a parameter is unused - * - * Some compilers (eg. gcc with -W or -Wunused) warn about unused - * function parameters. This suppresses such warnings and indicates - * to the reader that it's deliberate. - * - * Example: - * // This is used as a callback, so needs to have this prototype. - * static int some_callback(void *unused UNUSED) - * { - * return 0; - * } - */ -#define UNUSED __attribute__((__unused__)) -#endif -#else -#ifndef UNNEEDED -#define UNNEEDED -#endif -#ifndef NEEDED -#define NEEDED -#endif -#ifndef UNUSED -#define UNUSED -#endif -#endif - -#ifndef IS_COMPILE_CONSTANT -#if HAVE_BUILTIN_CONSTANT_P -/** - * IS_COMPILE_CONSTANT - does the compiler know the value of this expression? - * @expr: the expression to evaluate - * - * When an expression manipulation is complicated, it is usually better to - * implement it in a function. However, if the expression being manipulated is - * known at compile time, it is better to have the compiler see the entire - * expression so it can simply substitute the result. - * - * This can be done using the IS_COMPILE_CONSTANT() macro. - * - * Example: - * enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON }; - * - * // Out-of-line version. - * const char *greek_name(enum greek greek); - * - * // Inline version. - * static inline const char *_greek_name(enum greek greek) - * { - * switch (greek) { - * case ALPHA: return "alpha"; - * case BETA: return "beta"; - * case GAMMA: return "gamma"; - * case DELTA: return "delta"; - * case EPSILON: return "epsilon"; - * default: return "**INVALID**"; - * } - * } - * - * // Use inline if compiler knows answer. Otherwise call function - * // to avoid copies of the same code everywhere. - * #define greek_name(g) \ - * (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g)) - */ -#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr) -#else -/* If we don't know, assume it's not. */ -#define IS_COMPILE_CONSTANT(expr) 0 -#endif -#endif - -#ifndef WARN_UNUSED_RESULT -#if HAVE_WARN_UNUSED_RESULT -/** - * WARN_UNUSED_RESULT - warn if a function return value is unused. - * - * Used to mark a function where it is extremely unlikely that the caller - * can ignore the result, eg realloc(). - * - * Example: - * // buf param may be freed by this; need return value! - * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size) - * { - * return realloc(buf, (*size) *= 2); - * } - */ -#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -#else -#define WARN_UNUSED_RESULT -#endif -#endif -#endif /* CCAN_COMPILER_H */ diff --git a/ccan/compiler/test/compile_fail-printf.c b/ccan/compiler/test/compile_fail-printf.c @@ -1,24 +0,0 @@ -#include <ccan/compiler/compiler.h> - -static void PRINTF_FMT(2,3) my_printf(int x, const char *fmt, ...) -{ - (void)x; - (void)fmt; -} - -int main(void) -{ - unsigned int i = 0; - - my_printf(1, "Not a pointer " -#ifdef FAIL - "%p", -#if !HAVE_ATTRIBUTE_PRINTF -#error "Unfortunately we don't fail if !HAVE_ATTRIBUTE_PRINTF." -#endif -#else - "%i", -#endif - i); - return 0; -} diff --git a/ccan/compiler/test/run-is_compile_constant.c b/ccan/compiler/test/run-is_compile_constant.c @@ -1,17 +0,0 @@ -#include <ccan/compiler/compiler.h> -#include <ccan/tap/tap.h> - -int main(int argc, char *argv[]) -{ - (void)argc; - (void)argv; - plan_tests(2); - - ok1(!IS_COMPILE_CONSTANT(argc)); -#if HAVE_BUILTIN_CONSTANT_P - ok1(IS_COMPILE_CONSTANT(7)); -#else - pass("If !HAVE_BUILTIN_CONSTANT_P, IS_COMPILE_CONSTANT always false"); -#endif - return exit_status(); -} diff --git a/ccan/container_of/LICENSE b/ccan/container_of/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/container_of/_info b/ccan/container_of/_info @@ -1,65 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * container_of - routine for upcasting - * - * It is often convenient to create code where the caller registers a pointer - * to a generic structure and a callback. The callback might know that the - * pointer points to within a larger structure, and container_of gives a - * convenient and fairly type-safe way of returning to the enclosing structure. - * - * This idiom is an alternative to providing a void * pointer for every - * callback. - * - * Example: - * #include <stdio.h> - * #include <ccan/container_of/container_of.h> - * - * struct timer { - * void *members; - * }; - * - * struct info { - * int my_stuff; - * struct timer timer; - * }; - * - * static void my_timer_callback(struct timer *timer) - * { - * struct info *info = container_of(timer, struct info, timer); - * printf("my_stuff is %u\n", info->my_stuff); - * } - * - * static void register_timer(struct timer *timer) - * { - * (void)timer; - * (void)my_timer_callback; - * //... - * } - * - * int main(void) - * { - * struct info info = { .my_stuff = 1 }; - * - * register_timer(&info.timer); - * // ... - * return 0; - * } - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/check_type\n"); - return 0; - } - - return 1; -} diff --git a/ccan/container_of/container_of.h b/ccan/container_of/container_of.h @@ -1,145 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_CONTAINER_OF_H -#define CCAN_CONTAINER_OF_H -#include <stddef.h> - -#include "config.h" -#include <ccan/check_type/check_type.h> - -/** - * container_of - get pointer to enclosing structure - * @member_ptr: pointer to the structure member - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info(struct foo *foo) - * { - * return container_of(foo, struct info, my_foo); - * } - */ -#define container_of(member_ptr, containing_type, member) \ - ((containing_type *) \ - ((char *)(member_ptr) \ - - container_off(containing_type, member)) \ - + check_types_match(*(member_ptr), ((containing_type *)0)->member)) - - -/** - * container_of_or_null - get pointer to enclosing structure, or NULL - * @member_ptr: pointer to the structure member - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type, unless it - * is given NULL, in which case it also returns NULL. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info_allowing_null(struct foo *foo) - * { - * return container_of_or_null(foo, struct info, my_foo); - * } - */ -static inline char *container_of_or_null_(void *member_ptr, size_t offset) -{ - return member_ptr ? (char *)member_ptr - offset : NULL; -} -#define container_of_or_null(member_ptr, containing_type, member) \ - ((containing_type *) \ - container_of_or_null_(member_ptr, \ - container_off(containing_type, member)) \ - + check_types_match(*(member_ptr), ((containing_type *)0)->member)) - -/** - * container_off - get offset to enclosing structure - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does - * typechecking and figures out the offset to the enclosing type. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info(struct foo *foo) - * { - * size_t off = container_off(struct info, my_foo); - * return (void *)((char *)foo - off); - * } - */ -#define container_off(containing_type, member) \ - offsetof(containing_type, member) - -/** - * container_of_var - get pointer to enclosing structure using a variable - * @member_ptr: pointer to the structure member - * @container_var: a pointer of same type as this member's container - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type. - * - * Example: - * static struct info *foo_to_i(struct foo *foo) - * { - * struct info *i = container_of_var(foo, i, my_foo); - * return i; - * } - */ -#if HAVE_TYPEOF -#define container_of_var(member_ptr, container_var, member) \ - container_of(member_ptr, typeof(*container_var), member) -#else -#define container_of_var(member_ptr, container_var, member) \ - ((void *)((char *)(member_ptr) - \ - container_off_var(container_var, member))) -#endif - -/** - * container_off_var - get offset of a field in enclosing structure - * @container_var: a pointer to a container structure - * @member: the name of a member within the structure. - * - * Given (any) pointer to a structure and a its member name, this - * macro does pointer subtraction to return offset of member in a - * structure memory layout. - * - */ -#if HAVE_TYPEOF -#define container_off_var(var, member) \ - container_off(typeof(*var), member) -#else -#define container_off_var(var, member) \ - ((const char *)&(var)->member - (const char *)(var)) -#endif - -#endif /* CCAN_CONTAINER_OF_H */ diff --git a/ccan/container_of/test/compile_fail-bad-type.c b/ccan/container_of/test/compile_fail-bad-type.c @@ -1,22 +0,0 @@ -#include <ccan/container_of/container_of.h> -#include <stdlib.h> - -struct foo { - int a; - char b; -}; - -int main(void) -{ - struct foo foo = { .a = 1, .b = 2 }; - int *intp = &foo.a; - char *p; - -#ifdef FAIL - /* p is a char *, but this gives a struct foo * */ - p = container_of(intp, struct foo, a); -#else - p = (char *)intp; -#endif - return p == NULL; -} diff --git a/ccan/container_of/test/compile_fail-types.c b/ccan/container_of/test/compile_fail-types.c @@ -1,22 +0,0 @@ -#include <ccan/container_of/container_of.h> -#include <stdlib.h> - -struct foo { - int a; - char b; -}; - -int main(void) -{ - struct foo foo = { .a = 1, .b = 2 }, *foop; - int *intp = &foo.a; - -#ifdef FAIL - /* b is a char, but intp is an int * */ - foop = container_of(intp, struct foo, b); -#else - foop = NULL; -#endif - (void) foop; /* Suppress unused-but-set-variable warning. */ - return intp == NULL; -} diff --git a/ccan/container_of/test/compile_fail-var-types.c b/ccan/container_of/test/compile_fail-var-types.c @@ -1,25 +0,0 @@ -#include <ccan/container_of/container_of.h> -#include <stdlib.h> - -struct foo { - int a; - char b; -}; - -int main(void) -{ - struct foo foo = { .a = 1, .b = 2 }, *foop; - int *intp = &foo.a; - -#ifdef FAIL - /* b is a char, but intp is an int * */ - foop = container_of_var(intp, foop, b); -#if !HAVE_TYPEOF -#error "Unfortunately we don't fail if we don't have typeof." -#endif -#else - foop = NULL; -#endif - (void) foop; /* Suppress unused-but-set-variable warning. */ - return intp == NULL; -} diff --git a/ccan/container_of/test/run.c b/ccan/container_of/test/run.c @@ -1,30 +0,0 @@ -#include <ccan/container_of/container_of.h> -#include <ccan/tap/tap.h> - -struct foo { - int a; - char b; -}; - -int main(void) -{ - struct foo foo = { .a = 1, .b = 2 }; - int *intp = &foo.a; - char *charp = &foo.b; - - plan_tests(12); - ok1(container_of(intp, struct foo, a) == &foo); - ok1(container_of(charp, struct foo, b) == &foo); - ok1(container_of_or_null(intp, struct foo, a) == &foo); - ok1(container_of_or_null(charp, struct foo, b) == &foo); - ok1(container_of_or_null((int *)NULL, struct foo, a) == NULL); - ok1(container_of_or_null((char *)NULL, struct foo, b) == NULL); - ok1(container_of_var(intp, &foo, a) == &foo); - ok1(container_of_var(charp, &foo, b) == &foo); - - ok1(container_off(struct foo, a) == 0); - ok1(container_off(struct foo, b) == offsetof(struct foo, b)); - ok1(container_off_var(&foo, a) == 0); - ok1(container_off_var(&foo, b) == offsetof(struct foo, b)); - return exit_status(); -} diff --git a/ccan/hash/LICENSE b/ccan/hash/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/hash/_info b/ccan/hash/_info @@ -1,32 +0,0 @@ -#include "config.h" -#include <string.h> -#include <stdio.h> - -/** - * hash - routines for hashing bytes - * - * When creating a hash table it's important to have a hash function - * which mixes well and is fast. This package supplies such functions. - * - * The hash functions come in two flavors: the normal ones and the - * stable ones. The normal ones can vary from machine-to-machine and - * may change if we find better or faster hash algorithms in future. - * The stable ones will always give the same results on any computer, - * and on any version of this package. - * - * License: CC0 (Public domain) - * Maintainer: Rusty Russell <rusty@rustcorp.com.au> - * Author: Bob Jenkins <bob_jenkins@burtleburtle.net> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/build_assert\n"); - return 0; - } - - return 1; -} diff --git a/ccan/hash/hash.c b/ccan/hash/hash.c @@ -1,926 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hash_word(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -------------------------------------------------------------------------------- -*/ -//#define SELF_TEST 1 - -#if 0 -#include <stdio.h> /* defines printf for tests */ -#include <time.h> /* defines time_t for timings in the test */ -#include <stdint.h> /* defines uint32_t etc */ -#include <sys/param.h> /* attempt to define endianness */ - -#ifdef linux -# include <endian.h> /* attempt to define endianness */ -#endif - -/* - * My best guess at if you are big-endian or little-endian. This may - * need adjustment. - */ -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(i386) || defined(__i386__) || defined(__i486__) || \ - defined(__i586__) || defined(__i686__) || defined(__x86_64) || \ - defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#else -# error Unknown endian -#endif -#endif /* old hash.c headers. */ - -#include "hash.h" - -#if HAVE_LITTLE_ENDIAN -#define HASH_LITTLE_ENDIAN 1 -#define HASH_BIG_ENDIAN 0 -#elif HAVE_BIG_ENDIAN -#define HASH_LITTLE_ENDIAN 0 -#define HASH_BIG_ENDIAN 1 -#else -#error Unknown endian -#endif - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* --------------------------------------------------------------------- - This works on all machines. To be useful, it requires - -- that the key be an array of uint32_t's, and - -- that the length be the number of uint32_t's in the key - - The function hash_word() is identical to hashlittle() on little-endian - machines, and identical to hashbig() on big-endian machines, - except that the length has to be measured in uint32_ts rather than in - bytes. hashlittle() is more complicated than hash_word() only because - hashlittle() has to dance around fitting the key bytes into registers. --------------------------------------------------------------------- -*/ -uint32_t hash_u32( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t initval) /* the previous hash, or an arbitrary value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - return c; -} - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - val2 : IN: can be any 4-byte value OUT: second 32 bit hash. -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. Note that the return value is better -mixed than val2, so use that first. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h); - -By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this -code any way you wish, private, educational, or commercial. It's free. - -Use for hash table lookup, or anything where one collision in 2^^32 is -acceptable. Do NOT use for cryptographic purposes. -------------------------------------------------------------------------------- -*/ - -static uint32_t hashlittle( const void *key, size_t length, uint32_t *val2 ) -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *val2; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - * - * Not on my testing with gcc 4.5 on an intel i5 CPU, at least --RR. - */ -#if 0 - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - *val2 = b; - return c; -} - -/* - * hashbig(): - * This is the same as hash_word() on big-endian machines. It is different - * from hashlittle() on all machines. hashbig() takes advantage of - * big-endian byte ordering. - */ -static uint32_t hashbig( const void *key, size_t length, uint32_t *val2) -{ - uint32_t a,b,c; - union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *val2; - - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - const uint8_t *k8; - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - * - * Not on my testing with gcc 4.5 on an intel i5 CPU, at least --RR. - */ -#if 0 - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; - case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; - case 5 : b+=k[1]&0xff000000; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff00; break; - case 2 : a+=k[0]&0xffff0000; break; - case 1 : a+=k[0]&0xff000000; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k8[0])<<24; break; - case 0 : return c; - } - -#endif /* !VALGRIND */ - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[11]; - case 11: c+=((uint32_t)k[10])<<8; - case 10: c+=((uint32_t)k[9])<<16; - case 9 : c+=((uint32_t)k[8])<<24; - case 8 : b+=k[7]; - case 7 : b+=((uint32_t)k[6])<<8; - case 6 : b+=((uint32_t)k[5])<<16; - case 5 : b+=((uint32_t)k[4])<<24; - case 4 : a+=k[3]; - case 3 : a+=((uint32_t)k[2])<<8; - case 2 : a+=((uint32_t)k[1])<<16; - case 1 : a+=((uint32_t)k[0])<<24; - break; - case 0 : return c; - } - } - - final(a,b,c); - *val2 = b; - return c; -} - -/* I basically use hashlittle here, but use native endian within each - * element. This delivers least-surprise: hash such as "int arr[] = { - * 1, 2 }; hash_stable(arr, 2, 0);" will be the same on big and little - * endian machines, even though a bytewise hash wouldn't be. */ -uint64_t hash64_stable_64(const void *key, size_t n, uint64_t base) -{ - const uint64_t *k = key; - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)n*8) + (base >> 32) + base; - - while (n > 3) { - a += (uint32_t)k[0]; - b += (uint32_t)(k[0] >> 32); - c += (uint32_t)k[1]; - mix(a,b,c); - a += (uint32_t)(k[1] >> 32); - b += (uint32_t)k[2]; - c += (uint32_t)(k[2] >> 32); - mix(a,b,c); - n -= 3; - k += 3; - } - switch (n) { - case 2: - a += (uint32_t)k[0]; - b += (uint32_t)(k[0] >> 32); - c += (uint32_t)k[1]; - mix(a,b,c); - a += (uint32_t)(k[1] >> 32); - break; - case 1: - a += (uint32_t)k[0]; - b += (uint32_t)(k[0] >> 32); - break; - case 0: - return c; - } - final(a,b,c); - return ((uint64_t)b << 32) | c; -} - -uint64_t hash64_stable_32(const void *key, size_t n, uint64_t base) -{ - const uint32_t *k = key; - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)n*4) + (base >> 32) + base; - - while (n > 3) { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - - n -= 3; - k += 3; - } - switch (n) { - case 2: - b += (uint32_t)k[1]; - case 1: - a += (uint32_t)k[0]; - break; - case 0: - return c; - } - final(a,b,c); - return ((uint64_t)b << 32) | c; -} - -uint64_t hash64_stable_16(const void *key, size_t n, uint64_t base) -{ - const uint16_t *k = key; - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)n*2) + (base >> 32) + base; - - while (n > 6) { - a += (uint32_t)k[0] + ((uint32_t)k[1] << 16); - b += (uint32_t)k[2] + ((uint32_t)k[3] << 16); - c += (uint32_t)k[4] + ((uint32_t)k[5] << 16); - mix(a,b,c); - - n -= 6; - k += 6; - } - - switch (n) { - case 5: - c += (uint32_t)k[4]; - case 4: - b += ((uint32_t)k[3] << 16); - case 3: - b += (uint32_t)k[2]; - case 2: - a += ((uint32_t)k[1] << 16); - case 1: - a += (uint32_t)k[0]; - break; - case 0: - return c; - } - final(a,b,c); - return ((uint64_t)b << 32) | c; -} - -uint64_t hash64_stable_8(const void *key, size_t n, uint64_t base) -{ - uint32_t b32 = base + (base >> 32); - uint32_t lower = hashlittle(key, n, &b32); - - return ((uint64_t)b32 << 32) | lower; -} - -uint32_t hash_any(const void *key, size_t length, uint32_t base) -{ - if (HASH_BIG_ENDIAN) - return hashbig(key, length, &base); - else - return hashlittle(key, length, &base); -} - -uint32_t hash_stable_64(const void *key, size_t n, uint32_t base) -{ - return hash64_stable_64(key, n, base); -} - -uint32_t hash_stable_32(const void *key, size_t n, uint32_t base) -{ - return hash64_stable_32(key, n, base); -} - -uint32_t hash_stable_16(const void *key, size_t n, uint32_t base) -{ - return hash64_stable_16(key, n, base); -} - -uint32_t hash_stable_8(const void *key, size_t n, uint32_t base) -{ - return hashlittle(key, n, &base); -} - -/* Jenkins' lookup8 is a 64 bit hash, but he says it's obsolete. Use - * the plain one and recombine into 64 bits. */ -uint64_t hash64_any(const void *key, size_t length, uint64_t base) -{ - uint32_t b32 = base + (base >> 32); - uint32_t lower; - - if (HASH_BIG_ENDIAN) - lower = hashbig(key, length, &b32); - else - lower = hashlittle(key, length, &b32); - - return ((uint64_t)b32 << 32) | lower; -} - -#ifdef SELF_TEST - -/* used for timings */ -void driver1() -{ - uint8_t buf[256]; - uint32_t i; - uint32_t h=0; - time_t a,z; - - time(&a); - for (i=0; i<256; ++i) buf[i] = 'x'; - for (i=0; i<1; ++i) - { - h = hashlittle(&buf[0],1,h); - } - time(&z); - if (z-a > 0) printf("time %d %.8x\n", z-a, h); -} - -/* check that every input bit changes every output bit half the time */ -#define HASHSTATE 1 -#define HASHLEN 1 -#define MAXPAIR 60 -#define MAXLEN 70 -void driver2() -{ - uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; - uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; - uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; - uint32_t x[HASHSTATE],y[HASHSTATE]; - uint32_t hlen; - - printf("No more than %d trials should ever be needed \n",MAXPAIR/2); - for (hlen=0; hlen < MAXLEN; ++hlen) - { - z=0; - for (i=0; i<hlen; ++i) /*----------------------- for each input byte, */ - { - for (j=0; j<8; ++j) /*------------------------ for each input bit, */ - { - for (m=1; m<8; ++m) /*------------ for several possible initvals, */ - { - for (l=0; l<HASHSTATE; ++l) - e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0); - - /*---- check that every output bit is affected by that input bit */ - for (k=0; k<MAXPAIR; k+=2) - { - uint32_t finished=1; - /* keys have one bit different */ - for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;} - /* have a and b be two keys differing in only one bit */ - a[i] ^= (k<<j); - a[i] ^= (k>>(8-j)); - c[0] = hashlittle(a, hlen, m); - b[i] ^= ((k+1)<<j); - b[i] ^= ((k+1)>>(8-j)); - d[0] = hashlittle(b, hlen, m); - /* check every bit is 1, 0, set, and not set at least once */ - for (l=0; l<HASHSTATE; ++l) - { - e[l] &= (c[l]^d[l]); - f[l] &= ~(c[l]^d[l]); - g[l] &= c[l]; - h[l] &= ~c[l]; - x[l] &= d[l]; - y[l] &= ~d[l]; - if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0; - } - if (finished) break; - } - if (k>z) z=k; - if (k==MAXPAIR) - { - printf("Some bit didn't change: "); - printf("%.8x %.8x %.8x %.8x %.8x %.8x ", - e[0],f[0],g[0],h[0],x[0],y[0]); - printf("i %d j %d m %d len %d\n", i, j, m, hlen); - } - if (z==MAXPAIR) goto done; - } - } - } - done: - if (z < MAXPAIR) - { - printf("Mix success %2d bytes %2d initvals ",i,m); - printf("required %d trials\n", z/2); - } - } - printf("\n"); -} - -/* Check for reading beyond the end of the buffer and alignment problems */ -void driver3() -{ - uint8_t buf[MAXLEN+20], *b; - uint32_t len; - uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; - uint32_t h; - uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; - uint32_t i; - uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; - uint32_t j; - uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; - uint32_t ref,x,y; - uint8_t *p; - - printf("Endianness. These lines should all be the same (for values filled in):\n"); - printf("%.8x %.8x %.8x\n", - hash_word((const uint32_t *)q, (sizeof(q)-1)/4, 13), - hash_word((const uint32_t *)q, (sizeof(q)-5)/4, 13), - hash_word((const uint32_t *)q, (sizeof(q)-9)/4, 13)); - p = q; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qq[1]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqq[2]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqqq[3]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - printf("\n"); - - /* check that hashlittle2 and hashlittle produce the same results */ - i=47; j=0; - hashlittle2(q, sizeof(q), &i, &j); - if (hashlittle(q, sizeof(q), 47) != i) - printf("hashlittle2 and hashlittle mismatch\n"); - - /* check that hash_word2 and hash_word produce the same results */ - len = 0xdeadbeef; - i=47, j=0; - hash_word2(&len, 1, &i, &j); - if (hash_word(&len, 1, 47) != i) - printf("hash_word2 and hash_word mismatch %x %x\n", - i, hash_word(&len, 1, 47)); - - /* check hashlittle doesn't read before or after the ends of the string */ - for (h=0, b=buf+1; h<8; ++h, ++b) - { - for (i=0; i<MAXLEN; ++i) - { - len = i; - for (j=0; j<i; ++j) *(b+j)=0; - - /* these should all be equal */ - ref = hashlittle(b, len, (uint32_t)1); - *(b+i)=(uint8_t)~0; - *(b-1)=(uint8_t)~0; - x = hashlittle(b, len, (uint32_t)1); - y = hashlittle(b, len, (uint32_t)1); - if ((ref != x) || (ref != y)) - { - printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y, - h, i); - } - } - } -} - -/* check for problems with nulls */ - void driver4() -{ - uint8_t buf[1]; - uint32_t h,i,state[HASHSTATE]; - - - buf[0] = ~0; - for (i=0; i<HASHSTATE; ++i) state[i] = 1; - printf("These should all be different\n"); - for (i=0, h=0; i<8; ++i) - { - h = hashlittle(buf, 0, h); - printf("%2ld 0-byte strings, hash is %.8x\n", i, h); - } -} - - -int main() -{ - driver1(); /* test that the key is hashed: used for timings */ - driver2(); /* test that whole key is hashed thoroughly */ - driver3(); /* test that nothing but the key is hashed */ - driver4(); /* test hashing multiple buffers (all buffers are null) */ - return 1; -} - -#endif /* SELF_TEST */ diff --git a/ccan/hash/hash.h b/ccan/hash/hash.h @@ -1,313 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_HASH_H -#define CCAN_HASH_H -#include "config.h" -#include <stdint.h> -#include <stdlib.h> -#include <ccan/build_assert/build_assert.h> - -/* Stolen mostly from: lookup3.c, by Bob Jenkins, May 2006, Public Domain. - * - * http://burtleburtle.net/bob/c/lookup3.c - */ - -/** - * hash - fast hash of an array for internal use - * @p: the array or pointer to first element - * @num: the number of elements to hash - * @base: the base number to roll into the hash (usually 0) - * - * The memory region pointed to by p is combined with the base to form - * a 32-bit hash. - * - * This hash will have different results on different machines, so is - * only useful for internal hashes (ie. not hashes sent across the - * network or saved to disk). - * - * It may also change with future versions: it could even detect at runtime - * what the fastest hash to use is. - * - * See also: hash64, hash_stable. - * - * Example: - * #include <ccan/hash/hash.h> - * #include <err.h> - * #include <stdio.h> - * #include <string.h> - * - * // Simple demonstration: idential strings will have the same hash, but - * // two different strings will probably not. - * int main(int argc, char *argv[]) - * { - * uint32_t hash1, hash2; - * - * if (argc != 3) - * err(1, "Usage: %s <string1> <string2>", argv[0]); - * - * hash1 = hash(argv[1], strlen(argv[1]), 0); - * hash2 = hash(argv[2], strlen(argv[2]), 0); - * printf("Hash is %s\n", hash1 == hash2 ? "same" : "different"); - * return 0; - * } - */ -#define hash(p, num, base) hash_any((p), (num)*sizeof(*(p)), (base)) - -/** - * hash_stable - hash of an array for external use - * @p: the array or pointer to first element - * @num: the number of elements to hash - * @base: the base number to roll into the hash (usually 0) - * - * The array of simple integer types pointed to by p is combined with - * the base to form a 32-bit hash. - * - * This hash will have the same results on different machines, so can - * be used for external hashes (ie. hashes sent across the network or - * saved to disk). The results will not change in future versions of - * this module. - * - * Note that it is only legal to hand an array of simple integer types - * to this hash (ie. char, uint16_t, int64_t, etc). In these cases, - * the same values will have the same hash result, even though the - * memory representations of integers depend on the machine - * endianness. - * - * See also: - * hash64_stable - * - * Example: - * #include <ccan/hash/hash.h> - * #include <err.h> - * #include <stdio.h> - * #include <string.h> - * - * int main(int argc, char *argv[]) - * { - * if (argc != 2) - * err(1, "Usage: %s <string-to-hash>", argv[0]); - * - * printf("Hash stable result is %u\n", - * hash_stable(argv[1], strlen(argv[1]), 0)); - * return 0; - * } - */ -#define hash_stable(p, num, base) \ - (BUILD_ASSERT_OR_ZERO(sizeof(*(p)) == 8 || sizeof(*(p)) == 4 \ - || sizeof(*(p)) == 2 || sizeof(*(p)) == 1) + \ - sizeof(*(p)) == 8 ? hash_stable_64((p), (num), (base)) \ - : sizeof(*(p)) == 4 ? hash_stable_32((p), (num), (base)) \ - : sizeof(*(p)) == 2 ? hash_stable_16((p), (num), (base)) \ - : hash_stable_8((p), (num), (base))) - -/** - * hash_u32 - fast hash an array of 32-bit values for internal use - * @key: the array of uint32_t - * @num: the number of elements to hash - * @base: the base number to roll into the hash (usually 0) - * - * The array of uint32_t pointed to by @key is combined with the base - * to form a 32-bit hash. This is 2-3 times faster than hash() on small - * arrays, but the advantage vanishes over large hashes. - * - * This hash will have different results on different machines, so is - * only useful for internal hashes (ie. not hashes sent across the - * network or saved to disk). - */ -uint32_t hash_u32(const uint32_t *key, size_t num, uint32_t base); - -/** - * hash_string - very fast hash of an ascii string - * @str: the nul-terminated string - * - * The string is hashed, using a hash function optimized for ASCII and - * similar strings. It's weaker than the other hash functions. - * - * This hash may have different results on different machines, so is - * only useful for internal hashes (ie. not hashes sent across the - * network or saved to disk). The results will be different from the - * other hash functions in this module, too. - */ -static inline uint32_t hash_string(const char *string) -{ - /* This is Karl Nelson <kenelson@ece.ucdavis.edu>'s X31 hash. - * It's a little faster than the (much better) lookup3 hash(): 56ns vs - * 84ns on my 2GHz Intel Core Duo 2 laptop for a 10 char string. */ - uint32_t ret; - - for (ret = 0; *string; string++) - ret = (ret << 5) - ret + *string; - - return ret; -} - -/** - * hash64 - fast 64-bit hash of an array for internal use - * @p: the array or pointer to first element - * @num: the number of elements to hash - * @base: the 64-bit base number to roll into the hash (usually 0) - * - * The memory region pointed to by p is combined with the base to form - * a 64-bit hash. - * - * This hash will have different results on different machines, so is - * only useful for internal hashes (ie. not hashes sent across the - * network or saved to disk). - * - * It may also change with future versions: it could even detect at runtime - * what the fastest hash to use is. - * - * See also: hash. - * - * Example: - * #include <ccan/hash/hash.h> - * #include <err.h> - * #include <stdio.h> - * #include <string.h> - * - * // Simple demonstration: idential strings will have the same hash, but - * // two different strings will probably not. - * int main(int argc, char *argv[]) - * { - * uint64_t hash1, hash2; - * - * if (argc != 3) - * err(1, "Usage: %s <string1> <string2>", argv[0]); - * - * hash1 = hash64(argv[1], strlen(argv[1]), 0); - * hash2 = hash64(argv[2], strlen(argv[2]), 0); - * printf("Hash is %s\n", hash1 == hash2 ? "same" : "different"); - * return 0; - * } - */ -#define hash64(p, num, base) hash64_any((p), (num)*sizeof(*(p)), (base)) - -/** - * hash64_stable - 64 bit hash of an array for external use - * @p: the array or pointer to first element - * @num: the number of elements to hash - * @base: the base number to roll into the hash (usually 0) - * - * The array of simple integer types pointed to by p is combined with - * the base to form a 64-bit hash. - * - * This hash will have the same results on different machines, so can - * be used for external hashes (ie. hashes sent across the network or - * saved to disk). The results will not change in future versions of - * this module. - * - * Note that it is only legal to hand an array of simple integer types - * to this hash (ie. char, uint16_t, int64_t, etc). In these cases, - * the same values will have the same hash result, even though the - * memory representations of integers depend on the machine - * endianness. - * - * See also: - * hash_stable - * - * Example: - * #include <ccan/hash/hash.h> - * #include <err.h> - * #include <stdio.h> - * #include <string.h> - * - * int main(int argc, char *argv[]) - * { - * if (argc != 2) - * err(1, "Usage: %s <string-to-hash>", argv[0]); - * - * printf("Hash stable result is %llu\n", - * (long long)hash64_stable(argv[1], strlen(argv[1]), 0)); - * return 0; - * } - */ -#define hash64_stable(p, num, base) \ - (BUILD_ASSERT_OR_ZERO(sizeof(*(p)) == 8 || sizeof(*(p)) == 4 \ - || sizeof(*(p)) == 2 || sizeof(*(p)) == 1) + \ - sizeof(*(p)) == 8 ? hash64_stable_64((p), (num), (base)) \ - : sizeof(*(p)) == 4 ? hash64_stable_32((p), (num), (base)) \ - : sizeof(*(p)) == 2 ? hash64_stable_16((p), (num), (base)) \ - : hash64_stable_8((p), (num), (base))) - - -/** - * hashl - fast 32/64-bit hash of an array for internal use - * @p: the array or pointer to first element - * @num: the number of elements to hash - * @base: the base number to roll into the hash (usually 0) - * - * This is either hash() or hash64(), on 32/64 bit long machines. - */ -#define hashl(p, num, base) \ - (BUILD_ASSERT_OR_ZERO(sizeof(long) == sizeof(uint32_t) \ - || sizeof(long) == sizeof(uint64_t)) + \ - (sizeof(long) == sizeof(uint64_t) \ - ? hash64((p), (num), (base)) : hash((p), (num), (base)))) - -/* Our underlying operations. */ -uint32_t hash_any(const void *key, size_t length, uint32_t base); -uint32_t hash_stable_64(const void *key, size_t n, uint32_t base); -uint32_t hash_stable_32(const void *key, size_t n, uint32_t base); -uint32_t hash_stable_16(const void *key, size_t n, uint32_t base); -uint32_t hash_stable_8(const void *key, size_t n, uint32_t base); -uint64_t hash64_any(const void *key, size_t length, uint64_t base); -uint64_t hash64_stable_64(const void *key, size_t n, uint64_t base); -uint64_t hash64_stable_32(const void *key, size_t n, uint64_t base); -uint64_t hash64_stable_16(const void *key, size_t n, uint64_t base); -uint64_t hash64_stable_8(const void *key, size_t n, uint64_t base); - -/** - * hash_pointer - hash a pointer for internal use - * @p: the pointer value to hash - * @base: the base number to roll into the hash (usually 0) - * - * The pointer p (not what p points to!) is combined with the base to form - * a 32-bit hash. - * - * This hash will have different results on different machines, so is - * only useful for internal hashes (ie. not hashes sent across the - * network or saved to disk). - * - * Example: - * #include <ccan/hash/hash.h> - * - * // Code to keep track of memory regions. - * struct region { - * struct region *chain; - * void *start; - * unsigned int size; - * }; - * // We keep a simple hash table. - * static struct region *region_hash[128]; - * - * static void add_region(struct region *r) - * { - * unsigned int h = hash_pointer(r->start, 0); - * - * r->chain = region_hash[h]; - * region_hash[h] = r->chain; - * } - * - * static struct region *find_region(const void *start) - * { - * struct region *r; - * - * for (r = region_hash[hash_pointer(start, 0)]; r; r = r->chain) - * if (r->start == start) - * return r; - * return NULL; - * } - */ -static inline uint32_t hash_pointer(const void *p, uint32_t base) -{ - if (sizeof(p) % sizeof(uint32_t) == 0) { - /* This convoluted union is the right way of aliasing. */ - union { - uint32_t a[sizeof(p) / sizeof(uint32_t)]; - const void *p; - } u; - u.p = p; - return hash_u32(u.a, sizeof(p) / sizeof(uint32_t), base); - } else - return hash(&p, 1, base); -} -#endif /* HASH_H */ diff --git a/ccan/hash/test/api-hash_stable.c b/ccan/hash/test/api-hash_stable.c @@ -1,300 +0,0 @@ -#include <ccan/hash/hash.h> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define ARRAY_WORDS 5 - -int main(int argc, char *argv[]) -{ - unsigned int i; - uint8_t u8array[ARRAY_WORDS]; - uint16_t u16array[ARRAY_WORDS]; - uint32_t u32array[ARRAY_WORDS]; - uint64_t u64array[ARRAY_WORDS]; - - /* Initialize arrays. */ - for (i = 0; i < ARRAY_WORDS; i++) { - u8array[i] = i; - u16array[i] = i; - u32array[i] = i; - u64array[i] = i; - } - - plan_tests(264); - - /* hash_stable is API-guaranteed. */ - ok1(hash_stable(u8array, ARRAY_WORDS, 0) == 0x1d4833cc); - ok1(hash_stable(u8array, ARRAY_WORDS, 1) == 0x37125e2 ); - ok1(hash_stable(u8array, ARRAY_WORDS, 2) == 0x330a007a); - ok1(hash_stable(u8array, ARRAY_WORDS, 4) == 0x7b0df29b); - ok1(hash_stable(u8array, ARRAY_WORDS, 8) == 0xe7e5d741); - ok1(hash_stable(u8array, ARRAY_WORDS, 16) == 0xaae57471); - ok1(hash_stable(u8array, ARRAY_WORDS, 32) == 0xc55399e5); - ok1(hash_stable(u8array, ARRAY_WORDS, 64) == 0x67f21f7 ); - ok1(hash_stable(u8array, ARRAY_WORDS, 128) == 0x1d795b71); - ok1(hash_stable(u8array, ARRAY_WORDS, 256) == 0xeb961671); - ok1(hash_stable(u8array, ARRAY_WORDS, 512) == 0xc2597247); - ok1(hash_stable(u8array, ARRAY_WORDS, 1024) == 0x3f5c4d75); - ok1(hash_stable(u8array, ARRAY_WORDS, 2048) == 0xe65cf4f9); - ok1(hash_stable(u8array, ARRAY_WORDS, 4096) == 0xf2cd06cb); - ok1(hash_stable(u8array, ARRAY_WORDS, 8192) == 0x443041e1); - ok1(hash_stable(u8array, ARRAY_WORDS, 16384) == 0xdfc618f5); - ok1(hash_stable(u8array, ARRAY_WORDS, 32768) == 0x5e3d5b97); - ok1(hash_stable(u8array, ARRAY_WORDS, 65536) == 0xd5f64730); - ok1(hash_stable(u8array, ARRAY_WORDS, 131072) == 0x372bbecc); - ok1(hash_stable(u8array, ARRAY_WORDS, 262144) == 0x7c194c8d); - ok1(hash_stable(u8array, ARRAY_WORDS, 524288) == 0x16cbb416); - ok1(hash_stable(u8array, ARRAY_WORDS, 1048576) == 0x53e99222); - ok1(hash_stable(u8array, ARRAY_WORDS, 2097152) == 0x6394554a); - ok1(hash_stable(u8array, ARRAY_WORDS, 4194304) == 0xd83a506d); - ok1(hash_stable(u8array, ARRAY_WORDS, 8388608) == 0x7619d9a4); - ok1(hash_stable(u8array, ARRAY_WORDS, 16777216) == 0xfe98e5f6); - ok1(hash_stable(u8array, ARRAY_WORDS, 33554432) == 0x6c262927); - ok1(hash_stable(u8array, ARRAY_WORDS, 67108864) == 0x3f0106fd); - ok1(hash_stable(u8array, ARRAY_WORDS, 134217728) == 0xc91e3a28); - ok1(hash_stable(u8array, ARRAY_WORDS, 268435456) == 0x14229579); - ok1(hash_stable(u8array, ARRAY_WORDS, 536870912) == 0x9dbefa76); - ok1(hash_stable(u8array, ARRAY_WORDS, 1073741824) == 0xb05c0c78); - ok1(hash_stable(u8array, ARRAY_WORDS, 2147483648U) == 0x88f24d81); - - ok1(hash_stable(u16array, ARRAY_WORDS, 0) == 0xecb5f507); - ok1(hash_stable(u16array, ARRAY_WORDS, 1) == 0xadd666e6); - ok1(hash_stable(u16array, ARRAY_WORDS, 2) == 0xea0f214c); - ok1(hash_stable(u16array, ARRAY_WORDS, 4) == 0xae4051ba); - ok1(hash_stable(u16array, ARRAY_WORDS, 8) == 0x6ed28026); - ok1(hash_stable(u16array, ARRAY_WORDS, 16) == 0xa3917a19); - ok1(hash_stable(u16array, ARRAY_WORDS, 32) == 0xf370f32b); - ok1(hash_stable(u16array, ARRAY_WORDS, 64) == 0x807af460); - ok1(hash_stable(u16array, ARRAY_WORDS, 128) == 0xb4c8cd83); - ok1(hash_stable(u16array, ARRAY_WORDS, 256) == 0xa10cb5b0); - ok1(hash_stable(u16array, ARRAY_WORDS, 512) == 0x8b7d7387); - ok1(hash_stable(u16array, ARRAY_WORDS, 1024) == 0x9e49d1c ); - ok1(hash_stable(u16array, ARRAY_WORDS, 2048) == 0x288830d1); - ok1(hash_stable(u16array, ARRAY_WORDS, 4096) == 0xbe078a43); - ok1(hash_stable(u16array, ARRAY_WORDS, 8192) == 0xa16d5d88); - ok1(hash_stable(u16array, ARRAY_WORDS, 16384) == 0x46839fcd); - ok1(hash_stable(u16array, ARRAY_WORDS, 32768) == 0x9db9bd4f); - ok1(hash_stable(u16array, ARRAY_WORDS, 65536) == 0xedff58f8); - ok1(hash_stable(u16array, ARRAY_WORDS, 131072) == 0x95ecef18); - ok1(hash_stable(u16array, ARRAY_WORDS, 262144) == 0x23c31b7d); - ok1(hash_stable(u16array, ARRAY_WORDS, 524288) == 0x1d85c7d0); - ok1(hash_stable(u16array, ARRAY_WORDS, 1048576) == 0x25218842); - ok1(hash_stable(u16array, ARRAY_WORDS, 2097152) == 0x711d985c); - ok1(hash_stable(u16array, ARRAY_WORDS, 4194304) == 0x85470eca); - ok1(hash_stable(u16array, ARRAY_WORDS, 8388608) == 0x99ed4ceb); - ok1(hash_stable(u16array, ARRAY_WORDS, 16777216) == 0x67b3710c); - ok1(hash_stable(u16array, ARRAY_WORDS, 33554432) == 0x77f1ab35); - ok1(hash_stable(u16array, ARRAY_WORDS, 67108864) == 0x81f688aa); - ok1(hash_stable(u16array, ARRAY_WORDS, 134217728) == 0x27b56ca5); - ok1(hash_stable(u16array, ARRAY_WORDS, 268435456) == 0xf21ba203); - ok1(hash_stable(u16array, ARRAY_WORDS, 536870912) == 0xd48d1d1 ); - ok1(hash_stable(u16array, ARRAY_WORDS, 1073741824) == 0xa542b62d); - ok1(hash_stable(u16array, ARRAY_WORDS, 2147483648U) == 0xa04c7058); - - ok1(hash_stable(u32array, ARRAY_WORDS, 0) == 0x13305f8c); - ok1(hash_stable(u32array, ARRAY_WORDS, 1) == 0x171abf74); - ok1(hash_stable(u32array, ARRAY_WORDS, 2) == 0x7646fcc7); - ok1(hash_stable(u32array, ARRAY_WORDS, 4) == 0xa758ed5); - ok1(hash_stable(u32array, ARRAY_WORDS, 8) == 0x2dedc2e4); - ok1(hash_stable(u32array, ARRAY_WORDS, 16) == 0x28e2076b); - ok1(hash_stable(u32array, ARRAY_WORDS, 32) == 0xb73091c5); - ok1(hash_stable(u32array, ARRAY_WORDS, 64) == 0x87daf5db); - ok1(hash_stable(u32array, ARRAY_WORDS, 128) == 0xa16dfe20); - ok1(hash_stable(u32array, ARRAY_WORDS, 256) == 0x300c63c3); - ok1(hash_stable(u32array, ARRAY_WORDS, 512) == 0x255c91fc); - ok1(hash_stable(u32array, ARRAY_WORDS, 1024) == 0x6357b26); - ok1(hash_stable(u32array, ARRAY_WORDS, 2048) == 0x4bc5f339); - ok1(hash_stable(u32array, ARRAY_WORDS, 4096) == 0x1301617c); - ok1(hash_stable(u32array, ARRAY_WORDS, 8192) == 0x506792c9); - ok1(hash_stable(u32array, ARRAY_WORDS, 16384) == 0xcd596705); - ok1(hash_stable(u32array, ARRAY_WORDS, 32768) == 0xa8713cac); - ok1(hash_stable(u32array, ARRAY_WORDS, 65536) == 0x94d9794); - ok1(hash_stable(u32array, ARRAY_WORDS, 131072) == 0xac753e8); - ok1(hash_stable(u32array, ARRAY_WORDS, 262144) == 0xcd8bdd20); - ok1(hash_stable(u32array, ARRAY_WORDS, 524288) == 0xd44faf80); - ok1(hash_stable(u32array, ARRAY_WORDS, 1048576) == 0x2547ccbe); - ok1(hash_stable(u32array, ARRAY_WORDS, 2097152) == 0xbab06dbc); - ok1(hash_stable(u32array, ARRAY_WORDS, 4194304) == 0xaac0e882); - ok1(hash_stable(u32array, ARRAY_WORDS, 8388608) == 0x443f48d0); - ok1(hash_stable(u32array, ARRAY_WORDS, 16777216) == 0xdff49fcc); - ok1(hash_stable(u32array, ARRAY_WORDS, 33554432) == 0x9ce0fd65); - ok1(hash_stable(u32array, ARRAY_WORDS, 67108864) == 0x9ddb1def); - ok1(hash_stable(u32array, ARRAY_WORDS, 134217728) == 0x86096f25); - ok1(hash_stable(u32array, ARRAY_WORDS, 268435456) == 0xe713b7b5); - ok1(hash_stable(u32array, ARRAY_WORDS, 536870912) == 0x5baeffc5); - ok1(hash_stable(u32array, ARRAY_WORDS, 1073741824) == 0xde874f52); - ok1(hash_stable(u32array, ARRAY_WORDS, 2147483648U) == 0xeca13b4e); - - ok1(hash_stable(u64array, ARRAY_WORDS, 0) == 0x12ef6302); - ok1(hash_stable(u64array, ARRAY_WORDS, 1) == 0xe9aeb406); - ok1(hash_stable(u64array, ARRAY_WORDS, 2) == 0xc4218ceb); - ok1(hash_stable(u64array, ARRAY_WORDS, 4) == 0xb3d11412); - ok1(hash_stable(u64array, ARRAY_WORDS, 8) == 0xdafbd654); - ok1(hash_stable(u64array, ARRAY_WORDS, 16) == 0x9c336cba); - ok1(hash_stable(u64array, ARRAY_WORDS, 32) == 0x65059721); - ok1(hash_stable(u64array, ARRAY_WORDS, 64) == 0x95b5bbe6); - ok1(hash_stable(u64array, ARRAY_WORDS, 128) == 0xe7596b84); - ok1(hash_stable(u64array, ARRAY_WORDS, 256) == 0x503622a2); - ok1(hash_stable(u64array, ARRAY_WORDS, 512) == 0xecdcc5ca); - ok1(hash_stable(u64array, ARRAY_WORDS, 1024) == 0xc40d0513); - ok1(hash_stable(u64array, ARRAY_WORDS, 2048) == 0xaab25e4d); - ok1(hash_stable(u64array, ARRAY_WORDS, 4096) == 0xcc353fb9); - ok1(hash_stable(u64array, ARRAY_WORDS, 8192) == 0x18e2319f); - ok1(hash_stable(u64array, ARRAY_WORDS, 16384) == 0xfddaae8d); - ok1(hash_stable(u64array, ARRAY_WORDS, 32768) == 0xef7976f2); - ok1(hash_stable(u64array, ARRAY_WORDS, 65536) == 0x86359fc9); - ok1(hash_stable(u64array, ARRAY_WORDS, 131072) == 0x8b5af385); - ok1(hash_stable(u64array, ARRAY_WORDS, 262144) == 0x80d4ee31); - ok1(hash_stable(u64array, ARRAY_WORDS, 524288) == 0x42f5f85b); - ok1(hash_stable(u64array, ARRAY_WORDS, 1048576) == 0x9a6920e1); - ok1(hash_stable(u64array, ARRAY_WORDS, 2097152) == 0x7b7c9850); - ok1(hash_stable(u64array, ARRAY_WORDS, 4194304) == 0x69573e09); - ok1(hash_stable(u64array, ARRAY_WORDS, 8388608) == 0xc942bc0e); - ok1(hash_stable(u64array, ARRAY_WORDS, 16777216) == 0x7a89f0f1); - ok1(hash_stable(u64array, ARRAY_WORDS, 33554432) == 0x2dd641ca); - ok1(hash_stable(u64array, ARRAY_WORDS, 67108864) == 0x89bbd391); - ok1(hash_stable(u64array, ARRAY_WORDS, 134217728) == 0xbcf88e31); - ok1(hash_stable(u64array, ARRAY_WORDS, 268435456) == 0xfa7a3460); - ok1(hash_stable(u64array, ARRAY_WORDS, 536870912) == 0x49a37be0); - ok1(hash_stable(u64array, ARRAY_WORDS, 1073741824) == 0x1b346394); - ok1(hash_stable(u64array, ARRAY_WORDS, 2147483648U) == 0x6c3a1592); - - ok1(hash64_stable(u8array, ARRAY_WORDS, 0) == 16887282882572727244ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 1) == 12032777473133454818ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 2) == 18183407363221487738ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 4) == 17860764172704150171ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 8) == 18076051600675559233ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 16) == 9909361918431556721ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 32) == 12937969888744675813ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 64) == 5245669057381736951ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 128) == 4376874646406519665ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 256) == 14219974419871569521ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 512) == 2263415354134458951ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 1024) == 4953859694526221685ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 2048) == 3432228642067641593ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 4096) == 1219647244417697483ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 8192) == 7629939424585859553ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 16384) == 10041660531376789749ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 32768) == 13859885793922603927ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 65536) == 15069060338344675120ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 131072) == 818163430835601100ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 262144) == 14914314323019517069ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 524288) == 17518437749769352214ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 1048576) == 14920048004901212706ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 2097152) == 8758567366332536138ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 4194304) == 6226655736088907885ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 8388608) == 13716650013685832100ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 16777216) == 305325651636315638ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 33554432) == 16784147606583781671ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 67108864) == 16509467555140798205ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 134217728) == 8717281234694060584ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 268435456) == 8098476701725660537ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 536870912) == 16345871539461094006ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 1073741824) == 3755557000429964408ULL); - ok1(hash64_stable(u8array, ARRAY_WORDS, 2147483648U) == 15017348801959710081ULL); - - ok1(hash64_stable(u16array, ARRAY_WORDS, 0) == 1038028831307724039ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 1) == 10155473272642627302ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 2) == 5714751190106841420ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 4) == 3923885607767527866ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 8) == 3931017318293995558ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 16) == 1469696588339313177ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 32) == 11522218526952715051ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 64) == 6953517591561958496ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 128) == 7406689491740052867ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 256) == 10101844489704093104ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 512) == 12511348870707245959ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 1024) == 1614019938016861468ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 2048) == 5294796182374592721ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 4096) == 16089570706643716675ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 8192) == 1689302638424579464ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 16384) == 1446340172370386893ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 32768) == 16535503506744393039ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 65536) == 3496794142527150328ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 131072) == 6568245367474548504ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 262144) == 9487676460765485949ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 524288) == 4519762130966530000ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 1048576) == 15623412069215340610ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 2097152) == 544013388676438108ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 4194304) == 5594904760290840266ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 8388608) == 18098755780041592043ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 16777216) == 6389168672387330316ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 33554432) == 896986127732419381ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 67108864) == 13232626471143901354ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 134217728) == 53378562890493093ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 268435456) == 10072361400297824771ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 536870912) == 14511948118285144529ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 1073741824) == 6981033484844447277ULL); - ok1(hash64_stable(u16array, ARRAY_WORDS, 2147483648U) == 5619339091684126808ULL); - - ok1(hash64_stable(u32array, ARRAY_WORDS, 0) == 3037571077312110476ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 1) == 14732398743825071988ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 2) == 14949132158206672071ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 4) == 1291370080511561429ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 8) == 10792665964172133092ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 16) == 14250138032054339435ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 32) == 17136741522078732741ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 64) == 3260193403318236635ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 128) == 10526616652205653536ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 256) == 9019690373358576579ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 512) == 6997491436599677436ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 1024) == 18302783371416533798ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 2048) == 10149320644446516025ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 4096) == 7073759949410623868ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 8192) == 17442399482223760073ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 16384) == 2983906194216281861ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 32768) == 4975845419129060524ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 65536) == 594019910205413268ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 131072) == 11903010186073691112ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 262144) == 7339636527154847008ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 524288) == 15243305400579108736ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 1048576) == 16737926245392043198ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 2097152) == 15725083267699862972ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 4194304) == 12527834265678833794ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 8388608) == 13908436455987824848ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 16777216) == 9672773345173872588ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 33554432) == 2305314279896710501ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 67108864) == 1866733780381408751ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 134217728) == 11906263969465724709ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 268435456) == 5501594918093830069ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 536870912) == 15823785789276225477ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 1073741824) == 17353000723889475410ULL); - ok1(hash64_stable(u32array, ARRAY_WORDS, 2147483648U) == 7494736910655503182ULL); - - ok1(hash64_stable(u64array, ARRAY_WORDS, 0) == 9765419389786481410ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 1) == 11182806172127114246ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 2) == 2559155171395472619ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 4) == 3311692033324815378ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 8) == 1297175419505333844ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 16) == 617896928653569210ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 32) == 1517398559958603553ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 64) == 4504821917445110758ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 128) == 1971743331114904452ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 256) == 6177667912354374306ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 512) == 15570521289777792458ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 1024) == 9204559632415917331ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 2048) == 9008982669760028237ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 4096) == 14803537660281700281ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 8192) == 2873966517448487327ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 16384) == 5859277625928363661ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 32768) == 15520461285618185970ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 65536) == 16746489793331175369ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 131072) == 514952025484227461ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 262144) == 10867212269810675249ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 524288) == 9822204377278314587ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 1048576) == 3295088921987850465ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 2097152) == 7559197431498053712ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 4194304) == 1667267269116771849ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 8388608) == 2916804068951374862ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 16777216) == 14422558383125688561ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 33554432) == 10083112683694342602ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 67108864) == 7222777647078298513ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 134217728) == 18424513674048212529ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 268435456) == 14913668581101810784ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 536870912) == 14377721174297902048ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 1073741824) == 6031715005667500948ULL); - ok1(hash64_stable(u64array, ARRAY_WORDS, 2147483648U) == 4827100319722378642ULL); - - return exit_status(); -} diff --git a/ccan/hash/test/run.c b/ccan/hash/test/run.c @@ -1,149 +0,0 @@ -#include <ccan/hash/hash.h> -#include <ccan/tap/tap.h> -#include <ccan/hash/hash.c> -#include <stdbool.h> -#include <string.h> - -#define ARRAY_WORDS 5 - -int main(int argc, char *argv[]) -{ - unsigned int i, j, k; - uint32_t array[ARRAY_WORDS], val; - char array2[sizeof(array) + sizeof(uint32_t)]; - uint32_t results[256]; - - /* Initialize array. */ - for (i = 0; i < ARRAY_WORDS; i++) - array[i] = i; - - plan_tests(39); - /* Hash should be the same, indep of memory alignment. */ - val = hash(array, ARRAY_WORDS, 0); - for (i = 0; i < sizeof(uint32_t); i++) { - memcpy(array2 + i, array, sizeof(array)); - ok(hash(array2 + i, ARRAY_WORDS, 0) != val, - "hash matched at offset %i", i); - } - - /* Hash of random values should have random distribution: - * check one byte at a time. */ - for (i = 0; i < sizeof(uint32_t); i++) { - unsigned int lowest = -1U, highest = 0; - - memset(results, 0, sizeof(results)); - - for (j = 0; j < 256000; j++) { - for (k = 0; k < ARRAY_WORDS; k++) - array[k] = random(); - results[(hash(array, ARRAY_WORDS, 0) >> i*8)&0xFF]++; - } - - for (j = 0; j < 256; j++) { - if (results[j] < lowest) - lowest = results[j]; - if (results[j] > highest) - highest = results[j]; - } - /* Expect within 20% */ - ok(lowest > 800, "Byte %i lowest %i", i, lowest); - ok(highest < 1200, "Byte %i highest %i", i, highest); - diag("Byte %i, range %u-%u", i, lowest, highest); - } - - /* Hash of random values should have random distribution: - * check one byte at a time. */ - for (i = 0; i < sizeof(uint64_t); i++) { - unsigned int lowest = -1U, highest = 0; - - memset(results, 0, sizeof(results)); - - for (j = 0; j < 256000; j++) { - for (k = 0; k < ARRAY_WORDS; k++) - array[k] = random(); - results[(hash64(array, sizeof(array)/sizeof(uint64_t), - 0) >> i*8)&0xFF]++; - } - - for (j = 0; j < 256; j++) { - if (results[j] < lowest) - lowest = results[j]; - if (results[j] > highest) - highest = results[j]; - } - /* Expect within 20% */ - ok(lowest > 800, "Byte %i lowest %i", i, lowest); - ok(highest < 1200, "Byte %i highest %i", i, highest); - diag("Byte %i, range %u-%u", i, lowest, highest); - } - - /* Hash of pointer values should also have random distribution. */ - for (i = 0; i < sizeof(uint32_t); i++) { - unsigned int lowest = -1U, highest = 0; - char *p = malloc(256000); - - memset(results, 0, sizeof(results)); - - for (j = 0; j < 256000; j++) - results[(hash_pointer(p + j, 0) >> i*8)&0xFF]++; - free(p); - - for (j = 0; j < 256; j++) { - if (results[j] < lowest) - lowest = results[j]; - if (results[j] > highest) - highest = results[j]; - } - /* Expect within 20% */ - ok(lowest > 800, "hash_pointer byte %i lowest %i", i, lowest); - ok(highest < 1200, "hash_pointer byte %i highest %i", - i, highest); - diag("hash_pointer byte %i, range %u-%u", i, lowest, highest); - } - - if (sizeof(long) == sizeof(uint32_t)) - ok1(hashl(array, ARRAY_WORDS, 0) - == hash(array, ARRAY_WORDS, 0)); - else - ok1(hashl(array, ARRAY_WORDS, 0) - == hash64(array, ARRAY_WORDS, 0)); - - /* String hash: weak, so only test bottom byte */ - for (i = 0; i < 1; i++) { - unsigned int num = 0, cursor, lowest = -1U, highest = 0; - char p[5]; - - memset(results, 0, sizeof(results)); - - memset(p, 'A', sizeof(p)); - p[sizeof(p)-1] = '\0'; - - for (;;) { - for (cursor = 0; cursor < sizeof(p)-1; cursor++) { - p[cursor]++; - if (p[cursor] <= 'z') - break; - p[cursor] = 'A'; - } - if (cursor == sizeof(p)-1) - break; - - results[(hash_string(p) >> i*8)&0xFF]++; - num++; - } - - for (j = 0; j < 256; j++) { - if (results[j] < lowest) - lowest = results[j]; - if (results[j] > highest) - highest = results[j]; - } - /* Expect within 20% */ - ok(lowest > 35000, "hash_pointer byte %i lowest %i", i, lowest); - ok(highest < 53000, "hash_pointer byte %i highest %i", - i, highest); - diag("hash_pointer byte %i, range %u-%u", i, lowest, highest); - } - - return exit_status(); -} diff --git a/ccan/htable/LICENSE b/ccan/htable/LICENSE @@ -1 +0,0 @@ -../../licenses/LGPL-2.1- \ No newline at end of file diff --git a/ccan/htable/_info b/ccan/htable/_info @@ -1,117 +0,0 @@ -#include "config.h" -#include <string.h> -#include <stdio.h> - -/** - * htable - hash table routines - * - * A hash table is an efficient structure for looking up keys. This version - * grows with usage and allows efficient deletion. - * - * Example: - * #include <ccan/htable/htable.h> - * #include <ccan/hash/hash.h> - * #include <stdio.h> - * #include <err.h> - * #include <string.h> - * - * struct name_to_digit { - * const char *name; - * unsigned int val; - * }; - * - * static struct name_to_digit map[] = { - * { "zero", 0}, - * { "one", 1 }, - * { "two", 2 }, - * { "three", 3 }, - * { "four", 4 }, - * { "five", 5 }, - * { "six", 6 }, - * { "seven", 7 }, - * { "eight", 8 }, - * { "nine", 9 } - * }; - * - * // Wrapper for rehash function pointer. - * static size_t rehash(const void *e, void *unused) - * { - * (void)unused; - * return hash_string(((struct name_to_digit *)e)->name); - * } - * - * // Comparison function. - * static bool streq(const void *e, void *string) - * { - * return strcmp(((struct name_to_digit *)e)->name, string) == 0; - * } - * - * // We let them add their own aliases, eg. --alias=v=5 - * static void add_alias(struct htable *ht, const char *alias) - * { - * char *eq; - * struct name_to_digit *n; - * - * n = malloc(sizeof(*n)); - * n->name = strdup(alias); - * - * eq = strchr(n->name, '='); - * if (!eq || ((n->val = atoi(eq+1)) == 0 && !strcmp(eq+1, "0"))) - * errx(1, "Usage: --alias=<name>=<value>"); - * *eq = '\0'; - * htable_add(ht, hash_string(n->name), n); - * } - * - * int main(int argc, char *argv[]) - * { - * struct htable ht; - * int i; - * unsigned long val; - * - * if (argc < 2) - * errx(1, "Usage: %s [--alias=<name>=<val>]... <str>...", - * argv[0]); - * - * // Create and populate hash table. - * htable_init(&ht, rehash, NULL); - * for (i = 0; i < (int)(sizeof(map)/sizeof(map[0])); i++) - * htable_add(&ht, hash_string(map[i].name), &map[i]); - * - * // Add any aliases to the hash table. - * for (i = 1; i < argc; i++) { - * if (!strncmp(argv[i], "--alias=", strlen("--alias="))) - * add_alias(&ht, argv[i] + strlen("--alias=")); - * else - * break; - * } - * - * // Find the other args in the hash table. - * for (val = 0; i < argc; i++) { - * struct name_to_digit *n; - * n = htable_get(&ht, hash_string(argv[i]), - * streq, argv[i]); - * if (!n) - * errx(1, "Invalid digit name %s", argv[i]); - * // Append it to the value we are building up. - * val *= 10; - * val += n->val; - * } - * printf("%lu\n", val); - * return 0; - * } - * - * License: LGPL (v2.1 or any later version) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/compiler\n"); - return 0; - } - - return 1; -} diff --git a/ccan/htable/htable.c b/ccan/htable/htable.c @@ -1,325 +0,0 @@ -/* Licensed under LGPLv2+ - see LICENSE file for details */ -#include <ccan/htable/htable.h> -#include <ccan/compiler/compiler.h> -#include <stdlib.h> -#include <limits.h> -#include <stdbool.h> -#include <assert.h> -#include <string.h> - -/* We use 0x1 as deleted marker. */ -#define HTABLE_DELETED (0x1) - -/* We clear out the bits which are always the same, and put metadata there. */ -static inline uintptr_t get_extra_ptr_bits(const struct htable *ht, - uintptr_t e) -{ - return e & ht->common_mask; -} - -static inline void *get_raw_ptr(const struct htable *ht, uintptr_t e) -{ - return (void *)((e & ~ht->common_mask) | ht->common_bits); -} - -static inline uintptr_t make_hval(const struct htable *ht, - const void *p, uintptr_t bits) -{ - return ((uintptr_t)p & ~ht->common_mask) | bits; -} - -static inline bool entry_is_valid(uintptr_t e) -{ - return e > HTABLE_DELETED; -} - -static inline uintptr_t get_hash_ptr_bits(const struct htable *ht, - size_t hash) -{ - /* Shuffling the extra bits (as specified in mask) down the - * end is quite expensive. But the lower bits are redundant, so - * we fold the value first. */ - return (hash ^ (hash >> ht->bits)) - & ht->common_mask & ~ht->perfect_bit; -} - -void htable_init(struct htable *ht, - size_t (*rehash)(const void *elem, void *priv), void *priv) -{ - struct htable empty = HTABLE_INITIALIZER(empty, NULL, NULL); - *ht = empty; - ht->rehash = rehash; - ht->priv = priv; - ht->table = &ht->perfect_bit; -} - -/* We've changed ht->bits, update ht->max and ht->max_with_deleted */ -static void htable_adjust_capacity(struct htable *ht) -{ - ht->max = ((size_t)3 << ht->bits) / 4; - ht->max_with_deleted = ((size_t)9 << ht->bits) / 10; -} - -bool htable_init_sized(struct htable *ht, - size_t (*rehash)(const void *, void *), - void *priv, size_t expect) -{ - htable_init(ht, rehash, priv); - - /* Don't go insane with sizing. */ - for (ht->bits = 1; ((size_t)3 << ht->bits) / 4 < expect; ht->bits++) { - if (ht->bits == 30) - break; - } - - ht->table = calloc(1 << ht->bits, sizeof(size_t)); - if (!ht->table) { - ht->table = &ht->perfect_bit; - return false; - } - htable_adjust_capacity(ht); - return true; -} - -void htable_clear(struct htable *ht) -{ - if (ht->table != &ht->perfect_bit) - free((void *)ht->table); - htable_init(ht, ht->rehash, ht->priv); -} - -bool htable_copy(struct htable *dst, const struct htable *src) -{ - uintptr_t *htable = malloc(sizeof(size_t) << src->bits); - - if (!htable) - return false; - - *dst = *src; - dst->table = htable; - memcpy(dst->table, src->table, sizeof(size_t) << src->bits); - return true; -} - -static size_t hash_bucket(const struct htable *ht, size_t h) -{ - return h & ((1 << ht->bits)-1); -} - -static void *htable_val(const struct htable *ht, - struct htable_iter *i, size_t hash, uintptr_t perfect) -{ - uintptr_t h2 = get_hash_ptr_bits(ht, hash) | perfect; - - while (ht->table[i->off]) { - if (ht->table[i->off] != HTABLE_DELETED) { - if (get_extra_ptr_bits(ht, ht->table[i->off]) == h2) - return get_raw_ptr(ht, ht->table[i->off]); - } - i->off = (i->off + 1) & ((1 << ht->bits)-1); - h2 &= ~perfect; - } - return NULL; -} - -void *htable_firstval(const struct htable *ht, - struct htable_iter *i, size_t hash) -{ - i->off = hash_bucket(ht, hash); - return htable_val(ht, i, hash, ht->perfect_bit); -} - -void *htable_nextval(const struct htable *ht, - struct htable_iter *i, size_t hash) -{ - i->off = (i->off + 1) & ((1 << ht->bits)-1); - return htable_val(ht, i, hash, 0); -} - -void *htable_first(const struct htable *ht, struct htable_iter *i) -{ - for (i->off = 0; i->off < (size_t)1 << ht->bits; i->off++) { - if (entry_is_valid(ht->table[i->off])) - return get_raw_ptr(ht, ht->table[i->off]); - } - return NULL; -} - -void *htable_next(const struct htable *ht, struct htable_iter *i) -{ - for (i->off++; i->off < (size_t)1 << ht->bits; i->off++) { - if (entry_is_valid(ht->table[i->off])) - return get_raw_ptr(ht, ht->table[i->off]); - } - return NULL; -} - -void *htable_prev(const struct htable *ht, struct htable_iter *i) -{ - for (;;) { - if (!i->off) - return NULL; - i->off --; - if (entry_is_valid(ht->table[i->off])) - return get_raw_ptr(ht, ht->table[i->off]); - } -} - -/* This does not expand the hash table, that's up to caller. */ -static void ht_add(struct htable *ht, const void *new, size_t h) -{ - size_t i; - uintptr_t perfect = ht->perfect_bit; - - i = hash_bucket(ht, h); - - while (entry_is_valid(ht->table[i])) { - perfect = 0; - i = (i + 1) & ((1 << ht->bits)-1); - } - ht->table[i] = make_hval(ht, new, get_hash_ptr_bits(ht, h)|perfect); -} - -static COLD bool double_table(struct htable *ht) -{ - unsigned int i; - size_t oldnum = (size_t)1 << ht->bits; - uintptr_t *oldtable, e; - - oldtable = ht->table; - ht->table = calloc(1 << (ht->bits+1), sizeof(size_t)); - if (!ht->table) { - ht->table = oldtable; - return false; - } - ht->bits++; - htable_adjust_capacity(ht); - - /* If we lost our "perfect bit", get it back now. */ - if (!ht->perfect_bit && ht->common_mask) { - for (i = 0; i < sizeof(ht->common_mask) * CHAR_BIT; i++) { - if (ht->common_mask & ((size_t)1 << i)) { - ht->perfect_bit = (size_t)1 << i; - break; - } - } - } - - if (oldtable != &ht->perfect_bit) { - for (i = 0; i < oldnum; i++) { - if (entry_is_valid(e = oldtable[i])) { - void *p = get_raw_ptr(ht, e); - ht_add(ht, p, ht->rehash(p, ht->priv)); - } - } - free(oldtable); - } - ht->deleted = 0; - return true; -} - -static COLD void rehash_table(struct htable *ht) -{ - size_t start, i; - uintptr_t e; - - /* Beware wrap cases: we need to start from first empty bucket. */ - for (start = 0; ht->table[start]; start++); - - for (i = 0; i < (size_t)1 << ht->bits; i++) { - size_t h = (i + start) & ((1 << ht->bits)-1); - e = ht->table[h]; - if (!e) - continue; - if (e == HTABLE_DELETED) - ht->table[h] = 0; - else if (!(e & ht->perfect_bit)) { - void *p = get_raw_ptr(ht, e); - ht->table[h] = 0; - ht_add(ht, p, ht->rehash(p, ht->priv)); - } - } - ht->deleted = 0; -} - -/* We stole some bits, now we need to put them back... */ -static COLD void update_common(struct htable *ht, const void *p) -{ - unsigned int i; - uintptr_t maskdiff, bitsdiff; - - if (ht->elems == 0) { - /* Always reveal one bit of the pointer in the bucket, - * so it's not zero or HTABLE_DELETED (1), even if - * hash happens to be 0. Assumes (void *)1 is not a - * valid pointer. */ - for (i = sizeof(uintptr_t)*CHAR_BIT - 1; i > 0; i--) { - if ((uintptr_t)p & ((uintptr_t)1 << i)) - break; - } - - ht->common_mask = ~((uintptr_t)1 << i); - ht->common_bits = ((uintptr_t)p & ht->common_mask); - ht->perfect_bit = 1; - return; - } - - /* Find bits which are unequal to old common set. */ - maskdiff = ht->common_bits ^ ((uintptr_t)p & ht->common_mask); - - /* These are the bits which go there in existing entries. */ - bitsdiff = ht->common_bits & maskdiff; - - for (i = 0; i < (size_t)1 << ht->bits; i++) { - if (!entry_is_valid(ht->table[i])) - continue; - /* Clear the bits no longer in the mask, set them as - * expected. */ - ht->table[i] &= ~maskdiff; - ht->table[i] |= bitsdiff; - } - - /* Take away those bits from our mask, bits and perfect bit. */ - ht->common_mask &= ~maskdiff; - ht->common_bits &= ~maskdiff; - ht->perfect_bit &= ~maskdiff; -} - -bool htable_add(struct htable *ht, size_t hash, const void *p) -{ - if (ht->elems+1 > ht->max && !double_table(ht)) - return false; - if (ht->elems+1 + ht->deleted > ht->max_with_deleted) - rehash_table(ht); - assert(p); - if (((uintptr_t)p & ht->common_mask) != ht->common_bits) - update_common(ht, p); - - ht_add(ht, p, hash); - ht->elems++; - return true; -} - -bool htable_del(struct htable *ht, size_t h, const void *p) -{ - struct htable_iter i; - void *c; - - for (c = htable_firstval(ht,&i,h); c; c = htable_nextval(ht,&i,h)) { - if (c == p) { - htable_delval(ht, &i); - return true; - } - } - return false; -} - -void htable_delval(struct htable *ht, struct htable_iter *i) -{ - assert(i->off < (size_t)1 << ht->bits); - assert(entry_is_valid(ht->table[i->off])); - - ht->elems--; - ht->table[i->off] = HTABLE_DELETED; - ht->deleted++; -} diff --git a/ccan/htable/htable.h b/ccan/htable/htable.h @@ -1,226 +0,0 @@ -/* Licensed under LGPLv2+ - see LICENSE file for details */ -#ifndef CCAN_HTABLE_H -#define CCAN_HTABLE_H -#include "config.h" -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> - -/** - * struct htable - private definition of a htable. - * - * It's exposed here so you can put it in your structures and so we can - * supply inline functions. - */ -struct htable { - size_t (*rehash)(const void *elem, void *priv); - void *priv; - unsigned int bits; - size_t elems, deleted, max, max_with_deleted; - /* These are the bits which are the same in all pointers. */ - uintptr_t common_mask, common_bits; - uintptr_t perfect_bit; - uintptr_t *table; -}; - -/** - * HTABLE_INITIALIZER - static initialization for a hash table. - * @name: name of this htable. - * @rehash: hash function to use for rehashing. - * @priv: private argument to @rehash function. - * - * This is useful for setting up static and global hash tables. - * - * Example: - * // For simplicity's sake, say hash value is contents of elem. - * static size_t rehash(const void *elem, void *unused) - * { - * (void)unused; - * return *(size_t *)elem; - * } - * static struct htable ht = HTABLE_INITIALIZER(ht, rehash, NULL); - */ -#define HTABLE_INITIALIZER(name, rehash, priv) \ - { rehash, priv, 0, 0, 0, 0, 0, -1, 0, 0, &name.perfect_bit } - -/** - * htable_init - initialize an empty hash table. - * @ht: the hash table to initialize - * @rehash: hash function to use for rehashing. - * @priv: private argument to @rehash function. - */ -void htable_init(struct htable *ht, - size_t (*rehash)(const void *elem, void *priv), void *priv); - -/** - * htable_init_sized - initialize an empty hash table of given size. - * @ht: the hash table to initialize - * @rehash: hash function to use for rehashing. - * @priv: private argument to @rehash function. - * @size: the number of element. - * - * If this returns false, @ht is still usable, but may need to do reallocation - * upon an add. If this returns true, it will not need to reallocate within - * @size htable_adds. - */ -bool htable_init_sized(struct htable *ht, - size_t (*rehash)(const void *elem, void *priv), - void *priv, size_t size); - -/** - * htable_clear - empty a hash table. - * @ht: the hash table to clear - * - * This doesn't do anything to any pointers left in it. - */ -void htable_clear(struct htable *ht); - -/** - * htable_copy - duplicate a hash table. - * @dst: the hash table to overwrite - * @src: the hash table to copy - * - * Only fails on out-of-memory. - * - * Equivalent to (but faster than): - * if (!htable_init_sized(dst, src->rehash, src->priv, 1U << src->bits)) - * return false; - * v = htable_first(src, &i); - * while (v) { - * htable_add(dst, v); - * v = htable_next(src, i); - * } - * return true; - */ -bool htable_copy(struct htable *dst, const struct htable *src); - -/** - * htable_rehash - use a hashtree's rehash function - * @elem: the argument to rehash() - * - */ -size_t htable_rehash(const void *elem); - -/** - * htable_add - add a pointer into a hash table. - * @ht: the htable - * @hash: the hash value of the object - * @p: the non-NULL pointer - * - * Also note that this can only fail due to allocation failure. Otherwise, it - * returns true. - */ -bool htable_add(struct htable *ht, size_t hash, const void *p); - -/** - * htable_del - remove a pointer from a hash table - * @ht: the htable - * @hash: the hash value of the object - * @p: the pointer - * - * Returns true if the pointer was found (and deleted). - */ -bool htable_del(struct htable *ht, size_t hash, const void *p); - -/** - * struct htable_iter - iterator or htable_first or htable_firstval etc. - * - * This refers to a location inside the hashtable. - */ -struct htable_iter { - size_t off; -}; - -/** - * htable_firstval - find a candidate for a given hash value - * @htable: the hashtable - * @i: the struct htable_iter to initialize - * @hash: the hash value - * - * You'll need to check the value is what you want; returns NULL if none. - * See Also: - * htable_delval() - */ -void *htable_firstval(const struct htable *htable, - struct htable_iter *i, size_t hash); - -/** - * htable_nextval - find another candidate for a given hash value - * @htable: the hashtable - * @i: the struct htable_iter to initialize - * @hash: the hash value - * - * You'll need to check the value is what you want; returns NULL if no more. - */ -void *htable_nextval(const struct htable *htable, - struct htable_iter *i, size_t hash); - -/** - * htable_get - find an entry in the hash table - * @ht: the hashtable - * @h: the hash value of the entry - * @cmp: the comparison function - * @ptr: the pointer to hand to the comparison function. - * - * Convenient inline wrapper for htable_firstval/htable_nextval loop. - */ -static inline void *htable_get(const struct htable *ht, - size_t h, - bool (*cmp)(const void *candidate, void *ptr), - const void *ptr) -{ - struct htable_iter i; - void *c; - - for (c = htable_firstval(ht,&i,h); c; c = htable_nextval(ht,&i,h)) { - if (cmp(c, (void *)ptr)) - return c; - } - return NULL; -} - -/** - * htable_first - find an entry in the hash table - * @ht: the hashtable - * @i: the struct htable_iter to initialize - * - * Get an entry in the hashtable; NULL if empty. - */ -void *htable_first(const struct htable *htable, struct htable_iter *i); - -/** - * htable_next - find another entry in the hash table - * @ht: the hashtable - * @i: the struct htable_iter to use - * - * Get another entry in the hashtable; NULL if all done. - * This is usually used after htable_first or prior non-NULL htable_next. - */ -void *htable_next(const struct htable *htable, struct htable_iter *i); - -/** - * htable_prev - find the previous entry in the hash table - * @ht: the hashtable - * @i: the struct htable_iter to use - * - * Get previous entry in the hashtable; NULL if all done. - * - * "previous" here only means the item that would have been returned by - * htable_next() before the item it returned most recently. - * - * This is usually used in the middle of (or after) a htable_next iteration and - * to "unwind" actions taken. - */ -void *htable_prev(const struct htable *htable, struct htable_iter *i); - -/** - * htable_delval - remove an iterated pointer from a hash table - * @ht: the htable - * @i: the htable_iter - * - * Usually used to delete a hash entry after it has been found with - * htable_firstval etc. - */ -void htable_delval(struct htable *ht, struct htable_iter *i); - -#endif /* CCAN_HTABLE_H */ diff --git a/ccan/htable/htable_type.h b/ccan/htable/htable_type.h @@ -1,166 +0,0 @@ -/* Licensed under LGPLv2+ - see LICENSE file for details */ -#ifndef CCAN_HTABLE_TYPE_H -#define CCAN_HTABLE_TYPE_H -#include <ccan/htable/htable.h> -#include <ccan/compiler/compiler.h> -#include "config.h" - -/** - * HTABLE_DEFINE_TYPE - create a set of htable ops for a type - * @type: a type whose pointers will be values in the hash. - * @keyof: a function/macro to extract a key: <keytype> @keyof(const type *elem) - * @hashfn: a hash function for a @key: size_t @hashfn(const <keytype> *) - * @eqfn: an equality function keys: bool @eqfn(const type *, const <keytype> *) - * @prefix: a prefix for all the functions to define (of form <name>_*) - * - * NULL values may not be placed into the hash table. - * - * This defines the type hashtable type and an iterator type: - * struct <name>; - * struct <name>_iter; - * - * It also defines initialization and freeing functions: - * void <name>_init(struct <name> *); - * bool <name>_init_sized(struct <name> *, size_t); - * void <name>_clear(struct <name> *); - * bool <name>_copy(struct <name> *dst, const struct <name> *src); - * - * Add function only fails if we run out of memory: - * bool <name>_add(struct <name> *ht, const <type> *e); - * - * Delete and delete-by key return true if it was in the set: - * bool <name>_del(struct <name> *ht, const <type> *e); - * bool <name>_delkey(struct <name> *ht, const <keytype> *k); - * - * Find and return the (first) matching element, or NULL: - * type *<name>_get(const struct @name *ht, const <keytype> *k); - * - * Find and return all matching elements, or NULL: - * type *<name>_getfirst(const struct @name *ht, const <keytype> *k, - * struct <name>_iter *i); - * type *<name>_getnext(const struct @name *ht, const <keytype> *k, - * struct <name>_iter *i); - * - * Iteration over hashtable is also supported: - * type *<name>_first(const struct <name> *ht, struct <name>_iter *i); - * type *<name>_next(const struct <name> *ht, struct <name>_iter *i); - * type *<name>_prev(const struct <name> *ht, struct <name>_iter *i); - * - * It's currently safe to iterate over a changing hashtable, but you might - * miss an element. Iteration isn't very efficient, either. - * - * You can use HTABLE_INITIALIZER like so: - * struct <name> ht = { HTABLE_INITIALIZER(ht.raw, <name>_hash, NULL) }; - */ -#define HTABLE_DEFINE_TYPE(type, keyof, hashfn, eqfn, name) \ - struct name { struct htable raw; }; \ - struct name##_iter { struct htable_iter i; }; \ - static inline size_t name##_hash(const void *elem, void *priv) \ - { \ - (void)priv; \ - return hashfn(keyof((const type *)elem)); \ - } \ - static inline UNNEEDED void name##_init(struct name *ht) \ - { \ - htable_init(&ht->raw, name##_hash, NULL); \ - } \ - static inline UNNEEDED bool name##_init_sized(struct name *ht, \ - size_t s) \ - { \ - return htable_init_sized(&ht->raw, name##_hash, NULL, s); \ - } \ - static inline UNNEEDED void name##_clear(struct name *ht) \ - { \ - htable_clear(&ht->raw); \ - } \ - static inline UNNEEDED bool name##_copy(struct name *dst, \ - const struct name *src) \ - { \ - return htable_copy(&dst->raw, &src->raw); \ - } \ - static inline bool name##_add(struct name *ht, const type *elem) \ - { \ - return htable_add(&ht->raw, hashfn(keyof(elem)), elem); \ - } \ - static inline UNNEEDED bool name##_del(struct name *ht, \ - const type *elem) \ - { \ - return htable_del(&ht->raw, hashfn(keyof(elem)), elem); \ - } \ - static inline UNNEEDED type *name##_get(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k) \ - { \ - struct htable_iter i; \ - size_t h = hashfn(k); \ - void *c; \ - \ - for (c = htable_firstval(&ht->raw,&i,h); \ - c; \ - c = htable_nextval(&ht->raw,&i,h)) { \ - if (eqfn(c, k)) \ - return c; \ - } \ - return NULL; \ - } \ - static inline UNNEEDED type *name##_getmatch_(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k, \ - size_t h, \ - type *v, \ - struct name##_iter *iter) \ - { \ - while (v) { \ - if (eqfn(v, k)) \ - break; \ - v = htable_nextval(&ht->raw, &iter->i, h); \ - } \ - return v; \ - } \ - static inline UNNEEDED type *name##_getfirst(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k, \ - struct name##_iter *iter) \ - { \ - size_t h = hashfn(k); \ - type *v = htable_firstval(&ht->raw, &iter->i, h); \ - return name##_getmatch_(ht, k, h, v, iter); \ - } \ - static inline UNNEEDED type *name##_getnext(const struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k, \ - struct name##_iter *iter) \ - { \ - size_t h = hashfn(k); \ - type *v = htable_nextval(&ht->raw, &iter->i, h); \ - return name##_getmatch_(ht, k, h, v, iter); \ - } \ - static inline UNNEEDED bool name##_delkey(struct name *ht, \ - const HTABLE_KTYPE(keyof, type) k) \ - { \ - type *elem = name##_get(ht, k); \ - if (elem) \ - return name##_del(ht, elem); \ - return false; \ - } \ - static inline UNNEEDED type *name##_first(const struct name *ht, \ - struct name##_iter *iter) \ - { \ - return htable_first(&ht->raw, &iter->i); \ - } \ - static inline UNNEEDED type *name##_next(const struct name *ht, \ - struct name##_iter *iter) \ - { \ - return htable_next(&ht->raw, &iter->i); \ - } \ - static inline UNNEEDED type *name##_prev(const struct name *ht, \ - struct name##_iter *iter) \ - { \ - return htable_prev(&ht->raw, &iter->i); \ - } - -#if HAVE_TYPEOF -#define HTABLE_KTYPE(keyof, type) typeof(keyof((const type *)NULL)) -#else -/* Assumes keys are a pointer: if not, override. */ -#ifndef HTABLE_KTYPE -#define HTABLE_KTYPE(keyof, type) void * -#endif -#endif -#endif /* CCAN_HTABLE_TYPE_H */ diff --git a/ccan/htable/test/run-copy.c b/ccan/htable/test/run-copy.c @@ -1,44 +0,0 @@ -#include <ccan/htable/htable.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define NUM_VALS 512 - -static size_t hash(const void *elem, void *unused UNNEEDED) -{ - size_t h = *(uint64_t *)elem / 2; - return h; -} - -static bool cmp(const void *candidate, void *ptr) -{ - return *(const uint64_t *)candidate == *(const uint64_t *)ptr; -} - -int main(void) -{ - struct htable ht, ht2; - uint64_t val[NUM_VALS], i; - - plan_tests((NUM_VALS) * 3); - for (i = 0; i < NUM_VALS; i++) - val[i] = i; - - htable_init(&ht, hash, NULL); - for (i = 0; i < NUM_VALS; i++) { - ok1(ht.max >= i); - ok1(ht.max <= i * 2); - htable_add(&ht, hash(&val[i], NULL), &val[i]); - } - - htable_copy(&ht2, &ht); - htable_clear(&ht); - - for (i = 0; i < NUM_VALS; i++) - ok1(htable_get(&ht2, hash(&i, NULL), cmp, &i) == &val[i]); - htable_clear(&ht2); - - return exit_status(); -} diff --git a/ccan/htable/test/run-size.c b/ccan/htable/test/run-size.c @@ -1,36 +0,0 @@ -#include <ccan/htable/htable.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define NUM_VALS 512 - -/* We use the number divided by two as the hash (for lots of - collisions). */ -static size_t hash(const void *elem, void *unused UNNEEDED) -{ - size_t h = *(uint64_t *)elem / 2; - return h; -} - -int main(void) -{ - struct htable ht; - uint64_t val[NUM_VALS]; - unsigned int i; - - plan_tests((NUM_VALS) * 2); - for (i = 0; i < NUM_VALS; i++) - val[i] = i; - - htable_init(&ht, hash, NULL); - for (i = 0; i < NUM_VALS; i++) { - ok1(ht.max >= i); - ok1(ht.max <= i * 2); - htable_add(&ht, hash(&val[i], NULL), &val[i]); - } - htable_clear(&ht); - - return exit_status(); -} diff --git a/ccan/htable/test/run-type-int.c b/ccan/htable/test/run-type-int.c @@ -1,215 +0,0 @@ -/* Key is an unsigned int, not a pointer. */ -#include "config.h" -#if !defined(HAVE_TYPEOF) || !HAVE_TYPEOF -#define HTABLE_KTYPE(keyof, type) unsigned int -#endif -#include <ccan/htable/htable_type.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define NUM_BITS 7 -#define NUM_VALS (1 << NUM_BITS) - -struct obj { - /* Makes sure we don't try to treat and obj as a key or vice versa */ - unsigned char unused; - unsigned int key; -}; - -static const unsigned int objkey(const struct obj *obj) -{ - return obj->key; -} - -/* We use the number divided by two as the hash (for lots of - collisions), plus set all the higher bits so we can detect if they - don't get masked out. */ -static size_t objhash(const unsigned int key) -{ - size_t h = key / 2; - h |= -1UL << NUM_BITS; - return h; -} - -static bool cmp(const struct obj *obj, const unsigned int key) -{ - return obj->key == key; -} - -HTABLE_DEFINE_TYPE(struct obj, objkey, objhash, cmp, htable_obj); - -static void add_vals(struct htable_obj *ht, - struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (htable_obj_get(ht, i)) { - fail("%u already in hash", i); - return; - } - htable_obj_add(ht, &val[i]); - if (htable_obj_get(ht, i) != &val[i]) { - fail("%u not added to hash", i); - return; - } - } - pass("Added %u numbers to hash", i); -} - -static void find_vals(const struct htable_obj *ht, - const struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (htable_obj_get(ht, i) != &val[i]) { - fail("%u not found in hash", i); - return; - } - } - pass("Found %u numbers in hash", i); -} - -static void del_vals(struct htable_obj *ht, - const struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (!htable_obj_delkey(ht, val[i].key)) { - fail("%u not deleted from hash", i); - return; - } - } - pass("Deleted %u numbers in hash", i); -} - -static void del_vals_bykey(struct htable_obj *ht, - const struct obj val[] UNNEEDED, unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (!htable_obj_delkey(ht, i)) { - fail("%u not deleted by key from hash", i); - return; - } - } - pass("Deleted %u numbers by key from hash", i); -} - -static bool check_mask(struct htable *ht, const struct obj val[], unsigned num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (((uintptr_t)&val[i] & ht->common_mask) != ht->common_bits) - return false; - } - return true; -} - -int main(void) -{ - unsigned int i; - struct htable_obj ht, ht2; - struct obj val[NUM_VALS], *result; - unsigned int dne; - void *p; - struct htable_obj_iter iter; - - plan_tests(29); - for (i = 0; i < NUM_VALS; i++) - val[i].key = i; - dne = i; - - htable_obj_init(&ht); - ok1(ht.raw.max == 0); - ok1(ht.raw.bits == 0); - - /* We cannot find an entry which doesn't exist. */ - ok1(!htable_obj_get(&ht, dne)); - - /* Fill it, it should increase in size. */ - add_vals(&ht, val, NUM_VALS); - ok1(ht.raw.bits == NUM_BITS + 1); - ok1(ht.raw.max < (1 << ht.raw.bits)); - - /* Mask should be set. */ - ok1(ht.raw.common_mask != 0); - ok1(ht.raw.common_mask != -1); - ok1(check_mask(&ht.raw, val, NUM_VALS)); - - /* Find all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, dne)); - - /* Walk once, should get them all. */ - i = 0; - for (p = htable_obj_first(&ht,&iter); p; p = htable_obj_next(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - i = 0; - for (p = htable_obj_prev(&ht,&iter); p; p = htable_obj_prev(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - - /* Delete all. */ - del_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, val[0].key)); - - /* Worst case, a "pointer" which doesn't have any matching bits. */ - htable_add(&ht.raw, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - htable_obj_add(&ht, &val[NUM_VALS-1]); - ok1(ht.raw.common_mask == 0); - ok1(ht.raw.common_bits == 0); - /* Delete the bogus one before we trip over it. */ - htable_del(&ht.raw, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - - /* Add the rest. */ - add_vals(&ht, val, NUM_VALS-1); - - /* Check we can find them all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, dne)); - - /* Check copy. */ - ok1(htable_obj_copy(&ht2, &ht)); - - /* Delete them all by key. */ - del_vals_bykey(&ht, val, NUM_VALS); - del_vals_bykey(&ht2, val, NUM_VALS); - - /* Write two of the same value. */ - val[1] = val[0]; - htable_obj_add(&ht, &val[0]); - htable_obj_add(&ht, &val[1]); - i = 0; - - result = htable_obj_getfirst(&ht, i, &iter); - ok1(result == &val[0] || result == &val[1]); - if (result == &val[0]) { - ok1(htable_obj_getnext(&ht, i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); - - /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[0])); - ok1(htable_obj_getfirst(&ht, i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); - } else { - ok1(htable_obj_getnext(&ht, i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); - - /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[1])); - ok1(htable_obj_getfirst(&ht, i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, i, &iter) == NULL); - } - - htable_obj_clear(&ht); - htable_obj_clear(&ht2); - return exit_status(); -} diff --git a/ccan/htable/test/run-type.c b/ccan/htable/test/run-type.c @@ -1,210 +0,0 @@ -#include <ccan/htable/htable_type.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define NUM_BITS 7 -#define NUM_VALS (1 << NUM_BITS) - -struct obj { - /* Makes sure we don't try to treat and obj as a key or vice versa */ - unsigned char unused; - unsigned int key; -}; - -static const unsigned int *objkey(const struct obj *obj) -{ - return &obj->key; -} - -/* We use the number divided by two as the hash (for lots of - collisions), plus set all the higher bits so we can detect if they - don't get masked out. */ -static size_t objhash(const unsigned int *key) -{ - size_t h = *key / 2; - h |= -1UL << NUM_BITS; - return h; -} - -static bool cmp(const struct obj *obj, const unsigned int *key) -{ - return obj->key == *key; -} - -HTABLE_DEFINE_TYPE(struct obj, objkey, objhash, cmp, htable_obj); - -static void add_vals(struct htable_obj *ht, - struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (htable_obj_get(ht, &i)) { - fail("%u already in hash", i); - return; - } - htable_obj_add(ht, &val[i]); - if (htable_obj_get(ht, &i) != &val[i]) { - fail("%u not added to hash", i); - return; - } - } - pass("Added %u numbers to hash", i); -} - -static void find_vals(const struct htable_obj *ht, - const struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (htable_obj_get(ht, &i) != &val[i]) { - fail("%u not found in hash", i); - return; - } - } - pass("Found %u numbers in hash", i); -} - -static void del_vals(struct htable_obj *ht, - const struct obj val[], unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (!htable_obj_delkey(ht, &val[i].key)) { - fail("%u not deleted from hash", i); - return; - } - } - pass("Deleted %u numbers in hash", i); -} - -static void del_vals_bykey(struct htable_obj *ht, - const struct obj val[] UNNEEDED, unsigned int num) -{ - unsigned int i; - - for (i = 0; i < num; i++) { - if (!htable_obj_delkey(ht, &i)) { - fail("%u not deleted by key from hash", i); - return; - } - } - pass("Deleted %u numbers by key from hash", i); -} - -static bool check_mask(struct htable *ht, const struct obj val[], unsigned num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (((uintptr_t)&val[i] & ht->common_mask) != ht->common_bits) - return false; - } - return true; -} - -int main(void) -{ - unsigned int i; - struct htable_obj ht, ht2; - struct obj val[NUM_VALS], *result; - unsigned int dne; - void *p; - struct htable_obj_iter iter; - - plan_tests(29); - for (i = 0; i < NUM_VALS; i++) - val[i].key = i; - dne = i; - - htable_obj_init(&ht); - ok1(ht.raw.max == 0); - ok1(ht.raw.bits == 0); - - /* We cannot find an entry which doesn't exist. */ - ok1(!htable_obj_get(&ht, &dne)); - - /* Fill it, it should increase in size. */ - add_vals(&ht, val, NUM_VALS); - ok1(ht.raw.bits == NUM_BITS + 1); - ok1(ht.raw.max < (1 << ht.raw.bits)); - - /* Mask should be set. */ - ok1(ht.raw.common_mask != 0); - ok1(ht.raw.common_mask != -1); - ok1(check_mask(&ht.raw, val, NUM_VALS)); - - /* Find all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, &dne)); - - /* Walk once, should get them all. */ - i = 0; - for (p = htable_obj_first(&ht,&iter); p; p = htable_obj_next(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - i = 0; - for (p = htable_obj_prev(&ht,&iter); p; p = htable_obj_prev(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - - /* Delete all. */ - del_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, &val[0].key)); - - /* Worst case, a "pointer" which doesn't have any matching bits. */ - htable_add(&ht.raw, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - htable_obj_add(&ht, &val[NUM_VALS-1]); - ok1(ht.raw.common_mask == 0); - ok1(ht.raw.common_bits == 0); - /* Delete the bogus one before we trip over it. */ - htable_del(&ht.raw, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - - /* Add the rest. */ - add_vals(&ht, val, NUM_VALS-1); - - /* Check we can find them all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_obj_get(&ht, &dne)); - - /* Check copy. */ - ok1(htable_obj_copy(&ht2, &ht)); - - /* Delete them all by key. */ - del_vals_bykey(&ht, val, NUM_VALS); - del_vals_bykey(&ht2, val, NUM_VALS); - - /* Write two of the same value. */ - val[1] = val[0]; - htable_obj_add(&ht, &val[0]); - htable_obj_add(&ht, &val[1]); - i = 0; - - result = htable_obj_getfirst(&ht, &i, &iter); - ok1(result == &val[0] || result == &val[1]); - if (result == &val[0]) { - ok1(htable_obj_getnext(&ht, &i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); - - /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[0])); - ok1(htable_obj_getfirst(&ht, &i, &iter) == &val[1]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); - } else { - ok1(htable_obj_getnext(&ht, &i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); - - /* Deleting first should make us iterate over the other. */ - ok1(htable_obj_del(&ht, &val[1])); - ok1(htable_obj_getfirst(&ht, &i, &iter) == &val[0]); - ok1(htable_obj_getnext(&ht, &i, &iter) == NULL); - } - - htable_obj_clear(&ht); - htable_obj_clear(&ht2); - return exit_status(); -} diff --git a/ccan/htable/test/run-zero-hash-first-entry.c b/ccan/htable/test/run-zero-hash-first-entry.c @@ -1,61 +0,0 @@ -#include <ccan/htable/htable.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> - -struct data { - size_t key; -}; - -/* Hash is simply key itself. */ -static size_t hash(const void *e, void *unused UNNEEDED) -{ - struct data *d = (struct data *)e; - - return d->key; -} - -static bool eq(const void *e, void *k) -{ - struct data *d = (struct data *)e; - size_t *key = (size_t *)k; - - return (d->key == *key); -} - -int main(void) -{ - struct htable table; - struct data *d0, *d1; - - plan_tests(6); - - d1 = malloc(sizeof(struct data)); - d1->key = 1; - d0 = malloc(sizeof(struct data)); - d0->key = 0; - - htable_init(&table, hash, NULL); - - htable_add(&table, d0->key, d0); - htable_add(&table, d1->key, d1); - - ok1(table.elems == 2); - ok1(htable_get(&table, 1, eq, &d1->key) == d1); - ok1(htable_get(&table, 0, eq, &d0->key) == d0); - htable_clear(&table); - - /* Now add in reverse order, should still be OK. */ - htable_add(&table, d1->key, d1); - htable_add(&table, d0->key, d0); - - ok1(table.elems == 2); - ok1(htable_get(&table, 1, eq, &d1->key) == d1); - ok1(htable_get(&table, 0, eq, &d0->key) == d0); - htable_clear(&table); - - free(d0); - free(d1); - return exit_status(); -} - diff --git a/ccan/htable/test/run.c b/ccan/htable/test/run.c @@ -1,212 +0,0 @@ -#include <ccan/htable/htable.h> -#include <ccan/htable/htable.c> -#include <ccan/tap/tap.h> -#include <stdbool.h> -#include <string.h> - -#define NUM_BITS 7 -#define NUM_VALS (1 << NUM_BITS) - -/* We use the number divided by two as the hash (for lots of - collisions), plus set all the higher bits so we can detect if they - don't get masked out. */ -static size_t hash(const void *elem, void *unused UNNEEDED) -{ - size_t h = *(uint64_t *)elem / 2; - h |= -1UL << NUM_BITS; - return h; -} - -static bool objcmp(const void *htelem, void *cmpdata) -{ - return *(uint64_t *)htelem == *(uint64_t *)cmpdata; -} - -static void add_vals(struct htable *ht, - const uint64_t val[], - unsigned int off, unsigned int num) -{ - uint64_t i; - - for (i = off; i < off+num; i++) { - if (htable_get(ht, hash(&i, NULL), objcmp, &i)) { - fail("%llu already in hash", (long long)i); - return; - } - htable_add(ht, hash(&val[i], NULL), &val[i]); - if (htable_get(ht, hash(&i, NULL), objcmp, &i) != &val[i]) { - fail("%llu not added to hash", (long long)i); - return; - } - } - pass("Added %llu numbers to hash", (long long)i); -} - -#if 0 -static void refill_vals(struct htable *ht, - const uint64_t val[], unsigned int num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (htable_get(ht, hash(&i, NULL), objcmp, &i)) - continue; - htable_add(ht, hash(&val[i], NULL), &val[i]); - } -} -#endif - -static void find_vals(struct htable *ht, - const uint64_t val[], unsigned int num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (htable_get(ht, hash(&i, NULL), objcmp, &i) != &val[i]) { - fail("%llu not found in hash", (long long)i); - return; - } - } - pass("Found %llu numbers in hash", (long long)i); -} - -static void del_vals(struct htable *ht, - const uint64_t val[], unsigned int num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (!htable_del(ht, hash(&val[i], NULL), &val[i])) { - fail("%llu not deleted from hash", (long long)i); - return; - } - } - pass("Deleted %llu numbers in hash", (long long)i); -} - -static bool check_mask(struct htable *ht, uint64_t val[], unsigned num) -{ - uint64_t i; - - for (i = 0; i < num; i++) { - if (((uintptr_t)&val[i] & ht->common_mask) != ht->common_bits) - return false; - } - return true; -} - -int main(void) -{ - unsigned int i, weight; - uintptr_t perfect_bit; - struct htable ht; - uint64_t val[NUM_VALS]; - uint64_t dne; - void *p; - struct htable_iter iter; - - plan_tests(36); - for (i = 0; i < NUM_VALS; i++) - val[i] = i; - dne = i; - - htable_init(&ht, hash, NULL); - ok1(ht.max == 0); - ok1(ht.bits == 0); - - /* We cannot find an entry which doesn't exist. */ - ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne)); - - /* This should increase it once. */ - add_vals(&ht, val, 0, 1); - ok1(ht.bits == 1); - ok1(ht.max == 1); - weight = 0; - for (i = 0; i < sizeof(ht.common_mask) * CHAR_BIT; i++) { - if (ht.common_mask & ((uintptr_t)1 << i)) { - weight++; - } - } - /* Only one bit should be clear. */ - ok1(weight == i-1); - - /* Mask should be set. */ - ok1(check_mask(&ht, val, 1)); - - /* This should increase it again. */ - add_vals(&ht, val, 1, 1); - ok1(ht.bits == 2); - ok1(ht.max == 3); - - /* Mask should be set. */ - ok1(ht.common_mask != 0); - ok1(ht.common_mask != -1); - ok1(check_mask(&ht, val, 2)); - - /* Now do the rest. */ - add_vals(&ht, val, 2, NUM_VALS - 2); - - /* Find all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne)); - - /* Walk once, should get them all. */ - i = 0; - for (p = htable_first(&ht,&iter); p; p = htable_next(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - - i = 0; - for (p = htable_prev(&ht, &iter); p; p = htable_prev(&ht, &iter)) - i++; - ok1(i == NUM_VALS); - - /* Delete all. */ - del_vals(&ht, val, NUM_VALS); - ok1(!htable_get(&ht, hash(&val[0], NULL), objcmp, &val[0])); - - /* Worst case, a "pointer" which doesn't have any matching bits. */ - htable_add(&ht, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - htable_add(&ht, hash(&val[NUM_VALS-1], NULL), &val[NUM_VALS-1]); - ok1(ht.common_mask == 0); - ok1(ht.common_bits == 0); - /* Get rid of bogus pointer before we trip over it! */ - htable_del(&ht, 0, (void *)~(uintptr_t)&val[NUM_VALS-1]); - - /* Add the rest. */ - add_vals(&ht, val, 0, NUM_VALS-1); - - /* Check we can find them all. */ - find_vals(&ht, val, NUM_VALS); - ok1(!htable_get(&ht, hash(&dne, NULL), objcmp, &dne)); - - /* Corner cases: wipe out the perfect bit using bogus pointer. */ - htable_clear(&ht); - htable_add(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1])); - ok1(ht.perfect_bit); - perfect_bit = ht.perfect_bit; - htable_add(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1] - | perfect_bit)); - ok1(ht.perfect_bit == 0); - htable_del(&ht, 0, (void *)((uintptr_t)&val[NUM_VALS-1] | perfect_bit)); - - /* Enlarging should restore it... */ - add_vals(&ht, val, 0, NUM_VALS-1); - - ok1(ht.perfect_bit != 0); - htable_clear(&ht); - - ok1(htable_init_sized(&ht, hash, NULL, 1024)); - ok1(ht.max >= 1024); - htable_clear(&ht); - - ok1(htable_init_sized(&ht, hash, NULL, 1023)); - ok1(ht.max >= 1023); - htable_clear(&ht); - - ok1(htable_init_sized(&ht, hash, NULL, 1025)); - ok1(ht.max >= 1025); - htable_clear(&ht); - - return exit_status(); -} diff --git a/ccan/htable/tools/Makefile b/ccan/htable/tools/Makefile @@ -1,40 +0,0 @@ -CCANDIR=../../.. -CFLAGS=-Wall -Werror -O3 -I$(CCANDIR) -#CFLAGS=-Wall -Werror -g -I$(CCANDIR) - -CCAN_OBJS:=ccan-tal.o ccan-tal-str.o ccan-tal-grab_file.o ccan-take.o ccan-time.o ccan-str.o ccan-noerr.o ccan-list.o - -all: speed stringspeed hsearchspeed - -speed: speed.o hash.o $(CCAN_OBJS) - -speed.o: speed.c ../htable.h ../htable.c - -hash.o: ../../hash/hash.c - $(CC) $(CFLAGS) -c -o $@ $< - -stringspeed: stringspeed.o hash.o $(CCAN_OBJS) - -stringspeed.o: speed.c ../htable.h ../htable.c - -hsearchspeed: hsearchspeed.o $(CCAN_OBJS) - -clean: - rm -f stringspeed speed hsearchspeed *.o - -ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-tal-str.o: $(CCANDIR)/ccan/tal/str/str.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-take.o: $(CCANDIR)/ccan/take/take.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-tal-grab_file.o: $(CCANDIR)/ccan/tal/grab_file/grab_file.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-time.o: $(CCANDIR)/ccan/time/time.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-list.o: $(CCANDIR)/ccan/list/list.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-str.o: $(CCANDIR)/ccan/str/str.c - $(CC) $(CFLAGS) -c -o $@ $< -ccan-noerr.o: $(CCANDIR)/ccan/noerr/noerr.c - $(CC) $(CFLAGS) -c -o $@ $< diff --git a/ccan/htable/tools/hsearchspeed.c b/ccan/htable/tools/hsearchspeed.c @@ -1,95 +0,0 @@ -/* Simple speed tests for a hash of strings using hsearch */ -#include <ccan/htable/htable_type.h> -#include <ccan/htable/htable.c> -#include <ccan/tal/str/str.h> -#include <ccan/tal/grab_file/grab_file.h> -#include <ccan/tal/tal.h> -#include <ccan/hash/hash.h> -#include <ccan/time/time.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <sys/time.h> -#include <search.h> - -/* Nanoseconds per operation */ -static size_t normalize(const struct timeabs *start, - const struct timeabs *stop, - unsigned int num) -{ - return time_to_nsec(time_divide(time_between(*stop, *start), num)); -} - -int main(int argc, char *argv[]) -{ - size_t i, j, num; - struct timeabs start, stop; - char **w; - ENTRY *words, *misswords; - - w = tal_strsplit(NULL, grab_file(NULL, - argv[1] ? argv[1] : "/usr/share/dict/words"), "\n", STR_NO_EMPTY); - num = tal_count(w) - 1; - printf("%zu words\n", num); - - hcreate(num+num/3); - - words = tal_arr(w, ENTRY, num); - for (i = 0; i < num; i++) { - words[i].key = w[i]; - words[i].data = words[i].key; - } - - /* Append and prepend last char for miss testing. */ - misswords = tal_arr(w, ENTRY, num); - for (i = 0; i < num; i++) { - char lastc; - if (strlen(w[i])) - lastc = w[i][strlen(w[i])-1]; - else - lastc = 'z'; - misswords[i].key = tal_fmt(misswords, "%c%s%c%c", - lastc, w[i], lastc, lastc); - } - - printf("#01: Initial insert: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - hsearch(words[i], ENTER); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#02: Initial lookup (match): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (hsearch(words[i], FIND)->data != words[i].data) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#03: Initial lookup (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - if (hsearch(misswords[i], FIND)) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Lookups in order are very cache-friendly for judy; try random */ - printf("#04: Initial lookup (random): "); - fflush(stdout); - start = time_now(); - for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) - if (hsearch(words[i], FIND)->data != words[i].data) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - return 0; -} diff --git a/ccan/htable/tools/speed.c b/ccan/htable/tools/speed.c @@ -1,370 +0,0 @@ -/* Simple speed tests for hashtables. */ -#include <ccan/htable/htable_type.h> -#include <ccan/htable/htable.c> -#include <ccan/hash/hash.h> -#include <ccan/time/time.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -static size_t hashcount; -struct object { - /* The key. */ - unsigned int key; - - /* Some contents. Doubles as consistency check. */ - struct object *self; -}; - -static const unsigned int *objkey(const struct object *obj) -{ - return &obj->key; -} - -static size_t hash_obj(const unsigned int *key) -{ - hashcount++; - return hashl(key, 1, 0); -} - -static bool cmp(const struct object *object, const unsigned int *key) -{ - return object->key == *key; -} - -HTABLE_DEFINE_TYPE(struct object, objkey, hash_obj, cmp, htable_obj); - -static unsigned int popcount(unsigned long val) -{ -#if HAVE_BUILTIN_POPCOUNTL - return __builtin_popcountl(val); -#else - if (sizeof(long) == sizeof(u64)) { - u64 v = val; - v = (v & 0x5555555555555555ULL) - + ((v >> 1) & 0x5555555555555555ULL); - v = (v & 0x3333333333333333ULL) - + ((v >> 1) & 0x3333333333333333ULL); - v = (v & 0x0F0F0F0F0F0F0F0FULL) - + ((v >> 1) & 0x0F0F0F0F0F0F0F0FULL); - v = (v & 0x00FF00FF00FF00FFULL) - + ((v >> 1) & 0x00FF00FF00FF00FFULL); - v = (v & 0x0000FFFF0000FFFFULL) - + ((v >> 1) & 0x0000FFFF0000FFFFULL); - v = (v & 0x00000000FFFFFFFFULL) - + ((v >> 1) & 0x00000000FFFFFFFFULL); - return v; - } - val = (val & 0x55555555ULL) + ((val >> 1) & 0x55555555ULL); - val = (val & 0x33333333ULL) + ((val >> 1) & 0x33333333ULL); - val = (val & 0x0F0F0F0FULL) + ((val >> 1) & 0x0F0F0F0FULL); - val = (val & 0x00FF00FFULL) + ((val >> 1) & 0x00FF00FFULL); - val = (val & 0x0000FFFFULL) + ((val >> 1) & 0x0000FFFFULL); - return val; -#endif -} - -static size_t perfect(const struct htable *ht) -{ - size_t i, placed_perfect = 0; - - for (i = 0; i < ((size_t)1 << ht->bits); i++) { - if (!entry_is_valid(ht->table[i])) - continue; - if (hash_bucket(ht, ht->rehash(get_raw_ptr(ht, ht->table[i]), - ht->priv)) == i) { - assert((ht->table[i] & ht->perfect_bit) - == ht->perfect_bit); - placed_perfect++; - } - } - return placed_perfect; -} - -static size_t count_deleted(const struct htable *ht) -{ - size_t i, delete_markers = 0; - - for (i = 0; i < ((size_t)1 << ht->bits); i++) { - if (ht->table[i] == HTABLE_DELETED) - delete_markers++; - } - return delete_markers; -} - -/* Nanoseconds per operation */ -static size_t normalize(const struct timeabs *start, - const struct timeabs *stop, - unsigned int num) -{ - return time_to_nsec(time_divide(time_between(*stop, *start), num)); -} - -static size_t worst_run(struct htable *ht, size_t *deleted) -{ - size_t longest = 0, len = 0, this_del = 0, i; - - *deleted = 0; - /* This doesn't take into account end-wrap, but gives an idea. */ - for (i = 0; i < ((size_t)1 << ht->bits); i++) { - if (ht->table[i]) { - len++; - if (ht->table[i] == HTABLE_DELETED) - this_del++; - } else { - if (len > longest) { - longest = len; - *deleted = this_del; - } - len = 0; - this_del = 0; - } - } - return longest; -} - -int main(int argc, char *argv[]) -{ - struct object *objs; - unsigned int i, j; - size_t num, deleted; - struct timeabs start, stop; - struct htable_obj ht; - bool make_dumb = false; - - if (argv[1] && strcmp(argv[1], "--dumb") == 0) { - argv++; - make_dumb = true; - } - num = argv[1] ? atoi(argv[1]) : 1000000; - objs = calloc(num, sizeof(objs[0])); - - for (i = 0; i < num; i++) { - objs[i].key = i; - objs[i].self = &objs[i]; - } - - htable_obj_init(&ht); - - printf("Initial insert: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - htable_obj_add(&ht, objs[i].self); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - printf("Details: hash size %u, mask bits %u, perfect %.0f%%\n", - 1U << ht.raw.bits, popcount(ht.raw.common_mask), - perfect(&ht.raw) * 100.0 / ht.raw.elems); - - if (make_dumb) { - /* Screw with mask, to hobble us. */ - update_common(&ht.raw, (void *)~ht.raw.common_bits); - printf("Details: DUMB MODE: mask bits %u\n", - popcount(ht.raw.common_mask)); - } - - printf("Initial lookup (match): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (htable_obj_get(&ht, &i)->self != objs[i].self) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Initial lookup (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - unsigned int n = i + num; - if (htable_obj_get(&ht, &n)) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Lookups in order are very cache-friendly for judy; try random */ - printf("Initial lookup (random): "); - fflush(stdout); - start = time_now(); - for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) - if (htable_obj_get(&ht, &j)->self != &objs[j]) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - hashcount = 0; - printf("Initial delete all: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (!htable_obj_del(&ht, objs[i].self)) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - printf("Details: rehashes %zu\n", hashcount); - - printf("Initial re-inserting: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - htable_obj_add(&ht, objs[i].self); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - hashcount = 0; - printf("Deleting first half: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i+=2) - if (!htable_obj_del(&ht, objs[i].self)) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Details: rehashes %zu, delete markers %zu\n", - hashcount, count_deleted(&ht.raw)); - - printf("Adding (a different) half: "); - fflush(stdout); - - for (i = 0; i < num; i+=2) - objs[i].key = num+i; - - start = time_now(); - for (i = 0; i < num; i+=2) - htable_obj_add(&ht, objs[i].self); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Details: delete markers %zu, perfect %.0f%%\n", - count_deleted(&ht.raw), perfect(&ht.raw) * 100.0 / ht.raw.elems); - - printf("Lookup after half-change (match): "); - fflush(stdout); - start = time_now(); - for (i = 1; i < num; i+=2) - if (htable_obj_get(&ht, &i)->self != objs[i].self) - abort(); - for (i = 0; i < num; i+=2) { - unsigned int n = i + num; - if (htable_obj_get(&ht, &n)->self != objs[i].self) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Lookup after half-change (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - unsigned int n = i + num * 2; - if (htable_obj_get(&ht, &n)) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Hashtables with delete markers can fill with markers over time. - * so do some changes to see how it operates in long-term. */ - for (i = 0; i < 5; i++) { - if (i == 0) { - /* We don't measure this: jmap is different. */ - printf("Details: initial churn\n"); - } else { - printf("Churning %s time: ", - i == 1 ? "second" - : i == 2 ? "third" - : i == 3 ? "fourth" - : "fifth"); - fflush(stdout); - } - start = time_now(); - for (j = 0; j < num; j++) { - if (!htable_obj_del(&ht, &objs[j])) - abort(); - objs[j].key = num*i+j; - if (!htable_obj_add(&ht, &objs[j])) - abort(); - } - stop = time_now(); - if (i != 0) - printf(" %zu ns\n", normalize(&start, &stop, num)); - } - - /* Spread out the keys more to try to make it harder. */ - printf("Details: reinserting with spread\n"); - for (i = 0; i < num; i++) { - if (!htable_obj_del(&ht, objs[i].self)) - abort(); - objs[i].key = num * 5 + i * 9; - if (!htable_obj_add(&ht, objs[i].self)) - abort(); - } - printf("Details: delete markers %zu, perfect %.0f%%\n", - count_deleted(&ht.raw), perfect(&ht.raw) * 100.0 / ht.raw.elems); - i = worst_run(&ht.raw, &deleted); - printf("Details: worst run %u (%zu deleted)\n", i, deleted); - - printf("Lookup after churn & spread (match): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - unsigned int n = num * 5 + i * 9; - if (htable_obj_get(&ht, &n)->self != objs[i].self) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Lookup after churn & spread (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - unsigned int n = num * (5 + 9) + i * 9; - if (htable_obj_get(&ht, &n)) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Lookup after churn & spread (random): "); - fflush(stdout); - start = time_now(); - for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) { - unsigned int n = num * 5 + j * 9; - if (htable_obj_get(&ht, &n)->self != &objs[j]) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - hashcount = 0; - printf("Deleting half after churn & spread: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i+=2) - if (!htable_obj_del(&ht, objs[i].self)) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Adding (a different) half after churn & spread: "); - fflush(stdout); - - for (i = 0; i < num; i+=2) - objs[i].key = num*6+i*9; - - start = time_now(); - for (i = 0; i < num; i+=2) - htable_obj_add(&ht, objs[i].self); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Details: delete markers %zu, perfect %.0f%%\n", - count_deleted(&ht.raw), perfect(&ht.raw) * 100.0 / ht.raw.elems); - - return 0; -} diff --git a/ccan/htable/tools/stringspeed.c b/ccan/htable/tools/stringspeed.c @@ -1,240 +0,0 @@ -/* Simple speed tests for a hash of strings. */ -#include <ccan/htable/htable_type.h> -#include <ccan/htable/htable.c> -#include <ccan/tal/str/str.h> -#include <ccan/tal/grab_file/grab_file.h> -#include <ccan/tal/tal.h> -#include <ccan/hash/hash.h> -#include <ccan/time/time.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <sys/time.h> - -static size_t hashcount; - -static const char *strkey(const char *str) -{ - return str; -} - -static size_t hash_str(const char *key) -{ - hashcount++; - return hash(key, strlen(key), 0); -} - -static bool cmp(const char *obj, const char *key) -{ - return strcmp(obj, key) == 0; -} - -HTABLE_DEFINE_TYPE(char, strkey, hash_str, cmp, htable_str); - -/* Nanoseconds per operation */ -static size_t normalize(const struct timeabs *start, - const struct timeabs *stop, - unsigned int num) -{ - return time_to_nsec(time_divide(time_between(*stop, *start), num)); -} - -int main(int argc, char *argv[]) -{ - size_t i, j, num; - struct timeabs start, stop; - struct htable_str ht; - char **words, **misswords; - - words = tal_strsplit(NULL, grab_file(NULL, - argv[1] ? argv[1] : "/usr/share/dict/words"), "\n", - STR_NO_EMPTY); - htable_str_init(&ht); - num = tal_count(words) - 1; - /* Note that on my system, num is just > 98304, where we double! */ - printf("%zu words\n", num); - - /* Append and prepend last char for miss testing. */ - misswords = tal_arr(words, char *, num); - for (i = 0; i < num; i++) { - char lastc; - if (strlen(words[i])) - lastc = words[i][strlen(words[i])-1]; - else - lastc = 'z'; - misswords[i] = tal_fmt(misswords, "%c%s%c%c", - lastc, words[i], lastc, lastc); - } - - printf("#01: Initial insert: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - htable_str_add(&ht, words[i]); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("Bytes allocated: %zu\n", - sizeof(ht.raw.table[0]) << ht.raw.bits); - - printf("#02: Initial lookup (match): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (htable_str_get(&ht, words[i]) != words[i]) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#03: Initial lookup (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - if (htable_str_get(&ht, misswords[i])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Lookups in order are very cache-friendly for judy; try random */ - printf("#04: Initial lookup (random): "); - fflush(stdout); - start = time_now(); - for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) - if (htable_str_get(&ht, words[j]) != words[j]) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - hashcount = 0; - printf("#05: Initial delete all: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (!htable_str_del(&ht, words[i])) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#06: Initial re-inserting: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - htable_str_add(&ht, words[i]); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - hashcount = 0; - printf("#07: Deleting first half: "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i+=2) - if (!htable_str_del(&ht, words[i])) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#08: Adding (a different) half: "); - fflush(stdout); - - start = time_now(); - for (i = 0; i < num; i+=2) - htable_str_add(&ht, misswords[i]); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#09: Lookup after half-change (match): "); - fflush(stdout); - start = time_now(); - for (i = 1; i < num; i+=2) - if (htable_str_get(&ht, words[i]) != words[i]) - abort(); - for (i = 0; i < num; i+=2) { - if (htable_str_get(&ht, misswords[i]) != misswords[i]) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#10: Lookup after half-change (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i+=2) - if (htable_str_get(&ht, words[i])) - abort(); - for (i = 1; i < num; i+=2) { - if (htable_str_get(&ht, misswords[i])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Hashtables with delete markers can fill with markers over time. - * so do some changes to see how it operates in long-term. */ - printf("#11: Churn 1: "); - start = time_now(); - for (j = 0; j < num; j+=2) { - if (!htable_str_del(&ht, misswords[j])) - abort(); - if (!htable_str_add(&ht, words[j])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#12: Churn 2: "); - start = time_now(); - for (j = 1; j < num; j+=2) { - if (!htable_str_del(&ht, words[j])) - abort(); - if (!htable_str_add(&ht, misswords[j])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#13: Churn 3: "); - start = time_now(); - for (j = 1; j < num; j+=2) { - if (!htable_str_del(&ht, misswords[j])) - abort(); - if (!htable_str_add(&ht, words[j])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Now it's back to normal... */ - printf("#14: Post-Churn lookup (match): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) - if (htable_str_get(&ht, words[i]) != words[i]) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - printf("#15: Post-Churn lookup (miss): "); - fflush(stdout); - start = time_now(); - for (i = 0; i < num; i++) { - if (htable_str_get(&ht, misswords[i])) - abort(); - } - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - /* Lookups in order are very cache-friendly for judy; try random */ - printf("#16: Post-Churn lookup (random): "); - fflush(stdout); - start = time_now(); - for (i = 0, j = 0; i < num; i++, j = (j + 10007) % num) - if (htable_str_get(&ht, words[j]) != words[j]) - abort(); - stop = time_now(); - printf(" %zu ns\n", normalize(&start, &stop, num)); - - return 0; -} diff --git a/ccan/licenses/BSD-MIT b/ccan/licenses/BSD-MIT @@ -1,17 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/ccan/licenses/CC0 b/ccan/licenses/CC0 @@ -1,28 +0,0 @@ -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: - - the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; - moral rights retained by the original author(s) and/or performer(s); - publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; - rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; - rights protecting the extraction, dissemination, use and reuse of data in a Work; - database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and - other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. - -4. Limitations and Disclaimers. - - No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. - Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. - Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. - Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. diff --git a/ccan/licenses/LGPL-2.1 b/ccan/licenses/LGPL-2.1 @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/ccan/likely/LICENSE b/ccan/likely/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/likely/_info b/ccan/likely/_info @@ -1,57 +0,0 @@ -#include "config.h" -#include <string.h> -#include <stdio.h> - -/** - * likely - macros for annotating likely/unlikely branches in the code - * - * Inspired by Andi Kleen's macros for the Linux Kernel, these macros - * help you annotate rare paths in your code for the convenience of the - * compiler and the reader. - * - * With CCAN_LIKELY_DEBUG defined, it provides statistics for each - * likely()/unlikely() call (but note that this requires LGPL dependencies). - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - * - * Example: - * #include <ccan/likely/likely.h> - * #include <stdio.h> - * - * int main(int argc, char *argv[]) - * { - * // This example is silly: the compiler knows exit() is unlikely. - * if (unlikely(argc == 1)) { - * fprintf(stderr, "Usage: %s <args>...\n", argv[0]); - * return 1; - * } - * for (argc++; argv[argc]; argc++) - * printf("%s\n", argv[argc]); - * return 0; - * } - */ -int main(int argc, char *argv[]) -{ - /* Expect exactly one argument */ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { -#ifdef CCAN_LIKELY_DEBUG - printf("ccan/str\n"); - printf("ccan/htable\n"); - printf("ccan/hash\n"); -#endif - return 0; - } - if (strcmp(argv[1], "testdepends") == 0) { -#ifndef CCAN_LIKELY_DEBUG - printf("ccan/str\n"); - printf("ccan/htable\n"); - printf("ccan/hash\n"); -#endif - return 0; - } - return 1; -} diff --git a/ccan/likely/likely.c b/ccan/likely/likely.c @@ -1,136 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details. */ -#ifdef CCAN_LIKELY_DEBUG -#include <ccan/likely/likely.h> -#include <ccan/hash/hash.h> -#include <ccan/htable/htable_type.h> -#include <stdlib.h> -#include <stdio.h> -struct trace { - const char *condstr; - const char *file; - unsigned int line; - bool expect; - unsigned long count, right; -}; - -static size_t hash_trace(const struct trace *trace) -{ - return hash(trace->condstr, strlen(trace->condstr), - hash(trace->file, strlen(trace->file), - trace->line + trace->expect)); -} - -static bool trace_eq(const struct trace *t1, const struct trace *t2) -{ - return t1->condstr == t2->condstr - && t1->file == t2->file - && t1->line == t2->line - && t1->expect == t2->expect; -} - -/* struct thash */ -HTABLE_DEFINE_TYPE(struct trace, (const struct trace *), hash_trace, trace_eq, - thash); - -static struct thash htable -= { HTABLE_INITIALIZER(htable.raw, thash_hash, NULL) }; - -static void init_trace(struct trace *trace, - const char *condstr, const char *file, unsigned int line, - bool expect) -{ - trace->condstr = condstr; - trace->file = file; - trace->line = line; - trace->expect = expect; - trace->count = trace->right = 0; -} - -static struct trace *add_trace(const struct trace *t) -{ - struct trace *trace = malloc(sizeof(*trace)); - *trace = *t; - thash_add(&htable, trace); - return trace; -} - -long _likely_trace(bool cond, bool expect, - const char *condstr, - const char *file, unsigned int line) -{ - struct trace *p, trace; - - init_trace(&trace, condstr, file, line, expect); - p = thash_get(&htable, &trace); - if (!p) - p = add_trace(&trace); - - p->count++; - if (cond == expect) - p->right++; - - return cond; -} - -static double right_ratio(const struct trace *t) -{ - return (double)t->right / t->count; -} - -char *likely_stats(unsigned int min_hits, unsigned int percent) -{ - struct trace *worst; - double worst_ratio; - struct thash_iter i; - char *ret; - struct trace *t; - - worst = NULL; - worst_ratio = 2; - - /* This is O(n), but it's not likely called that often. */ - for (t = thash_first(&htable, &i); t; t = thash_next(&htable, &i)) { - if (t->count >= min_hits) { - if (right_ratio(t) < worst_ratio) { - worst = t; - worst_ratio = right_ratio(t); - } - } - } - - if (worst_ratio * 100 > percent) - return NULL; - - ret = malloc(strlen(worst->condstr) + - strlen(worst->file) + - sizeof(long int) * 8 + - sizeof("%s:%u:%slikely(%s) correct %u%% (%lu/%lu)")); - sprintf(ret, "%s:%u:%slikely(%s) correct %u%% (%lu/%lu)", - worst->file, worst->line, - worst->expect ? "" : "un", worst->condstr, - (unsigned)(worst_ratio * 100), - worst->right, worst->count); - - thash_del(&htable, worst); - free(worst); - - return ret; -} - -void likely_stats_reset(void) -{ - struct thash_iter i; - struct trace *t; - - /* This is a bit better than O(n^2), but we have to loop since - * first/next during delete is unreliable. */ - while ((t = thash_first(&htable, &i)) != NULL) { - for (; t; t = thash_next(&htable, &i)) { - thash_del(&htable, t); - free(t); - } - } - - thash_clear(&htable); -} -#endif /*CCAN_LIKELY_DEBUG*/ diff --git a/ccan/likely/likely.h b/ccan/likely/likely.h @@ -1,111 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_LIKELY_H -#define CCAN_LIKELY_H -#include "config.h" -#include <stdbool.h> - -#ifndef CCAN_LIKELY_DEBUG -#if HAVE_BUILTIN_EXPECT -/** - * likely - indicate that a condition is likely to be true. - * @cond: the condition - * - * This uses a compiler extension where available to indicate a likely - * code path and optimize appropriately; it's also useful for readers - * to quickly identify exceptional paths through functions. The - * threshold for "likely" is usually considered to be between 90 and - * 99%; marginal cases should not be marked either way. - * - * See Also: - * unlikely(), likely_stats() - * - * Example: - * // Returns false if we overflow. - * static inline bool inc_int(unsigned int *val) - * { - * (*val)++; - * if (likely(*val)) - * return true; - * return false; - * } - */ -#define likely(cond) __builtin_expect(!!(cond), 1) - -/** - * unlikely - indicate that a condition is unlikely to be true. - * @cond: the condition - * - * This uses a compiler extension where available to indicate an unlikely - * code path and optimize appropriately; see likely() above. - * - * See Also: - * likely(), likely_stats(), COLD (compiler.h) - * - * Example: - * // Prints a warning if we overflow. - * static inline void inc_int(unsigned int *val) - * { - * (*val)++; - * if (unlikely(*val == 0)) - * fprintf(stderr, "Overflow!"); - * } - */ -#define unlikely(cond) __builtin_expect(!!(cond), 0) -#else -#define likely(cond) (!!(cond)) -#define unlikely(cond) (!!(cond)) -#endif -#else /* CCAN_LIKELY_DEBUG versions */ -#include <ccan/str/str.h> - -#define likely(cond) \ - (_likely_trace(!!(cond), 1, stringify(cond), __FILE__, __LINE__)) -#define unlikely(cond) \ - (_likely_trace(!!(cond), 0, stringify(cond), __FILE__, __LINE__)) - -long _likely_trace(bool cond, bool expect, - const char *condstr, - const char *file, unsigned int line); -/** - * likely_stats - return description of abused likely()/unlikely() - * @min_hits: minimum number of hits - * @percent: maximum percentage correct - * - * When CCAN_LIKELY_DEBUG is defined, likely() and unlikely() trace their - * results: this causes a significant slowdown, but allows analysis of - * whether the branches are labelled correctly. - * - * This function returns a malloc'ed description of the least-correct - * usage of likely() or unlikely(). It ignores places which have been - * called less than @min_hits times, and those which were predicted - * correctly more than @percent of the time. It returns NULL when - * nothing meets those criteria. - * - * Note that this call is destructive; the returned offender is - * removed from the trace so that the next call to likely_stats() will - * return the next-worst likely()/unlikely() usage. - * - * Example: - * // Print every place hit more than twice which was wrong > 5%. - * static void report_stats(void) - * { - * #ifdef CCAN_LIKELY_DEBUG - * const char *bad; - * - * while ((bad = likely_stats(2, 95)) != NULL) { - * printf("Suspicious likely: %s", bad); - * free(bad); - * } - * #endif - * } - */ -char *likely_stats(unsigned int min_hits, unsigned int percent); - -/** - * likely_stats_reset - free up memory of likely()/unlikely() branches. - * - * This can also plug memory leaks. - */ -void likely_stats_reset(void); -#endif /* CCAN_LIKELY_DEBUG */ -#endif /* CCAN_LIKELY_H */ diff --git a/ccan/likely/test/run-debug.c b/ccan/likely/test/run-debug.c @@ -1,105 +0,0 @@ -#define CCAN_LIKELY_DEBUG 1 -#include <ccan/likely/likely.c> -#include <ccan/likely/likely.h> -#include <ccan/tap/tap.h> -#include <stdlib.h> - -static bool one_seems_likely(unsigned int val) -{ - if (likely(val == 1)) - return true; - return false; -} - -static bool one_seems_unlikely(unsigned int val) -{ - if (unlikely(val == 1)) - return true; - return false; -} - -static bool likely_one_unlikely_two(unsigned int val1, unsigned int val2) -{ - /* Same line, check we don't get confused! */ - if (likely(val1 == 1) && unlikely(val2 == 2)) - return true; - return false; -} - -int main(void) -{ - char *bad; - - plan_tests(14); - - /* Correct guesses. */ - one_seems_likely(1); - ok1(likely_stats(0, 90) == NULL); - one_seems_unlikely(2); - ok1(likely_stats(0, 90) == NULL); - - /* Incorrect guesses. */ - one_seems_likely(0); - one_seems_likely(2); - /* Hasn't been hit 4 times, so this fails */ - ok1(!likely_stats(4, 90)); - bad = likely_stats(3, 90); - ok(strends(bad, "run-debug.c:9:likely(val == 1) correct 33% (1/3)"), - "likely_stats returned %s", bad); - free(bad); - - /* Nothing else above 90% */ - ok1(!likely_stats(0, 90)); - - /* This should get everything. */ - bad = likely_stats(0, 100); - ok(strends(bad, "run-debug.c:16:unlikely(val == 1) correct 100% (1/1)"), - "likely_stats returned %s", bad); - free(bad); - - /* Nothing left (table is actually cleared) */ - ok1(!likely_stats(0, 100)); - - /* Make sure unlikely works */ - one_seems_unlikely(0); - one_seems_unlikely(2); - one_seems_unlikely(1); - - bad = likely_stats(0, 90); - ok(strends(bad, "run-debug.c:16:unlikely(val == 1) correct 66% (2/3)"), - "likely_stats returned %s", bad); - free(bad); - ok1(!likely_stats(0, 100)); - - likely_one_unlikely_two(1, 1); - likely_one_unlikely_two(1, 1); - likely_one_unlikely_two(1, 1); - ok1(!likely_stats(0, 90)); - likely_one_unlikely_two(1, 2); - - bad = likely_stats(0, 90); - ok(strends(bad, "run-debug.c:24:unlikely(val2 == 2) correct 75% (3/4)"), - "likely_stats returned %s", bad); - free(bad); - bad = likely_stats(0, 100); - ok(strends(bad, "run-debug.c:24:likely(val1 == 1) correct 100% (4/4)"), - "likely_stats returned %s", bad); - free(bad); - - ok1(!likely_stats(0, 100)); - - /* Check that reset works! */ - one_seems_unlikely(0); - one_seems_unlikely(2); - one_seems_unlikely(1); - likely_stats_reset(); - - ok1(!likely_stats(0, 100)); - - exit(exit_status()); -} - -/* Fools ccanlint: it doesn't think we use str, htable or hash. */ -#include <ccan/hash/hash.h> -#include <ccan/htable/htable.h> -#include <ccan/str/str.h> diff --git a/ccan/likely/test/run.c b/ccan/likely/test/run.c @@ -1,30 +0,0 @@ -#include <ccan/likely/likely.c> -#include <ccan/likely/likely.h> -#include <ccan/tap/tap.h> -#include <stdlib.h> - -static bool one_seems_likely(unsigned int val) -{ - if (likely(val == 1)) - return true; - return false; -} - -static bool one_seems_unlikely(unsigned int val) -{ - if (unlikely(val == 1)) - return true; - return false; -} - -int main(void) -{ - plan_tests(4); - - /* Without debug, we can only check that it doesn't effect functions. */ - ok1(one_seems_likely(1)); - ok1(!one_seems_likely(2)); - ok1(one_seems_unlikely(1)); - ok1(!one_seems_unlikely(2)); - exit(exit_status()); -} diff --git a/ccan/list/LICENSE b/ccan/list/LICENSE @@ -1 +0,0 @@ -../../licenses/BSD-MIT- \ No newline at end of file diff --git a/ccan/list/_info b/ccan/list/_info @@ -1,72 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * list - double linked list routines - * - * The list header contains routines for manipulating double linked lists. - * It defines two types: struct list_head used for anchoring lists, and - * struct list_node which is usually embedded in the structure which is placed - * in the list. - * - * Example: - * #include <err.h> - * #include <stdio.h> - * #include <stdlib.h> - * #include <ccan/list/list.h> - * - * struct parent { - * const char *name; - * struct list_head children; - * unsigned int num_children; - * }; - * - * struct child { - * const char *name; - * struct list_node list; - * }; - * - * int main(int argc, char *argv[]) - * { - * struct parent p; - * struct child *c; - * int i; - * - * if (argc < 2) - * errx(1, "Usage: %s parent children...", argv[0]); - * - * p.name = argv[1]; - * list_head_init(&p.children); - * p.num_children = 0; - * for (i = 2; i < argc; i++) { - * c = malloc(sizeof(*c)); - * c->name = argv[i]; - * list_add(&p.children, &c->list); - * p.num_children++; - * } - * - * printf("%s has %u children:", p.name, p.num_children); - * list_for_each(&p.children, c, list) - * printf("%s ", c->name); - * printf("\n"); - * return 0; - * } - * - * License: BSD-MIT - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/str\n"); - printf("ccan/container_of\n"); - printf("ccan/check_type\n"); - return 0; - } - - return 1; -} diff --git a/ccan/list/list.c b/ccan/list/list.c @@ -1,43 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#include <stdio.h> -#include <stdlib.h> -#include "list.h" - -static void *corrupt(const char *abortstr, - const struct list_node *head, - const struct list_node *node, - unsigned int count) -{ - if (abortstr) { - fprintf(stderr, - "%s: prev corrupt in node %p (%u) of %p\n", - abortstr, node, count, head); - abort(); - } - return NULL; -} - -struct list_node *list_check_node(const struct list_node *node, - const char *abortstr) -{ - const struct list_node *p, *n; - int count = 0; - - for (p = node, n = node->next; n != node; p = n, n = n->next) { - count++; - if (n->prev != p) - return corrupt(abortstr, node, n, count); - } - /* Check prev on head node. */ - if (node->prev != p) - return corrupt(abortstr, node, node, 0); - - return (struct list_node *)node; -} - -struct list_head *list_check(const struct list_head *h, const char *abortstr) -{ - if (!list_check_node(&h->n, abortstr)) - return NULL; - return (struct list_head *)h; -} diff --git a/ccan/list/list.h b/ccan/list/list.h @@ -1,842 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#ifndef CCAN_LIST_H -#define CCAN_LIST_H -//#define CCAN_LIST_DEBUG 1 -#include <stdbool.h> -#include <assert.h> -#include <ccan/str/str.h> -#include <ccan/container_of/container_of.h> -#include <ccan/check_type/check_type.h> - -/** - * struct list_node - an entry in a doubly-linked list - * @next: next entry (self if empty) - * @prev: previous entry (self if empty) - * - * This is used as an entry in a linked list. - * Example: - * struct child { - * const char *name; - * // Linked list of all us children. - * struct list_node list; - * }; - */ -struct list_node -{ - struct list_node *next, *prev; -}; - -/** - * struct list_head - the head of a doubly-linked list - * @h: the list_head (containing next and prev pointers) - * - * This is used as the head of a linked list. - * Example: - * struct parent { - * const char *name; - * struct list_head children; - * unsigned int num_children; - * }; - */ -struct list_head -{ - struct list_node n; -}; - -/** - * list_check - check head of a list for consistency - * @h: the list_head - * @abortstr: the location to print on aborting, or NULL. - * - * Because list_nodes have redundant information, consistency checking between - * the back and forward links can be done. This is useful as a debugging check. - * If @abortstr is non-NULL, that will be printed in a diagnostic if the list - * is inconsistent, and the function will abort. - * - * Returns the list head if the list is consistent, NULL if not (it - * can never return NULL if @abortstr is set). - * - * See also: list_check_node() - * - * Example: - * static void dump_parent(struct parent *p) - * { - * struct child *c; - * - * printf("%s (%u children):\n", p->name, p->num_children); - * list_check(&p->children, "bad child list"); - * list_for_each(&p->children, c, list) - * printf(" -> %s\n", c->name); - * } - */ -struct list_head *list_check(const struct list_head *h, const char *abortstr); - -/** - * list_check_node - check node of a list for consistency - * @n: the list_node - * @abortstr: the location to print on aborting, or NULL. - * - * Check consistency of the list node is in (it must be in one). - * - * See also: list_check() - * - * Example: - * static void dump_child(const struct child *c) - * { - * list_check_node(&c->list, "bad child list"); - * printf("%s\n", c->name); - * } - */ -struct list_node *list_check_node(const struct list_node *n, - const char *abortstr); - -#define LIST_LOC __FILE__ ":" stringify(__LINE__) -#ifdef CCAN_LIST_DEBUG -#define list_debug(h, loc) list_check((h), loc) -#define list_debug_node(n, loc) list_check_node((n), loc) -#else -#define list_debug(h, loc) ((void)loc, h) -#define list_debug_node(n, loc) ((void)loc, n) -#endif - -/** - * LIST_HEAD_INIT - initializer for an empty list_head - * @name: the name of the list. - * - * Explicit initializer for an empty list. - * - * See also: - * LIST_HEAD, list_head_init() - * - * Example: - * static struct list_head my_list = LIST_HEAD_INIT(my_list); - */ -#define LIST_HEAD_INIT(name) { { &(name).n, &(name).n } } - -/** - * LIST_HEAD - define and initialize an empty list_head - * @name: the name of the list. - * - * The LIST_HEAD macro defines a list_head and initializes it to an empty - * list. It can be prepended by "static" to define a static list_head. - * - * See also: - * LIST_HEAD_INIT, list_head_init() - * - * Example: - * static LIST_HEAD(my_global_list); - */ -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -/** - * list_head_init - initialize a list_head - * @h: the list_head to set to the empty list - * - * Example: - * ... - * struct parent *parent = malloc(sizeof(*parent)); - * - * list_head_init(&parent->children); - * parent->num_children = 0; - */ -static inline void list_head_init(struct list_head *h) -{ - h->n.next = h->n.prev = &h->n; -} - -/** - * list_node_init - initialize a list_node - * @n: the list_node to link to itself. - * - * You don't need to use this normally! But it lets you list_del(@n) - * safely. - */ -static inline void list_node_init(struct list_node *n) -{ - n->next = n->prev = n; -} - -/** - * list_add_after - add an entry after an existing node in a linked list - * @h: the list_head to add the node to (for debugging) - * @p: the existing list_node to add the node after - * @n: the new list_node to add to the list. - * - * The existing list_node must already be a member of the list. - * The new list_node does not need to be initialized; it will be overwritten. - * - * Example: - * struct child c1, c2, c3; - * LIST_HEAD(h); - * - * list_add_tail(&h, &c1.list); - * list_add_tail(&h, &c3.list); - * list_add_after(&h, &c1.list, &c2.list); - */ -#define list_add_after(h, p, n) list_add_after_(h, p, n, LIST_LOC) -static inline void list_add_after_(struct list_head *h, - struct list_node *p, - struct list_node *n, - const char *abortstr) -{ - n->next = p->next; - n->prev = p; - p->next->prev = n; - p->next = n; - (void)list_debug(h, abortstr); -} - -/** - * list_add - add an entry at the start of a linked list. - * @h: the list_head to add the node to - * @n: the list_node to add to the list. - * - * The list_node does not need to be initialized; it will be overwritten. - * Example: - * struct child *child = malloc(sizeof(*child)); - * - * child->name = "marvin"; - * list_add(&parent->children, &child->list); - * parent->num_children++; - */ -#define list_add(h, n) list_add_(h, n, LIST_LOC) -static inline void list_add_(struct list_head *h, - struct list_node *n, - const char *abortstr) -{ - list_add_after_(h, &h->n, n, abortstr); -} - -/** - * list_add_before - add an entry before an existing node in a linked list - * @h: the list_head to add the node to (for debugging) - * @p: the existing list_node to add the node before - * @n: the new list_node to add to the list. - * - * The existing list_node must already be a member of the list. - * The new list_node does not need to be initialized; it will be overwritten. - * - * Example: - * list_head_init(&h); - * list_add_tail(&h, &c1.list); - * list_add_tail(&h, &c3.list); - * list_add_before(&h, &c3.list, &c2.list); - */ -#define list_add_before(h, p, n) list_add_before_(h, p, n, LIST_LOC) -static inline void list_add_before_(struct list_head *h, - struct list_node *p, - struct list_node *n, - const char *abortstr) -{ - n->next = p; - n->prev = p->prev; - p->prev->next = n; - p->prev = n; - (void)list_debug(h, abortstr); -} - -/** - * list_add_tail - add an entry at the end of a linked list. - * @h: the list_head to add the node to - * @n: the list_node to add to the list. - * - * The list_node does not need to be initialized; it will be overwritten. - * Example: - * list_add_tail(&parent->children, &child->list); - * parent->num_children++; - */ -#define list_add_tail(h, n) list_add_tail_(h, n, LIST_LOC) -static inline void list_add_tail_(struct list_head *h, - struct list_node *n, - const char *abortstr) -{ - list_add_before_(h, &h->n, n, abortstr); -} - -/** - * list_empty - is a list empty? - * @h: the list_head - * - * If the list is empty, returns true. - * - * Example: - * assert(list_empty(&parent->children) == (parent->num_children == 0)); - */ -#define list_empty(h) list_empty_(h, LIST_LOC) -static inline bool list_empty_(const struct list_head *h, const char* abortstr) -{ - (void)list_debug(h, abortstr); - return h->n.next == &h->n; -} - -/** - * list_empty_nodebug - is a list empty (and don't perform debug checks)? - * @h: the list_head - * - * If the list is empty, returns true. - * This differs from list_empty() in that if CCAN_LIST_DEBUG is set it - * will NOT perform debug checks. Only use this function if you REALLY - * know what you're doing. - * - * Example: - * assert(list_empty_nodebug(&parent->children) == (parent->num_children == 0)); - */ -#ifndef CCAN_LIST_DEBUG -#define list_empty_nodebug(h) list_empty(h) -#else -static inline bool list_empty_nodebug(const struct list_head *h) -{ - return h->n.next == &h->n; -} -#endif - -/** - * list_empty_nocheck - is a list empty? - * @h: the list_head - * - * If the list is empty, returns true. This doesn't perform any - * debug check for list consistency, so it can be called without - * locks, racing with the list being modified. This is ok for - * checks where an incorrect result is not an issue (optimized - * bail out path for example). - */ -static inline bool list_empty_nocheck(const struct list_head *h) -{ - return h->n.next == &h->n; -} - -/** - * list_del - delete an entry from an (unknown) linked list. - * @n: the list_node to delete from the list. - * - * Note that this leaves @n in an undefined state; it can be added to - * another list, but not deleted again. - * - * See also: - * list_del_from(), list_del_init() - * - * Example: - * list_del(&child->list); - * parent->num_children--; - */ -#define list_del(n) list_del_(n, LIST_LOC) -static inline void list_del_(struct list_node *n, const char* abortstr) -{ - (void)list_debug_node(n, abortstr); - n->next->prev = n->prev; - n->prev->next = n->next; -#ifdef CCAN_LIST_DEBUG - /* Catch use-after-del. */ - n->next = n->prev = NULL; -#endif -} - -/** - * list_del_init - delete a node, and reset it so it can be deleted again. - * @n: the list_node to be deleted. - * - * list_del(@n) or list_del_init() again after this will be safe, - * which can be useful in some cases. - * - * See also: - * list_del_from(), list_del() - * - * Example: - * list_del_init(&child->list); - * parent->num_children--; - */ -#define list_del_init(n) list_del_init_(n, LIST_LOC) -static inline void list_del_init_(struct list_node *n, const char *abortstr) -{ - list_del_(n, abortstr); - list_node_init(n); -} - -/** - * list_del_from - delete an entry from a known linked list. - * @h: the list_head the node is in. - * @n: the list_node to delete from the list. - * - * This explicitly indicates which list a node is expected to be in, - * which is better documentation and can catch more bugs. - * - * See also: list_del() - * - * Example: - * list_del_from(&parent->children, &child->list); - * parent->num_children--; - */ -static inline void list_del_from(struct list_head *h, struct list_node *n) -{ -#ifdef CCAN_LIST_DEBUG - { - /* Thorough check: make sure it was in list! */ - struct list_node *i; - for (i = h->n.next; i != n; i = i->next) - assert(i != &h->n); - } -#endif /* CCAN_LIST_DEBUG */ - - /* Quick test that catches a surprising number of bugs. */ - assert(!list_empty(h)); - list_del(n); -} - -/** - * list_swap - swap out an entry from an (unknown) linked list for a new one. - * @o: the list_node to replace from the list. - * @n: the list_node to insert in place of the old one. - * - * Note that this leaves @o in an undefined state; it can be added to - * another list, but not deleted/swapped again. - * - * See also: - * list_del() - * - * Example: - * struct child x1, x2; - * LIST_HEAD(xh); - * - * list_add(&xh, &x1.list); - * list_swap(&x1.list, &x2.list); - */ -#define list_swap(o, n) list_swap_(o, n, LIST_LOC) -static inline void list_swap_(struct list_node *o, - struct list_node *n, - const char* abortstr) -{ - (void)list_debug_node(o, abortstr); - *n = *o; - n->next->prev = n; - n->prev->next = n; -#ifdef CCAN_LIST_DEBUG - /* Catch use-after-del. */ - o->next = o->prev = NULL; -#endif -} - -/** - * list_entry - convert a list_node back into the structure containing it. - * @n: the list_node - * @type: the type of the entry - * @member: the list_node member of the type - * - * Example: - * // First list entry is children.next; convert back to child. - * child = list_entry(parent->children.n.next, struct child, list); - * - * See Also: - * list_top(), list_for_each() - */ -#define list_entry(n, type, member) container_of(n, type, member) - -/** - * list_top - get the first entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *first; - * first = list_top(&parent->children, struct child, list); - * if (!first) - * printf("Empty list!\n"); - */ -#define list_top(h, type, member) \ - ((type *)list_top_((h), list_off_(type, member))) - -static inline const void *list_top_(const struct list_head *h, size_t off) -{ - if (list_empty(h)) - return NULL; - return (const char *)h->n.next - off; -} - -/** - * list_pop - remove the first entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *one; - * one = list_pop(&parent->children, struct child, list); - * if (!one) - * printf("Empty list!\n"); - */ -#define list_pop(h, type, member) \ - ((type *)list_pop_((h), list_off_(type, member))) - -static inline const void *list_pop_(const struct list_head *h, size_t off) -{ - struct list_node *n; - - if (list_empty(h)) - return NULL; - n = h->n.next; - list_del(n); - return (const char *)n - off; -} - -/** - * list_tail - get the last entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *last; - * last = list_tail(&parent->children, struct child, list); - * if (!last) - * printf("Empty list!\n"); - */ -#define list_tail(h, type, member) \ - ((type *)list_tail_((h), list_off_(type, member))) - -static inline const void *list_tail_(const struct list_head *h, size_t off) -{ - if (list_empty(h)) - return NULL; - return (const char *)h->n.prev - off; -} - -/** - * list_for_each - iterate through a list. - * @h: the list_head (warning: evaluated multiple times!) - * @i: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. - * - * Example: - * list_for_each(&parent->children, child, list) - * printf("Name: %s\n", child->name); - */ -#define list_for_each(h, i, member) \ - list_for_each_off(h, i, list_off_var_(i, member)) - -/** - * list_for_each_rev - iterate through a list backwards. - * @h: the list_head - * @i: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. - * - * Example: - * list_for_each_rev(&parent->children, child, list) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_rev(h, i, member) \ - list_for_each_rev_off(h, i, list_off_var_(i, member)) - -/** - * list_for_each_rev_safe - iterate through a list backwards, - * maybe during deletion - * @h: the list_head - * @i: the structure containing the list_node - * @nxt: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list backwards. - * It's a for loop, so you can break and continue as normal. The extra - * variable * @nxt is used to hold the next element, so you can delete @i - * from the list. - * - * Example: - * struct child *next; - * list_for_each_rev_safe(&parent->children, child, next, list) { - * printf("Name: %s\n", child->name); - * } - */ -#define list_for_each_rev_safe(h, i, nxt, member) \ - list_for_each_rev_safe_off(h, i, nxt, list_off_var_(i, member)) - -/** - * list_for_each_safe - iterate through a list, maybe during deletion - * @h: the list_head - * @i: the structure containing the list_node - * @nxt: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. The extra variable - * @nxt is used to hold the next element, so you can delete @i from the list. - * - * Example: - * list_for_each_safe(&parent->children, child, next, list) { - * list_del(&child->list); - * parent->num_children--; - * } - */ -#define list_for_each_safe(h, i, nxt, member) \ - list_for_each_safe_off(h, i, nxt, list_off_var_(i, member)) - -/** - * list_next - get the next entry in a list - * @h: the list_head - * @i: a pointer to an entry in the list. - * @member: the list_node member of the structure - * - * If @i was the last entry in the list, returns NULL. - * - * Example: - * struct child *second; - * second = list_next(&parent->children, first, list); - * if (!second) - * printf("No second child!\n"); - */ -#define list_next(h, i, member) \ - ((list_typeof(i))list_entry_or_null(list_debug(h, \ - __FILE__ ":" stringify(__LINE__)), \ - (i)->member.next, \ - list_off_var_((i), member))) - -/** - * list_prev - get the previous entry in a list - * @h: the list_head - * @i: a pointer to an entry in the list. - * @member: the list_node member of the structure - * - * If @i was the first entry in the list, returns NULL. - * - * Example: - * first = list_prev(&parent->children, second, list); - * if (!first) - * printf("Can't go back to first child?!\n"); - */ -#define list_prev(h, i, member) \ - ((list_typeof(i))list_entry_or_null(list_debug(h, \ - __FILE__ ":" stringify(__LINE__)), \ - (i)->member.prev, \ - list_off_var_((i), member))) - -/** - * list_append_list - empty one list onto the end of another. - * @to: the list to append into - * @from: the list to empty. - * - * This takes the entire contents of @from and moves it to the end of - * @to. After this @from will be empty. - * - * Example: - * struct list_head adopter; - * - * list_append_list(&adopter, &parent->children); - * assert(list_empty(&parent->children)); - * parent->num_children = 0; - */ -#define list_append_list(t, f) list_append_list_(t, f, \ - __FILE__ ":" stringify(__LINE__)) -static inline void list_append_list_(struct list_head *to, - struct list_head *from, - const char *abortstr) -{ - struct list_node *from_tail = list_debug(from, abortstr)->n.prev; - struct list_node *to_tail = list_debug(to, abortstr)->n.prev; - - /* Sew in head and entire list. */ - to->n.prev = from_tail; - from_tail->next = &to->n; - to_tail->next = &from->n; - from->n.prev = to_tail; - - /* Now remove head. */ - list_del(&from->n); - list_head_init(from); -} - -/** - * list_prepend_list - empty one list into the start of another. - * @to: the list to prepend into - * @from: the list to empty. - * - * This takes the entire contents of @from and moves it to the start - * of @to. After this @from will be empty. - * - * Example: - * list_prepend_list(&adopter, &parent->children); - * assert(list_empty(&parent->children)); - * parent->num_children = 0; - */ -#define list_prepend_list(t, f) list_prepend_list_(t, f, LIST_LOC) -static inline void list_prepend_list_(struct list_head *to, - struct list_head *from, - const char *abortstr) -{ - struct list_node *from_tail = list_debug(from, abortstr)->n.prev; - struct list_node *to_head = list_debug(to, abortstr)->n.next; - - /* Sew in head and entire list. */ - to->n.next = &from->n; - from->n.prev = &to->n; - to_head->prev = from_tail; - from_tail->next = to_head; - - /* Now remove head. */ - list_del(&from->n); - list_head_init(from); -} - -/* internal macros, do not use directly */ -#define list_for_each_off_dir_(h, i, off, dir) \ - for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ - (off)); \ - list_node_from_off_((void *)i, (off)) != &(h)->n; \ - i = list_node_to_off_(list_node_from_off_((void *)i, (off))->dir, \ - (off))) - -#define list_for_each_safe_off_dir_(h, i, nxt, off, dir) \ - for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ - (off)), \ - nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ - (off)); \ - list_node_from_off_(i, (off)) != &(h)->n; \ - i = nxt, \ - nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ - (off))) - -/** - * list_for_each_off - iterate through a list of memory regions. - * @h: the list_head - * @i: the pointer to a memory region wich contains list node data. - * @off: offset(relative to @i) at which list node data resides. - * - * This is a low-level wrapper to iterate @i over the entire list, used to - * implement all oher, more high-level, for-each constructs. It's a for loop, - * so you can break and continue as normal. - * - * WARNING! Being the low-level macro that it is, this wrapper doesn't know - * nor care about the type of @i. The only assumption made is that @i points - * to a chunk of memory that at some @offset, relative to @i, contains a - * properly filled `struct list_node' which in turn contains pointers to - * memory chunks and it's turtles all the way down. With all that in mind - * remember that given the wrong pointer/offset couple this macro will - * happily churn all you memory until SEGFAULT stops it, in other words - * caveat emptor. - * - * It is worth mentioning that one of legitimate use-cases for that wrapper - * is operation on opaque types with known offset for `struct list_node' - * member(preferably 0), because it allows you not to disclose the type of - * @i. - * - * Example: - * list_for_each_off(&parent->children, child, - * offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_off(h, i, off) \ - list_for_each_off_dir_((h),(i),(off),next) - -/** - * list_for_each_rev_off - iterate through a list of memory regions backwards - * @h: the list_head - * @i: the pointer to a memory region wich contains list node data. - * @off: offset(relative to @i) at which list node data resides. - * - * See list_for_each_off for details - */ -#define list_for_each_rev_off(h, i, off) \ - list_for_each_off_dir_((h),(i),(off),prev) - -/** - * list_for_each_safe_off - iterate through a list of memory regions, maybe - * during deletion - * @h: the list_head - * @i: the pointer to a memory region wich contains list node data. - * @nxt: the structure containing the list_node - * @off: offset(relative to @i) at which list node data resides. - * - * For details see `list_for_each_off' and `list_for_each_safe' - * descriptions. - * - * Example: - * list_for_each_safe_off(&parent->children, child, - * next, offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_safe_off(h, i, nxt, off) \ - list_for_each_safe_off_dir_((h),(i),(nxt),(off),next) - -/** - * list_for_each_rev_safe_off - iterate backwards through a list of - * memory regions, maybe during deletion - * @h: the list_head - * @i: the pointer to a memory region wich contains list node data. - * @nxt: the structure containing the list_node - * @off: offset(relative to @i) at which list node data resides. - * - * For details see `list_for_each_rev_off' and `list_for_each_rev_safe' - * descriptions. - * - * Example: - * list_for_each_rev_safe_off(&parent->children, child, - * next, offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_rev_safe_off(h, i, nxt, off) \ - list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev) - -/* Other -off variants. */ -#define list_entry_off(n, type, off) \ - ((type *)list_node_from_off_((n), (off))) - -#define list_head_off(h, type, off) \ - ((type *)list_head_off((h), (off))) - -#define list_tail_off(h, type, off) \ - ((type *)list_tail_((h), (off))) - -#define list_add_off(h, n, off) \ - list_add((h), list_node_from_off_((n), (off))) - -#define list_del_off(n, off) \ - list_del(list_node_from_off_((n), (off))) - -#define list_del_from_off(h, n, off) \ - list_del_from(h, list_node_from_off_((n), (off))) - -/* Offset helper functions so we only single-evaluate. */ -static inline void *list_node_to_off_(struct list_node *node, size_t off) -{ - return (void *)((char *)node - off); -} -static inline struct list_node *list_node_from_off_(void *ptr, size_t off) -{ - return (struct list_node *)((char *)ptr + off); -} - -/* Get the offset of the member, but make sure it's a list_node. */ -#define list_off_(type, member) \ - (container_off(type, member) + \ - check_type(((type *)0)->member, struct list_node)) - -#define list_off_var_(var, member) \ - (container_off_var(var, member) + \ - check_type(var->member, struct list_node)) - -#if HAVE_TYPEOF -#define list_typeof(var) typeof(var) -#else -#define list_typeof(var) void * -#endif - -/* Returns member, or NULL if at end of list. */ -static inline void *list_entry_or_null(const struct list_head *h, - const struct list_node *n, - size_t off) -{ - if (n == &h->n) - return NULL; - return (char *)n - off; -} -#endif /* CCAN_LIST_H */ diff --git a/ccan/list/test/compile_ok-constant.c b/ccan/list/test/compile_ok-constant.c @@ -1,49 +0,0 @@ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include <stdbool.h> -#include <stdio.h> - -struct child { - const char *name; - struct list_node list; -}; - -static bool children(const struct list_head *list) -{ - return !list_empty(list); -} - -static const struct child *first_child(const struct list_head *list) -{ - return list_top(list, struct child, list); -} - -static const struct child *last_child(const struct list_head *list) -{ - return list_tail(list, struct child, list); -} - -static void check_children(const struct list_head *list) -{ - list_check(list, "bad child list"); -} - -static void print_children(const struct list_head *list) -{ - const struct child *c; - list_for_each(list, c, list) - printf("%s\n", c->name); -} - -int main(void) -{ - LIST_HEAD(h); - - children(&h); - first_child(&h); - last_child(&h); - check_children(&h); - print_children(&h); - return 0; -} diff --git a/ccan/list/test/helper.c b/ccan/list/test/helper.c @@ -1,56 +0,0 @@ -#include <stdlib.h> -#include <stdbool.h> -#include <time.h> - -#include <ccan/list/list.h> -#include "helper.h" - -#define ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING \ - (42) - -struct opaque { - struct list_node list; - size_t secret_offset; - char secret_drawer[42]; -}; - -static bool not_randomized = true; - -struct opaque *create_opaque_blob(void) -{ - struct opaque *blob = calloc(1, sizeof(struct opaque)); - - if (not_randomized) { - srandom((int)time(NULL)); - not_randomized = false; - } - - blob->secret_offset = random() % (sizeof(blob->secret_drawer)); - blob->secret_drawer[blob->secret_offset] = - ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING; - - return blob; -} - -bool if_blobs_know_the_secret(struct opaque *blob) -{ - bool answer = true; - int i; - for (i = 0; i < sizeof(blob->secret_drawer) / - sizeof(blob->secret_drawer[0]); i++) - if (i != blob->secret_offset) - answer = answer && (blob->secret_drawer[i] == 0); - else - answer = answer && - (blob->secret_drawer[blob->secret_offset] == - ANSWER_TO_THE_ULTIMATE_QUESTION_OF_LIFE_THE_UNIVERSE_AND_EVERYTHING); - - return answer; -} - -void destroy_opaque_blob(struct opaque *blob) -{ - free(blob); -} - - diff --git a/ccan/list/test/helper.h b/ccan/list/test/helper.h @@ -1,9 +0,0 @@ -/* These are in a separate C file so we can test undefined structures. */ -struct opaque; -typedef struct opaque opaque_t; - -opaque_t *create_opaque_blob(void); -bool if_blobs_know_the_secret(opaque_t *blob); -void destroy_opaque_blob(opaque_t *blob); - - diff --git a/ccan/list/test/run-CCAN_LIST_DEBUG.c b/ccan/list/test/run-CCAN_LIST_DEBUG.c @@ -1,60 +0,0 @@ -/* Check that CCAN_LIST_DEBUG works */ -#include <setjmp.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <err.h> - -/* We don't actually want it to exit... */ -static jmp_buf aborted; -#define abort() longjmp(aborted, 1) - -#define fprintf my_fprintf -static char printf_buffer[1000]; - -static int my_fprintf(FILE *stream, const char *format, ...) -{ - va_list ap; - int ret; - (void)stream; - va_start(ap, format); - ret = vsprintf(printf_buffer, format, ap); - va_end(ap); - return ret; -} - -#define CCAN_LIST_DEBUG 1 -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> - -int main(void) -{ - struct list_head list; - struct list_node n1; - char expect[100]; - - plan_tests(2); - /* Empty list. */ - list.n.next = &list.n; - list.n.prev = &list.n; - ok1(list_check(&list, NULL) == &list); - - /* Bad back ptr */ - list.n.prev = &n1; - - /* Aborting version. */ - sprintf(expect, "run-CCAN_LIST_DEBUG.c:51: prev corrupt in node %p (0) of %p\n", - &list, &list); - if (setjmp(aborted) == 0) { - assert(list_empty(&list)); - fail("list_empty on empty with bad back ptr didn't fail!"); - } else { - /* __FILE__ might give full path. */ - int prep = strlen(printf_buffer) - strlen(expect); - ok1(prep >= 0 && strcmp(printf_buffer + prep, expect) == 0); - } - - return exit_status(); -} diff --git a/ccan/list/test/run-check-corrupt.c b/ccan/list/test/run-check-corrupt.c @@ -1,90 +0,0 @@ -#include <setjmp.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <err.h> - -/* We don't actually want it to exit... */ -static jmp_buf aborted; -#define abort() longjmp(aborted, 1) - -#define fprintf my_fprintf -static char printf_buffer[1000]; - -static int my_fprintf(FILE *stream, const char *format, ...) -{ - va_list ap; - int ret; - (void)stream; - va_start(ap, format); - ret = vsprintf(printf_buffer, format, ap); - va_end(ap); - return ret; -} - -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> - -int main(void) -{ - struct list_head list; - struct list_node n1; - char expect[100]; - - plan_tests(9); - /* Empty list. */ - list.n.next = &list.n; - list.n.prev = &list.n; - ok1(list_check(&list, NULL) == &list); - - /* Bad back ptr */ - list.n.prev = &n1; - /* Non-aborting version. */ - ok1(list_check(&list, NULL) == NULL); - - /* Aborting version. */ - sprintf(expect, "test message: prev corrupt in node %p (0) of %p\n", - &list, &list); - if (setjmp(aborted) == 0) { - list_check(&list, "test message"); - fail("list_check on empty with bad back ptr didn't fail!"); - } else { - ok1(strcmp(printf_buffer, expect) == 0); - } - - /* n1 in list. */ - list.n.next = &n1; - list.n.prev = &n1; - n1.prev = &list.n; - n1.next = &list.n; - ok1(list_check(&list, NULL) == &list); - ok1(list_check_node(&n1, NULL) == &n1); - - /* Bad back ptr */ - n1.prev = &n1; - ok1(list_check(&list, NULL) == NULL); - ok1(list_check_node(&n1, NULL) == NULL); - - /* Aborting version. */ - sprintf(expect, "test message: prev corrupt in node %p (1) of %p\n", - &n1, &list); - if (setjmp(aborted) == 0) { - list_check(&list, "test message"); - fail("list_check on n1 bad back ptr didn't fail!"); - } else { - ok1(strcmp(printf_buffer, expect) == 0); - } - - sprintf(expect, "test message: prev corrupt in node %p (0) of %p\n", - &n1, &n1); - if (setjmp(aborted) == 0) { - list_check_node(&n1, "test message"); - fail("list_check_node on n1 bad back ptr didn't fail!"); - } else { - ok1(strcmp(printf_buffer, expect) == 0); - } - - return exit_status(); -} diff --git a/ccan/list/test/run-check-nonconst.c b/ccan/list/test/run-check-nonconst.c @@ -1,27 +0,0 @@ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include "helper.h" - -struct child { - const char *name; - struct list_node list; -}; - -int main(void) -{ - struct child c1, c2; - struct list_head list = LIST_HEAD_INIT(list); - - plan_tests(1); - - list_add(&list, &c1.list); - list_add_tail(list_check(&list, "Bad list!"), &c2.list); - list_del_from(list_check(&list, "Bad list!"), - list_check_node(&c2.list, "Bad node!")); - list_del_from(list_check(&list, "Bad list!"), - list_check_node(&c1.list, "Bad node!")); - ok1(list_empty(list_check(&list, "Bad emptied list"))); - - return exit_status(); -} diff --git a/ccan/list/test/run-list_del_from-assert.c b/ccan/list/test/run-list_del_from-assert.c @@ -1,36 +0,0 @@ -#define CCAN_LIST_DEBUG 1 -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <signal.h> - -int main(void) -{ - struct list_head list1, list2; - struct list_node n1, n2, n3; - pid_t child; - int status; - - plan_tests(1); - list_head_init(&list1); - list_head_init(&list2); - list_add(&list1, &n1); - list_add(&list2, &n2); - list_add_tail(&list2, &n3); - - child = fork(); - if (child) { - wait(&status); - } else { - /* This should abort. */ - list_del_from(&list1, &n3); - exit(0); - } - - ok1(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT); - list_del_from(&list2, &n3); - return exit_status(); -} diff --git a/ccan/list/test/run-list_prev-list_next.c b/ccan/list/test/run-list_prev-list_next.c @@ -1,65 +0,0 @@ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include "helper.h" - -struct parent { - const char *name; - unsigned int num_children; - struct list_head children; -}; - -struct child { - const char *name; - struct list_node list; -}; - -int main(void) -{ - struct parent parent; - struct child c1, c2, c3; - const struct parent *p; - const struct child *c; - - plan_tests(20); - parent.num_children = 0; - list_head_init(&parent.children); - - c1.name = "c1"; - list_add(&parent.children, &c1.list); - - ok1(list_next(&parent.children, &c1, list) == NULL); - ok1(list_prev(&parent.children, &c1, list) == NULL); - - c2.name = "c2"; - list_add_tail(&parent.children, &c2.list); - - ok1(list_next(&parent.children, &c1, list) == &c2); - ok1(list_prev(&parent.children, &c1, list) == NULL); - ok1(list_next(&parent.children, &c2, list) == NULL); - ok1(list_prev(&parent.children, &c2, list) == &c1); - - c3.name = "c3"; - list_add_tail(&parent.children, &c3.list); - - ok1(list_next(&parent.children, &c1, list) == &c2); - ok1(list_prev(&parent.children, &c1, list) == NULL); - ok1(list_next(&parent.children, &c2, list) == &c3); - ok1(list_prev(&parent.children, &c2, list) == &c1); - ok1(list_next(&parent.children, &c3, list) == NULL); - ok1(list_prev(&parent.children, &c3, list) == &c2); - - /* Const variants */ - p = &parent; - c = &c2; - ok1(list_next(&p->children, &c1, list) == &c2); - ok1(list_prev(&p->children, &c1, list) == NULL); - ok1(list_next(&p->children, c, list) == &c3); - ok1(list_prev(&p->children, c, list) == &c1); - ok1(list_next(&parent.children, c, list) == &c3); - ok1(list_prev(&parent.children, c, list) == &c1); - ok1(list_next(&p->children, &c3, list) == NULL); - ok1(list_prev(&p->children, &c3, list) == &c2); - - return exit_status(); -} diff --git a/ccan/list/test/run-prepend_list.c b/ccan/list/test/run-prepend_list.c @@ -1,111 +0,0 @@ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include <stdarg.h> - -static bool list_expect(struct list_head *h, ...) -{ - va_list ap; - struct list_node *n = &h->n, *expected; - - va_start(ap, h); - while ((expected = va_arg(ap, struct list_node *)) != NULL) { - n = n->next; - if (n != expected) - return false; - } - return (n->next == &h->n); -} - -int main(void) -{ - struct list_head h1, h2; - struct list_node n[4]; - - plan_tests(40); - - list_head_init(&h1); - list_head_init(&h2); - - /* Append an empty list to an empty list. */ - list_append_list(&h1, &h2); - ok1(list_empty(&h1)); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - - /* Prepend an empty list to an empty list. */ - list_prepend_list(&h1, &h2); - ok1(list_empty(&h1)); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - - /* Append an empty list to a non-empty list */ - list_add(&h1, &n[0]); - list_append_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[0], NULL)); - - /* Prepend an empty list to a non-empty list */ - list_prepend_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[0], NULL)); - - /* Append a non-empty list to an empty list. */ - list_append_list(&h2, &h1); - ok1(list_empty(&h1)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h2, &n[0], NULL)); - - /* Prepend a non-empty list to an empty list. */ - list_prepend_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[0], NULL)); - - /* Prepend a non-empty list to non-empty list. */ - list_add(&h2, &n[1]); - list_prepend_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[1], &n[0], NULL)); - - /* Append a non-empty list to non-empty list. */ - list_add(&h2, &n[2]); - list_append_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[1], &n[0], &n[2], NULL)); - - /* Prepend a 2-entry list to a 2-entry list. */ - list_del_from(&h1, &n[2]); - list_add(&h2, &n[2]); - list_add_tail(&h2, &n[3]); - list_prepend_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[2], &n[3], &n[1], &n[0], NULL)); - - /* Append a 2-entry list to a 2-entry list. */ - list_del_from(&h1, &n[2]); - list_del_from(&h1, &n[3]); - list_add(&h2, &n[2]); - list_add_tail(&h2, &n[3]); - list_append_list(&h1, &h2); - ok1(list_empty(&h2)); - ok1(list_check(&h1, NULL)); - ok1(list_check(&h2, NULL)); - ok1(list_expect(&h1, &n[1], &n[0], &n[2], &n[3], NULL)); - - return exit_status(); -} diff --git a/ccan/list/test/run-single-eval.c b/ccan/list/test/run-single-eval.c @@ -1,168 +0,0 @@ -/* Make sure macros only evaluate their args once. */ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> - -struct parent { - const char *name; - struct list_head children; - unsigned int num_children; - int eval_count; -}; - -struct child { - const char *name; - struct list_node list; -}; - -static LIST_HEAD(static_list); - -#define ref(obj, counter) ((counter)++, (obj)) - -int main(void) -{ - struct parent parent; - struct child c1, c2, c3, *c, *n; - unsigned int i; - unsigned int static_count = 0, parent_count = 0, list_count = 0, - node_count = 0; - struct list_head list = LIST_HEAD_INIT(list); - - plan_tests(74); - /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */ - ok1(list_empty(ref(&static_list, static_count))); - ok1(static_count == 1); - ok1(list_check(ref(&static_list, static_count), NULL)); - ok1(static_count == 2); - ok1(list_empty(ref(&list, list_count))); - ok1(list_count == 1); - ok1(list_check(ref(&list, list_count), NULL)); - ok1(list_count == 2); - - parent.num_children = 0; - list_head_init(ref(&parent.children, parent_count)); - ok1(parent_count == 1); - /* Test list_head_init */ - ok1(list_empty(ref(&parent.children, parent_count))); - ok1(parent_count == 2); - ok1(list_check(ref(&parent.children, parent_count), NULL)); - ok1(parent_count == 3); - - c2.name = "c2"; - list_add(ref(&parent.children, parent_count), &c2.list); - ok1(parent_count == 4); - /* Test list_add and !list_empty. */ - ok1(!list_empty(ref(&parent.children, parent_count))); - ok1(parent_count == 5); - ok1(c2.list.next == &parent.children.n); - ok1(c2.list.prev == &parent.children.n); - ok1(parent.children.n.next == &c2.list); - ok1(parent.children.n.prev == &c2.list); - /* Test list_check */ - ok1(list_check(ref(&parent.children, parent_count), NULL)); - ok1(parent_count == 6); - - c1.name = "c1"; - list_add(ref(&parent.children, parent_count), &c1.list); - ok1(parent_count == 7); - /* Test list_add and !list_empty. */ - ok1(!list_empty(ref(&parent.children, parent_count))); - ok1(parent_count == 8); - ok1(c2.list.next == &parent.children.n); - ok1(c2.list.prev == &c1.list); - ok1(parent.children.n.next == &c1.list); - ok1(parent.children.n.prev == &c2.list); - ok1(c1.list.next == &c2.list); - ok1(c1.list.prev == &parent.children.n); - /* Test list_check */ - ok1(list_check(ref(&parent.children, parent_count), NULL)); - ok1(parent_count == 9); - - c3.name = "c3"; - list_add_tail(ref(&parent.children, parent_count), &c3.list); - ok1(parent_count == 10); - /* Test list_add_tail and !list_empty. */ - ok1(!list_empty(ref(&parent.children, parent_count))); - ok1(parent_count == 11); - ok1(parent.children.n.next == &c1.list); - ok1(parent.children.n.prev == &c3.list); - ok1(c1.list.next == &c2.list); - ok1(c1.list.prev == &parent.children.n); - ok1(c2.list.next == &c3.list); - ok1(c2.list.prev == &c1.list); - ok1(c3.list.next == &parent.children.n); - ok1(c3.list.prev == &c2.list); - /* Test list_check */ - ok1(list_check(ref(&parent.children, parent_count), NULL)); - ok1(parent_count == 12); - - /* Test list_check_node */ - ok1(list_check_node(&c1.list, NULL)); - ok1(list_check_node(&c2.list, NULL)); - ok1(list_check_node(&c3.list, NULL)); - - /* Test list_top */ - ok1(list_top(ref(&parent.children, parent_count), struct child, list) == &c1); - ok1(parent_count == 13); - - /* Test list_tail */ - ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == &c3); - ok1(parent_count == 14); - - /* Test list_for_each. */ - i = 0; - list_for_each(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c1); - break; - case 1: - ok1(c == &c2); - break; - case 2: - ok1(c == &c3); - break; - } - if (i > 2) - break; - } - ok1(i == 3); - - /* Test list_for_each_safe, list_del and list_del_from. */ - i = 0; - list_for_each_safe(&parent.children, c, n, list) { - switch (i++) { - case 0: - ok1(c == &c1); - list_del(ref(&c->list, node_count)); - ok1(node_count == 1); - break; - case 1: - ok1(c == &c2); - list_del_from(ref(&parent.children, parent_count), - ref(&c->list, node_count)); - ok1(node_count == 2); - break; - case 2: - ok1(c == &c3); - list_del_from(ref(&parent.children, parent_count), - ref(&c->list, node_count)); - ok1(node_count == 3); - break; - } - ok1(list_check(ref(&parent.children, parent_count), NULL)); - if (i > 2) - break; - } - ok1(i == 3); - ok1(parent_count == 19); - ok1(list_empty(ref(&parent.children, parent_count))); - ok1(parent_count == 20); - - /* Test list_top/list_tail on empty list. */ - ok1(list_top(ref(&parent.children, parent_count), struct child, list) == NULL); - ok1(parent_count == 21); - ok1(list_tail(ref(&parent.children, parent_count), struct child, list) == NULL); - ok1(parent_count == 22); - return exit_status(); -} diff --git a/ccan/list/test/run-with-debug.c b/ccan/list/test/run-with-debug.c @@ -1,3 +0,0 @@ -/* Just like run.c, but with all debug checks enabled. */ -#define CCAN_LIST_DEBUG 1 -#include <ccan/list/test/run.c> diff --git a/ccan/list/test/run.c b/ccan/list/test/run.c @@ -1,305 +0,0 @@ -#include <ccan/list/list.h> -#include <ccan/tap/tap.h> -#include <ccan/list/list.c> -#include "helper.h" - -struct parent { - const char *name; - struct list_head children; - unsigned int num_children; -}; - -struct child { - const char *name; - struct list_node list; -}; - -static LIST_HEAD(static_list); - -int main(void) -{ - struct parent parent; - struct child c1, c2, c3, x1, *c, *n; - unsigned int i; - struct list_head list = LIST_HEAD_INIT(list); - opaque_t *q, *nq; - struct list_head opaque_list = LIST_HEAD_INIT(opaque_list); - LIST_HEAD(rev); - - plan_tests(92); - /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */ - ok1(list_empty(&static_list)); - ok1(list_check(&static_list, NULL)); - ok1(list_empty(&list)); - ok1(list_check(&list, NULL)); - - parent.num_children = 0; - list_head_init(&parent.children); - /* Test list_head_init */ - ok1(list_empty(&parent.children)); - ok1(list_check(&parent.children, NULL)); - - c2.name = "c2"; - list_add(&parent.children, &c2.list); - /* Test list_add and !list_empty. */ - ok1(!list_empty(&parent.children)); - ok1(c2.list.next == &parent.children.n); - ok1(c2.list.prev == &parent.children.n); - ok1(parent.children.n.next == &c2.list); - ok1(parent.children.n.prev == &c2.list); - /* Test list_check */ - ok1(list_check(&parent.children, NULL)); - - c1.name = "c1"; - list_add(&parent.children, &c1.list); - /* Test list_add and !list_empty. */ - ok1(!list_empty(&parent.children)); - ok1(c2.list.next == &parent.children.n); - ok1(c2.list.prev == &c1.list); - ok1(parent.children.n.next == &c1.list); - ok1(parent.children.n.prev == &c2.list); - ok1(c1.list.next == &c2.list); - ok1(c1.list.prev == &parent.children.n); - /* Test list_check */ - ok1(list_check(&parent.children, NULL)); - - c3.name = "c3"; - list_add_tail(&parent.children, &c3.list); - /* Test list_add_tail and !list_empty. */ - ok1(!list_empty(&parent.children)); - ok1(parent.children.n.next == &c1.list); - ok1(parent.children.n.prev == &c3.list); - ok1(c1.list.next == &c2.list); - ok1(c1.list.prev == &parent.children.n); - ok1(c2.list.next == &c3.list); - ok1(c2.list.prev == &c1.list); - ok1(c3.list.next == &parent.children.n); - ok1(c3.list.prev == &c2.list); - /* Test list_check */ - ok1(list_check(&parent.children, NULL)); - - /* Test list_check_node */ - ok1(list_check_node(&c1.list, NULL)); - ok1(list_check_node(&c2.list, NULL)); - ok1(list_check_node(&c3.list, NULL)); - - /* Test list_top */ - ok1(list_top(&parent.children, struct child, list) == &c1); - - /* Test list_pop */ - ok1(list_pop(&parent.children, struct child, list) == &c1); - ok1(list_top(&parent.children, struct child, list) == &c2); - list_add(&parent.children, &c1.list); - - /* Test list_tail */ - ok1(list_tail(&parent.children, struct child, list) == &c3); - - /* Test list_for_each. */ - i = 0; - list_for_each(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c1); - break; - case 1: - ok1(c == &c2); - break; - case 2: - ok1(c == &c3); - break; - } - if (i > 2) - break; - } - ok1(i == 3); - - /* Test list_for_each_rev. */ - i = 0; - list_for_each_rev(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c3); - break; - case 1: - ok1(c == &c2); - break; - case 2: - ok1(c == &c1); - break; - } - if (i > 2) - break; - } - ok1(i == 3); - - /* Test list_for_each_safe, list_del and list_del_from. */ - i = 0; - list_for_each_safe(&parent.children, c, n, list) { - switch (i++) { - case 0: - ok1(c == &c1); - list_del(&c->list); - break; - case 1: - ok1(c == &c2); - list_del_from(&parent.children, &c->list); - break; - case 2: - ok1(c == &c3); - list_del_from(&parent.children, &c->list); - break; - } - - /* prepare for list_for_each_rev_safe test */ - list_add(&rev, &c->list); - - ok1(list_check(&parent.children, NULL)); - if (i > 2) - break; - } - ok1(i == 3); - ok1(list_empty(&parent.children)); - - /* Test list_for_each_rev_safe, list_del and list_del_from. */ - i = 0; - list_for_each_rev_safe(&rev, c, n, list) { - switch (i++) { - case 0: - ok1(c == &c1); - list_del(&c->list); - break; - case 1: - ok1(c == &c2); - list_del_from(&rev, &c->list); - break; - case 2: - ok1(c == &c3); - list_del_from(&rev, &c->list); - break; - } - ok1(list_check(&rev, NULL)); - if (i > 2) - break; - } - ok1(i == 3); - ok1(list_empty(&rev)); - - /* Test list_node_init: safe to list_del after this. */ - list_node_init(&c->list); - list_del(&c->list); - - /* Test list_del_init */ - list_add(&parent.children, &c->list); - ok1(!list_empty(&parent.children)); - list_del_init(&c->list); - ok1(list_empty(&parent.children)); - /* We can call this as many times as we like. */ - list_del_init(&c->list); - list_del_init(&c->list); - - /* Test list_for_each_off. */ - list_add_tail(&opaque_list, - (struct list_node *)create_opaque_blob()); - list_add_tail(&opaque_list, - (struct list_node *)create_opaque_blob()); - list_add_tail(&opaque_list, - (struct list_node *)create_opaque_blob()); - - i = 0; - - list_for_each_off(&opaque_list, q, 0) { - i++; - ok1(if_blobs_know_the_secret(q)); - } - ok1(i == 3); - - /* Test list_for_each_safe_off, list_del_off and list_del_from_off. */ - i = 0; - list_for_each_safe_off(&opaque_list, q, nq, 0) { - switch (i++) { - case 0: - ok1(if_blobs_know_the_secret(q)); - list_del_off(q, 0); - destroy_opaque_blob(q); - break; - case 1: - ok1(if_blobs_know_the_secret(q)); - list_del_from_off(&opaque_list, q, 0); - destroy_opaque_blob(q); - break; - case 2: - ok1(c == &c3); - list_del_from_off(&opaque_list, q, 0); - destroy_opaque_blob(q); - break; - } - ok1(list_check(&opaque_list, NULL)); - if (i > 2) - break; - } - ok1(i == 3); - ok1(list_empty(&opaque_list)); - - /* Test list_top/list_tail/list_pop on empty list. */ - ok1(list_top(&parent.children, struct child, list) == NULL); - ok1(list_tail(&parent.children, struct child, list) == NULL); - ok1(list_pop(&parent.children, struct child, list) == NULL); - - /* Test list_add_before and list_add_after */ - list_add(&parent.children, &c1.list); - list_add_after(&parent.children, &c1.list, &c2.list); - ok1(list_check(&parent.children, "list_add_after")); - - i = 0; - list_for_each(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c1); - break; - case 1: - ok1(c == &c2); - break; - } - } - ok1(i == 2); - - list_add_before(&parent.children, &c2.list, &c3.list); - ok1(list_check(&parent.children, "list_add_before")); - - i = 0; - list_for_each(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c1); - break; - case 1: - ok1(c == &c3); - break; - case 2: - ok1(c == &c2); - break; - } - } - ok1(i == 3); - - /* test list_swap */ - list_swap(&c3.list, &x1.list); - ok1(list_check(&parent.children, "list_swap")); - i = 0; - list_for_each(&parent.children, c, list) { - switch (i++) { - case 0: - ok1(c == &c1); - break; - case 1: - ok1(c == &x1); - break; - case 2: - ok1(c == &c2); - break; - } - } - ok1(i == 3); - - return exit_status(); -} diff --git a/ccan/str/LICENSE b/ccan/str/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/str/_info b/ccan/str/_info @@ -1,52 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * str - string helper routines - * - * This is a grab bag of functions for string operations, designed to enhance - * the standard string.h. - * - * Note that if you define CCAN_STR_DEBUG, you will get extra compile - * checks on common misuses of the following functions (they will now - * be out-of-line, so there is a runtime penalty!). - * - * strstr, strchr, strrchr: - * Return const char * if first argument is const (gcc only). - * - * isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, - * islower, isprint, ispunct, isspace, isupper, isxdigit: - * Static and runtime check that input is EOF or an *unsigned* - * char, as per C standard (really!). - * - * Example: - * #include <stdio.h> - * #include <ccan/str/str.h> - * - * int main(int argc, char *argv[]) - * { - * if (argc > 1 && streq(argv[1], "--verbose")) - * printf("verbose set\n"); - * if (argc > 1 && strstarts(argv[1], "--")) - * printf("Some option set\n"); - * if (argc > 1 && strends(argv[1], "cow-powers")) - * printf("Magic option set\n"); - * return 0; - * } - * - * License: CC0 (Public domain) - * Author: Rusty Russell <rusty@rustcorp.com.au> - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/build_assert\n"); - return 0; - } - - return 1; -} diff --git a/ccan/str/debug.c b/ccan/str/debug.c @@ -1,108 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#include "config.h" -#include <ccan/str/str_debug.h> -#include <assert.h> -#include <ctype.h> -#include <string.h> - -#ifdef CCAN_STR_DEBUG -/* Because we mug the real ones with macros, we need our own wrappers. */ -int str_isalnum(int i) -{ - assert(i >= -1 && i < 256); - return isalnum(i); -} - -int str_isalpha(int i) -{ - assert(i >= -1 && i < 256); - return isalpha(i); -} - -int str_isascii(int i) -{ - assert(i >= -1 && i < 256); - return isascii(i); -} - -#if HAVE_ISBLANK -int str_isblank(int i) -{ - assert(i >= -1 && i < 256); - return isblank(i); -} -#endif - -int str_iscntrl(int i) -{ - assert(i >= -1 && i < 256); - return iscntrl(i); -} - -int str_isdigit(int i) -{ - assert(i >= -1 && i < 256); - return isdigit(i); -} - -int str_isgraph(int i) -{ - assert(i >= -1 && i < 256); - return isgraph(i); -} - -int str_islower(int i) -{ - assert(i >= -1 && i < 256); - return islower(i); -} - -int str_isprint(int i) -{ - assert(i >= -1 && i < 256); - return isprint(i); -} - -int str_ispunct(int i) -{ - assert(i >= -1 && i < 256); - return ispunct(i); -} - -int str_isspace(int i) -{ - assert(i >= -1 && i < 256); - return isspace(i); -} - -int str_isupper(int i) -{ - assert(i >= -1 && i < 256); - return isupper(i); -} - -int str_isxdigit(int i) -{ - assert(i >= -1 && i < 256); - return isxdigit(i); -} - -#undef strstr -#undef strchr -#undef strrchr - -char *str_strstr(const char *haystack, const char *needle) -{ - return strstr(haystack, needle); -} - -char *str_strchr(const char *haystack, int c) -{ - return strchr(haystack, c); -} - -char *str_strrchr(const char *haystack, int c) -{ - return strrchr(haystack, c); -} -#endif diff --git a/ccan/str/str.c b/ccan/str/str.c @@ -1,13 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#include <ccan/str/str.h> - -size_t strcount(const char *haystack, const char *needle) -{ - size_t i = 0, nlen = strlen(needle); - - while ((haystack = strstr(haystack, needle)) != NULL) { - i++; - haystack += nlen; - } - return i; -} diff --git a/ccan/str/str.h b/ccan/str/str.h @@ -1,228 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_STR_H -#define CCAN_STR_H -#include "config.h" -#include <string.h> -#include <stdbool.h> -#include <limits.h> -#include <ctype.h> - -/** - * streq - Are two strings equal? - * @a: first string - * @b: first string - * - * This macro is arguably more readable than "!strcmp(a, b)". - * - * Example: - * if (streq(somestring, "")) - * printf("String is empty!\n"); - */ -#define streq(a,b) (strcmp((a),(b)) == 0) - -/** - * strstarts - Does this string start with this prefix? - * @str: string to test - * @prefix: prefix to look for at start of str - * - * Example: - * if (strstarts(somestring, "foo")) - * printf("String %s begins with 'foo'!\n", somestring); - */ -#define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0) - -/** - * strends - Does this string end with this postfix? - * @str: string to test - * @postfix: postfix to look for at end of str - * - * Example: - * if (strends(somestring, "foo")) - * printf("String %s end with 'foo'!\n", somestring); - */ -static inline bool strends(const char *str, const char *postfix) -{ - if (strlen(str) < strlen(postfix)) - return false; - - return streq(str + strlen(str) - strlen(postfix), postfix); -} - -/** - * stringify - Turn expression into a string literal - * @expr: any C expression - * - * Example: - * #define PRINT_COND_IF_FALSE(cond) \ - * ((cond) || printf("%s is false!", stringify(cond))) - */ -#define stringify(expr) stringify_1(expr) -/* Double-indirection required to stringify expansions */ -#define stringify_1(expr) #expr - -/** - * strcount - Count number of (non-overlapping) occurrences of a substring. - * @haystack: a C string - * @needle: a substring - * - * Example: - * assert(strcount("aaa aaa", "a") == 6); - * assert(strcount("aaa aaa", "ab") == 0); - * assert(strcount("aaa aaa", "aa") == 2); - */ -size_t strcount(const char *haystack, const char *needle); - -/** - * STR_MAX_CHARS - Maximum possible size of numeric string for this type. - * @type_or_expr: a pointer or integer type or expression. - * - * This provides enough space for a nul-terminated string which represents the - * largest possible value for the type or expression. - * - * Note: The implementation adds extra space so hex values or negative - * values will fit (eg. sprintf(... "%p"). ) - * - * Example: - * char str[STR_MAX_CHARS(int)]; - * - * sprintf(str, "%i", 7); - */ -#define STR_MAX_CHARS(type_or_expr) \ - ((sizeof(type_or_expr) * CHAR_BIT + 8) / 9 * 3 + 2 \ - + STR_MAX_CHARS_TCHECK_(type_or_expr)) - -#if HAVE_TYPEOF -/* Only a simple type can have 0 assigned, so test that. */ -#define STR_MAX_CHARS_TCHECK_(type_or_expr) \ - (sizeof(({ typeof(type_or_expr) x = 0; x; }))*0) -#else -#define STR_MAX_CHARS_TCHECK_(type_or_expr) 0 -#endif - -/** - * cisalnum - isalnum() which takes a char (and doesn't accept EOF) - * @c: a character - * - * Surprisingly, the standard ctype.h isalnum() takes an int, which - * must have the value of EOF (-1) or an unsigned char. This variant - * takes a real char, and doesn't accept EOF. - */ -static inline bool cisalnum(char c) -{ - return isalnum((unsigned char)c); -} -static inline bool cisalpha(char c) -{ - return isalpha((unsigned char)c); -} -static inline bool cisascii(char c) -{ - return isascii((unsigned char)c); -} -#if HAVE_ISBLANK -static inline bool cisblank(char c) -{ - return isblank((unsigned char)c); -} -#endif -static inline bool ciscntrl(char c) -{ - return iscntrl((unsigned char)c); -} -static inline bool cisdigit(char c) -{ - return isdigit((unsigned char)c); -} -static inline bool cisgraph(char c) -{ - return isgraph((unsigned char)c); -} -static inline bool cislower(char c) -{ - return islower((unsigned char)c); -} -static inline bool cisprint(char c) -{ - return isprint((unsigned char)c); -} -static inline bool cispunct(char c) -{ - return ispunct((unsigned char)c); -} -static inline bool cisspace(char c) -{ - return isspace((unsigned char)c); -} -static inline bool cisupper(char c) -{ - return isupper((unsigned char)c); -} -static inline bool cisxdigit(char c) -{ - return isxdigit((unsigned char)c); -} - -#include <ccan/str/str_debug.h> - -/* These checks force things out of line, hence they are under DEBUG. */ -#ifdef CCAN_STR_DEBUG -#include <ccan/build_assert/build_assert.h> - -/* These are commonly misused: they take -1 or an *unsigned* char value. */ -#undef isalnum -#undef isalpha -#undef isascii -#undef isblank -#undef iscntrl -#undef isdigit -#undef isgraph -#undef islower -#undef isprint -#undef ispunct -#undef isspace -#undef isupper -#undef isxdigit - -/* You can use a char if char is unsigned. */ -#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF -#define str_check_arg_(i) \ - ((i) + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(i), \ - char) \ - || (char)255 > 0)) -#else -#define str_check_arg_(i) (i) -#endif - -#define isalnum(i) str_isalnum(str_check_arg_(i)) -#define isalpha(i) str_isalpha(str_check_arg_(i)) -#define isascii(i) str_isascii(str_check_arg_(i)) -#if HAVE_ISBLANK -#define isblank(i) str_isblank(str_check_arg_(i)) -#endif -#define iscntrl(i) str_iscntrl(str_check_arg_(i)) -#define isdigit(i) str_isdigit(str_check_arg_(i)) -#define isgraph(i) str_isgraph(str_check_arg_(i)) -#define islower(i) str_islower(str_check_arg_(i)) -#define isprint(i) str_isprint(str_check_arg_(i)) -#define ispunct(i) str_ispunct(str_check_arg_(i)) -#define isspace(i) str_isspace(str_check_arg_(i)) -#define isupper(i) str_isupper(str_check_arg_(i)) -#define isxdigit(i) str_isxdigit(str_check_arg_(i)) - -#if HAVE_TYPEOF -/* With GNU magic, we can make const-respecting standard string functions. */ -#undef strstr -#undef strchr -#undef strrchr - -/* + 0 is needed to decay array into pointer. */ -#define strstr(haystack, needle) \ - ((typeof((haystack) + 0))str_strstr((haystack), (needle))) -#define strchr(haystack, c) \ - ((typeof((haystack) + 0))str_strchr((haystack), (c))) -#define strrchr(haystack, c) \ - ((typeof((haystack) + 0))str_strrchr((haystack), (c))) -#endif -#endif /* CCAN_STR_DEBUG */ - -#endif /* CCAN_STR_H */ diff --git a/ccan/str/str_debug.h b/ccan/str/str_debug.h @@ -1,30 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_STR_DEBUG_H -#define CCAN_STR_DEBUG_H - -/* #define CCAN_STR_DEBUG 1 */ - -#ifdef CCAN_STR_DEBUG -/* Because we mug the real ones with macros, we need our own wrappers. */ -int str_isalnum(int i); -int str_isalpha(int i); -int str_isascii(int i); -#if HAVE_ISBLANK -int str_isblank(int i); -#endif -int str_iscntrl(int i); -int str_isdigit(int i); -int str_isgraph(int i); -int str_islower(int i); -int str_isprint(int i); -int str_ispunct(int i); -int str_isspace(int i); -int str_isupper(int i); -int str_isxdigit(int i); - -char *str_strstr(const char *haystack, const char *needle); -char *str_strchr(const char *s, int c); -char *str_strrchr(const char *s, int c); -#endif /* CCAN_STR_DEBUG */ - -#endif /* CCAN_STR_DEBUG_H */ diff --git a/ccan/str/test/compile_fail-STR_MAX_CHARS.c b/ccan/str/test/compile_fail-STR_MAX_CHARS.c @@ -1,23 +0,0 @@ -#include <ccan/str/str.h> - -struct s { - int val; -}; - -int main(void) -{ - struct s -#ifdef FAIL -#if !HAVE_TYPEOF - #error We need typeof to check STR_MAX_CHARS. -#endif -#else - /* A pointer is OK. */ - * -#endif - val; - char str[STR_MAX_CHARS(val)]; - - str[0] = '\0'; - return str[0] ? 0 : 1; -} diff --git a/ccan/str/test/compile_fail-isalnum.c b/ccan/str/test/compile_fail-isalnum.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isalnum. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isalnum(c); -} diff --git a/ccan/str/test/compile_fail-isalpha.c b/ccan/str/test/compile_fail-isalpha.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isalpha. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isalpha(c); -} diff --git a/ccan/str/test/compile_fail-isascii.c b/ccan/str/test/compile_fail-isascii.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isascii. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isascii(c); -} diff --git a/ccan/str/test/compile_fail-isblank.c b/ccan/str/test/compile_fail-isblank.c @@ -1,27 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF || !HAVE_ISBLANK -#error We need typeof to check isblank. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - -#if HAVE_ISBLANK - return isblank(c); -#else - return c; -#endif -} diff --git a/ccan/str/test/compile_fail-iscntrl.c b/ccan/str/test/compile_fail-iscntrl.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check iscntrl. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return iscntrl(c); -} diff --git a/ccan/str/test/compile_fail-isdigit.c b/ccan/str/test/compile_fail-isdigit.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isdigit. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isdigit(c); -} diff --git a/ccan/str/test/compile_fail-islower.c b/ccan/str/test/compile_fail-islower.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check islower. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return islower(c); -} diff --git a/ccan/str/test/compile_fail-isprint.c b/ccan/str/test/compile_fail-isprint.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isprint. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isprint(c); -} diff --git a/ccan/str/test/compile_fail-ispunct.c b/ccan/str/test/compile_fail-ispunct.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check ispunct. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return ispunct(c); -} diff --git a/ccan/str/test/compile_fail-isspace.c b/ccan/str/test/compile_fail-isspace.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isspace. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isspace(c); -} diff --git a/ccan/str/test/compile_fail-isupper.c b/ccan/str/test/compile_fail-isupper.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isupper. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isupper(c); -} diff --git a/ccan/str/test/compile_fail-isxdigit.c b/ccan/str/test/compile_fail-isxdigit.c @@ -1,23 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(int argc, char *argv[]) -{ - (void)argc; -#ifdef FAIL -#if !HAVE_BUILTIN_TYPES_COMPATIBLE_P || !HAVE_TYPEOF -#error We need typeof to check isxdigit. -#endif - char -#else - unsigned char -#endif - c = argv[0][0]; - -#ifdef FAIL - /* Fake fail on unsigned char platforms. */ - BUILD_ASSERT((char)255 < 0); -#endif - - return isxdigit(c); -} diff --git a/ccan/str/test/compile_fail-strchr.c b/ccan/str/test/compile_fail-strchr.c @@ -1,18 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(void) -{ -#ifdef FAIL -#if !HAVE_TYPEOF - #error We need typeof to check strstr. -#endif -#else - const -#endif - char *ret; - const char *str = "hello"; - - ret = strchr(str, 'l'); - return ret ? 0 : 1; -} diff --git a/ccan/str/test/compile_fail-strrchr.c b/ccan/str/test/compile_fail-strrchr.c @@ -1,18 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(void) -{ -#ifdef FAIL -#if !HAVE_TYPEOF - #error We need typeof to check strstr. -#endif -#else - const -#endif - char *ret; - const char *str = "hello"; - - ret = strrchr(str, 'l'); - return ret ? 0 : 1; -} diff --git a/ccan/str/test/compile_fail-strstr.c b/ccan/str/test/compile_fail-strstr.c @@ -1,18 +0,0 @@ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/str.h> - -int main(void) -{ -#ifdef FAIL -#if !HAVE_TYPEOF - #error We need typeof to check strstr. -#endif -#else - const -#endif - char *ret; - const char *str = "hello"; - - ret = strstr(str, "hell"); - return ret ? 0 : 1; -} diff --git a/ccan/str/test/compile_ok-STR_MAX_CHARS-static.c b/ccan/str/test/compile_ok-STR_MAX_CHARS-static.c @@ -1,8 +0,0 @@ -#include <ccan/str/str.h> - -int main(void) -{ - static char str[STR_MAX_CHARS(int)]; - - return str[0] ? 0 : 1; -} diff --git a/ccan/str/test/debug.c b/ccan/str/test/debug.c @@ -1,5 +0,0 @@ -/* We can't use the normal "#include the .c file" trick, since this is - contaminated by str.h's macro overrides. So we put it in all tests - like this. */ -#define CCAN_STR_DEBUG 1 -#include <ccan/str/debug.c> diff --git a/ccan/str/test/run-STR_MAX_CHARS.c b/ccan/str/test/run-STR_MAX_CHARS.c @@ -1,59 +0,0 @@ -#include <ccan/str/str.h> -#include <stdlib.h> -#include <stdio.h> -#include <ccan/tap/tap.h> -#include <stdint.h> - -int main(void) -{ - char str[1000]; - struct { - uint8_t u1byte; - int8_t s1byte; - uint16_t u2byte; - int16_t s2byte; - uint32_t u4byte; - int32_t s4byte; - uint64_t u8byte; - int64_t s8byte; - void *ptr; - } types; - - plan_tests(13); - - memset(&types, 0xFF, sizeof(types)); - - /* Hex versions */ - sprintf(str, "0x%llx", (unsigned long long)types.u1byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u1byte)); - sprintf(str, "0x%llx", (unsigned long long)types.u2byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u2byte)); - sprintf(str, "0x%llx", (unsigned long long)types.u4byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u4byte)); - sprintf(str, "0x%llx", (unsigned long long)types.u8byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u8byte)); - - /* Decimal versions */ - sprintf(str, "%u", types.u1byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u1byte)); - sprintf(str, "%d", types.s1byte); - ok1(strlen(str) < STR_MAX_CHARS(types.s1byte)); - sprintf(str, "%u", types.u2byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u2byte)); - sprintf(str, "%d", types.s2byte); - ok1(strlen(str) < STR_MAX_CHARS(types.s2byte)); - sprintf(str, "%u", types.u4byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u4byte)); - sprintf(str, "%d", types.s4byte); - ok1(strlen(str) < STR_MAX_CHARS(types.s4byte)); - sprintf(str, "%llu", (unsigned long long)types.u8byte); - ok1(strlen(str) < STR_MAX_CHARS(types.u8byte)); - sprintf(str, "%lld", (long long)types.s8byte); - ok1(strlen(str) < STR_MAX_CHARS(types.s8byte)); - - /* Pointer version. */ - sprintf(str, "%p", types.ptr); - ok1(strlen(str) < STR_MAX_CHARS(types.ptr)); - - return exit_status(); -} diff --git a/ccan/str/test/run.c b/ccan/str/test/run.c @@ -1,106 +0,0 @@ -#include <ccan/str/str.h> -#include <ccan/str/str.c> -#include <stdlib.h> -#include <stdio.h> -#include <ccan/tap/tap.h> - -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) - -static const char *substrings[] = { "far", "bar", "baz", "b", "ba", "z", "ar", - NULL }; - -#define NUM_SUBSTRINGS (ARRAY_SIZE(substrings) - 1) - -static char *strdup_rev(const char *s) -{ - char *ret = strdup(s); - unsigned int i; - - for (i = 0; i < strlen(s); i++) - ret[i] = s[strlen(s) - i - 1]; - return ret; -} - -int main(void) -{ - unsigned int i, j, n; - char *strings[NUM_SUBSTRINGS * NUM_SUBSTRINGS]; - - n = 0; - for (i = 0; i < NUM_SUBSTRINGS; i++) { - for (j = 0; j < NUM_SUBSTRINGS; j++) { - strings[n] = malloc(strlen(substrings[i]) - + strlen(substrings[j]) + 1); - sprintf(strings[n++], "%s%s", - substrings[i], substrings[j]); - } - } - - plan_tests(n * n * 5 + 16); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - unsigned int k, identical = 0; - char *reva, *revb; - - /* Find first difference. */ - for (k = 0; strings[i][k]==strings[j][k]; k++) { - if (k == strlen(strings[i])) { - identical = 1; - break; - } - } - - if (identical) - ok1(streq(strings[i], strings[j])); - else - ok1(!streq(strings[i], strings[j])); - - /* Postfix test should be equivalent to prefix - * test on reversed string. */ - reva = strdup_rev(strings[i]); - revb = strdup_rev(strings[j]); - - if (!strings[i][k]) { - ok1(strstarts(strings[j], strings[i])); - ok1(strends(revb, reva)); - } else { - ok1(!strstarts(strings[j], strings[i])); - ok1(!strends(revb, reva)); - } - if (!strings[j][k]) { - ok1(strstarts(strings[i], strings[j])); - ok1(strends(reva, revb)); - } else { - ok1(!strstarts(strings[i], strings[j])); - ok1(!strends(reva, revb)); - } - free(reva); - free(revb); - } - } - - for (i = 0; i < n; i++) - free(strings[i]); - - ok1(streq(stringify(NUM_SUBSTRINGS), - "((sizeof(substrings) / sizeof(substrings[0])) - 1)")); - ok1(streq(stringify(ARRAY_SIZE(substrings)), - "(sizeof(substrings) / sizeof(substrings[0]))")); - ok1(streq(stringify(i == 0), "i == 0")); - - ok1(strcount("aaaaaa", "b") == 0); - ok1(strcount("aaaaaa", "a") == 6); - ok1(strcount("aaaaaa", "aa") == 3); - ok1(strcount("aaaaaa", "aaa") == 2); - ok1(strcount("aaaaaa", "aaaa") == 1); - ok1(strcount("aaaaaa", "aaaaa") == 1); - ok1(strcount("aaaaaa", "aaaaaa") == 1); - ok1(strcount("aaa aaa", "b") == 0); - ok1(strcount("aaa aaa", "a") == 6); - ok1(strcount("aaa aaa", "aa") == 2); - ok1(strcount("aaa aaa", "aaa") == 2); - ok1(strcount("aaa aaa", "aaaa") == 0); - ok1(strcount("aaa aaa", "aaaaa") == 0); - - return exit_status(); -} diff --git a/ccan/take/LICENSE b/ccan/take/LICENSE @@ -1 +0,0 @@ -../../licenses/CC0- \ No newline at end of file diff --git a/ccan/take/_info b/ccan/take/_info @@ -1,61 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * take - routines to mark pointers to be consumed by called functions. - * - * This code helps to implement ownership transfer on a per-arg basis: - * the caller wraps the pointer argument in take() and the callee checks - * taken() to see if it should consume it. - * - * Author: Rusty Russell <rusty@rustcorp.com.au> - * License: CC0 (Public domain) - * - * Example: - * // Given "foo/bar.c" outputs basename is bar.c - * #include <ccan/take/take.h> - * #include <string.h> - * - * // Dumb basename program and driver. - * static char *base(const char *file TAKES) - * { - * const char *p = strrchr(file, '/'); - * if (!p) - * p = file; - * else - * p++; - * - * // Use arg in place if we're allowed. - * if (taken(file)) - * return memmove((char *)file, p, strlen(p)+1); - * else - * return strdup(p); - * } - * - * int main(int argc, char *argv[]) - * { - * char *b; - * - * if (argc > 1) // Mangle in place. - * b = base(take(argv[1])); - * else - * b = base("test/string"); - * - * printf("basename is %s\n", b); - * return 0; - * } - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/likely\n"); - printf("ccan/str\n"); - return 0; - } - - return 1; -} diff --git a/ccan/take/take.c b/ccan/take/take.c @@ -1,115 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#include <ccan/take/take.h> -#include <ccan/likely/likely.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static const void **takenarr; -static const char **labelarr; -static size_t max_taken, num_taken; -static size_t allocfail; -static void (*allocfailfn)(const void *p); - -void *take_(const void *p, const char *label) -{ - /* Overallocate: it's better than risking calloc returning NULL! */ - if (unlikely(label && !labelarr)) - labelarr = calloc(max_taken+1, sizeof(*labelarr)); - - if (unlikely(num_taken == max_taken)) { - const void **new; - - new = realloc(takenarr, sizeof(*takenarr) * (max_taken+1)); - if (unlikely(!new)) { - if (allocfailfn) { - allocfail++; - allocfailfn(p); - return NULL; - } - /* Otherwise we leak p. */ - return (void *)p; - } - takenarr = new; - /* Once labelarr is set, we maintain it. */ - if (labelarr) - labelarr = realloc(labelarr, - sizeof(*labelarr) * (max_taken+1)); - max_taken++; - } - if (unlikely(labelarr)) - labelarr[num_taken] = label; - takenarr[num_taken++] = p; - - return (void *)p; -} - -static size_t find_taken(const void *p) -{ - size_t i; - - for (i = 0; i < num_taken; i++) { - if (takenarr[i] == p) - return i+1; - } - return 0; -} - -bool taken(const void *p) -{ - size_t i; - - if (!p && unlikely(allocfail)) { - allocfail--; - return true; - } - - i = find_taken(p); - if (!i) - return false; - - memmove(&takenarr[i-1], &takenarr[i], - (--num_taken - (i - 1))*sizeof(takenarr[0])); - return true; -} - -bool is_taken(const void *p) -{ - if (!p && unlikely(allocfail)) - return true; - - return find_taken(p) > 0; -} - -const char *taken_any(void) -{ - static char pointer_buf[32]; - - if (num_taken == 0) - return NULL; - - /* We're *allowed* to have some with labels, some without. */ - if (labelarr) { - size_t i; - for (i = 0; i < num_taken; i++) - if (labelarr[i]) - return labelarr[i]; - } - - sprintf(pointer_buf, "%p", takenarr[0]); - return pointer_buf; -} - -void take_cleanup(void) -{ - max_taken = num_taken = 0; - free(takenarr); - takenarr = NULL; - free(labelarr); - labelarr = NULL; -} - -void take_allocfail(void (*fn)(const void *p)) -{ - allocfailfn = fn; -} diff --git a/ccan/take/take.h b/ccan/take/take.h @@ -1,136 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_TAKE_H -#define CCAN_TAKE_H -#include "config.h" -#include <stdbool.h> -#include <ccan/str/str.h> - -#ifdef CCAN_TAKE_DEBUG -#define TAKE_LABEL(p) __FILE__ ":" stringify(__LINE__) ":" stringify(p) -#else -#define TAKE_LABEL(p) NULL -#endif - -/** - * TAKES - annotate a formal parameter as being take()-able - * - * This doesn't do anything, but useful for documentation. - * - * Example: - * void print_string(const char *str TAKES); - * - */ -#define TAKES - -/** - * take - record a pointer to be consumed by the function its handed to. - * @p: the pointer to mark, or NULL. - * - * This marks a pointer object to be freed by the called function, - * which is extremely useful for chaining functions. It works on - * NULL, for pass-through error handling. - */ -#define take(p) (take_typeof(p) take_((p), TAKE_LABEL(p))) - -/** - * taken - check (and un-take) a pointer was passed with take() - * @p: the pointer to check. - * - * A function which accepts take() arguments uses this to see if it - * should own the pointer; it will be removed from the take list, so - * this only returns true once. - * - * Example: - * // Silly routine to add 1 - * static int *add_one(const int *num TAKES) - * { - * int *ret; - * if (taken(num)) - * ret = (int *)num; - * else - * ret = malloc(sizeof(int)); - * if (ret) - * *ret = (*num) + 1; - * return ret; - * } - */ -bool taken(const void *p); - -/** - * is_taken - check if a pointer was passed with take() - * @p: the pointer to check. - * - * This is like the above, but doesn't remove it from the taken list. - * - * Example: - * // Silly routine to add 1: doesn't handle taken args! - * static int *add_one_notake(const int *num) - * { - * int *ret = malloc(sizeof(int)); - * assert(!is_taken(num)); - * if (ret) - * *ret = (*num) + 1; - * return ret; - * } - */ -bool is_taken(const void *p); - -/** - * taken_any - are there any taken pointers? - * - * Mainly useful for debugging take() leaks. With CCAN_TAKE_DEBUG, returns - * the label where the pointer was passed to take(), otherwise returns - * a static char buffer with the pointer value in it. NULL if none are taken. - * - * Example: - * static void cleanup(void) - * { - * assert(!taken_any()); - * } - */ -const char *taken_any(void); - -/** - * take_cleanup - remove all taken pointers from list. - * - * This is useful in atexit() handlers for valgrind-style leak detection. - * - * Example: - * static void cleanup2(void) - * { - * take_cleanup(); - * } - */ -void take_cleanup(void); - -/** - * take_allocfail - set function to call if we can't reallocated taken array. - * @fn: the function. - * - * If this is not set, then if the array reallocation fails, the - * pointer won't be marked taken(). If @fn returns, it is expected to - * free the pointer; we return NULL from take() and the function handles - * it like any allocation failure. - * - * Example: - * static void free_on_fail(const void *p) - * { - * free((void *)p); - * } - * - * static void init(void) - * { - * take_allocfail(free_on_fail); - * } - */ -void take_allocfail(void (*fn)(const void *p)); - -/* Private functions */ -#if HAVE_TYPEOF -#define take_typeof(ptr) (__typeof__(ptr)) -#else -#define take_typeof(ptr) -#endif - -void *take_(const void *p, const char *label); -#endif /* CCAN_TAKE_H */ diff --git a/ccan/take/test/run-debug.c b/ccan/take/test/run-debug.c @@ -1,34 +0,0 @@ -#include <stdlib.h> -#include <stdbool.h> - -#define CCAN_TAKE_DEBUG 1 -#include <ccan/take/take.h> -#include <ccan/take/take.c> -#include <ccan/tap/tap.h> - -int main(void) -{ - const char *p = "hi"; - - plan_tests(14); - - /* We can take NULL. */ - ok1(take(NULL) == NULL); - ok1(is_taken(NULL)); - ok1(strstr(taken_any(), "run-debug.c:16:")); - ok1(taken(NULL)); /* Undoes take() */ - ok1(!is_taken(NULL)); - ok1(!taken(NULL)); - ok1(!taken_any()); - - /* We can take a real pointer. */ - ok1(take(p) == p); - ok1(is_taken(p)); - ok1(strends(taken_any(), "run-debug.c:25:p")); - ok1(taken(p)); /* Undoes take() */ - ok1(!is_taken(p)); - ok1(!taken(p)); - ok1(!taken_any()); - - return exit_status(); -} diff --git a/ccan/take/test/run.c b/ccan/take/test/run.c @@ -1,102 +0,0 @@ -#include <stdlib.h> -#include <stdbool.h> - -static bool fail_realloc; -static void *my_realloc(void *p, size_t len) -{ - if (fail_realloc) - return NULL; - return realloc(p, len); -} -#define realloc my_realloc - -#include <ccan/take/take.h> -#include <ccan/take/take.c> -#include <ccan/tap/tap.h> - -static int my_allocfail_called; -static void my_allocfail(const void *p UNNEEDED) -{ - my_allocfail_called++; -} - -static void recurse(const char *takeme, int count) -{ - if (count < 1000) - recurse(take(strdup(takeme)), count+1); - if (taken(takeme)) - free((char *)takeme); -} - -int main(void) -{ - const char *p = "hi"; - - plan_tests(43); - - /* We can take NULL. */ - ok1(take(NULL) == NULL); - ok1(is_taken(NULL)); - ok1(taken_any()); - ok1(taken(NULL)); /* Undoes take() */ - ok1(!is_taken(NULL)); - ok1(!taken(NULL)); - - /* We can take NULL twice! */ - ok1(take(NULL) == NULL); - ok1(take(NULL) == NULL); - ok1(is_taken(NULL)); - ok1(taken_any()); - ok1(taken(NULL)); /* Undoes take() */ - ok1(is_taken(NULL)); - ok1(taken_any()); - ok1(taken(NULL)); /* Undoes take() */ - ok1(!is_taken(NULL)); - ok1(!taken(NULL)); - ok1(!taken_any()); - - /* We can take a real pointer. */ - ok1(take(p) == p); - ok1(is_taken(p)); - ok1(taken_any()); - ok1(taken(p)); /* Undoes take() */ - ok1(!is_taken(p)); - ok1(!taken(p)); - ok1(!taken_any()); - - /* Force a failure. */ - ok1(!my_allocfail_called); - ok1(take(p) == p); - ok1(take(p+1) == p+1); - - fail_realloc = true; - /* Without a handler, must pass through and leak. */ - ok1(take(p+2) == p+2); - ok1(!taken(p+2)); - - /* Now, with a handler. */ - take_allocfail(my_allocfail); - ok1(take(p+2) == NULL); - - ok1(my_allocfail_called == 1); - ok1(taken_any()); - ok1(taken(p)); - ok1(taken(p+1)); - ok1(is_taken(NULL)); - ok1(taken(NULL)); - ok1(!taken(NULL)); - ok1(!taken_any()); - - /* Test some deep nesting. */ - fail_realloc = false; - recurse("hello", 0); - ok1(max_taken == 1000); - ok1(!taken_any()); - - take_cleanup(); - ok1(num_taken == 0); - ok1(max_taken == 0); - ok1(takenarr == NULL); - - return exit_status(); -} diff --git a/ccan/tal/LICENSE b/ccan/tal/LICENSE @@ -1 +0,0 @@ -../../licenses/BSD-MIT- \ No newline at end of file diff --git a/ccan/tal/_info b/ccan/tal/_info @@ -1,108 +0,0 @@ -#include "config.h" -#include <stdio.h> -#include <string.h> - -/** - * tal - compact tree allocator routines (inspired by talloc) - * - * Tal is a hierarchical allocator; any pointer allocated by tal can - * become the parent of another allocation. When you free that parent, - * the children (and grandchildren, etc) are automatically freed. - * - * This allows you to build complex objects based on their lifetimes, eg: - * - * struct foo *X = tal(NULL, struct foo); - * X->val = tal(X, int); - * - * and the pointer X->val would be a "child" of the tal context "X"; - * tal_free(X->val) would free X->val as expected, by tal_free(X) would - * free X and X->val. - * - * With an overhead of approximately 4 pointers per object - * (vs. talloc's 12 pointers), it uses dynamic allocation for - * destructors and child lists, so those operations can fail. It does - * not support talloc's references or failing destructors. - * - * See Also: - * ccan/tal/str (useful string helpers) - * - * Example: - * #include <stdio.h> - * #include <err.h> - * #include <ccan/tal/tal.h> - * - * // A structure containing a popened command. - * struct command { - * FILE *f; - * char *command; - * }; - * - * // When struct command is freed, we also want to pclose pipe. - * static void close_cmd(struct command *cmd) - * { - * pclose(cmd->f); - * } - * - * // This function opens a writable pipe to the given command. - * static struct command *open_output_cmd(const tal_t *ctx, - * const char *a0, const char *a1) - * { - * struct command *cmd = tal(ctx, struct command); - * - * if (!cmd) - * return NULL; - * - * // Note that tal/str has helpers to make this much easier! - * cmd->command = tal_arrz(cmd, char, strlen(a0) + strlen(a1) + 2); - * if (!cmd->command) { - * tal_free(cmd); - * return NULL; - * } - * strcat(cmd->command, a0); - * strcat(cmd->command, " "); - * strcat(cmd->command, a1); - * - * cmd->f = popen(cmd->command, "w"); - * if (!cmd->f) { - * tal_free(cmd); - * return NULL; - * } - * tal_add_destructor(cmd, close_cmd); - * return cmd; - * } - * - * int main(int argc, char *argv[]) - * { - * struct command *cmd; - * - * if (argc != 2) - * errx(1, "Usage: %s <command>\n", argv[0]); - * - * cmd = open_output_cmd(NULL, argv[1], "hello"); - * if (!cmd) - * err(1, "Running '%s hello'", argv[1]); - * fprintf(cmd->f, "This is a test\n"); - * tal_free(cmd); - * return 0; - * } - * - * License: BSD-MIT - */ -int main(int argc, char *argv[]) -{ - if (argc != 2) - return 1; - - if (strcmp(argv[1], "depends") == 0) { - printf("ccan/alignof\n"); - printf("ccan/compiler\n"); - printf("ccan/likely\n"); - printf("ccan/list\n"); - printf("ccan/str\n"); - printf("ccan/take\n"); - printf("ccan/typesafe_cb\n"); - return 0; - } - - return 1; -} diff --git a/ccan/tal/benchmark/Makefile b/ccan/tal/benchmark/Makefile @@ -1,26 +0,0 @@ -CFLAGS=-O3 -Wall -flto -I../../.. -#CFLAGS=-O3 -Wall -I../../.. -#CFLAGS=-g -Wall -I../../.. -LDFLAGS=-O3 -flto -LDLIBS=-lrt - -all: speed samba-allocs - -speed: speed.o tal.o talloc.o time.o list.o take.o str.o -samba-allocs: samba-allocs.o tal.o talloc.o time.o list.o take.o - -tal.o: ../tal.c - $(CC) $(CFLAGS) -c -o $@ $< -str.o: ../str/str.c - $(CC) $(CFLAGS) -c -o $@ $< -talloc.o: ../../talloc/talloc.c - $(CC) $(CFLAGS) -c -o $@ $< -time.o: ../../time/time.c - $(CC) $(CFLAGS) -c -o $@ $< -list.o: ../../list/list.c - $(CC) $(CFLAGS) -c -o $@ $< -take.o: ../../take/take.c - $(CC) $(CFLAGS) -c -o $@ $< - -clean: - rm -f speed samba-allocs *.o diff --git a/ccan/tal/benchmark/samba-allocs.c b/ccan/tal/benchmark/samba-allocs.c @@ -1,381 +0,0 @@ -/* Grab dump of Samba4 talloc tree to do benchmarks on it. */ -#include <ccan/talloc/talloc.h> -#include <ccan/tal/tal.h> -#include <ccan/time/time.h> -#include <ccan/err/err.h> -#include <ccan/str/str.h> -#include <string.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> -#include <inttypes.h> - -struct node { - void *n; - struct node *parent; - char *name; - bool destructor; - size_t len; - unsigned int num_children; - struct node *children[0]; -}; - -static int node_count; - -static struct node *new_node(void) -{ - node_count++; - return calloc(sizeof(struct node), 1); -} - -/* struct db_context contains 282 bytes in 5 blocks (ref 0) d=(nil) 0x1f64e70 */ -static struct node *parse(const char *line) -{ - struct node *n = new_node(); - const char *p; - - p = strstr(line, " contains "); - p += strlen(" contains "); - p += strspn(line, " "); - n->len = strtol(p, NULL, 0); - p = strstr(p, "d="); - if (p[2] != '(') - n->destructor = true; - return n; -} - -static void add_child(struct node *parent, struct node *child) -{ - unsigned int i; - struct node *oldp = parent; - - parent = realloc(parent, sizeof(*parent) - + sizeof(parent->children[0]) * (parent->num_children+1)); - parent->children[parent->num_children++] = child; - child->parent = parent; - - if (parent == oldp) - return; - - /* Fix up children's parent pointers. */ - for (i = 0; i < parent->num_children-1; i++) { - assert(parent->children[i]->parent == oldp); - parent->children[i]->parent = parent; - } - - /* Fix up parent's child pointer. */ - if (parent->parent) { - assert(parent->parent->children[parent->parent->num_children-1] - == oldp); - parent->parent->children[parent->parent->num_children-1] - = parent; - } -} - -/* Random string of required length */ -static char *namelen(int len) -{ - char *p = malloc(len); - memset(p, 'x', len-1); - p[len-1] = '\0'; - return p; -} - -static struct node *read_nodes(FILE *f) -{ - char line[4096]; - unsigned int curr_indent = 0, indent; - struct node *n, *curr = new_node(); - - /* Ignore first line */ - fgets(line, 4096, f); - - while (fgets(line, 4096, f)) { - bool is_name; - - indent = strspn(line, " "); - - /* Ignore references for now. */ - if (strstarts(line + indent, "reference to: ")) - continue; - - /* Blank name? Use offset of 'contains' to guess indent! */ - if (strstarts(line + indent, "contains ")) - indent -= 31; - - is_name = strstarts(line + indent, ".name "); - - n = parse(line + indent); - if (is_name) { - curr->name = namelen(n->len); - free(n); - } else { - if (indent > curr_indent) { - assert(indent == curr_indent + 4); - curr_indent += 4; - } else { - /* Go back up to parent. */ - for (curr_indent += 4; - curr_indent != indent; - curr_indent -= 4) - curr = curr->parent; - } - add_child(curr, n); - curr = n; - } - } - while (curr->parent) { - curr = curr->parent; - curr_indent -= 4; - } - assert(curr_indent == 0); - return curr; -} - -static int unused_talloc_destructor(void *p) -{ - return 0; -} - -static void do_tallocs(struct node *node) -{ - unsigned int i; - static int count; - - if (count++ % 16 == 0) - node->n = talloc_array(node->parent ? node->parent->n : NULL, - char, node->len); - else - node->n = talloc_size(node->parent ? node->parent->n : NULL, - node->len); - if (node->destructor) - talloc_set_destructor(node->n, unused_talloc_destructor); - if (node->name) - talloc_set_name(node->n, "%s", node->name); - - for (i = 0; i < node->num_children; i++) - do_tallocs(node->children[i]); -} - -static void free_tallocs(struct node *node) -{ - unsigned int i; - - for (i = 0; i < node->num_children; i++) - free_tallocs(node->children[i]); - - talloc_free(node->n); -} - -static void unused_tal_destructor(void *p) -{ -} - -static void do_tals(struct node *node) -{ - unsigned int i; - static int count; - - /* Tal pays a penalty for arrays, but we can't tell which is an array - * and which isn't. Grepping samba source gives 1221 talloc_array of - * 33137 talloc occurrences, so conservatively assume 1 in 16 */ - if (count++ % 16 == 0) - node->n = tal_arr(node->parent ? node->parent->n : NULL, - char, node->len); - else - node->n = tal_alloc_(node->parent ? node->parent->n : NULL, - node->len, false, false, TAL_LABEL(type, "")); - - if (node->destructor) - tal_add_destructor(node->n, unused_tal_destructor); - if (node->name) - tal_set_name(node->n, node->name); - - for (i = 0; i < node->num_children; i++) - do_tals(node->children[i]); -} - -static void free_tals(struct node *node) -{ - unsigned int i; - - for (i = 0; i < node->num_children; i++) - free_tals(node->children[i]); - - tal_free(node->n); -} - -static void do_mallocs(struct node *node) -{ - unsigned int i; - - node->n = malloc(node->len + (node->name ? strlen(node->name) + 1 : 1)); - - for (i = 0; i < node->num_children; i++) - do_mallocs(node->children[i]); -} - -static void free_mallocs(struct node *node) -{ - unsigned int i; - - for (i = 0; i < node->num_children; i++) - free_mallocs(node->children[i]); - - free(node->n); -} - -/* See proc(5): field 23 is vsize, 24 is rss (in pages) */ -static void dump_vsize(void) -{ - int fd, i; - char buf[1000], *p = buf; - - sprintf(buf, "/proc/%u/stat", getpid()); - fd = open(buf, O_RDONLY); - read(fd, buf, sizeof(buf)); - close(fd); - - for (i = 0; i < 22; i++) { - p += strcspn(p, " "); - p += strspn(p, " "); - } - i = atoi(p); - printf("Virtual size = %i, ", i); - p += strcspn(p, " "); - p += strspn(p, " "); - i = atoi(p); - printf("RSS = %i\n", i * getpagesize()); -} - -#define LOOPS 1000 - -int main(int argc, char *argv[]) -{ - struct timeabs start; - struct timerel alloc_time, free_time; - struct node *root; - unsigned int i; - FILE *f; - bool run_talloc = true, run_tal = true, run_malloc = true; - - f = argv[1] ? fopen(argv[1], "r") : stdin; - root = read_nodes(f); - fclose(f); - printf("Read %u nodes\n", node_count); - - if (argc > 2) { - if (streq(argv[2], "--talloc-size")) { - do_tallocs(root); - dump_vsize(); - exit(0); - } - if (streq(argv[2], "--tal-size")) { - do_tals(root); - dump_vsize(); - exit(0); - } - if (strcmp(argv[2], "--talloc") == 0) - run_tal = run_malloc = false; - else if (strcmp(argv[2], "--tal") == 0) - run_talloc = run_malloc = false; - else if (strcmp(argv[2], "--malloc") == 0) - run_talloc = run_tal = false; - else - errx(1, "Bad flag %s", argv[2]); - } - - if (!run_malloc) - goto after_malloc; - - alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0; - free_time.ts.tv_sec = free_time.ts.tv_nsec = 0; - for (i = 0; i < LOOPS; i++) { - start = time_now(); - do_mallocs(root); - alloc_time = timerel_add(alloc_time, - time_between(time_now(), start)); - - start = time_now(); - free_mallocs(root); - free_time = timerel_add(free_time, - time_between(time_now(), start)); - } - alloc_time = time_divide(alloc_time, i); - free_time = time_divide(free_time, i); - printf("Malloc time: %"PRIu64"ns\n", time_to_nsec(alloc_time)); - printf("Free time: %"PRIu64"ns\n", time_to_nsec(free_time)); - -after_malloc: - if (!run_talloc) - goto after_talloc; - - alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0; - free_time.ts.tv_sec = free_time.ts.tv_nsec = 0; - for (i = 0; i < LOOPS; i++) { - start = time_now(); - do_tallocs(root); - alloc_time = timerel_add(alloc_time, - time_between(time_now(), start)); - - start = time_now(); - free_tallocs(root); - free_time = timerel_add(free_time, - time_between(time_now(), start)); - } - alloc_time = time_divide(alloc_time, i); - free_time = time_divide(free_time, i); - printf("Talloc time: %"PRIu64"ns\n", time_to_nsec(alloc_time)); - printf("talloc_free time: %"PRIu64"ns\n", time_to_nsec(free_time)); - - free_time.ts.tv_sec = free_time.ts.tv_nsec = 0; - for (i = 0; i < LOOPS; i++) { - do_tallocs(root); - - start = time_now(); - talloc_free(root->n); - free_time = timerel_add(free_time, - time_between(time_now(), start)); - } - free_time = time_divide(free_time, i); - printf("Single talloc_free time: %"PRIu64"\n", time_to_nsec(free_time)); - -after_talloc: - if (!run_tal) - goto after_tal; - - alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0; - free_time.ts.tv_sec = free_time.ts.tv_nsec = 0; - for (i = 0; i < LOOPS; i++) { - start = time_now(); - do_tals(root); - alloc_time = timerel_add(alloc_time, - time_between(time_now(), start)); - - start = time_now(); - free_tals(root); - free_time = timerel_add(free_time, - time_between(time_now(), start)); - } - alloc_time = time_divide(alloc_time, i); - free_time = time_divide(free_time, i); - printf("Tal time: %"PRIu64"ns\n", time_to_nsec(alloc_time)); - printf("Tal_free time: %"PRIu64"ns\n", time_to_nsec(free_time)); - - free_time.ts.tv_sec = free_time.ts.tv_nsec = 0; - for (i = 0; i < LOOPS; i++) { - do_tals(root); - - start = time_now(); - tal_free(root->n); - free_time = timerel_add(free_time, - time_between(time_now(), start)); - } - free_time = time_divide(free_time, i); - printf("Single tal_free time: %"PRIu64"ns\n", time_to_nsec(free_time)); -after_tal: - - return 0; -} diff --git a/ccan/tal/benchmark/speed.c b/ccan/tal/benchmark/speed.c @@ -1,125 +0,0 @@ -/* - Taken from samba/lib/talloc/testsuite.c: Unix SMB/CIFS implementation. - - local testing of talloc routines. - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include <ccan/talloc/talloc.h> -#include <ccan/tal/tal.h> -#include <ccan/tal/str/str.h> -#include <ccan/time/time.h> -#include <ccan/err/err.h> -#include <string.h> - -#define LOOPS 1024 - -int main(int argc, char *argv[]) -{ - void *ctx; - unsigned count; - int i, j; - struct timeabs tv; - void *p1, *p2[100], *p3[100]; - bool run_talloc = true, run_tal = true, run_malloc = true; - - if (argv[1]) { - if (strcmp(argv[1], "--talloc") == 0) - run_tal = run_malloc = false; - else if (strcmp(argv[1], "--tal") == 0) - run_talloc = run_malloc = false; - else if (strcmp(argv[1], "--malloc") == 0) - run_talloc = run_tal = false; - else - errx(1, "Bad flag %s", argv[1]); - } - - if (!run_talloc) - goto after_talloc; - - ctx = talloc_new(NULL); - tv = time_now(); - count = 0; - do { - for (i=0;i<LOOPS;i++) { - p1 = talloc_size(ctx, LOOPS % 128); - for (j = 0; j < 100; j++) { - p2[j] = talloc_strdup(p1, "foo bar"); - p3[j] = talloc_size(p1, 300); - } - talloc_free(p1); - } - count += (1 + 200) * LOOPS; - } while (time_between(time_now(), tv).ts.tv_sec < 5); - - fprintf(stderr, "talloc: %.0f ops/sec\n", count/5.0); - - talloc_free(ctx); - -after_talloc: - if (!run_tal) - goto after_tal; - - ctx = tal(NULL, char); - tv = time_now(); - count = 0; - do { - for (i=0;i<LOOPS;i++) { - p1 = tal_arr(ctx, char, LOOPS % 128); - for (j = 0; j < 100; j++) { - p2[j] = tal_strdup(p1, "foo bar"); - p3[j] = tal_arr(p1, char, 300); - } - tal_free(p1); - } - count += (1 + 200) * LOOPS; - } while (time_between(time_now(), tv).ts.tv_sec < 5); - fprintf(stderr, "tal: %.0f ops/sec\n", count/5.0); - - tal_free(ctx); - -after_tal: - if (!run_malloc) - goto after_malloc; - - tv = time_now(); - count = 0; - do { - for (i=0;i<LOOPS;i++) { - p1 = malloc(LOOPS % 128); - for (j = 0; j < 100; j++) { - p2[j] = strdup("foo bar"); - p3[j] = malloc(300); - } - for (j = 0; j < 100; j++) { - free(p2[j]); - free(p3[j]); - } - free(p1); - } - count += (1 + 200) * LOOPS; - } while (time_between(time_now(), tv).ts.tv_sec < 5); - fprintf(stderr, "malloc: %.0f ops/sec\n", count/5.0); - -after_malloc: - printf("success: speed\n"); - - return 0; -} diff --git a/ccan/tal/benchmark/talloc.dump b/ccan/tal/benchmark/talloc.dump @@ -1,26137 +0,0 @@ -full talloc report on 'null_context' (total 1129164 bytes in 26137 blocks) - struct db_context contains 282 bytes in 5 blocks (ref 0) d=(nil) 0x1f64e70 - struct db_tdb_ctx contains 114 bytes in 4 blocks (ref 0) d=(nil) 0x1f64f90 - struct tdb_wrap contains 90 bytes in 3 blocks (ref 0) d=(nil) 0x1c028b0 - struct tdb_wrap_private contains 82 bytes in 2 blocks (ref 1) d=0x2af279e7ff20 0x1ec7690 - /home/rusty/samba/st/fl2000dc/private/secrets.tdb contains 50 bytes in 1 blocks (ref 0) d=(nil) 0x26c14a0 - TALLOC_CTX * contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x1c02b70 - gid_t contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x2c851a0 - struct ldb_hooks contains 24 bytes in 1 blocks (ref 0) d=(nil) 0x182c660 - struct backends_list_entry contains 160 bytes in 8 blocks (ref 0) d=(nil) 0x1829d80 - struct backends_list_entry contains 40 bytes in 2 blocks (ref 0) d=(nil) 0x1840180 - struct ldb_backend_ops contains 16 bytes in 1 blocks (ref 0) d=(nil) 0x1840210 - struct backends_list_entry contains 40 bytes in 2 blocks (ref 0) d=(nil) 0x1829fa0 - struct ldb_backend_ops contains 16 bytes in 1 blocks (ref 0) d=(nil) 0x182a030 - struct backends_list_entry contains 40 bytes in 2 blocks (ref 0) d=(nil) 0x1829e90 - struct ldb_backend_ops contains 16 bytes in 1 blocks (ref 0) d=(nil) 0x1829f20 - struct ldb_backend_ops contains 16 bytes in 1 blocks (ref 0) d=(nil) 0x1829e10 - struct loaded contains 1568 bytes in 49 blocks (ref 0) d=(nil) 0x17fc810 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1840dd0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1840290 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183f9e0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183f0e0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183e730 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183dfa0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183d5a0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183cc00 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183c240 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183ba80 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x183a800 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1839df0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1839490 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1838d30 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x18382f0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1837b30 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1837140 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1836770 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1835ea0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x18353d0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182a9e0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1833f70 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x18337f0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1833050 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1832450 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x18319f0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1831250 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1830ab0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1830060 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182f680 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182ed30 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182e320 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182da10 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182d100 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182c6f0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182b440 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182aaf0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x182a0b0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1829270 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1828920 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1827de0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x18273d0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1826a90 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1801e20 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fd0d0 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17ff010 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fe340 - struct loaded contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fe160 - struct tevent_ops_list contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fbb20 - struct tevent_ops_list contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fba90 - struct tevent_ops_list contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fba00 - struct tevent_ops_list contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x17fb970 - struct tevent_ops_list contains 32 bytes in 1 blocks (ref 0) d=(nil) 0x1825f20 - struct process_model contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f2d00 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f9cb0 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f6730 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f4560 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f2370 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17f00f0 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17ed9a0 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17eb310 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17e8c80 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17e6ae0 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17e4460 - struct bitmap contains 64 bytes in 1 blocks (ref 0) d=(nil) 0x17e1de0 - /home/rusty/samba/st/fl2000dc/logs/log.%m contains 42 bytes in 1 blocks (ref 0) d=(nil) 0x17df6d0 - struct loadparm_context contains 21579 bytes in 1046 blocks (ref 49) d=0x2af276201d0a 0x17d5a90 - simple contains 7 bytes in 1 blocks (ref 0) d=(nil) 0x17f5a20 - struct loadparm_service * contains 14119 bytes in 771 blocks (ref 0) d=(nil) 0x17f8550 - struct loadparm_service contains 1152 bytes in 66 blocks (ref 0) d=(nil) 0x17f8620 - IPC contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17f93c0 - char * contains 24 bytes in 2 blocks (ref 0) d=(nil) 0x17fa6a0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17fa720 - /dev/null contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17fa620 - IPC Service contains 12 bytes in 1 blocks (ref 0) d=(nil) 0x17fa5a0 - IPC$ contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17fa530 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17fa3a0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17fa4b0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17fa430 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9b40 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17fa080 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17fa320 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17fa2a0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17fa220 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17fa1a0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17fa120 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f9d60 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17fa000 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9f80 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9f00 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9e80 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f9e00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9510 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f94a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9430 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9350 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f92e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9270 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9200 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9190 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9120 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f90b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f9040 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8fd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8f60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8ef0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8e80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8e10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8da0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8d30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8cc0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8c50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8be0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8b70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8b00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8a90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8a20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f89b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f8940 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f88d0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17dd920 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f9c30 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f9bb0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f9820 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f9ac0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9a40 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f99c0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9940 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f98c0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f9580 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f97a0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9720 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f96a0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f9620 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ddb20 - struct loadparm_service contains 1403 bytes in 79 blocks (ref 0) d=(nil) 0x17f4f20 - char * contains 26 bytes in 2 blocks (ref 0) d=(nil) 0x17f7780 - cifsposix contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f7800 - char * contains 23 bytes in 2 blocks (ref 0) d=(nil) 0x17f7700 - simple contains 7 bytes in 1 blocks (ref 0) d=(nil) 0x17f51d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f6530 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f73e0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f7680 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f7600 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f7580 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f7500 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f7480 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f70c0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f7360 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f72e0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f7260 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f71e0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f7160 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5e80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5e10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5da0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17f5d30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5cc0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5c50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5be0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5b70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5b00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5a90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f59b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5940 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f58d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5860 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f57f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5780 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5710 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f56a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5630 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f55c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5550 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f54e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5470 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5400 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5390 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5320 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f52b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f5240 - /home/rusty/samba/st/fl2000dc/share contains 36 bytes in 1 blocks (ref 0) d=(nil) 0x17f7030 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ee8c0 - cifsposix contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6fb0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f6e20 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f6f30 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f6eb0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f6b00 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f6da0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6d20 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6ca0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6c20 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f6ba0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f67e0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f6a80 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6a00 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6980 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6900 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f6880 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f65a0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f66b0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f6630 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f6210 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f64b0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6430 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f63b0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6330 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f62b0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f5ef0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f6190 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6110 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6090 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f6010 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f5f90 - struct loadparm_service contains 1188 bytes in 64 blocks (ref 0) d=(nil) 0x17f2dc0 - /home/rusty/samba/st/fl2000dc/statedir/sysvol/samba2000.example.com/scripts contains 76 bytes in 1 blocks (ref 0) d=(nil) 0x17f4e60 - netlogon contains 9 bytes in 1 blocks (ref 0) d=(nil) 0x17f4de0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f4c50 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f4d60 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f4ce0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f4360 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f4930 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f4bd0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4b50 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4ad0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4a50 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f49d0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f4610 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f48b0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4830 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f47b0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4730 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f46b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3cb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3c40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3bd0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17f3b60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3af0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3a80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3a10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f39a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3930 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f38c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3850 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f37e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3770 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3700 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3690 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3620 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f35b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3540 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f34d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3460 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f33f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3380 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3310 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f32a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3230 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f31c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3150 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f30e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f3070 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0e10 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f43d0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f44e0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f4460 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f4040 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f42e0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4260 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f41e0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f4160 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f40e0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f3d20 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f3fc0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f3f40 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f3ec0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f3e40 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f3dc0 - struct loadparm_service contains 1156 bytes in 64 blocks (ref 0) d=(nil) 0x17f0af0 - /home/rusty/samba/st/fl2000dc/statedir/sysvol contains 46 bytes in 1 blocks (ref 0) d=(nil) 0x17f2c60 - sysvol contains 7 bytes in 1 blocks (ref 0) d=(nil) 0x17f2bf0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f2a60 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f2b70 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f2af0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f2170 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f2740 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f29e0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f2960 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f28e0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f2860 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f27e0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f2420 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f26c0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f2640 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f25c0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f2540 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f24c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1ac0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1a50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f19e0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17f1970 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1900 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1890 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1820 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f17b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1740 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f16d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1660 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f15f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1580 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1510 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f14a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1430 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f13c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1350 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f12e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1270 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1200 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1190 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1120 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f10b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f1040 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0fd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0f60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0ef0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0e80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17f0da0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f21e0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f22f0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f2270 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f1e50 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f20f0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f2070 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f1ff0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f1f70 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f1ef0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f1b30 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f1dd0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f1d50 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f1cd0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f1c50 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f1bd0 - struct loadparm_service contains 1169 bytes in 66 blocks (ref 0) d=(nil) 0x17ee970 - char * contains 23 bytes in 2 blocks (ref 0) d=(nil) 0x17f0a70 - simple contains 7 bytes in 1 blocks (ref 0) d=(nil) 0x17eec20 - /home/rusty/samba/st/fl2000dc/share contains 36 bytes in 1 blocks (ref 0) d=(nil) 0x17f09e0 - simple contains 7 bytes in 1 blocks (ref 0) d=(nil) 0x17f0970 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17f07e0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f08f0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f0870 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eff80 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f04c0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f0760 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f06e0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f0660 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f05e0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f0560 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17f01a0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17f0440 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f03c0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f0340 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17f02c0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17f0240 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef8d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef860 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef7f0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17ef780 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef710 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef6a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef630 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef5c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef550 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef4e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef470 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef400 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef390 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef320 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef2b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef240 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef1d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef160 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef0f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef080 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ef010 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eefa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eef30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eeec0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eee50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eede0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eed70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eed00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eec90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5130 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17ee720 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17f0070 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17efff0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17efc60 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17eff00 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efe80 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efe00 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efd80 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17efd00 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17ef940 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17efbe0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efb60 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efae0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17efa60 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ef9e0 - struct loadparm_service contains 1328 bytes in 75 blocks (ref 0) d=(nil) 0x17ec190 - struct parmlist_entry contains 71 bytes in 3 blocks (ref 0) d=(nil) 0x17ee7b0 - yes contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17ee850 - cifs:use-s4u2proxy contains 19 bytes in 1 blocks (ref 0) d=(nil) 0x17ee380 - struct parmlist_entry contains 63 bytes in 3 blocks (ref 0) d=(nil) 0x17ee590 - tmp contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17ee6b0 - cifs:share contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ee630 - struct parmlist_entry contains 64 bytes in 3 blocks (ref 0) d=(nil) 0x17ee400 - DC5 contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17ee520 - cifs:server contains 12 bytes in 1 blocks (ref 0) d=(nil) 0x17ee4a0 - char * contains 21 bytes in 2 blocks (ref 0) d=(nil) 0x17ee290 - cifs contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17ee310 - cifs contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17ee220 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17ee090 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17ee1a0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17ee120 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ed7a0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17edd70 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17ee010 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17edf90 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17edf10 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ede90 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ede10 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17eda50 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17edcf0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17edc70 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17edbf0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17edb70 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17edaf0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ed0f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ed080 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ed010 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17ecfa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecf30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecec0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ece50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecde0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecd70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecd00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecc90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecc20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecbb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecb40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ecad0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eca60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec9f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec980 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec910 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec8a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec830 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec7c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec750 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec6e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec670 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec600 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec590 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec520 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec4b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ec440 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ebfe0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17ed810 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17ed920 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17ed8a0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17ed480 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17ed720 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed6a0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed620 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed5a0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ed520 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17ed160 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17ed400 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed380 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed300 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17ed280 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17ed200 - struct loadparm_service contains 1373 bytes in 73 blocks (ref 0) d=(nil) 0x17e9b00 - struct parmlist_entry contains 81 bytes in 3 blocks (ref 0) d=(nil) 0x17ec080 - 50000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17ec120 - posix:writetimeupdatedelay contains 27 bytes in 1 blocks (ref 0) d=(nil) 0x17ebca0 - struct parmlist_entry contains 70 bytes in 3 blocks (ref 0) d=(nil) 0x17ebe50 - 3 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17ebf70 - posix:oplocktimeout contains 20 bytes in 1 blocks (ref 0) d=(nil) 0x17ebef0 - struct parmlist_entry contains 71 bytes in 3 blocks (ref 0) d=(nil) 0x17ebd30 - 10000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e9db0 - posix:sharedelay contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17ebdd0 - /home/rusty/samba/st/fl2000dc/share/test2 contains 42 bytes in 1 blocks (ref 0) d=(nil) 0x17ebc00 - test2 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17ebb90 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17eba00 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17ebb10 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17eba90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eb110 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17eb6e0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17eb980 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb900 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb880 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb800 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17eb780 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17eb3c0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17eb660 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb5e0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb560 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb4e0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17eb460 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17eaa60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea9f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea980 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17ea910 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea8a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea830 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea7c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea750 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea6e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea670 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea600 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea590 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea520 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea4b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea440 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea3d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea360 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea2f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea280 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea210 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea1a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea130 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea0c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17ea050 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9fe0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9f70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9f00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9e90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9e20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e9950 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17eb180 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17eb290 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17eb210 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17eadf0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17eb090 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eb010 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eaf90 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eaf10 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17eae90 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17eaad0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17ead70 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eacf0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eac70 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17eabf0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17eab70 - struct loadparm_service contains 1373 bytes in 73 blocks (ref 0) d=(nil) 0x17e7470 - struct parmlist_entry contains 81 bytes in 3 blocks (ref 0) d=(nil) 0x17e99f0 - 50000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e9a90 - posix:writetimeupdatedelay contains 27 bytes in 1 blocks (ref 0) d=(nil) 0x17e9610 - struct parmlist_entry contains 70 bytes in 3 blocks (ref 0) d=(nil) 0x17e97c0 - 3 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17e98e0 - posix:oplocktimeout contains 20 bytes in 1 blocks (ref 0) d=(nil) 0x17e9860 - struct parmlist_entry contains 71 bytes in 3 blocks (ref 0) d=(nil) 0x17e96a0 - 10000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e7720 - posix:sharedelay contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17e9740 - /home/rusty/samba/st/fl2000dc/share/test1 contains 42 bytes in 1 blocks (ref 0) d=(nil) 0x17e9570 - test1 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e9500 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e9370 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e9480 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e9400 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e8a80 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e9050 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e92f0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e9270 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e91f0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e9170 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e90f0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e8d30 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e8fd0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8f50 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8ed0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8e50 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e8dd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e83d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e8360 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e82f0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17e8280 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e8210 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e81a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e8130 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e80c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e8050 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7fe0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7f70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7f00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7e90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7e20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7db0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7d40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7cd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7c60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7bf0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7b80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7b10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7aa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7a30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e79c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7950 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e78e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7870 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7800 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e7790 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5600 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e8af0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e8c00 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e8b80 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e8760 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e8a00 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8980 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8900 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8880 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e8800 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e8440 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e86e0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8660 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e85e0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e8560 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e84e0 - struct loadparm_service contains 1151 bytes in 64 blocks (ref 0) d=(nil) 0x17e52e0 - /home/rusty/samba/st/fl2000dc/share contains 36 bytes in 1 blocks (ref 0) d=(nil) 0x17e73e0 - posix_share contains 12 bytes in 1 blocks (ref 0) d=(nil) 0x17e7360 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e71d0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e72e0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e7260 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e68e0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e6eb0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e7150 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e70d0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e7050 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6fd0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e6f50 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e6b90 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e6e30 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6db0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6d30 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6cb0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e6c30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e62b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e6240 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e61d0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17e6160 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e60f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e6080 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e6010 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5fa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5f30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5ec0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5e50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5de0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5d70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5d00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5c90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5c20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5bb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5b40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5ad0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5a60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e59f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5980 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5910 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e58a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5830 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e57c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5750 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e56e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5670 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e5590 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e6950 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e6a60 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e69e0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e65c0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e6860 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e67e0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6760 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e66e0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e6660 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e6320 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e6540 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e64c0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e6440 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e63c0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e0570 - struct loadparm_service contains 1373 bytes in 73 blocks (ref 0) d=(nil) 0x17e2c50 - struct parmlist_entry contains 81 bytes in 3 blocks (ref 0) d=(nil) 0x17e51d0 - 50000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e5270 - posix:writetimeupdatedelay contains 27 bytes in 1 blocks (ref 0) d=(nil) 0x17e4df0 - struct parmlist_entry contains 70 bytes in 3 blocks (ref 0) d=(nil) 0x17e4fa0 - 3 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17e50c0 - posix:oplocktimeout contains 20 bytes in 1 blocks (ref 0) d=(nil) 0x17e5040 - struct parmlist_entry contains 71 bytes in 3 blocks (ref 0) d=(nil) 0x17e4e80 - 10000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e2f00 - posix:sharedelay contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17e4f20 - /home/rusty/samba/st/fl2000dc/share contains 36 bytes in 1 blocks (ref 0) d=(nil) 0x17e4d60 - xcopy_share contains 12 bytes in 1 blocks (ref 0) d=(nil) 0x17e4ce0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e4b50 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e4c60 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e4be0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e4260 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e4830 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e4ad0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4a50 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e49d0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4950 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e48d0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e4510 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e47b0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4730 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e46b0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4630 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e45b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3bb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3b40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3ad0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17e3a60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e39f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3980 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3910 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e38a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3830 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e37c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3750 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e36e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3670 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3600 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3590 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3520 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e34b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3440 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e33d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3360 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e32f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3280 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3210 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e31a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3130 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e30c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e3050 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e2fe0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e2f70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e2aa0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e42d0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e43e0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e4360 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e3f40 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e41e0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4160 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e40e0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e4060 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e3fe0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e3c20 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e3ec0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e3e40 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e3dc0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e3d40 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e3cc0 - struct loadparm_service contains 1365 bytes in 73 blocks (ref 0) d=(nil) 0x17e05f0 - struct parmlist_entry contains 81 bytes in 3 blocks (ref 0) d=(nil) 0x17e2b40 - 50000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e2be0 - posix:writetimeupdatedelay contains 27 bytes in 1 blocks (ref 0) d=(nil) 0x17e2760 - struct parmlist_entry contains 70 bytes in 3 blocks (ref 0) d=(nil) 0x17e2910 - 3 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17e2a30 - posix:oplocktimeout contains 20 bytes in 1 blocks (ref 0) d=(nil) 0x17e29b0 - struct parmlist_entry contains 71 bytes in 3 blocks (ref 0) d=(nil) 0x17e27f0 - 10000 contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17e0910 - posix:sharedelay contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17e2890 - /home/rusty/samba/st/fl2000dc/share contains 36 bytes in 1 blocks (ref 0) d=(nil) 0x17e26d0 - tmp contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17e2660 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17e24d0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e25e0 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e2560 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1c70 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e21b0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e2450 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e23d0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e2350 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e22d0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e2250 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e1e90 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e2130 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e20b0 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e2030 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1fb0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e1f30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e15c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1550 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e14e0 - NTFS contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17e1470 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1400 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1390 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1320 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e12b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1240 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e11d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1160 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e10f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1080 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e1010 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0fa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0f30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0ec0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0e50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0de0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0d70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0d00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0c90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0c20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0bb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0b40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0ad0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0a60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e09f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e0980 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17e08a0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17dfef0 - default contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e1d60 - unixuid contains 8 bytes in 1 blocks (ref 0) d=(nil) 0x17e1ce0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e1950 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e1bf0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1b70 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1af0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1a70 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e19f0 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e1630 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e18d0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1850 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e17d0 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e1750 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e16d0 - 1 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17d77f0 - /home/rusty/samba/st/fl2000dc/logs/log.%m contains 42 bytes in 1 blocks (ref 0) d=(nil) 0x17df770 - samba2000.example.com contains 22 bytes in 1 blocks (ref 0) d=(nil) 0x17deaf0 - SAMBA2000.EXAMPLE.COM contains 22 bytes in 1 blocks (ref 0) d=(nil) 0x17dea50 - SAMBA2000.EXAMPLE.COM contains 22 bytes in 1 blocks (ref 0) d=(nil) 0x17d91c0 - struct file_lists contains 118 bytes in 3 blocks (ref 0) d=(nil) 0x17dd430 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dd560 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dd4c0 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dd390 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dd2f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da8f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da3b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da340 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da2d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da260 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da1f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da180 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da110 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17da030 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9fc0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9f50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9e70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9e00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9d90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9d20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9cb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9c40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9bd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9b60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9af0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9a80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9a10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d99a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9930 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9850 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d97e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9770 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9700 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9690 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9620 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d95b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9540 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d94d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9460 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d93f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9150 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d90e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9070 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d9000 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8f90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8f20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8eb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8e40 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8dd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8d60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8cf0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8c80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8c10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8ba0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8b30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8ac0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8a50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d89e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8970 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8900 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8890 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8820 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d87b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8740 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d86d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8660 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d85f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8580 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8510 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d84a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8430 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d83c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8350 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d82e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8270 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8200 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8190 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8120 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d80b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d8040 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7fd0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7f60 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7ef0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7e80 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7e10 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7da0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7d30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7cc0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7c50 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7be0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7b70 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7b00 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7a90 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7a20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d79b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d78d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7780 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7710 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d76a0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7630 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d75c0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7550 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d74e0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7470 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7400 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7390 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d72b0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7240 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d71d0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7160 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d70f0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d7080 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6fa0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6f30 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6de0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6c20 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6bb0 - contains 1 bytes in 1 blocks (ref 0) d=(nil) 0x17d6b40 - struct loadparm_service contains 576 bytes in 1 blocks (ref 0) d=(nil) 0x17d6890 - struct loadparm_global contains 4498 bytes in 149 blocks (ref 0) d=(nil) 0x17d62a0 - char * contains 26 bytes in 2 blocks (ref 0) d=(nil) 0x17dd600 - 127.0.0.1 contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17dd680 - char * contains 103 bytes in 6 blocks (ref 0) d=(nil) 0x17e03d0 - streams_depot contains 14 bytes in 1 blocks (ref 0) d=(nil) 0x17e04f0 - xattr_tdb contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e0470 - fake_acls contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e0350 - acl_xattr contains 10 bytes in 1 blocks (ref 0) d=(nil) 0x17e02d0 - dfs_samba4 contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17e0250 - struct parmlist_entry contains 79 bytes in 3 blocks (ref 0) d=(nil) 0x17e00b0 - yes contains 4 bytes in 1 blocks (ref 0) d=(nil) 0x17e01e0 - dsdb:schema update allowed contains 27 bytes in 1 blocks (ref 0) d=(nil) 0x17e0150 - struct parmlist_entry contains 85 bytes in 3 blocks (ref 0) d=(nil) 0x17dffa0 - 0 contains 2 bytes in 1 blocks (ref 0) d=(nil) 0x17e0040 - dreplsrv:periodic_startup_interval contains 35 bytes in 1 blocks (ref 0) d=(nil) 0x17dc600 - struct parmlist_entry contains 100 bytes in 3 blocks (ref 0) d=(nil) 0x17dfe50 - /home/rusty/samba/st/dns_host_file contains 35 bytes in 1 blocks (ref 0) d=(nil) 0x17da9d0 - resolv:host file contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17dfc10 - char * contains 134 bytes in 4 blocks (ref 0) d=(nil) 0x17daa60 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dfdb0 - -s contains 3 bytes in 1 blocks (ref 0) d=(nil) 0x17dfd40 - /home/rusty/samba/source4/scripting/bin/samba_spnupdate contains 56 bytes in 1 blocks (ref 0) d=(nil) 0x17dfc90 - char * contains 213 bytes in 6 blocks (ref 0) d=(nil) 0x17dfa60 - /home/rusty/samba/st/fl2000dc/etc/smb.conf contains 43 bytes in 1 blocks (ref 0) d=(nil) 0x17dfb70 - -s contains 3 bytes in 1 blocks (ref 0) d=(nil) 0x17dfb00 - --use-file=/home/rusty/samba/st/dns_host_file contains 46 bytes in 1 blocks (ref 0) d=(nil) 0x17df9c0 - --all-interfaces contains 17 bytes in 1 blocks (ref 0) d=(nil) 0x17df890 - /home/rusty/samba/source4/scripting/bin/samba_dnsupdate contains 56 bytes in 1 blocks (ref 0) d=(nil) 0x17df910 - char * contains 21 bytes in 2 blocks (ref 0) d=(nil) 0x17df810 - true contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17d7860 - struct parmlist_entry contains 72 bytes in 3 blocks (ref 0) d=(nil) 0x17df5c0 - true contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17df660 - gensec:require_pac contains 19 bytes in 1 blocks (ref 0) d=(nil) 0x17df3b0 - struct parmlist_entry contains 64 bytes in 3 blocks (ref 0) d=(nil) 0x17df430 - true contains 5 bytes in 1 blocks (ref 0) d=(nil) 0x17df550 - ldb:nosync contains 11 bytes in 1 blocks (ref 0) d=(nil) 0x17df4d0 - struct parmlist_entry contains 69 bytes in 3 blocks (ref 0) d=(nil) 0x17df2a0 - false contains 6 bytes in 1 blocks (ref 0) d=(nil) 0x17df340 - notify:inotify contains 15 bytes in 1 blocks (ref 0) d=(nil) 0x17db6b0 - char * contains 40 bytes in 3 blocks (ref 0) d=(nil) 0x17dc7c0