diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-09-06 13:41:52 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2018-09-06 13:41:52 +0200 | 
| commit | d45dd31e35190cf08b1e716e7c3bd1468ddd5d88 (patch) | |
| tree | 362ed3bf52fa67d15e35fba042aafe4e2a938065 /src | |
| parent | bd82d030011cd8b9655e5ded6b6df9343b42a6bd (diff) | |
New upstream version 3.23upstream/3.23
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/Makefile.in | 33 | ||||
| -rw-r--r-- | src/internal.h | 1 | ||||
| -rw-r--r-- | src/io.c | 15 | ||||
| -rw-r--r-- | src/map.c | 192 | ||||
| -rw-r--r-- | src/map_int.h | 20 | ||||
| -rw-r--r-- | src/opt.c | 40 | ||||
| -rw-r--r-- | src/tc-cast.c | 4 | ||||
| -rw-r--r-- | src/tc-format.c | 2 | ||||
| -rw-r--r-- | src/tc-map.c | 21 | ||||
| -rw-r--r-- | src/tc-option.c | 2 | ||||
| -rw-r--r-- | src/tc-string.c | 86 | 
12 files changed, 279 insertions, 139 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index 0ed269b..6788ddd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ libHX_la_LDFLAGS = -no-undefined -version-info 31:0:3  if WITH_GNU_LD  libHX_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map  endif -libHX_la_DEPENDENCIES = libHX.map +EXTRA_libHX_la_DEPENDENCIES = libHX.map  if MINGW32  libHX_la_SOURCES += ux-file.c ux-mmap.c diff --git a/src/Makefile.in b/src/Makefile.in index 7b6f318..fd611ca 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am.  # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc.  # This Makefile.in is free software; the Free Software Foundation  # gives unlimited permission to copy and/or distribute it, @@ -17,7 +17,17 @@  # -*- Makefile -*-  VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ +  if test -z '$(MAKELEVEL)'; then \ +    false; \ +  elif test -n '$(MAKE_HOST)'; then \ +    true; \ +  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ +    true; \ +  else \ +    false; \ +  fi; \ +}  am__make_running_with_option = \    case $${target_option-} in \        ?) ;; \ @@ -101,9 +111,6 @@ TESTS = tc-strchr2$(EXEEXT) tc-strquote$(EXEEXT) $(am__EXEEXT_2)  @HAVE_CXX_TRUE@am__append_7 = tx-strchr2 tx-strquote  subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ -	$(top_srcdir)/build-aux/depcomp \ -	$(top_srcdir)/build-aux/test-driver  ACLOCAL_M4 = $(top_srcdir)/aclocal.m4  am__aclocal_m4_deps = $(top_srcdir)/m4/gcc4_visibility.m4 \  	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ @@ -111,6 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/gcc4_visibility.m4 \  	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac  am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \  	$(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)  mkinstalldirs = $(install_sh) -d  CONFIG_HEADER = $(top_builddir)/config.h  CONFIG_CLEAN_FILES = @@ -145,6 +153,8 @@ am__uninstall_files_from_dir = { \  am__installdirs = "$(DESTDIR)$(libdir)"  LTLIBRARIES = $(lib_LTLIBRARIES)  am__DEPENDENCIES_1 = +libHX_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ +	$(am__DEPENDENCIES_1)  am__libHX_la_SOURCES_DIST = deque.c dl.c format.c io.c map.c mc.c \  	misc.c opt.c rand.c string.c time.c ux-file.c ux-mmap.c proc.c  @MINGW32_TRUE@am__objects_1 = ux-file.lo ux-mmap.lo @@ -588,6 +598,9 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)  TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver  TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \  	$(TEST_LOG_FLAGS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ +	$(top_srcdir)/build-aux/depcomp \ +	$(top_srcdir)/build-aux/test-driver  DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)  ACLOCAL = @ACLOCAL@  AMTAR = @AMTAR@ @@ -632,6 +645,7 @@ LIBTOOL = @LIBTOOL@  LIPO = @LIPO@  LN_S = @LN_S@  LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@  LYX = @LYX@  MAKEINFO = @MAKEINFO@  MANIFEST_TOOL = @MANIFEST_TOOL@ @@ -725,7 +739,7 @@ libHX_la_SOURCES = deque.c dl.c format.c io.c map.c mc.c misc.c opt.c \  	rand.c string.c time.c $(am__append_3) $(am__append_4)  libHX_la_LIBADD = ${libdl_LIBS} ${libpthread_LIBS} ${librt_LIBS}  libHX_la_LDFLAGS = -no-undefined -version-info 31:0:3 $(am__append_2) -libHX_la_DEPENDENCIES = libHX.map +EXTRA_libHX_la_DEPENDENCIES = libHX.map  libHX_rtcheck_la_SOURCES = rtcheck.c  libHX_rtcheck_la_LIBADD = ${libdl_LIBS}  libHX_rtcheck_la_LDFLAGS = -no-undefined -avoid-version -module \ @@ -800,7 +814,6 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)  	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \  	$(am__cd) $(top_srcdir) && \  	  $(AUTOMAKE) --foreign src/Makefile -.PRECIOUS: Makefile  Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status  	@case '$?' in \  	  *config.status*) \ @@ -1263,7 +1276,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)  	if test -n "$$am__remaking_logs"; then \  	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \  	       "recursion detected" >&2; \ -	else \ +	elif test -n "$$redo_logs"; then \  	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \  	fi; \  	if $(am__make_dryrun); then :; else \ @@ -1578,6 +1591,8 @@ uninstall-am: uninstall-libLTLIBRARIES  	recheck tags tags-am uninstall uninstall-am \  	uninstall-libLTLIBRARIES +.PRECIOUS: Makefile +  # Tell versions [3.59,3.63) of GNU make to not export all variables.  # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/internal.h b/src/internal.h index 969c56f..83d2b9c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -21,7 +21,6 @@  #	define const_cast3(type, expr)      const_cast<type>(expr)  #	define dynamic_cast(type, expr)     dynamic_cast<type>(expr)  #	define signed_cast(type, expr)      signed_cast<type>(expr) -#	define static_cast(type, expr)      static_cast<type>(expr)  #	define reinterpret_cast(type, expr) reinterpret_cast<type>(expr)  #endif @@ -39,7 +39,7 @@ struct HXdir {  	bool got_first;  #else  	DIR *ptr; -	struct dirent dentry; /* must be last */ +	struct dirent *dentry;  #endif  }; @@ -96,7 +96,7 @@ EXPORT_SYMBOL struct HXdir *HXdir_open(const char *s)  	 */  	name_max = fpathconf(dirfd(tmp_dh), _PC_NAME_MAX);  	if (name_max > 0) { -		size -= sizeof(d->dentry) - offsetof(struct dirent, d_name); +		size -= sizeof(struct dirent) - offsetof(struct dirent, d_name);  		size += name_max + 1;  	} else {  #ifdef NAME_MAX @@ -135,13 +135,10 @@ EXPORT_SYMBOL const char *HXdir_read(struct HXdir *d)  	}  	return d->dentry.cFileName;  #else -	{ -		struct dirent *checkptr; -		int i = readdir_r(d->ptr, &d->dentry, &checkptr); -		if (checkptr == NULL || i < 0) -			return NULL; -	} -	return d->dentry.d_name; +	d->dentry = readdir(d->ptr); +	if (d->dentry == NULL) +		return NULL; +	return d->dentry->d_name;  #endif  } @@ -21,6 +21,8 @@  #include <libHX/string.h>  #include "internal.h"  #include "map_int.h" +#define N_LEFT  sub[RBT_LEFT] +#define N_RIGHT sub[RBT_RIGHT]  typedef void *(*clonefunc_t)(const void *, size_t); @@ -51,9 +53,9 @@ EXPORT_SYMBOL const unsigned int HXhash_primes[] = {  };  #endif -static void HXhmap_free(struct HXhmap *hmap) +static void HXumap_free(struct HXumap *hmap)  { -	struct HXhmap_node *drop, *dnext; +	struct HXumap_node *drop, *dnext;  	unsigned int i;  	for (i = 0; i < HXhash_primes[hmap->power]; ++i) { @@ -72,7 +74,7 @@ static void HXhmap_free(struct HXhmap *hmap)  }  static void HXrbtree_free_dive(const struct HXrbtree *btree, -    struct HXrbtree_node *node) +    struct HXrbnode *node)  {  	/*  	 * Recursively dives into the tree and destroys elements. Note that you @@ -80,10 +82,10 @@ static void HXrbtree_free_dive(const struct HXrbtree *btree,  	 * deletion with HXrbtree_del(). Since this functions is meant to free  	 * it all, it does not need to care about rebalancing.  	 */ -	if (node->sub[RBT_LEFT] != NULL) -		HXrbtree_free_dive(btree, node->sub[RBT_LEFT]); -	if (node->sub[RBT_RIGHT] != NULL) -		HXrbtree_free_dive(btree, node->sub[RBT_RIGHT]); +	if (node->N_LEFT != NULL) +		HXrbtree_free_dive(btree, node->N_LEFT); +	if (node->N_RIGHT != NULL) +		HXrbtree_free_dive(btree, node->N_RIGHT);  	if (btree->super.ops.k_free != NULL)  		btree->super.ops.k_free(node->key);  	if (btree->super.ops.d_free != NULL) @@ -105,7 +107,7 @@ EXPORT_SYMBOL void HXmap_free(struct HXmap *xmap)  	switch (map->type) {  	case HXMAPT_HASH: -		return HXhmap_free(vmap); +		return HXumap_free(vmap);  	case HXMAPT_RBTREE:  		return HXrbtree_free(vmap);  	default: @@ -277,15 +279,15 @@ x_frac(unsigned int n, unsigned int d, unsigned int v)  }  /** - * HXhmap_move - move elements from one map to another + * HXumap_move - move elements from one map to another   * @bk_array:	target bucket array   * @bk_number:	number of buckets   * @hmap:	old hash table   */ -static void HXhmap_move(struct HXlist_head *bk_array, unsigned int bk_number, -    struct HXhmap *hmap) +static void HXumap_move(struct HXlist_head *bk_array, unsigned int bk_number, +    struct HXumap *hmap)  { -	struct HXhmap_node *drop, *dnext; +	struct HXumap_node *drop, *dnext;  	unsigned int bk_idx, i;  #ifdef NONPRIME_HASH @@ -307,11 +309,11 @@ static void HXhmap_move(struct HXlist_head *bk_array, unsigned int bk_number,  }  /** - * HXhmap_layout - resize and rehash table + * HXumap_layout - resize and rehash table   * @hmap:	hash map   * @prime_idx:	requested new table size (prime power thereof)   */ -static int HXhmap_layout(struct HXhmap *hmap, unsigned int power) +static int HXumap_layout(struct HXumap *hmap, unsigned int power)  {  	const unsigned int bk_number = HXhash_primes[power];  	struct HXlist_head *bk_array, *old_array = NULL; @@ -323,7 +325,7 @@ static int HXhmap_layout(struct HXhmap *hmap, unsigned int power)  	for (i = 0; i < bk_number; ++i)  		HXlist_init(&bk_array[i]);  	if (hmap->bk_array != NULL) { -		HXhmap_move(bk_array, bk_number, hmap); +		HXumap_move(bk_array, bk_number, hmap);  		old_array = hmap->bk_array;  		/*  		 * It is ok to increment the TID this late. @map->bk_array is @@ -344,7 +346,7 @@ static struct HXmap *HXhashmap_init4(unsigned int flags,      const struct HXmap_ops *ops, size_t key_size, size_t data_size)  {  	struct HXmap_private *super; -	struct HXhmap *hmap; +	struct HXumap *hmap;  	int saved_errno;  	if ((hmap = calloc(1, sizeof(*hmap))) == NULL) @@ -358,7 +360,7 @@ static struct HXmap *HXhashmap_init4(unsigned int flags,  	super->data_size = data_size;  	HXmap_ops_setup(super, ops);  	hmap->tid = 1; -	errno = HXhmap_layout(hmap, 0); +	errno = HXumap_layout(hmap, 0);  	if (hmap->bk_array == NULL)  		goto out; @@ -367,7 +369,7 @@ static struct HXmap *HXhashmap_init4(unsigned int flags,   out:  	saved_errno = errno; -	HXhmap_free(hmap); +	HXumap_free(hmap);  	errno = saved_errno;  	return NULL;  } @@ -379,7 +381,7 @@ static struct HXmap *HXrbtree_init4(unsigned int flags,  	struct HXrbtree *btree;  	BUILD_BUG_ON(offsetof(struct HXrbtree, root) + -	             offsetof(struct HXrbtree_node, sub[0]) != +	             offsetof(struct HXrbnode, sub[0]) !=  	             offsetof(struct HXrbtree, root));  	if ((btree = calloc(1, sizeof(*btree))) == NULL) @@ -447,10 +449,10 @@ EXPORT_SYMBOL struct HXmap *HXmap_init(enum HXmap_type type,  	return HXmap_init5(type, flags, NULL, 0, 0);  } -static struct HXhmap_node *HXhmap_find(const struct HXhmap *hmap, +static struct HXumap_node *HXumap_find(const struct HXumap *hmap,      const void *key)  { -	struct HXhmap_node *drop; +	struct HXumap_node *drop;  	unsigned int bk_idx;  #ifdef NONPRIME_HASH @@ -470,7 +472,7 @@ static struct HXhmap_node *HXhmap_find(const struct HXhmap *hmap,  static const struct HXmap_node *HXrbtree_find(const struct HXrbtree *btree,      const void *key)  { -	struct HXrbtree_node *node = btree->root; +	struct HXrbnode *node = btree->root;  	int res;  	while (node != NULL) { @@ -491,7 +493,7 @@ HXmap_find(const struct HXmap *xmap, const void *key)  	switch (map->type) {  	case HXMAPT_HASH: { -		const struct HXhmap_node *node = HXhmap_find(vmap, key); +		const struct HXumap_node *node = HXumap_find(vmap, key);  		if (node == NULL)  			return NULL;  		return static_cast(const void *, &node->key); @@ -517,9 +519,9 @@ EXPORT_SYMBOL void *HXmap_get(const struct HXmap *map, const void *key)  }  /** - * HXhmap_replace - replace value in a drop + * HXumap_replace - replace value in a drop   */ -static int HXhmap_replace(const struct HXhmap *hmap, struct HXhmap_node *drop, +static int HXumap_replace(const struct HXumap *hmap, struct HXumap_node *drop,      const void *value)  {  	void *old_value, *new_value; @@ -537,21 +539,21 @@ static int HXhmap_replace(const struct HXhmap *hmap, struct HXhmap_node *drop,  	return 1;  } -static int HXhmap_add(struct HXhmap *hmap, const void *key, const void *value) +static int HXumap_add(struct HXumap *hmap, const void *key, const void *value)  { -	struct HXhmap_node *drop; +	struct HXumap_node *drop;  	unsigned int bk_idx;  	int ret, saved_errno; -	if ((drop = HXhmap_find(hmap, key)) != NULL) -		return HXhmap_replace(hmap, drop, value); +	if ((drop = HXumap_find(hmap, key)) != NULL) +		return HXumap_replace(hmap, drop, value);  	if (hmap->super.items >= hmap->max_load &&  	    hmap->power < ARRAY_SIZE(HXhash_primes) - 1) { -		if ((ret = HXhmap_layout(hmap, hmap->power + 1)) <= 0) +		if ((ret = HXumap_layout(hmap, hmap->power + 1)) <= 0)  			return ret;  	} else if (hmap->super.items < hmap->min_load && hmap->power > 0) { -		if ((ret = HXhmap_layout(hmap, hmap->power - 1)) <= 0) +		if ((ret = HXumap_layout(hmap, hmap->power - 1)) <= 0)  			return ret;  	} @@ -592,10 +594,10 @@ static int HXhmap_add(struct HXhmap *hmap, const void *key, const void *value)   * @depth:	current index in @path and @dir   * @tid:	pointer to transaction ID which may need updating   */ -static void HXrbtree_amov(struct HXrbtree_node **path, +static void HXrbtree_amov(struct HXrbnode **path,      const unsigned char *dir, unsigned int depth, unsigned int *tid)  { -	struct HXrbtree_node *uncle, *parent, *grandp, *newnode; +	struct HXrbnode *uncle, *parent, *grandp, *newnode;  	/*  	 * The newly inserted node (or the last rebalanced node) at @@ -657,7 +659,7 @@ static void HXrbtree_amov(struct HXrbtree_node **path,  }  static int HXrbtree_replace(const struct HXrbtree *btree, -    struct HXrbtree_node *node, const void *value) +    struct HXrbnode *node, const void *value)  {  	void *old_value, *new_value; @@ -677,18 +679,18 @@ static int HXrbtree_replace(const struct HXrbtree *btree,  static int HXrbtree_add(struct HXrbtree *btree,      const void *key, const void *value)  { -	struct HXrbtree_node *node, *path[RBT_MAXDEP]; +	struct HXrbnode *node, *path[RBT_MAXDEP];  	unsigned char dir[RBT_MAXDEP];  	unsigned int depth = 0;  	int saved_errno;  	/* -	 * Since our struct HXrbtree_node runs without a ->parent pointer, +	 * Since our struct HXrbnode runs without a ->parent pointer,  	 * the path "upwards" from @node needs to be recorded somehow,  	 * here with @path. Another array, @dir is used to speedup direction  	 * decisions. (WP's "n->parent == grandparent(n)->left" is just slow.)  	 */ -	path[depth]  = reinterpret_cast(struct HXrbtree_node *, &btree->root); +	path[depth]  = reinterpret_cast(struct HXrbnode *, &btree->root);  	dir[depth++] = 0;  	node = btree->root; @@ -708,7 +710,7 @@ static int HXrbtree_add(struct HXrbtree *btree,  		node         = node->sub[res];  	} -	if ((node = malloc(sizeof(struct HXrbtree_node))) == NULL) +	if ((node = malloc(sizeof(struct HXrbnode))) == NULL)  		return -errno;  	/* New node, push data into it */ @@ -724,7 +726,7 @@ static int HXrbtree_add(struct HXrbtree *btree,  	 * (each simple path has the same number of black nodes), it is colored  	 * red so that below we only need to check for rule 1 violations.  	 */ -	node->sub[RBT_LEFT] = node->sub[RBT_RIGHT] = NULL; +	node->N_LEFT = node->N_RIGHT = NULL;  	node->color = RBT_RED;  	path[depth-1]->sub[dir[depth-1]] = node;  	++btree->super.items; @@ -765,7 +767,7 @@ EXPORT_SYMBOL int HXmap_add(struct HXmap *xmap,  	switch (map->type) {  	case HXMAPT_HASH: -		return HXhmap_add(vmap, key, value); +		return HXumap_add(vmap, key, value);  	case HXMAPT_RBTREE:  		return HXrbtree_add(vmap, key, value);  	default: @@ -773,12 +775,12 @@ EXPORT_SYMBOL int HXmap_add(struct HXmap *xmap,  	}  } -static void *HXhmap_del(struct HXhmap *hmap, const void *key) +static void *HXumap_del(struct HXumap *hmap, const void *key)  { -	struct HXhmap_node *drop; +	struct HXumap_node *drop;  	void *value; -	if ((drop = HXhmap_find(hmap, key)) == NULL) { +	if ((drop = HXumap_find(hmap, key)) == NULL) {  		errno = ENOENT;  		return NULL;  	} @@ -791,7 +793,7 @@ static void *HXhmap_del(struct HXhmap *hmap, const void *key)  		 * Ignore return value. If it failed, it will continue to use  		 * the current bk_array.  		 */ -		HXhmap_layout(hmap, hmap->power - 1); +		HXumap_layout(hmap, hmap->power - 1);  	value = drop->data;  	if (hmap->super.ops.k_free != NULL) @@ -803,20 +805,20 @@ static void *HXhmap_del(struct HXhmap *hmap, const void *key)  	return value;  } -static unsigned int HXrbtree_del_mm(struct HXrbtree_node **path, +static unsigned int HXrbtree_del_mm(struct HXrbnode **path,      unsigned char *dir, unsigned int depth)  {  	/* Both subtrees exist */ -	struct HXrbtree_node *io_node, *io_parent, *orig_node = path[depth]; +	struct HXrbnode *io_node, *io_parent, *orig_node = path[depth];  	unsigned char color;  	unsigned int spos; -	io_node    = orig_node->sub[RBT_RIGHT]; +	io_node    = orig_node->N_RIGHT;  	dir[depth] = RBT_RIGHT; -	if (io_node->sub[RBT_LEFT] == NULL) { +	if (io_node->N_LEFT == NULL) {  		/* Right subtree node is direct inorder */ -		io_node->sub[RBT_LEFT] = orig_node->sub[RBT_LEFT]; +		io_node->N_LEFT = orig_node->N_LEFT;  		color                = io_node->color;  		io_node->color       = orig_node->color;  		orig_node->color     = color; @@ -836,14 +838,14 @@ static unsigned int HXrbtree_del_mm(struct HXrbtree_node **path,  		io_parent    = io_node;  		path[depth]  = io_parent;  		dir[depth++] = RBT_LEFT; -		io_node      = io_parent->sub[RBT_LEFT]; -	} while (io_node->sub[RBT_LEFT] != NULL); +		io_node      = io_parent->N_LEFT; +	} while (io_node->N_LEFT != NULL);  	/* move node up */  	path[spos-1]->sub[dir[spos-1]] = path[spos] = io_node; -	io_parent->sub[RBT_LEFT]         = io_node->sub[RBT_RIGHT]; -	io_node->sub[RBT_LEFT]           = orig_node->sub[RBT_LEFT]; -	io_node->sub[RBT_RIGHT]          = orig_node->sub[RBT_RIGHT]; +	io_parent->N_LEFT         = io_node->N_RIGHT; +	io_node->N_LEFT           = orig_node->N_LEFT; +	io_node->N_RIGHT          = orig_node->N_RIGHT;  	color          = io_node->color;  	io_node->color = orig_node->color; @@ -858,10 +860,10 @@ static unsigned int HXrbtree_del_mm(struct HXrbtree_node **path,  	return depth;  } -static void HXrbtree_dmov(struct HXrbtree_node **path, unsigned char *dir, +static void HXrbtree_dmov(struct HXrbnode **path, unsigned char *dir,      unsigned int depth)  { -	struct HXrbtree_node *w, *x; +	struct HXrbnode *w, *x;  	while (true) {  		unsigned char LR = dir[depth - 1]; @@ -906,7 +908,7 @@ static void HXrbtree_dmov(struct HXrbtree_node **path, unsigned char *dir,  		if (w->sub[!LR] == NULL || w->sub[!LR]->color == RBT_BLACK) {  			/* Case 5 */ -			struct HXrbtree_node *y = w->sub[LR]; +			struct HXrbnode *y = w->sub[LR];  			y->color = RBT_BLACK;  			w->color = RBT_RED;  			w->sub[LR] = y->sub[!LR]; @@ -927,7 +929,7 @@ static void HXrbtree_dmov(struct HXrbtree_node **path, unsigned char *dir,  static void *HXrbtree_del(struct HXrbtree *btree, const void *key)  { -	struct HXrbtree_node *path[RBT_MAXDEP], *node; +	struct HXrbnode *path[RBT_MAXDEP], *node;  	unsigned char dir[RBT_MAXDEP];  	unsigned int depth = 0;  	void *itemptr; @@ -935,7 +937,7 @@ static void *HXrbtree_del(struct HXrbtree *btree, const void *key)  	if (btree->root == NULL)  		return NULL; -	path[depth]  = reinterpret_cast(struct HXrbtree_node *, &btree->root); +	path[depth]  = reinterpret_cast(struct HXrbnode *, &btree->root);  	dir[depth++] = 0;  	node         = btree->root; @@ -966,12 +968,12 @@ static void *HXrbtree_del(struct HXrbtree *btree, const void *key)  	++btree->tid;  	path[depth] = node; -	if (node->sub[RBT_RIGHT] == NULL) +	if (node->N_RIGHT == NULL)  		/* Simple case: No right subtree, replace by left subtree. */ -		path[depth-1]->sub[dir[depth-1]] = node->sub[RBT_LEFT]; -	else if (node->sub[RBT_LEFT] == NULL) +		path[depth-1]->sub[dir[depth-1]] = node->N_LEFT; +	else if (node->N_LEFT == NULL)  		/* Simple case: No left subtree, replace by right subtree. */ -		path[depth-1]->sub[dir[depth-1]] = node->sub[RBT_RIGHT]; +		path[depth-1]->sub[dir[depth-1]] = node->N_RIGHT;  	else  		/*  		 * Find minimum/maximum element in right/left subtree and @@ -1006,7 +1008,7 @@ EXPORT_SYMBOL void *HXmap_del(struct HXmap *xmap, const void *key)  	switch (map->type) {  	case HXMAPT_HASH: -		return HXhmap_del(vmap, key); +		return HXumap_del(vmap, key);  	case HXMAPT_RBTREE:  		return HXrbtree_del(vmap, key);  	default: @@ -1015,10 +1017,10 @@ EXPORT_SYMBOL void *HXmap_del(struct HXmap *xmap, const void *key)  	}  } -static void HXhmap_keysvalues(const struct HXhmap *hmap, +static void HXumap_keysvalues(const struct HXumap *hmap,      struct HXmap_node *array)  { -	const struct HXhmap_node *node; +	const struct HXumap_node *node;  	unsigned int i;  	for (i = 0; i < HXhash_primes[hmap->power]; ++i) @@ -1029,7 +1031,7 @@ static void HXhmap_keysvalues(const struct HXhmap *hmap,  		}  } -static struct HXmap_node *HXrbtree_keysvalues(const struct HXrbtree_node *node, +static struct HXmap_node *HXrbtree_keysvalues(const struct HXrbnode *node,      struct HXmap_node *array)  {  	if (node->sub[0] != NULL) @@ -1062,7 +1064,7 @@ EXPORT_SYMBOL struct HXmap_node *HXmap_keysvalues(const struct HXmap *xmap)  	switch (map->type) {  	case HXMAPT_HASH: -		HXhmap_keysvalues(vmap, array); +		HXumap_keysvalues(vmap, array);  		break;  	case HXMAPT_RBTREE:  		HXrbtree_keysvalues( @@ -1073,9 +1075,9 @@ EXPORT_SYMBOL struct HXmap_node *HXmap_keysvalues(const struct HXmap *xmap)  	return array;  } -static void *HXhmap_travinit(const struct HXhmap *hmap, unsigned int flags) +static void *HXumap_travinit(const struct HXumap *hmap, unsigned int flags)  { -	struct HXhmap_trav *trav; +	struct HXumap_trav *trav;  	if ((trav = malloc(sizeof(*trav))) == NULL)  		return NULL; @@ -1109,7 +1111,7 @@ EXPORT_SYMBOL struct HXmap_trav *HXmap_travinit(const struct HXmap *xmap,  	switch (map->type) {  	case HXMAPT_HASH: -		return HXhmap_travinit(vmap, flags); +		return HXumap_travinit(vmap, flags);  	case HXMAPT_RBTREE:  		return HXrbtrav_init(vmap, flags);  	default: @@ -1118,10 +1120,10 @@ EXPORT_SYMBOL struct HXmap_trav *HXmap_travinit(const struct HXmap *xmap,  	}  } -static const struct HXmap_node *HXhmap_traverse(struct HXhmap_trav *trav) +static const struct HXmap_node *HXumap_traverse(struct HXumap_trav *trav)  { -	const struct HXhmap *hmap = trav->hmap; -	const struct HXhmap_node *drop; +	const struct HXumap *hmap = trav->hmap; +	const struct HXumap_node *drop;  	if (trav->head == NULL) {  		trav->head = hmap->bk_array[trav->bk_current].next; @@ -1145,12 +1147,12 @@ static const struct HXmap_node *HXhmap_traverse(struct HXhmap_trav *trav)  		trav->head = hmap->bk_array[trav->bk_current].next;  	} -	drop = HXlist_entry(trav->head, struct HXhmap_node, anchor); +	drop = HXlist_entry(trav->head, struct HXumap_node, anchor);  	return static_cast(const void *, &drop->key);  }  static void HXrbtrav_checkpoint(struct HXrbtrav *trav, -    const struct HXrbtree_node *node) +    const struct HXrbnode *node)  {  	const struct HXrbtree *tree = trav->tree; @@ -1166,19 +1168,19 @@ static void HXrbtrav_checkpoint(struct HXrbtrav *trav,  	}  } -static struct HXrbtree_node *HXrbtrav_next(struct HXrbtrav *trav) +static struct HXrbnode *HXrbtrav_next(struct HXrbtrav *trav)  { -	if (trav->current->sub[RBT_RIGHT] != NULL) { +	if (trav->current->N_RIGHT != NULL) {  		/* Got a right child */ -		struct HXrbtree_node *node; +		struct HXrbnode *node;  		trav->dir[trav->depth++] = RBT_RIGHT; -		node = trav->current->sub[RBT_RIGHT]; +		node = trav->current->N_RIGHT;  		/* Which might have left childs (our inorder successors!) */  		while (node != NULL) {  			trav->path[trav->depth] = node; -			node = node->sub[RBT_LEFT]; +			node = node->N_LEFT;  			trav->dir[trav->depth++] = RBT_LEFT;  		}  		trav->current = trav->path[--trav->depth]; @@ -1210,7 +1212,7 @@ static struct HXrbtree_node *HXrbtrav_next(struct HXrbtrav *trav)  	return trav->current;  } -static struct HXrbtree_node *HXrbtrav_rewalk(struct HXrbtrav *trav) +static struct HXrbnode *HXrbtrav_rewalk(struct HXrbtrav *trav)  {  	/*  	 * When the binary tree has been distorted (or the traverser is @@ -1219,7 +1221,7 @@ static struct HXrbtree_node *HXrbtrav_rewalk(struct HXrbtrav *trav)  	 * find the node we were last at.  	 */  	const struct HXrbtree *btree = trav->tree; -	struct HXrbtree_node *node   = btree->root; +	struct HXrbnode *node   = btree->root;  	bool go_next = false;  	trav->depth = 0; @@ -1228,12 +1230,12 @@ static struct HXrbtree_node *HXrbtrav_rewalk(struct HXrbtrav *trav)  		/* Walk down the tree to the smallest element */  		while (node != NULL) {  			trav->path[trav->depth] = node; -			node = node->sub[RBT_LEFT]; +			node = node->N_LEFT;  			trav->dir[trav->depth++] = RBT_LEFT;  		}  	} else {  		/* Search for the specific node to rebegin traversal at. */ -		const struct HXrbtree_node *newpath[RBT_MAXDEP]; +		const struct HXrbnode *newpath[RBT_MAXDEP];  		unsigned char newdir[RBT_MAXDEP];  		int newdepth = 0, res;  		bool found = false; @@ -1312,7 +1314,7 @@ static struct HXrbtree_node *HXrbtrav_rewalk(struct HXrbtrav *trav)  static const struct HXmap_node *HXrbtree_traverse(struct HXrbtrav *trav)  { -	const struct HXrbtree_node *node; +	const struct HXrbnode *node;  	if (trav->tid != trav->tree->tid || trav->current == NULL)  		/* @@ -1335,7 +1337,7 @@ EXPORT_SYMBOL const struct HXmap_node *HXmap_traverse(struct HXmap_trav *trav)  	switch (trav->type) {  	case HXMAPT_HASH: -		return HXhmap_traverse(xtrav); +		return HXumap_traverse(xtrav);  	case HXMAPT_RBTREE:  		return HXrbtree_traverse(xtrav);  	default: @@ -1369,9 +1371,9 @@ EXPORT_SYMBOL void HXmap_travfree(struct HXmap_trav *trav)  	}  } -static void HXhmap_qfe(const struct HXhmap *hmap, qfe_fn_t fn, void *arg) +static void HXumap_qfe(const struct HXumap *hmap, qfe_fn_t fn, void *arg)  { -	const struct HXhmap_node *hnode; +	const struct HXumap_node *hnode;  	unsigned int i;  	for (i = 0; i < HXhash_primes[hmap->power]; ++i) @@ -1380,15 +1382,15 @@ static void HXhmap_qfe(const struct HXhmap *hmap, qfe_fn_t fn, void *arg)  				return;  } -static void HXrbtree_qfe(const struct HXrbtree_node *node, +static void HXrbtree_qfe(const struct HXrbnode *node,      qfe_fn_t fn, void *arg)  { -	if (node->sub[RBT_LEFT] != NULL) -		HXrbtree_qfe(node->sub[RBT_LEFT], fn, arg); +	if (node->N_LEFT != NULL) +		HXrbtree_qfe(node->N_LEFT, fn, arg);  	if (!(*fn)(static_cast(const void *, &node->key), arg))  		return; -	if (node->sub[RBT_RIGHT] != NULL) -		HXrbtree_qfe(node->sub[RBT_RIGHT], fn, arg); +	if (node->N_RIGHT != NULL) +		HXrbtree_qfe(node->N_RIGHT, fn, arg);  }  EXPORT_SYMBOL void HXmap_qfe(const struct HXmap *xmap, qfe_fn_t fn, void *arg) @@ -1398,7 +1400,7 @@ EXPORT_SYMBOL void HXmap_qfe(const struct HXmap *xmap, qfe_fn_t fn, void *arg)  	switch (map->type) {  	case HXMAPT_HASH: -		HXhmap_qfe(vmap, fn, arg); +		HXumap_qfe(vmap, fn, arg);  		errno = 0;  		break;  	case HXMAPT_RBTREE: { diff --git a/src/map_int.h b/src/map_int.h index 6fea432..6e95c69 100644 --- a/src/map_int.h +++ b/src/map_int.h @@ -29,7 +29,7 @@ struct HXmap_private {   * @min_load:	minimum number of elements before table gets shrunk   * @tid:	transaction ID, used to track relayouts   */ -struct HXhmap { +struct HXumap {  	struct HXmap_private super;  	struct HXlist_head *bk_array; @@ -37,11 +37,11 @@ struct HXhmap {  };  /** - * @anchor:	anchor point in struct HXhmap_node + * @anchor:	anchor point in struct HXumap_node   * @key:	data that works as key   * @data:	data that works as value   */ -struct HXhmap_node { +struct HXumap_node {  	struct HXlist_head anchor;  	/* HXmap_node */  	union { @@ -59,9 +59,9 @@ struct HXmap_trav {  	unsigned int flags;  }; -struct HXhmap_trav { +struct HXumap_trav {  	struct HXmap_trav super; -	const struct HXhmap *hmap; +	const struct HXumap *hmap;  	const struct HXlist_head *head;  	unsigned int bk_current, tid;  }; @@ -86,8 +86,8 @@ enum {   * @sub:	leaves   * @color:	RBtree-specific node color   */ -struct HXrbtree_node { -	struct HXrbtree_node *sub[2]; +struct HXrbnode { +	struct HXrbnode *sub[2];  	/* HXmap_node */  	union {  		void *key; @@ -102,7 +102,7 @@ struct HXrbtree_node {  struct HXrbtree {  	struct HXmap_private super; -	struct HXrbtree_node *root; +	struct HXrbnode *root;  	unsigned int tid;  }; @@ -110,9 +110,9 @@ struct HXrbtrav {  	struct HXmap_trav super;  	unsigned int tid; /* last seen btree transaction */  	const struct HXrbtree *tree; -	struct HXrbtree_node *current; /* last visited node */ +	struct HXrbnode *current; /* last visited node */  	char *checkpoint; -	struct HXrbtree_node *path[RBT_MAXDEP]; /* stored path */ +	struct HXrbnode *path[RBT_MAXDEP]; /* stored path */  	unsigned char dir[RBT_MAXDEP];  	unsigned char depth;  }; @@ -70,6 +70,7 @@ enum {   * %HXOPT_E_LONG_MISSING:	long option requires an argument   * %HXOPT_E_SHORT_UNKNOWN:	unknown short option   * %HXOPT_E_SHORT_MISSING:	short option requires an argument + * %HXOPT_E_AMBIG_PREFIX:	used abbreviated long option but had multiple results   */  enum {  	HXOPT_E_LONG_UNKNOWN = 1, @@ -77,6 +78,7 @@ enum {  	HXOPT_E_LONG_MISSING,  	HXOPT_E_SHORT_UNKNOWN,  	HXOPT_E_SHORT_MISSING, +	HXOPT_E_AMBIG_PREFIX,  };  /** @@ -127,6 +129,8 @@ struct HX_getopt_vars {  	unsigned int flags;  }; +struct HXoption HXopt_ambig_prefix; +  static bool posix_me_harder(void)  {  	const char *s; @@ -241,6 +245,27 @@ lookup_short(const struct HXoption *table, char opt)  	return NULL;  } +static const struct HXoption * +lookup_long_pfx(const struct HXoption *table, const char *key) +{ +	const struct HXoption *cand = NULL; +	size_t klen = strlen(key); + +	for (; table->type != HXTYPE_XSNTMARK; ++table) { +		if (table->ln == NULL) +			continue; +		if (strncmp(table->ln, key, klen) != 0) +			continue; +		/* Prefix match */ +		if (table->ln[klen] == '\0') +			return table; /* Exact match */ +		if (cand != NULL) +			return &HXopt_ambig_prefix; +		cand = table; +	} +	return cand; +} +  static __inline__ const struct HXoption *  lookup_long(const struct HXoption *table, const char *key)  { @@ -462,6 +487,10 @@ static int HX_getopt_error(int err, const char *key, unsigned int flags)  			fprintf(stderr, "Option -%c requires an "  			        "argument\n", *key);  		return HXOPT_I_ERROR | HXOPT_ERR_MIS; +	case HXOPT_E_AMBIG_PREFIX: +		if (!(flags & HXOPT_QUIET)) +			fprintf(stderr, "Option %s is ambiguous\n", key); +		return HXOPT_I_ERROR | HXOPT_ERR_AMBIG;  	}  	return HXOPT_I_ERROR;  } @@ -471,7 +500,9 @@ static int HX_getopt_twolong(const char *const *opt,  {  	const char *key = opt[0], *value = opt[1]; -	par->cbi.current = lookup_long(par->cbi.table, key + 2); +	par->cbi.current = lookup_long_pfx(par->cbi.table, key + 2); +	if (par->cbi.current == &HXopt_ambig_prefix) +		return HX_getopt_error(HXOPT_E_AMBIG_PREFIX, key, par->flags);  	if (par->cbi.current == NULL) {  		if (par->flags & HXOPT_PTHRU) {  			char *tmp = HX_strdup(key); @@ -521,7 +552,12 @@ static int HX_getopt_long(const char *cur, struct HX_getopt_vars *par)  	value = strchr(key, '=');  	*value++ = '\0'; -	par->cbi.current = lookup_long(par->cbi.table, key + 2); +	par->cbi.current = lookup_long_pfx(par->cbi.table, key + 2); +	if (par->cbi.current == &HXopt_ambig_prefix) { +		ret = HX_getopt_error(HXOPT_E_AMBIG_PREFIX, key, par->flags); +		free(key); +		return ret; +	}  	if (par->cbi.current == NULL) {  		if (par->flags & HXOPT_PTHRU) {  			/* Undo nuke of '=' and reuse alloc */ diff --git a/src/tc-cast.c b/src/tc-cast.c index 73b7d66..422054c 100644 --- a/src/tc-cast.c +++ b/src/tc-cast.c @@ -15,6 +15,8 @@  #include "internal.h"  #define UNUSED __attribute__((unused)) +static int *v_1 UNUSED = const_cast1(int *, (const int *)NULL); +  static void c_signed(void)  {  	const char *si_00 = "foo"; @@ -53,7 +55,7 @@ static void c_const2(void)  {  	const int **co_02 = NULL;  	int **co_03 UNUSED = const_cast2(int **, co_02); -	int *const *co_04 = const_cast2(int *const *, co_02); +	int *const *co_04 UNUSED = const_cast2(int *const *, co_02);  	const int *const *co_05 = const_cast2(const int *const *, co_02);  	co_02 = const_cast2(const int **, co_05);  	co_04 = const_cast2(int *const *, co_05); diff --git a/src/tc-format.c b/src/tc-format.c index 7e90664..ad067ee 100644 --- a/src/tc-format.c +++ b/src/tc-format.c @@ -70,7 +70,7 @@ static void t_format(int argc)  	HXformat_add(fmt, "TWOARG", "a, b", HXTYPE_STRING | HXFORMAT_IMMED);  	++argc;  	printf("# HXformat2\n"); -	for (s = fmt2_strings; *s != '\0'; ++s) +	for (s = fmt2_strings; *s != NULL; ++s)  		HXformat_fprintf(fmt, stdout, *s);  	HXformat_free(fmt);  } diff --git a/src/tc-map.c b/src/tc-map.c index 4fe0408..8a22259 100644 --- a/src/tc-map.c +++ b/src/tc-map.c @@ -6,6 +6,7 @@   *	modify it under the terms of the WTF Public License version 2 or   *	(at your option) any later version.   */ +#include "config.h"  #include <errno.h>  #include <math.h>  #include <stdarg.h> @@ -27,7 +28,7 @@  union HXpoly {  	struct HXmap *map; -	struct HXhmap *hmap; +	struct HXumap *hmap;  	struct HXrbtree *rbt;  }; @@ -353,9 +354,9 @@ static void tmap_new_perfect_tree(struct HXmap *map,   * Compute an "agglomeration" index that models the lack of distributedness   * in hash maps. Range is 0-100%.   */ -static double hmap_agg_index(const struct HXhmap *hmap, bool verbose) +static double hmap_agg_index(const struct HXumap *hmap, bool verbose)  { -	const struct HXhmap_node *hnode; +	const struct HXumap_node *hnode;  	unsigned int i;  	int f = 0, j; @@ -365,7 +366,7 @@ static double hmap_agg_index(const struct HXhmap *hmap, bool verbose)  		printf("{");  	/* -	 * HXhmap is written such that the number of buckets is always equal or +	 * HXumap is written such that the number of buckets is always equal or  	 * greater than the element count. This is done because, in practice,  	 * buckets will be populated with more than a few (two/three) entries  	 * before elements/buckets >= grow_trigger_ratio. @@ -468,7 +469,7 @@ static void tmap_hmap_test_1(void)  	tmap_ipop();  } -static void __rbt_walk_tree(const struct HXrbtree_node *node, +static void __rbt_walk_tree(const struct HXrbnode *node,      char *buf, size_t s)  {  	bool has_children = node->sub[0] != NULL || node->sub[1] != NULL; @@ -494,7 +495,7 @@ static void __rbt_walk_tree(const struct HXrbtree_node *node,   * @buf:	buffer for texitree representation   * @size:	size for @buf   */ -static void rbt_walk_tree(const struct HXrbtree_node *node, +static void rbt_walk_tree(const struct HXrbnode *node,      char *buf, size_t size)  {  	*buf = '\0'; @@ -517,7 +518,7 @@ static struct HXmap *rbt_new_perfect_tree(unsigned int height,  	return tree;  } -static unsigned int rbt_tree_height(const struct HXrbtree_node *node) +static unsigned int rbt_tree_height(const struct HXrbnode *node)  {  	unsigned int a = 1, b = 1;  	if (node->sub[0] != NULL) @@ -593,7 +594,7 @@ static void tmap_rbt_test_1(void)   *   * Verify that there are no red nodes with red children.   */ -static bool rbt_no_2red_children(const struct HXrbtree_node *node) +static bool rbt_no_2red_children(const struct HXrbnode *node)  {  	if (node->sub[RBT_LEFT] != NULL) {  		if (node->color == RBT_RED && @@ -618,7 +619,7 @@ static bool rbt_no_2red_children(const struct HXrbtree_node *node)   *   * Returns the black height, or -1 if the black height is not consistent.   */ -static int rbt_black_height(const struct HXrbtree_node *node) +static int rbt_black_height(const struct HXrbnode *node)  {  	int lh = 0, rh = 0; @@ -637,7 +638,7 @@ static int rbt_black_height(const struct HXrbtree_node *node)  		return rh + (node->color == RBT_BLACK);  } -static bool rbt_verify_tree(const struct HXrbtree_node *root) +static bool rbt_verify_tree(const struct HXrbnode *root)  {  	/* Root is black */  	if (root->color != RBT_BLACK) { diff --git a/src/tc-option.c b/src/tc-option.c index dbd595c..aa6f12c 100644 --- a/src/tc-option.c +++ b/src/tc-option.c @@ -49,6 +49,8 @@ static struct HXoption table[] = {  	 .cb = opt_cbf, .help = "Mutually exclusive selection: either | or"},  	{.ln = "quiet", .sh = 'q', .type = HXOPT_DEC, .ptr = &opt_v,  	 .cb = opt_cbf, .help = "Decrease verbosity"}, +	{.ln = "quack", .type = HXOPT_INC, .ptr = &opt_v, +	 .cb = opt_cbf, .help = "Increase verbosity"},  	{.ln = "verbose", .sh = 'v', .type = HXOPT_INC, .ptr = &opt_v,  	 .cb = opt_cbf, .help = "Increase verbosity"},  	{.sh = 'A', .type = HXTYPE_INT | HXOPT_AND, .ptr = &opt_mask, diff --git a/src/tc-string.c b/src/tc-string.c index 826a9a0..112a845 100644 --- a/src/tc-string.c +++ b/src/tc-string.c @@ -12,12 +12,14 @@  #	include <stddef.h>  #	include <stdio.h>  #	include <stdlib.h> +#	include <time.h>  #else  #	include <cassert>  #	include <cerrno>  #	include <cstddef>  #	include <cstdio>  #	include <cstdlib> +#	include <ctime>  #endif  #include <libHX/defs.h>  #include <libHX/init.h> @@ -194,6 +196,89 @@ static void t_split2(void)  	HX_zvecfree(a);  } +/* avoid these being inlined */ +extern char *f_strlcpy_str(char *, const char *, size_t); +extern char *f_strlcpy_mem(char *, const char *, size_t); + +EXPORT_SYMBOL char *f_strlcpy_str(char *d, const char *s, size_t n) +{ +	strncpy(d, s, n); +	d[n-1] = '\0'; +	return d; +} + +EXPORT_SYMBOL char *f_strlcpy_mem(char *dest, const char *src, size_t dsize) +{ +	size_t slen = strlen(src); +	if (slen < dsize) +		return static_cast(char *, memcpy(dest, src, slen + 1)); +	if (dsize > 0) { +		memcpy(dest, src, dsize - 1); +		dest[dsize-1] = '\0'; +	} +	return dest; +} + +static const char s_lorem_ipsum[] = /* 1368 chars */ +"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo " +"ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis " +"parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, " +"pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec " +"pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, " +"rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede " +"mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper " +"nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, " +"consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra " +"quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. " +"Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur " +"ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, " +"tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing " +"sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit " +"id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut " +"libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros " +"faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec " +"sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit " +"cursus nunc,"; + +static void t_strlcpy(void) +{ +	static const size_t picksizes[] = +		{4, 8, 16, 32, 64, 80, 128, 256, 1024, 2048}; +	char ibuf[2048], obuf[2048]; +	size_t ipick, opick, k, runs = 10000000 + HX_irand(0, 1); +	struct timespec start, stop, d1, d2, d3; + +	for (ipick = 0; ipick < ARRAY_SIZE(picksizes); ++ipick) { +		/* Select string size */ +		HX_strlcpy(ibuf, s_lorem_ipsum, picksizes[ipick]); + +		for (opick = 0; opick < ARRAY_SIZE(picksizes); ++opick) { +			/* Select buffer size */ +			clock_gettime(CLOCK_MONOTONIC, &start); +			for (k = 0; k < runs; ++k) +				f_strlcpy_str(reinterpret_cast(char *, obuf), +					ibuf, picksizes[opick]); +			clock_gettime(CLOCK_MONOTONIC, &stop); +			HX_timespec_sub(&d1, &stop, &start); + +			clock_gettime(CLOCK_MONOTONIC, &start); +			for (k = 0; k < runs; ++k) +				f_strlcpy_mem(reinterpret_cast(char *, obuf), +					ibuf, picksizes[opick]); +			clock_gettime(CLOCK_MONOTONIC, &stop); +			HX_timespec_sub(&d2, &stop, &start); + +			HX_timespec_sub(&d3, &d1, &d2); +			printf("%4zu->%4zu: %1ld.%09ld (str=%ld.%09ld mem=%ld.%09ld)\n", +				strlen(ibuf), picksizes[opick], +				static_cast(long, d3.tv_sec), d3.tv_nsec, +				static_cast(long, d1.tv_sec), d1.tv_nsec, +				static_cast(long, d2.tv_sec), d2.tv_nsec +				); +		} +	} +} +  int main(int argc, const char **argv)  {  	hxmc_t *tx = NULL; @@ -222,6 +307,7 @@ int main(int argc, const char **argv)  	t_strtrim();  	t_split();  	t_split2(); +	t_strlcpy();  	HXmc_free(tx);  	HX_exit();  	return EXIT_SUCCESS; | 
