summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in33
-rw-r--r--src/internal.h1
-rw-r--r--src/io.c15
-rw-r--r--src/map.c192
-rw-r--r--src/map_int.h20
-rw-r--r--src/opt.c40
-rw-r--r--src/tc-cast.c4
-rw-r--r--src/tc-format.c2
-rw-r--r--src/tc-map.c21
-rw-r--r--src/tc-option.c2
-rw-r--r--src/tc-string.c86
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
diff --git a/src/io.c b/src/io.c
index 6d664d1..6616e88 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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
}
diff --git a/src/map.c b/src/map.c
index c1f332e..38f0d34 100644
--- a/src/map.c
+++ b/src/map.c
@@ -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;
};
diff --git a/src/opt.c b/src/opt.c
index 0326f89..d64e521 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -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;