summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2021-04-06 03:40:06 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2021-04-06 03:40:06 (GMT)
commit847be78dbec1116c5b9be6207dba5253b75da323 (patch)
treee3ab03849bcb1bf76db4628e7c93bf7cd93464c6
parentf0d1a03aa18843b8260c234cd535978a2145941e (diff)
downloadhdf5-847be78dbec1116c5b9be6207dba5253b75da323.zip
hdf5-847be78dbec1116c5b9be6207dba5253b75da323.tar.gz
hdf5-847be78dbec1116c5b9be6207dba5253b75da323.tar.bz2
Brings H5RS changes from develop
-rw-r--r--MANIFEST1
-rw-r--r--src/H5Gname.c282
-rw-r--r--src/H5RS.c524
-rw-r--r--src/H5RSmodule.h32
-rw-r--r--src/H5RSprivate.h6
-rw-r--r--test/trefstr.c246
6 files changed, 746 insertions, 345 deletions
diff --git a/MANIFEST b/MANIFEST
index bc8ac15..12ffa30 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -949,6 +949,7 @@
./src/H5UC.c
./src/H5UCprivate.h
./src/H5RS.c
+./src/H5RSmodule.h
./src/H5RSprivate.h
./src/H5S.c
./src/H5Sall.c
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 8020d86..fd63cbb 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -77,22 +77,16 @@ typedef struct H5G_gnba_iter_t {
/* Local Prototypes */
/********************/
-static htri_t H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r);
-static H5RS_str_t *H5G_build_fullpath(const char *prefix, const char *name);
-#ifdef NOT_YET
-static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r);
-#endif /* NOT_YET */
-static herr_t H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char *src_path,
- const char *dst_path);
-static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key);
+static htri_t H5G__common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r);
+static H5RS_str_t *H5G__build_fullpath(const char *prefix, const char *name);
+static herr_t H5G__name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char *src_path,
+ const char *dst_path);
+static int H5G__name_replace_cb(void *obj_ptr, hid_t obj_id, void *key);
/*********************/
/* Package Variables */
/*********************/
-/* Declare extern the PQ free list for the wrapped strings */
-H5FL_BLK_EXTERN(str_buf);
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -197,7 +191,7 @@ done:
} /* end H5G_normalize() */
/*-------------------------------------------------------------------------
- * Function: H5G_common_path
+ * Function: H5G__common_path
*
* Purpose: Determine if one path is a valid prefix of another path
*
@@ -211,14 +205,14 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
+H5G__common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
{
const char *fullpath; /* Pointer to actual fullpath string */
const char *prefix; /* Pointer to actual prefix string */
size_t nchars1, nchars2; /* Number of characters in components */
htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC_NOERR
/* Get component of each name */
fullpath = H5RS_get_str(fullpath_r);
@@ -259,10 +253,10 @@ H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_common_path() */
+} /* end H5G__common_path() */
/*-------------------------------------------------------------------------
- * Function: H5G_build_fullpath
+ * Function: H5G__build_fullpath
*
* Purpose: Build a full path from a prefix & base pair of strings
*
@@ -275,51 +269,26 @@ done:
*-------------------------------------------------------------------------
*/
static H5RS_str_t *
-H5G_build_fullpath(const char *prefix, const char *name)
+H5G__build_fullpath(const char *prefix, const char *name)
{
- char * full_path; /* Full user path built */
- size_t orig_path_len; /* Original length of the path */
- size_t path_len; /* Length of the path */
- size_t name_len; /* Length of the name */
- unsigned need_sep; /* Flag to indicate if separator is needed */
H5RS_str_t *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(prefix);
HDassert(name);
- /* Get the length of the prefix */
- orig_path_len = path_len = HDstrlen(prefix);
-
- /* Determine if there is a trailing separator in the name */
- if (prefix[path_len - 1] == '/')
- need_sep = 0;
- else
- need_sep = 1;
-
- /* Add in the length needed for the '/' separator and the relative path */
- name_len = HDstrlen(name);
- path_len += name_len + need_sep;
-
- /* Allocate space for the path */
- if (NULL == (full_path = (char *)H5FL_BLK_MALLOC(str_buf, path_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Build full path */
- HDstrncpy(full_path, prefix, orig_path_len + 1);
- if (need_sep)
- HDstrncat(full_path, "/", (size_t)1);
- HDstrncat(full_path, name, name_len);
-
- /* Create reference counted string for path */
- if (NULL == (ret_value = H5RS_own(full_path)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Create full path */
+ if (NULL == (ret_value = H5RS_create(prefix)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, NULL, "can't create ref-counted string")
+ if (prefix[HDstrlen(prefix) - 1] != '/')
+ H5RS_aputc(ret_value, '/'); /* Add separator, if the prefix doesn't end in one */
+ H5RS_acat(ret_value, name);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_build_fullpath() */
+} /* end H5G__build_fullpath() */
/*-------------------------------------------------------------------------
* Function: H5G_build_fullpath_refstr_str
@@ -350,49 +319,11 @@ H5G_build_fullpath_refstr_str(H5RS_str_t *prefix_r, const char *name)
HDassert(prefix);
/* Create reference counted string for path */
- ret_value = H5G_build_fullpath(prefix, name);
+ ret_value = H5G__build_fullpath(prefix, name);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_build_fullpath_refstr_str() */
-#ifdef NOT_YET
-
-/*-------------------------------------------------------------------------
- * Function: H5G_name_build_refstr_refstr
- *
- * Purpose: Build a full path from a prefix & base pair of reference counted
- * strings
- *
- * Return: Pointer to reference counted string on success, NULL on error
- *
- * Programmer: Quincey Koziol
- *
- * Date: August 19, 2005
- *
- *-------------------------------------------------------------------------
- */
-static H5RS_str_t *
-H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r)
-{
- const char *prefix; /* Pointer to raw string of prefix */
- const char *name; /* Pointer to raw string of name */
- H5RS_str_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Get the pointer to the prefix */
- prefix = H5RS_get_str(prefix_r);
-
- /* Get the pointer to the raw src user path */
- name = H5RS_get_str(name_r);
-
- /* Create reference counted string for path */
- ret_value = H5G_build_fullpath(prefix, name);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_build_fullpath_refstr_refstr() */
-#endif /* NOT_YET */
-
/*-------------------------------------------------------------------------
* Function: H5G__name_init
*
@@ -643,7 +574,7 @@ H5G_name_free(H5G_name_t *name)
} /* end H5G_name_free() */
/*-------------------------------------------------------------------------
- * Function: H5G_name_move_path
+ * Function: H5G__name_move_path
*
* Purpose: Update a user or canonical path after an object moves
*
@@ -656,15 +587,15 @@ H5G_name_free(H5G_name_t *name)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char *src_path,
- const char *dst_path)
+H5G__name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char *src_path,
+ const char *dst_path)
{
const char *path; /* Path to update */
size_t path_len; /* Length of path */
size_t full_suffix_len; /* Length of full suffix */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Check arguments */
HDassert(path_r_ptr && *path_r_ptr);
@@ -681,27 +612,23 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
path_len = HDstrlen(path);
if (full_suffix_len < path_len) {
const char *dst_suffix; /* Destination suffix that changes */
- size_t dst_suffix_len; /* Length of destination suffix */
const char *src_suffix; /* Source suffix that changes */
size_t path_prefix_len; /* Length of path prefix */
const char *path_prefix2; /* 2nd prefix for path */
size_t path_prefix2_len; /* Length of 2nd path prefix */
- const char *common_prefix; /* Common prefix for src & dst paths */
size_t common_prefix_len; /* Length of common prefix */
- char * new_path; /* Pointer to new path */
- size_t new_path_len; /* Length of new path */
+ H5RS_str_t *rs; /* Ref-counted string for new path */
- /* Compute path prefix before full suffix*/
+ /* Compute path prefix before full suffix */
path_prefix_len = path_len - full_suffix_len;
/* Determine the common prefix for src & dst paths */
- common_prefix = src_path;
common_prefix_len = 0;
/* Find first character that is different */
while (*(src_path + common_prefix_len) == *(dst_path + common_prefix_len))
common_prefix_len++;
/* Back up to previous '/' */
- while (*(common_prefix + common_prefix_len) != '/')
+ while (*(src_path + common_prefix_len) != '/')
common_prefix_len--;
/* Include '/' */
common_prefix_len++;
@@ -710,41 +637,36 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char
src_suffix = src_path + (common_prefix_len - 1);
/* Determine destination suffix */
- dst_suffix = dst_path + (common_prefix_len - 1);
- dst_suffix_len = HDstrlen(dst_suffix);
+ dst_suffix = dst_path + (common_prefix_len - 1);
- /* Compute path prefix before src suffix*/
+ /* Compute path prefix before src suffix */
path_prefix2 = path;
path_prefix2_len = path_prefix_len - HDstrlen(src_suffix);
- /* Allocate space for the new path */
- new_path_len = path_prefix2_len + dst_suffix_len + full_suffix_len;
- if (NULL == (new_path = (char *)H5FL_BLK_MALLOC(str_buf, new_path_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Allocate new ref-counted string */
+ if (NULL == (rs = H5RS_create(NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create ref-counted string")
/* Create the new path */
- if (path_prefix2_len > 0) {
- HDstrncpy(new_path, path_prefix2, path_prefix2_len + 1);
- HDstrncpy(new_path + path_prefix2_len, dst_suffix, dst_suffix_len + 1);
- } /* end if */
- else
- HDstrncpy(new_path, dst_suffix, dst_suffix_len + 1);
+ if (path_prefix2_len > 0)
+ H5RS_ancat(rs, path_prefix2, path_prefix2_len);
+ H5RS_acat(rs, dst_suffix);
if (full_suffix_len > 0)
- HDstrncat(new_path, full_suffix, full_suffix_len);
+ H5RS_acat(rs, full_suffix);
/* Release previous path */
H5RS_decr(*path_r_ptr);
/* Take ownership of the new full path */
- *path_r_ptr = H5RS_own(new_path);
+ *path_r_ptr = rs;
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_name_move_path() */
+} /* end H5G__name_move_path() */
/*-------------------------------------------------------------------------
- * Function: H5G_name_replace_cb
+ * Function: H5G__name_replace_cb
*
* Purpose: H5I_iterate callback function to replace group entry names
*
@@ -757,7 +679,7 @@ done:
*-------------------------------------------------------------------------
*/
static int
-H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
+H5G__name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
{
const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */
H5O_loc_t * oloc; /* Object location for object that the ID refers to */
@@ -766,7 +688,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
hbool_t obj_in_child = FALSE; /* Flag to indicate that the object is in the child mount hier. */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
HDassert(obj_ptr);
@@ -853,39 +775,30 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
case H5G_NAME_MOUNT:
/* Check if object is in child mount hier. */
if (obj_in_child) {
- const char *full_path; /* Full path of current object */
- const char *src_path; /* Full path of source object */
- size_t src_path_len; /* Length of source full path */
- char * new_full_path; /* New full path of object */
- size_t new_full_len; /* Length of new full path */
+ const char *full_path; /* Full path of current object */
+ const char *src_path; /* Full path of source object */
+ H5RS_str_t *rs; /* Ref-counted string for new path */
/* Get pointers to paths of interest */
- full_path = H5RS_get_str(obj_path->full_path_r);
- src_path = H5RS_get_str(names->src_full_path_r);
- src_path_len = HDstrlen(src_path);
-
- /* Build new full path */
-
- /* Allocate space for the new full path */
- new_full_len = src_path_len + HDstrlen(full_path);
- if (NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, new_full_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ full_path = H5RS_get_str(obj_path->full_path_r);
+ src_path = H5RS_get_str(names->src_full_path_r);
- /* Create the new full path */
- HDstrncpy(new_full_path, src_path, src_path_len + 1);
- HDstrncat(new_full_path, full_path, new_full_len);
+ /* Create new full path */
+ if (NULL == (rs = H5RS_create(src_path)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create ref-counted string")
+ H5RS_acat(rs, full_path);
/* Release previous full path */
H5RS_decr(obj_path->full_path_r);
/* Take ownership of the new full path */
- obj_path->full_path_r = H5RS_own(new_full_path);
+ obj_path->full_path_r = rs;
} /* end if */
/* Object must be in parent mount file hier. */
else {
/* Check if the source is along the entry's path */
/* (But not actually the entry itself) */
- if (H5G_common_path(obj_path->full_path_r, names->src_full_path_r) &&
+ if (H5G__common_path(obj_path->full_path_r, names->src_full_path_r) &&
H5RS_cmp(obj_path->full_path_r, names->src_full_path_r)) {
/* Hide the user path */
(obj_path->obj_hidden)++;
@@ -899,36 +812,30 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
*/
case H5G_NAME_UNMOUNT:
if (obj_in_child) {
- const char *full_path; /* Full path of current object */
- const char *full_suffix; /* Full path after source path */
- size_t full_suffix_len; /* Length of full path after source path */
- const char *src_path; /* Full path of source object */
- char * new_full_path; /* New full path of object */
+ const char *full_path; /* Full path of current object */
+ const char *full_suffix; /* Full path after source path */
+ const char *src_path; /* Full path of source object */
+ H5RS_str_t *rs; /* Ref-counted string for new path */
/* Get pointers to paths of interest */
full_path = H5RS_get_str(obj_path->full_path_r);
src_path = H5RS_get_str(names->src_full_path_r);
/* Construct full path suffix */
- full_suffix = full_path + HDstrlen(src_path);
- full_suffix_len = HDstrlen(full_suffix);
+ full_suffix = full_path + HDstrlen(src_path);
- /* Build new full path */
-
- /* Create the new full path */
- if (NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, full_suffix_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDstrncpy(new_full_path, full_suffix, full_suffix_len + 1);
+ /* Create new full path suffix */
+ if (NULL == (rs = H5RS_create(full_suffix)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create ref-counted string")
/* Release previous full path */
H5RS_decr(obj_path->full_path_r);
/* Take ownership of the new full path */
- obj_path->full_path_r = H5RS_own(new_full_path);
+ obj_path->full_path_r = rs;
/* Check if the object's user path should be invalidated */
- if (obj_path->user_path_r &&
- HDstrlen(new_full_path) < (size_t)H5RS_len(obj_path->user_path_r)) {
+ if (obj_path->user_path_r && H5RS_len(rs) < H5RS_len(obj_path->user_path_r)) {
/* Free user path */
H5RS_decr(obj_path->user_path_r);
obj_path->user_path_r = NULL;
@@ -936,7 +843,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
} /* end if */
else {
/* Check if file being unmounted was hiding the object */
- if (H5G_common_path(obj_path->full_path_r, names->src_full_path_r) &&
+ if (H5G__common_path(obj_path->full_path_r, names->src_full_path_r) &&
H5RS_cmp(obj_path->full_path_r, names->src_full_path_r)) {
/* Un-hide the user path */
(obj_path->obj_hidden)--;
@@ -950,7 +857,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
*/
case H5G_NAME_DELETE:
/* Check if the location being unlinked is in the path for the current object */
- if (H5G_common_path(obj_path->full_path_r, names->src_full_path_r)) {
+ if (H5G__common_path(obj_path->full_path_r, names->src_full_path_r)) {
/* Free paths for object */
H5G_name_free(obj_path);
} /* end if */
@@ -962,54 +869,43 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
*/
case H5G_NAME_MOVE: /* Link move case, check for relative names case */
/* Check if the src object moved is in the current object's path */
- if (H5G_common_path(obj_path->full_path_r, names->src_full_path_r)) {
- const char *full_path; /* Full path of current object */
- const char *full_suffix; /* Suffix of full path, after src_path */
- size_t full_suffix_len; /* Length of suffix of full path after src_path*/
- char * new_full_path; /* New full path of object */
- size_t new_full_len; /* Length of new full path */
- const char *src_path; /* Full path of source object */
- const char *dst_path; /* Full path of destination object */
- size_t dst_path_len; /* Length of destination's full path */
+ if (H5G__common_path(obj_path->full_path_r, names->src_full_path_r)) {
+ const char *full_path; /* Full path of current object */
+ const char *full_suffix; /* Suffix of full path, after src_path */
+ const char *src_path; /* Full path of source object */
+ const char *dst_path; /* Full path of destination object */
+ H5RS_str_t *rs; /* Ref-counted string for new path */
/* Sanity check */
HDassert(names->dst_full_path_r);
/* Get pointers to paths of interest */
- full_path = H5RS_get_str(obj_path->full_path_r);
- src_path = H5RS_get_str(names->src_full_path_r);
- dst_path = H5RS_get_str(names->dst_full_path_r);
- dst_path_len = HDstrlen(dst_path);
+ full_path = H5RS_get_str(obj_path->full_path_r);
+ src_path = H5RS_get_str(names->src_full_path_r);
+ dst_path = H5RS_get_str(names->dst_full_path_r);
/* Make certain that the source and destination names are full (not relative) paths */
HDassert(*src_path == '/');
HDassert(*dst_path == '/');
/* Get pointer to "full suffix" */
- full_suffix = full_path + HDstrlen(src_path);
- full_suffix_len = HDstrlen(full_suffix);
+ full_suffix = full_path + HDstrlen(src_path);
/* Update the user path, if one exists */
if (obj_path->user_path_r)
- if (H5G_name_move_path(&(obj_path->user_path_r), full_suffix, src_path, dst_path) < 0)
+ if (H5G__name_move_path(&(obj_path->user_path_r), full_suffix, src_path, dst_path) < 0)
HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build user path name")
- /* Build new full path */
-
- /* Allocate space for the new full path */
- new_full_len = dst_path_len + full_suffix_len;
- if (NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, new_full_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Create the new full path */
- HDstrncpy(new_full_path, dst_path, dst_path_len + 1);
- HDstrncat(new_full_path, full_suffix, full_suffix_len);
+ /* Create new full path */
+ if (NULL == (rs = H5RS_create(dst_path)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create ref-counted string")
+ H5RS_acat(rs, full_suffix);
/* Release previous full path */
H5RS_decr(obj_path->full_path_r);
/* Take ownership of the new full path */
- obj_path->full_path_r = H5RS_own(new_full_path);
+ obj_path->full_path_r = rs;
} /* end if */
break;
@@ -1019,7 +915,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5G_name_replace_cb() */
+} /* end H5G__name_replace_cb() */
/*-------------------------------------------------------------------------
* Function: H5G_name_replace
@@ -1144,17 +1040,17 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, H5RS
/* Search through group IDs */
if (search_group)
- if (H5I_iterate(H5I_GROUP, H5G_name_replace_cb, &names, FALSE) < 0)
+ if (H5I_iterate(H5I_GROUP, H5G__name_replace_cb, &names, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over groups")
/* Search through dataset IDs */
if (search_dataset)
- if (H5I_iterate(H5I_DATASET, H5G_name_replace_cb, &names, FALSE) < 0)
+ if (H5I_iterate(H5I_DATASET, H5G__name_replace_cb, &names, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datasets")
/* Search through datatype IDs */
if (search_datatype)
- if (H5I_iterate(H5I_DATATYPE, H5G_name_replace_cb, &names, FALSE) < 0)
+ if (H5I_iterate(H5I_DATATYPE, H5G__name_replace_cb, &names, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over datatypes")
} /* end if */
} /* end if */
@@ -1164,7 +1060,7 @@ done:
} /* end H5G_name_replace() */
/*-------------------------------------------------------------------------
- * Function: H5G_get_name_by_addr_cb
+ * Function: H5G__get_name_by_addr_cb
*
* Purpose: Callback for retrieving object's name by address
*
@@ -1178,7 +1074,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info2_t *linfo, void *_udata)
+H5G__get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info2_t *linfo, void *_udata)
{
H5G_gnba_iter_t *udata = (H5G_gnba_iter_t *)_udata; /* User data for iteration */
H5G_loc_t obj_loc; /* Location of object */
@@ -1187,7 +1083,7 @@ H5G_get_name_by_addr_cb(hid_t gid, const char *path, const H5L_info2_t *linfo, v
hbool_t obj_found = FALSE; /* Object at 'path' found */
herr_t ret_value = H5_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Sanity check */
HDassert(path);
@@ -1237,7 +1133,7 @@ done:
HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_get_name_by_addr_cb() */
+} /* end H5G__get_name_by_addr_cb() */
/*-------------------------------------------------------------------------
* Function: H5G_get_name_by_addr
@@ -1285,7 +1181,7 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size)
udata.path = NULL;
/* Visit all the links in the file */
- if ((status = H5G_visit(&root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G_get_name_by_addr_cb,
+ if ((status = H5G_visit(&root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G__get_name_by_addr_cb,
&udata)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, (-1), "group traversal failed while looking for object name")
else if (status > 0)
diff --git a/src/H5RS.c b/src/H5RS.c
index 77fa414..96d55e7 100644
--- a/src/H5RS.c
+++ b/src/H5RS.c
@@ -15,37 +15,89 @@
* Reference counted string algorithms.
*
* These are used for various internal strings which get copied multiple times.
+ * They also efficiently handle dynamically allocations and appends.
*
*/
-#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free lists */
-#include "H5RSprivate.h" /* Reference-counted strings */
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5RSmodule.h" /* This source code file is part of the H5RS module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5RSprivate.h" /* Reference-counted strings */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Initial buffer size to allocate */
+#define H5RS_ALLOC_SIZE 256
+
+/******************/
+/* Local Typedefs */
+/******************/
/* Private typedefs & structs */
struct H5RS_str_t {
char * s; /* String to be reference counted */
- unsigned wrapped; /* Indicates that the string to be ref-counted is not copied */
+ char * end; /* Pointer to terminating NUL character at the end of the string */
+ size_t len; /* Current length of the string */
+ size_t max; /* Size of allocated buffer */
+ hbool_t wrapped; /* Indicates that the string to be ref-counted is not copied */
unsigned n; /* Reference count of number of pointers sharing string */
};
+/********************/
+/* Package Typedefs */
+/********************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5RS__xstrdup(H5RS_str_t *rs, const char *s);
+static herr_t H5RS__prepare_for_append(H5RS_str_t *rs);
+static herr_t H5RS__resize_for_append(H5RS_str_t *rs, size_t len);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
/* Declare a free list to manage the H5RS_str_t struct */
H5FL_DEFINE_STATIC(H5RS_str_t);
/* Declare the PQ free list for the wrapped strings */
-H5FL_BLK_DEFINE(str_buf);
+H5FL_BLK_DEFINE_STATIC(str_buf);
/*--------------------------------------------------------------------------
NAME
- H5RS_xstrdup
+ H5RS__xstrdup
PURPOSE
Duplicate the string being reference counted
USAGE
- char *H5RS_xstrdup(s)
+ herr_t H5RS__xstrdup(rs, s)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to hold duplicated string
const char *s; IN: String to duplicate
RETURNS
- Returns a pointer to a new string on success, NULL on failure.
+ Non-negative on success/Negative on failure
DESCRIPTION
Duplicate a string buffer being reference counted. Use this instead of
[H5MM_][x]strdup, in order to use the free-list memory routines.
@@ -54,25 +106,145 @@ H5FL_BLK_DEFINE(str_buf);
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static char *
-H5RS_xstrdup(const char *s)
+static herr_t
+H5RS__xstrdup(H5RS_str_t *rs, const char *s)
{
- char *ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(rs);
if (s) {
- size_t len = HDstrlen(s) + 1;
+ size_t len = HDstrlen(s);
+
+ /* Determine size of buffer to allocate */
+ rs->max = H5RS_ALLOC_SIZE;
+ while ((len + 1) > rs->max)
+ rs->max *= 2;
+
+ /* Allocate the underlying string */
+ if (NULL == (rs->s = (char *)H5FL_BLK_MALLOC(str_buf, rs->max)))
+ HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ if (len)
+ HDmemcpy(rs->s, s, len);
+ rs->end = rs->s + len;
+ *rs->end = '\0';
+ rs->len = len;
+ } /* end if */
+ else {
+ /* Free previous string, if one */
+ if (rs->s) {
+ H5FL_BLK_FREE(str_buf, rs->s);
+ rs->s = rs->end = NULL;
+ rs->max = rs->len = 0;
+ } /* end if */
+ else {
+ /* Sanity checks */
+ HDassert(NULL == rs->end);
+ HDassert(0 == rs->max);
+ HDassert(0 == rs->len);
+ } /* end else */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS__xstrdup() */
- ret_value = (char *)H5FL_BLK_MALLOC(str_buf, len);
- HDassert(ret_value);
- HDstrncpy(ret_value, s, len);
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS__prepare_for_append
+ PURPOSE
+ Prepare a ref-counted string for an append
+ USAGE
+ herr_t H5RS__prepare_for_append(rs)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to hold duplicated string
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Allocate space for a string, or duplicate a wrapped string, in preparation
+ for appending another string.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5RS__prepare_for_append(H5RS_str_t *rs)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(rs);
+
+ if (NULL == rs->s) {
+ rs->max = H5RS_ALLOC_SIZE;
+ if (NULL == (rs->s = (char *)H5FL_BLK_MALLOC(str_buf, rs->max)))
+ HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ rs->end = rs->s;
+ *rs->s = '\0';
+ rs->len = 0;
} /* end if */
- else
- ret_value = NULL;
+ else {
+ /* If the ref-counted string started life as a wrapper around an
+ * existing string, duplicate the string now, so we can modify it.
+ */
+ if (rs->wrapped) {
+ if (H5RS__xstrdup(rs, rs->s) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTCOPY, FAIL, "can't copy string")
+ rs->wrapped = FALSE;
+ } /* end if */
+ } /* end else */
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5RS_xstrdup() */
+} /* end H5RS__prepare_for_append() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5RS__resize_for_append
+ PURPOSE
+ Resize ref-counted string buffer to accommodate appending another string
+ USAGE
+ herr_t H5RS__resize_for_append(rs, len)
+ H5RS_str_t *rs; IN/OUT: Ref-counted string to hold duplicated string
+ size_t len; IN: Additional length to accommodate
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Resize a ref-counted string buffer to be large enough to accommodate
+ another string of a specified length.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5RS__resize_for_append(H5RS_str_t *rs, size_t len)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(rs);
+
+ /* Check if buffer should be re-allocated */
+ if (len >= (rs->max - rs->len)) {
+ /* Allocate a large enough buffer */
+ while (len >= (rs->max - rs->len))
+ rs->max *= 2;
+ if (NULL == (rs->s = (char *)H5FL_BLK_REALLOC(str_buf, rs->s, rs->max)))
+ HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ rs->end = rs->s + rs->len;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS__resize() */
/*--------------------------------------------------------------------------
NAME
@@ -96,18 +268,19 @@ H5RS_xstrdup(const char *s)
H5RS_str_t *
H5RS_create(const char *s)
{
- H5RS_str_t *ret_value; /* Return value */
+ H5RS_str_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
/* Allocate ref-counted string structure */
- if (NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
- HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
+ if (NULL == (ret_value = H5FL_CALLOC(H5RS_str_t)))
+ HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s = H5RS_xstrdup(s);
- ret_value->wrapped = 0;
- ret_value->n = 1;
+ if (s)
+ if (H5RS__xstrdup(ret_value, s) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTCOPY, NULL, "can't copy string")
+ ret_value->n = 1;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -135,63 +308,233 @@ done:
H5RS_str_t *
H5RS_wrap(const char *s)
{
- H5RS_str_t *ret_value; /* Return value */
+ H5RS_str_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(NULL)
/* Allocate ref-counted string structure */
if (NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
- HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_RS, H5E_CANTALLOC, NULL, "memory allocation failed")
/* Set the internal fields */
- ret_value->s = (char *)s;
- ret_value->wrapped = 1;
+ ret_value->s = (char *)s;
+ ret_value->len = HDstrlen(s);
+ ret_value->end = ret_value->s + ret_value->len;
+
+ ret_value->wrapped = TRUE;
+ ret_value->max = 0; /* Wrapped, not allocated */
ret_value->n = 1;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_wrap() */
-/*--------------------------------------------------------------------------
- NAME
- H5RS_own
- PURPOSE
- Transfer ownership of a regular string to a reference counted string
- USAGE
- H5RS_str_t *H5RS_own(s)
- const char *s; IN: String to transfer ownership of
+/*-------------------------------------------------------------------------
+ * Function: H5RS_asprintf_cat
+ *
+ * Purpose: This function appends formatted output to a ref-counted string,
+ * allocating the managed string if necessary. The formatting
+ * string is printf() compatible.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+/* Disable warning for "format not a string literal" here -QAK */
+/*
+ * This pragma only needs to surround the sprintf() calls with
+ * format_templ in the code below, but early (4.4.7, at least) gcc only
+ * allows diagnostic pragmas to be toggled outside of functions.
+ */
+H5_GCC_DIAG_OFF("format-nonliteral")
+H5_ATTR_FORMAT(printf, 2, 3)
+herr_t
+H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...)
+{
+ va_list args1, args2;
+ size_t out_len;
+ herr_t ret_value = SUCCEED; /* Return value */
- RETURNS
- Returns a pointer to a new ref-counted string on success, NULL on failure.
- DESCRIPTION
- Transfer ownership of a dynamically allocated string to a reference counted
- string. The routine which passed in the string should not attempt to free
- it, the reference counting string routines will do that when the reference
- count drops to zero.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-H5RS_str_t *
-H5RS_own(char *s)
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(rs);
+ HDassert(fmt);
+
+ /* Prepare the [possibly wrapped or empty] ref-counted string for an append */
+ if (H5RS__prepare_for_append(rs) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTINIT, FAIL, "can't initialize ref-counted string")
+
+ /* Attempt to write formatted output into the managed string */
+ HDva_start(args1, fmt);
+ HDva_copy(args2, args1);
+ while ((out_len = (size_t)HDvsnprintf(rs->end, (rs->max - rs->len), fmt, args1)) >= (rs->max - rs->len)) {
+ /* Allocate a large enough buffer */
+ if (H5RS__resize_for_append(rs, out_len) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTRESIZE, FAIL, "can't resize ref-counted string buffer")
+
+ /* Restart the va_list */
+ HDva_end(args1);
+ HDva_copy(args1, args2);
+ } /* end while */
+
+ /* Increment the size & end of the string */
+ rs->len += out_len;
+ rs->end += out_len;
+
+ /* Finish access to varargs */
+ HDva_end(args1);
+ HDva_end(args2);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS_asprintf_cat() */
+H5_GCC_DIAG_ON("format-nonliteral")
+
+/*-------------------------------------------------------------------------
+ * Function: H5RS_acat
+ *
+ * Purpose: This function appends a character string to a ref-counted string,
+ * allocating the managed string if necessary.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RS_acat(H5RS_str_t *rs, const char *s)
{
- H5RS_str_t *ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI(FAIL)
- /* Allocate ref-counted string structure */
- if (NULL == (ret_value = H5FL_MALLOC(H5RS_str_t)))
- HGOTO_ERROR(H5E_RS, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Sanity checks */
+ HDassert(rs);
+ HDassert(s);
- /* Set the internal fields */
- ret_value->s = s;
- ret_value->wrapped = 0;
- ret_value->n = 1;
+ /* Concatenate the provided string on to the managed string */
+ if (*s) {
+ size_t len = HDstrlen(s);
+
+ /* Allocate the underlying string, if necessary */
+ if (H5RS__prepare_for_append(rs) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTINIT, FAIL, "can't initialize ref-counted string")
+
+ /* Increase the managed string's buffer size if necessary */
+ if ((rs->len + len) >= rs->max)
+ if (H5RS__resize_for_append(rs, len) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTRESIZE, FAIL, "can't resize ref-counted string buffer")
+
+ /* Append the string */
+ HDmemcpy(rs->end, s, len);
+ rs->end += len;
+ *rs->end = '\0';
+ rs->len += len;
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5RS_own() */
+} /* end H5RS_acat() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5RS_ancat
+ *
+ * Purpose: This function appends at most 'n' characters from a string
+ * to a ref-counted string, allocating the managed string if
+ * necessary.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RS_ancat(H5RS_str_t *rs, const char *s, size_t n)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(rs);
+ HDassert(s);
+
+ /* Concatenate the provided string on to the managed string */
+ if (n && *s) {
+ size_t len = HDstrlen(s);
+
+ /* Limit characters to copy to the minimum of 'n' and 'len' */
+ n = MIN(len, n);
+
+ /* Allocate the underlying string, if necessary */
+ if (H5RS__prepare_for_append(rs) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTINIT, FAIL, "can't initialize ref-counted string")
+
+ /* Increase the managed string's buffer size if necessary */
+ if ((rs->len + n) >= rs->max)
+ if (H5RS__resize_for_append(rs, n) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTRESIZE, FAIL, "can't resize ref-counted string buffer")
+
+ /* Append the string */
+ HDmemcpy(rs->end, s, n);
+ rs->end += n;
+ *rs->end = '\0';
+ rs->len += n;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS_ancat() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5RS_aputc
+ *
+ * Purpose: This function appends a character to a ref-counted string,
+ * allocating the managed string if necessary.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 18, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5RS_aputc(H5RS_str_t *rs, int c)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(rs);
+ HDassert(c);
+
+ /* Allocate the underlying string, if necessary */
+ if (H5RS__prepare_for_append(rs) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTINIT, FAIL, "can't initialize ref-counted string")
+
+ /* Increase the managed string's buffer size if necessary */
+ if ((rs->len + 1) >= rs->max)
+ if (H5RS__resize_for_append(rs, 1) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTRESIZE, FAIL, "can't resize ref-counted string buffer")
+
+ /* Append the current character */
+ *rs->end++ = (char)c;
+ rs->len++;
+ *rs->end = '\0';
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS_aputc() */
/*--------------------------------------------------------------------------
NAME
@@ -252,7 +595,9 @@ H5RS_decr(H5RS_str_t *rs)
herr_t
H5RS_incr(H5RS_str_t *rs)
{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
HDassert(rs);
@@ -263,14 +608,16 @@ H5RS_incr(H5RS_str_t *rs)
* scope appropriately.
*/
if (rs->wrapped) {
- rs->s = H5RS_xstrdup(rs->s);
- rs->wrapped = 0;
+ if (H5RS__xstrdup(rs, rs->s) < 0)
+ HGOTO_ERROR(H5E_RS, H5E_CANTCOPY, FAIL, "can't copy string")
+ rs->wrapped = FALSE;
} /* end if */
/* Increment reference count for string */
rs->n++;
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_incr() */
/*--------------------------------------------------------------------------
@@ -307,53 +654,6 @@ H5RS_dup(H5RS_str_t *ret_value)
/*--------------------------------------------------------------------------
NAME
- H5RS_dup_str
- PURPOSE
- "Duplicate" a regular string into a ref-counted string
- USAGE
- H5RS_str_t H5RS_dup_str(s)
- const char *s; IN: Regular string to duplicate
-
- RETURNS
- Returns a pointer to ref-counted string on success, NULL on failure.
- DESCRIPTION
- Duplicate a regular string into a ref-counted string.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-H5RS_str_t *
-H5RS_dup_str(const char *s)
-{
- char * new_str; /* Duplicate of string */
- size_t path_len; /* Length of the path */
- H5RS_str_t *ret_value;
-
- FUNC_ENTER_NOAPI(NULL)
-
- /* Sanity check */
- HDassert(s);
-
- /* Get the length of the string */
- path_len = HDstrlen(s);
-
- /* Allocate space for the string */
- if (NULL == (new_str = (char *)H5FL_BLK_MALLOC(str_buf, path_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Copy name for full path */
- HDstrncpy(new_str, s, (path_len + 1));
-
- /* Create reference counted string for path */
- ret_value = H5RS_own(new_str);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5RS_dup_str() */
-
-/*--------------------------------------------------------------------------
- NAME
H5RS_cmp
PURPOSE
Compare two ref-counted strings
diff --git a/src/H5RSmodule.h b/src/H5RSmodule.h
new file mode 100644
index 0000000..17977c7
--- /dev/null
+++ b/src/H5RSmodule.h
@@ -0,0 +1,32 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://www.hdfgroup.org/licenses. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol
+ * Saturday, October 10, 2020
+ *
+ * Purpose: This file contains declarations which define macros for the
+ * H5RS package. Including this header means that the source file
+ * is part of the H5RS package.
+ */
+#ifndef H5RSmodule_H
+#define H5RSmodule_H
+
+/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error
+ * reporting macros.
+ */
+#define H5RS_MODULE
+#define H5_MY_PKG H5RS
+#define H5_MY_PKG_ERR H5E_RS
+#define H5_MY_PKG_INIT NO
+
+#endif /* H5RSmodule_H */
diff --git a/src/H5RSprivate.h b/src/H5RSprivate.h
index 32e1dc6..7d2b728 100644
--- a/src/H5RSprivate.h
+++ b/src/H5RSprivate.h
@@ -45,11 +45,13 @@ typedef struct H5RS_str_t H5RS_str_t;
/********************/
H5_DLL H5RS_str_t *H5RS_create(const char *s);
H5_DLL H5RS_str_t *H5RS_wrap(const char *s);
-H5_DLL H5RS_str_t *H5RS_own(char *s);
H5_DLL herr_t H5RS_decr(H5RS_str_t *rs);
H5_DLL herr_t H5RS_incr(H5RS_str_t *rs);
H5_DLL H5RS_str_t *H5RS_dup(H5RS_str_t *s);
-H5_DLL H5RS_str_t *H5RS_dup_str(const char *s);
+H5_DLL herr_t H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...) H5_ATTR_FORMAT(printf, 2, 3);
+H5_DLL herr_t H5RS_acat(H5RS_str_t *rs, const char *s);
+H5_DLL herr_t H5RS_ancat(H5RS_str_t *rs, const char *s, size_t len);
+H5_DLL herr_t H5RS_aputc(H5RS_str_t *rs, int c);
H5_DLL int H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2);
H5_DLL ssize_t H5RS_len(const H5RS_str_t *rs);
H5_DLL char * H5RS_get_str(const H5RS_str_t *rs);
diff --git a/test/trefstr.c b/test/trefstr.c
index 049384f..a3f568a 100644
--- a/test/trefstr.c
+++ b/test/trefstr.c
@@ -265,7 +265,9 @@ test_refstr_wrap(void)
/* Get pointer to raw string in ref-counted string */
s = H5RS_get_str(rs);
CHECK_PTR(s, "H5RS_get_str");
- CHECK(s, buf, "wrapping");
+ if (s == buf)
+ TestErrPrintf("%d: Should not have gotten the same pointer from reference-counted string!\n",
+ __LINE__);
cmp = HDstrcmp(s, buf);
if (cmp <= 0)
TestErrPrintf("%d: string comparison incorrect!\n", __LINE__);
@@ -280,60 +282,225 @@ test_refstr_wrap(void)
/****************************************************************
**
-** test_refstr_own(): Test basic H5RS (ref-counted strings) code.
-** Tests transferring ownership of dynamically allocated strings
-** to ref-counted strings.
+** test_refstr_asprintf_cat(): Test basic H5RS (ref-counted strings) code.
+** Tests appending printf-formatted output to ref-counted strings.
**
****************************************************************/
static void
-test_refstr_own(void)
+test_refstr_asprintf_cat(void)
{
- H5RS_str_t *rs; /* Ref-counted string created */
- char * s; /* Pointer to string to transfer */
- const char *t; /* Temporary pointers to string */
- int cmp; /* Comparison value */
- herr_t ret; /* Generic return value */
+ H5RS_str_t *rs; /* Ref-counted string created */
+ const char *s; /* Pointer to raw string in ref-counted string */
+ char buf[256]; /* Buffer to compare against */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
/* Output message about test being performed */
- MESSAGE(5, ("Testing Transferring Ref-Counted Strings\n"));
+ MESSAGE(5, ("Testing Printf-formatted Output to Ref-Counted Strings\n"));
- /* Initialize buffer */
- s = (char *)H5FL_BLK_MALLOC(str_buf, HDstrlen("foo") + 1);
- CHECK_PTR(s, "H5FL_BLK_MALLOC");
- HDstrcpy(s, "foo");
+ /* Wrap ref-counted string around existing buffer */
+ rs = H5RS_create(NULL);
+ CHECK_PTR(rs, "H5RS_create");
- /* Transfer ownership of dynamically allocated string to ref-counted string */
- rs = H5RS_own(s);
- CHECK_PTR(rs, "H5RS_own");
+ /* Print initial output to ref-counted string */
+ ret = H5RS_asprintf_cat(rs, "%d-%s", (int)10, "foo");
+ CHECK(ret, FAIL, "H5RS_asprintf_cat");
/* Get pointer to raw string in ref-counted string */
- t = H5RS_get_str(rs);
- CHECK_PTR(t, "H5RS_get_str");
- CHECK_PTR_EQ(t, s, "transferring");
- cmp = HDstrcmp(s, t);
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDsprintf(buf, "%d-%s", (int)10, "foo");
+ cmp = HDstrcmp(s, buf);
VERIFY(cmp, 0, "HDstrcmp");
- /* Increment reference count (should NOT duplicate string) */
- ret = H5RS_incr(rs);
- CHECK(ret, FAIL, "H5RS_incr");
+ /* Append more output to ref-counted string */
+ ret = H5RS_asprintf_cat(rs, "-%f", (double)20.0);
+ CHECK(ret, FAIL, "H5RS_asprintf_cat");
- /* Change the buffer initially wrapped */
- *s = 'F';
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDsprintf(buf, "%d-%s-%f", (int)10, "foo", (double)20.0);
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Decrement reference count for string */
+ ret = H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+
+} /* end test_refstr_asprintf_cat() */
+
+/****************************************************************
+**
+** test_refstr_acat(): Test basic H5RS (ref-counted strings) code.
+** Tests appending strings to ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_acat(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ const char *s; /* Pointer to raw string in ref-counted string */
+ char buf[256]; /* Buffer to compare against */
+ char * large_str, *large_str2; /* Large strings to append */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Appending Strings to Ref-Counted Strings\n"));
+
+ /* Wrap ref-counted string around existing buffer */
+ rs = H5RS_create(NULL);
+ CHECK_PTR(rs, "H5RS_create");
+
+ /* Append first string to ref-counted string */
+ ret = H5RS_acat(rs, "foo");
+ CHECK(ret, FAIL, "H5RS_acat");
/* Get pointer to raw string in ref-counted string */
- t = H5RS_get_str(rs);
- CHECK_PTR(t, "H5RS_get_str");
- CHECK_PTR_EQ(t, s, "transferring");
- cmp = HDstrcmp(t, s);
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDsprintf(buf, "%s", "foo");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Append another string to ref-counted string */
+ ret = H5RS_acat(rs, "bar");
+ CHECK(ret, FAIL, "H5RS_acat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDsprintf(buf, "%s", "foobar");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Append a large string to ref-counted string */
+ large_str = HDmalloc(1024);
+ CHECK_PTR(large_str, "HDmalloc");
+ HDmemset(large_str, 'a', 1024);
+ large_str[1023] = '\0';
+ ret = H5RS_acat(rs, large_str);
+ CHECK(ret, FAIL, "H5RS_acat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDsprintf(buf, "%s", "foobar");
+ large_str2 = HDmalloc(1024 + 6);
+ CHECK_PTR(large_str2, "HDmalloc");
+ HDstrcpy(large_str2, "foobar");
+ HDmemset(&large_str2[6], 'a', 1024);
+ large_str2[1029] = '\0';
+ cmp = HDstrcmp(s, large_str2);
VERIFY(cmp, 0, "HDstrcmp");
/* Decrement reference count for string */
ret = H5RS_decr(rs);
CHECK(ret, FAIL, "H5RS_decr");
+
+ /* Free large strings */
+ HDfree(large_str);
+ HDfree(large_str2);
+} /* end test_refstr_acat() */
+
+/****************************************************************
+**
+** test_refstr_ancat(): Test basic H5RS (ref-counted strings) code.
+** Tests appending length-limited strings to ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_ancat(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ const char *s; /* Pointer to raw string in ref-counted string */
+ char buf[256]; /* Buffer to compare against */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Appending Strings to Ref-Counted Strings\n"));
+
+ /* Wrap ref-counted string around existing buffer */
+ rs = H5RS_create(NULL);
+ CHECK_PTR(rs, "H5RS_create");
+
+ /* Append first string to ref-counted string */
+ ret = H5RS_ancat(rs, "foo", 2);
+ CHECK(ret, FAIL, "H5RS_ancat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDstrcpy(buf, "fo");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Append another string to ref-counted string */
+ ret = H5RS_ancat(rs, "bar", 2);
+ CHECK(ret, FAIL, "H5RS_ancat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDstrcpy(buf, "foba");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Decrement reference count for string */
ret = H5RS_decr(rs);
CHECK(ret, FAIL, "H5RS_decr");
+} /* end test_refstr_ancat() */
+
+/****************************************************************
+**
+** test_refstr_aputc(): Test basic H5RS (ref-counted strings) code.
+** Tests appending characters to ref-counted strings.
+**
+****************************************************************/
+static void
+test_refstr_aputc(void)
+{
+ H5RS_str_t *rs; /* Ref-counted string created */
+ const char *s; /* Pointer to raw string in ref-counted string */
+ char buf[256]; /* Buffer to compare against */
+ int cmp; /* Comparison value */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Appending Strings to Ref-Counted Strings\n"));
-} /* end test_refstr_own() */
+ /* Wrap ref-counted string around existing buffer */
+ rs = H5RS_create(NULL);
+ CHECK_PTR(rs, "H5RS_create");
+
+ /* Append first character to ref-counted string */
+ ret = H5RS_aputc(rs, 'f');
+ CHECK(ret, FAIL, "H5RS_ancat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDstrcpy(buf, "f");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Append another character to ref-counted string */
+ ret = H5RS_aputc(rs, 'o');
+ CHECK(ret, FAIL, "H5RS_ancat");
+
+ /* Get pointer to raw string in ref-counted string */
+ s = H5RS_get_str(rs);
+ CHECK_PTR(s, "H5RS_get_str");
+ HDstrcpy(buf, "fo");
+ cmp = HDstrcmp(s, buf);
+ VERIFY(cmp, 0, "HDstrcmp");
+
+ /* Decrement reference count for string */
+ ret = H5RS_decr(rs);
+ CHECK(ret, FAIL, "H5RS_decr");
+} /* end test_refstr_aputc() */
/****************************************************************
**
@@ -361,12 +528,15 @@ test_refstr(void)
test_refstr_init();
/* Actual ref-counted strings tests */
- test_refstr_create(); /* Test ref-counted string creation */
- test_refstr_count(); /* Test ref-counted string counting */
- test_refstr_dup(); /* Test ref-counted string duplication */
- test_refstr_cmp(); /* Test ref-counted string comparison */
- test_refstr_wrap(); /* Test ref-counted string wrapping */
- test_refstr_own(); /* Test ref-counted string ownership transfer */
+ test_refstr_create(); /* Test ref-counted string creation */
+ test_refstr_count(); /* Test ref-counted string counting */
+ test_refstr_dup(); /* Test ref-counted string duplication */
+ test_refstr_cmp(); /* Test ref-counted string comparison */
+ test_refstr_wrap(); /* Test ref-counted string wrapping */
+ test_refstr_asprintf_cat(); /* Test ref-counted string printf-formatted output */
+ test_refstr_acat(); /* Test ref-counted string appends */
+ test_refstr_ancat(); /* Test ref-counted length-limited string appends */
+ test_refstr_aputc(); /* Test ref-counted character appends */
/* Finalize ref-counted strings testing data */
test_refstr_finalize();