summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2019-06-14 19:23:06 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2019-06-14 19:23:06 (GMT)
commitbb9370d777b645b9f0e2f5090421b63e207aa50f (patch)
tree932aa5b7867b332c854faed4e308abf4e265a5cf /src
parentd5a8b2a80cd1e5aaa62a523e03a5936260a56f60 (diff)
parent57d5c207d94bf876c934094cc7193858590a2c9f (diff)
downloadhdf5-bb9370d777b645b9f0e2f5090421b63e207aa50f.zip
hdf5-bb9370d777b645b9f0e2f5090421b63e207aa50f.tar.gz
hdf5-bb9370d777b645b9f0e2f5090421b63e207aa50f.tar.bz2
Merge branch 'develop' into vol_dev_headers
Also moved the wrapper functions from the H5VLconnector.h to H5VLconnector_passthru.h
Diffstat (limited to 'src')
-rw-r--r--src/H5Adense.c11
-rw-r--r--src/H5Aint.c43
-rw-r--r--src/H5Apkg.h2
-rw-r--r--src/H5Dchunk.c9
-rw-r--r--src/H5Dcompact.c7
-rw-r--r--src/H5Dvirtual.c7
-rw-r--r--src/H5F.c73
-rw-r--r--src/H5Fint.c4
-rw-r--r--src/H5Fpublic.h1
-rw-r--r--src/H5Oattr.c12
-rw-r--r--src/H5Pint.c105
-rw-r--r--src/H5Pprivate.h1
-rw-r--r--src/H5Ppublic.h4
-rw-r--r--src/H5S.c10
-rw-r--r--src/H5Shyper.c1053
-rw-r--r--src/H5Sselect.c11
-rw-r--r--src/H5VL.c136
-rw-r--r--src/H5VLcallback.c2
-rw-r--r--src/H5VLconnector.h87
-rw-r--r--src/H5VLconnector_passthru.h88
-rw-r--r--src/H5VLnative_file.c8
-rw-r--r--src/H5VLpassthru.c2
-rw-r--r--src/H5VLpublic.h2
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5trace.c6
-rw-r--r--src/Makefile.am18
-rw-r--r--src/h5cc.in399
-rw-r--r--src/libhdf5.settings.in2
28 files changed, 1548 insertions, 556 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 81e0dc5..bddfe31 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -325,14 +325,11 @@ H5A__dense_fnd_cb(const H5A_t *attr, hbool_t *took_ownership, void *_user_attr)
*/
if(*user_attr != NULL) {
H5A_t *old_attr = *user_attr;
- if(old_attr->shared) {
- /* Free any dynamically allocated items */
- if(H5A__free(old_attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
- /* Destroy shared attribute struct */
- old_attr->shared = H5FL_FREE(H5A_shared_t, old_attr->shared);
- } /* end if */
+ /* Free any dynamically allocated items */
+ if(old_attr->shared)
+ if(H5A__shared_free(old_attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
old_attr = H5FL_FREE(H5A_t, old_attr);
} /* end if */
diff --git a/src/H5Aint.c b/src/H5Aint.c
index d8ba92a..2126444 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -1092,48 +1092,55 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A__free
+ * Function: H5A__shared_free
*
- * Purpose: Frees all memory associated with an attribute, but does not
- * free the H5A_t structure (which should be done in H5T_close).
+ * Purpose: Cleans up the shared attribute data. This will free
+ * the attribute's shared structure as well.
+ *
+ * attr and attr->shared must not be NULL
*
* Return: SUCCEED/FAIL
*
- * Programmer: Quincey Koziol
- * Monday, November 15, 2004
+ * Programmer: Quincey Koziol
+ * Monday, November 15, 2004
*
*-------------------------------------------------------------------------
*/
herr_t
-H5A__free(H5A_t *attr)
+H5A__shared_free(H5A_t *attr)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
HDassert(attr);
+ HDassert(attr->shared);
- /* Free dynamically allocated items */
+ /* Free dynamically allocated items.
+ * When possible, keep trying to shut things down (via HDONE_ERROR).
+ */
if(attr->shared->name) {
H5MM_xfree(attr->shared->name);
attr->shared->name = NULL;
}
if(attr->shared->dt) {
if(H5T_close_real(attr->shared->dt) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
attr->shared->dt = NULL;
}
if(attr->shared->ds) {
if(H5S_close(attr->shared->ds) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
+ HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
attr->shared->ds = NULL;
}
if(attr->shared->data)
attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
-done:
+ /* Destroy shared attribute struct */
+ attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A__free() */
+} /* end H5A__shared_free() */
/*-------------------------------------------------------------------------
@@ -1197,11 +1204,9 @@ H5A__close(H5A_t *attr)
/* Reference count can be 0. It only happens when H5A__create fails. */
if(attr->shared->nrefs <= 1) {
/* Free dynamically allocated items */
- if(H5A__free(attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
-
- /* Destroy shared attribute struct */
- attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
+ if(attr->shared)
+ if(H5A__shared_free(attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
} /* end if */
else {
/* There are other references to the shared part of the attribute.
@@ -2396,9 +2401,13 @@ H5A__attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *attr_src,
/* Check for expanding references */
if(cpy_info->expand_ref) {
size_t ref_count;
+ size_t dst_dt_size; /* Destination datatype size */
+ /* Determine size of the destination datatype */
+ if(0 == (dst_dt_size = H5T_get_size(attr_dst->shared->dt)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
/* Determine # of reference elements to copy */
- ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt);
+ ref_count = attr_dst->shared->data_size / dst_dt_size;
/* Copy objects referenced in source buffer to destination file and set destination elements */
if(H5O_copy_expand_ref(file_src, attr_dst->shared->data, file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_dst->shared->dt), cpy_info) < 0)
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 91061cd..f3870c0 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -196,7 +196,7 @@ H5_DLL H5A_t *H5A__copy(H5A_t *new_attr, const H5A_t *old_attr);
H5_DLL hid_t H5A__get_type(H5A_t *attr);
H5_DLL herr_t H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo);
H5_DLL hid_t H5A__get_create_plist(H5A_t* attr);
-H5_DLL herr_t H5A__free(H5A_t *attr);
+H5_DLL herr_t H5A__shared_free(H5A_t *attr);
H5_DLL herr_t H5A__close(H5A_t *attr);
H5_DLL herr_t H5A__close_cb(H5VL_object_t *attr_vol_obj);
H5_DLL htri_t H5A__get_ainfo(H5F_t *f, H5O_t *oh, H5O_ainfo_t *ainfo);
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 60f2d8b..a8dc398 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -707,15 +707,18 @@ H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims,
/* Compute the # of chunks in dataset dimensions */
for(u = 0, layout->nchunks = 1, layout->max_nchunks = 1; u < ndims; u++) {
- /* Sanity check */
- HDassert(layout->dim[u] > 0);
-
/* Round up to the next integer # of chunks, to accommodate partial chunks */
layout->chunks[u] = ((curr_dims[u] + layout->dim[u]) - 1) / layout->dim[u];
if(H5S_UNLIMITED == max_dims[u])
layout->max_chunks[u] = H5S_UNLIMITED;
else
+ {
+ /* Sanity check */
+ if(layout->dim[u] == 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dimension size must be > 0, dim = %u ", u)
+
layout->max_chunks[u] = ((max_dims[u] + layout->dim[u]) - 1) / layout->dim[u];
+ }
/* Accumulate the # of chunks */
layout->nchunks *= layout->chunks[u];
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index df61856..29401f8 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -559,9 +559,14 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *_storage_src, H5F_t *f_ds
/* Check for expanding references */
if(cpy_info->expand_ref) {
size_t ref_count;
+ size_t src_dt_size; /* Source datatype size */
+
+ /* Determine largest datatype size */
+ if(0 == (src_dt_size = H5T_get_size(dt_src)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
/* Determine # of reference elements to copy */
- ref_count = storage_src->size / H5T_get_size(dt_src);
+ ref_count = storage_src->size / src_dt_size;
/* Copy objects referenced in source buffer to destination file and set destination elements */
if(H5O_copy_expand_ref(f_src, storage_src->buf, f_dst,
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index e3e0aa5..53640e7 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -35,6 +35,13 @@
* until the virtual dataset is closed.
*/
+/*
+ * Note: H5S_select_project_intersection has been updated to no longer require
+ * that the source and source intersect spaces have the same extent. This file
+ * should therefore be updated to remove code that ensures this condition, which
+ * should improve both maintainability and performance.
+ */
+
/****************/
/* Module Setup */
/****************/
diff --git a/src/H5F.c b/src/H5F.c
index 779c940..d216cd2 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -560,20 +560,21 @@ done:
*
* Purpose: Check if the file can be opened with the given fapl.
*
- * Return: TRUE/FALSE/FAIL
+ * Return: Succeed: TRUE/FALSE
+ * Failure: FAIL (includes file does not exist)
*
*-------------------------------------------------------------------------
*/
htri_t
-H5Fis_accessible(const char *name, hid_t fapl_id)
+H5Fis_accessible(const char *filename, hid_t fapl_id)
{
htri_t ret_value; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE2("t", "*si", name, fapl_id);
+ H5TRACE2("t", "*si", filename, fapl_id);
/* Check args */
- if(!name || !*name)
+ if(!filename || !*filename)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified")
/* Check the file access property list */
@@ -584,7 +585,7 @@ H5Fis_accessible(const char *name, hid_t fapl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list")
/* Check if file is accessible */
- if(H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, name, &ret_value) < 0)
+ if(H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, filename, &ret_value) < 0)
HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5")
done:
@@ -838,6 +839,68 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Fdelete
+ *
+ * Purpose: Deletes an HDF5 file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fdelete(const char *filename, hid_t fapl_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
+ htri_t is_hdf5 = FAIL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "*si", filename, fapl_id);
+
+ /* Check args */
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified")
+
+ /* Check the file access property list */
+ if(H5P_DEFAULT == fapl_id)
+ fapl_id = H5P_FILE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+
+ /* Get the VOL info from the fapl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(fapl_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list")
+ if(H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info")
+
+ /* Stash a copy of the "top-level" connector property, before any pass-through
+ * connectors modify or unwrap it.
+ */
+ if(H5CX_set_vol_connector_prop(&connector_prop) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context")
+
+ /* Make sure this is HDF5 storage for this VOL connector */
+ if(H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, filename, &is_hdf5) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5")
+ if(!is_hdf5)
+ HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "not an HDF5 file")
+
+ /* Delete the file */
+ if(H5VL_file_specific(NULL, H5VL_FILE_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, filename, &ret_value) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "unable to delete the file")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fdelete() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Freopen
*
* Purpose: Reopen a file. The new file handle which is returned points
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 2e8771c..ee9afed 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -863,7 +863,7 @@ H5F__is_hdf5(const char *name, hid_t fapl_id)
* should work with arbitrary VFDs, unlike H5Fis_hdf5().
*/
if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, fapl_id, HADDR_UNDEF)))
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to open file")
/* The file is an hdf5 file if the hdf5 file signature can be found */
if(H5FD_locate_signature(file, &sig_addr) < 0)
@@ -874,7 +874,7 @@ done:
/* Close the file */
if(file)
if(H5FD_close(file) < 0 && TRUE == ret_value)
- HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F__is_hdf5() */
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 52f1ee2..dd794e4 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -233,6 +233,7 @@ H5_DLL hid_t H5Fopen(const char *filename, unsigned flags,
H5_DLL hid_t H5Freopen(hid_t file_id);
H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
H5_DLL herr_t H5Fclose(hid_t file_id);
+H5_DLL herr_t H5Fdelete(const char *filename, hid_t fapl_id);
H5_DLL hid_t H5Fget_create_plist(hid_t file_id);
H5_DLL hid_t H5Fget_access_plist(hid_t file_id);
H5_DLL herr_t H5Fget_intent(hid_t file_id, unsigned *intent);
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 0a7c4bf..f685a00c 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -200,7 +200,7 @@ H5O_attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
* What's actually shared, though, is only the extent.
*/
if(NULL == (attr->shared->ds = H5FL_CALLOC(H5S_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Decode attribute's dataspace extent */
if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, open_oh,
@@ -253,15 +253,11 @@ H5O_attr_decode(H5F_t *f, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
done:
if(NULL == ret_value)
if(attr) {
- if(attr->shared) {
- /* Free any dynamically allocated items */
- if(H5A__free(attr) < 0)
+ /* Free any dynamically allocated items */
+ if(attr->shared)
+ if(H5A__shared_free(attr) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't release attribute info")
- /* Destroy shared attribute struct */
- attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
- } /* end if */
-
attr = H5FL_FREE(H5A_t, attr);
} /* end if */
diff --git a/src/H5Pint.c b/src/H5Pint.c
index b07f42d..04411a5 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -127,62 +127,65 @@ static herr_t H5P__free_del_name_cb(void *item, void H5_ATTR_UNUSED *key, void H
* Predefined property list classes. These are initialized at runtime by
* H5P__init_package() in this source file.
*/
-hid_t H5P_CLS_ROOT_ID_g = FAIL;
+hid_t H5P_CLS_ROOT_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_ROOT_g = NULL;
-hid_t H5P_CLS_OBJECT_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_OBJECT_CREATE_g = NULL;
-hid_t H5P_CLS_FILE_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_FILE_CREATE_g = NULL;
-hid_t H5P_CLS_FILE_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_FILE_ACCESS_g = NULL;
-hid_t H5P_CLS_DATASET_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATASET_CREATE_g = NULL;
-hid_t H5P_CLS_DATASET_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATASET_ACCESS_g = NULL;
-hid_t H5P_CLS_DATASET_XFER_ID_g = FAIL;
+hid_t H5P_CLS_DATASET_XFER_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATASET_XFER_g = NULL;
-hid_t H5P_CLS_FILE_MOUNT_ID_g = FAIL;
+hid_t H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_FILE_MOUNT_g = NULL;
-hid_t H5P_CLS_GROUP_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_GROUP_CREATE_g = NULL;
-hid_t H5P_CLS_GROUP_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_GROUP_ACCESS_g = NULL;
-hid_t H5P_CLS_DATATYPE_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATATYPE_CREATE_g = NULL;
-hid_t H5P_CLS_DATATYPE_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_DATATYPE_ACCESS_g = NULL;
-hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
-hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
-hid_t H5P_CLS_OBJECT_COPY_ID_g = FAIL;
+hid_t H5P_CLS_OBJECT_COPY_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_OBJECT_COPY_g = NULL;
-hid_t H5P_CLS_LINK_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_LINK_CREATE_g = NULL;
-hid_t H5P_CLS_LINK_ACCESS_ID_g = FAIL;
+hid_t H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_LINK_ACCESS_g = NULL;
-hid_t H5P_CLS_STRING_CREATE_ID_g = FAIL;
+hid_t H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID;
H5P_genclass_t *H5P_CLS_STRING_CREATE_g = NULL;
+hid_t H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
+H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL;
/*
* Predefined property lists for each predefined class. These are initialized
* at runtime by H5P__init_package() in this source file.
*/
-hid_t H5P_LST_FILE_CREATE_ID_g = FAIL;
-hid_t H5P_LST_FILE_ACCESS_ID_g = FAIL;
-hid_t H5P_LST_DATASET_CREATE_ID_g = FAIL;
-hid_t H5P_LST_DATASET_ACCESS_ID_g = FAIL;
-hid_t H5P_LST_DATASET_XFER_ID_g = FAIL;
-hid_t H5P_LST_FILE_MOUNT_ID_g = FAIL;
-hid_t H5P_LST_GROUP_CREATE_ID_g = FAIL;
-hid_t H5P_LST_GROUP_ACCESS_ID_g = FAIL;
-hid_t H5P_LST_DATATYPE_CREATE_ID_g = FAIL;
-hid_t H5P_LST_DATATYPE_ACCESS_ID_g = FAIL;
-hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = FAIL;
-hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = FAIL;
-hid_t H5P_LST_OBJECT_COPY_ID_g = FAIL;
-hid_t H5P_LST_LINK_CREATE_ID_g = FAIL;
-hid_t H5P_LST_LINK_ACCESS_ID_g = FAIL;
+hid_t H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATASET_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATASET_XFER_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_GROUP_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID;
+hid_t H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID;
/* Root property list class library initialization object */
const H5P_libclass_t H5P_CLS_ROOT[1] = {{
@@ -283,6 +286,26 @@ const H5P_libclass_t H5P_CLS_TACC[1] = {{
NULL /* Class close callback info */
}};
+/* VOL initialization property list class library initialization object */
+/* (move to proper source code file when used for real) */
+const H5P_libclass_t H5P_CLS_VINI[1] = {{
+ "VOL initialization", /* Class name for debugging */
+ H5P_TYPE_VOL_INITIALIZE, /* Class type */
+
+ &H5P_CLS_ROOT_g, /* Parent class */
+ &H5P_CLS_VOL_INITIALIZE_g, /* Pointer to class */
+ &H5P_CLS_VOL_INITIALIZE_ID_g, /* Pointer to class ID */
+ &H5P_LST_VOL_INITIALIZE_ID_g, /* Pointer to default property list ID */
+ NULL, /* Default property registration routine */
+
+ NULL, /* Class creation callback */
+ NULL, /* Class creation callback info */
+ NULL, /* Class copy callback */
+ NULL, /* Class copy callback info */
+ NULL, /* Class close callback */
+ NULL /* Class close callback info */
+}};
+
/* Library property list classes defined in other code modules */
/* (And not present in src/H5Pprivate.h) */
@@ -331,7 +354,8 @@ static H5P_libclass_t const * const init_class[] = {
H5P_CLS_TACC, /* Datatype access */
H5P_CLS_ACRT, /* Attribute creation */
H5P_CLS_AACC, /* Attribute access */
- H5P_CLS_LCRT /* Link creation */
+ H5P_CLS_LCRT, /* Link creation */
+ H5P_CLS_VINI /* VOL initialization */
};
/* Declare a free list to manage the H5P_genclass_t struct */
@@ -525,7 +549,8 @@ H5P_term_package(void)
H5P_LST_OBJECT_COPY_ID_g =
H5P_LST_LINK_CREATE_ID_g =
H5P_LST_LINK_ACCESS_ID_g =
- H5P_LST_FILE_MOUNT_ID_g = (-1);
+ H5P_LST_VOL_INITIALIZE_ID_g =
+ H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID;
} /* end if */
} /* end if */
@@ -552,6 +577,7 @@ H5P_term_package(void)
H5P_CLS_OBJECT_COPY_g =
H5P_CLS_LINK_CREATE_g =
H5P_CLS_LINK_ACCESS_g =
+ H5P_CLS_VOL_INITIALIZE_g =
H5P_CLS_FILE_MOUNT_g = NULL;
H5P_CLS_ROOT_ID_g =
@@ -571,7 +597,8 @@ H5P_term_package(void)
H5P_CLS_OBJECT_COPY_ID_g =
H5P_CLS_LINK_CREATE_ID_g =
H5P_CLS_LINK_ACCESS_ID_g =
- H5P_CLS_FILE_MOUNT_ID_g = (-1);
+ H5P_CLS_VOL_INITIALIZE_ID_g =
+ H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID;
} /* end if */
} /* end if */
@@ -5408,7 +5435,7 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
FUNC_ENTER_PACKAGE
/* Sanity checks */
- HDcompile_assert(H5P_TYPE_ATTRIBUTE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
+ HDcompile_assert(H5P_TYPE_VOL_INITIALIZE == (H5P_TYPE_MAX_TYPE - 1));
HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_LINK_ACCESS);
/* Check arguments */
@@ -5487,6 +5514,10 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
class_id = H5P_CLS_LINK_ACCESS_ID_g;
break;
+ case H5P_TYPE_VOL_INITIALIZE:
+ class_id = H5P_CLS_VOL_INITIALIZE_ID_g;
+ break;
+
case H5P_TYPE_USER: /* shut compiler warnings up */
case H5P_TYPE_ROOT:
case H5P_TYPE_MAX_TYPE:
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 49f7a12..07910c3 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -78,6 +78,7 @@ typedef enum H5P_plist_type_t {
H5P_TYPE_LINK_CREATE = 16,
H5P_TYPE_LINK_ACCESS = 17,
H5P_TYPE_ATTRIBUTE_ACCESS = 18,
+ H5P_TYPE_VOL_INITIALIZE = 19,
H5P_TYPE_MAX_TYPE
} H5P_plist_type_t;
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 90e6618..cad2071 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -68,6 +68,7 @@
#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_ID_g)
#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g)
#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g)
+#define H5P_VOL_INITIALIZE (H5OPEN H5P_CLS_VOL_INITIALIZE_ID_g)
/*
* The library's default property lists
@@ -87,6 +88,7 @@
#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_ID_g)
#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g)
#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g)
+#define H5P_VOL_INITIALIZE_DEFAULT (H5OPEN H5P_LST_VOL_INITIALIZE_ID_g)
/* Common creation order flags (for links in groups and attributes on objects) */
#define H5P_CRT_ORDER_TRACKED 0x0001
@@ -195,6 +197,7 @@ H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_ID_g;
H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_ID_g;
H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_ID_g;
+H5_DLLVAR hid_t H5P_CLS_VOL_INITIALIZE_ID_g;
/* Default roperty list IDs */
/* (Internal to library, do not use! Use macros above) */
@@ -213,6 +216,7 @@ H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_ID_g;
H5_DLLVAR hid_t H5P_LST_LINK_CREATE_ID_g;
H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_ID_g;
+H5_DLLVAR hid_t H5P_LST_VOL_INITIALIZE_ID_g;
/*********************/
/* Public Prototypes */
diff --git a/src/H5S.c b/src/H5S.c
index 3926b5f..e50985f 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -448,10 +448,14 @@ H5S_close(H5S_t *ds)
if(H5S__extent_release(&ds->extent) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent")
- /* Release the main structure */
- ds = H5FL_FREE(H5S_t, ds);
-
done:
+ /* Release the main structure.
+ * Always do this to ensure that we don't leak memory when calling this
+ * function on partially constructed dataspaces (which will fail one or
+ * both of the above calls)
+ */
+ H5FL_FREE(H5S_t, ds);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_close() */
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index c2cdf2b..63f457b 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -44,25 +44,13 @@
/* Macro for checking if two ranges overlap one another */
/*
- * Three possible conditions for overlapping:
- * 1. The lower bound of range #1 is between the lower and
- * higher bounds of range #2. In other words, the low
- * part of range #1 will at least overlap with range #2.
- * 2. The higher bound of range #1 is between the lower and
- * higher bounds of range #2. In other words, the upper
- * part of range #1 will at least overlap with range #2.
- * 3. Range #1 includes range #2, i.e. the lower bound
- * is smaller than that of range #2 and the higher bound
- * is larger than that of range #2.
+ * Check for the inverse of whether the ranges are disjoint. If they are
+ * disjoint, then the low bound of one of the ranges must be greater than the
+ * high bound of the other.
*/
/* (Assumes that low & high bounds are _inclusive_) */
#define H5S_RANGE_OVERLAP(L1, H1, L2, H2) \
- /* condition 1 */ \
- (((L1) >= (L2) && (L1) <= (H2)) || \
- /* condition 2 */ \
- ((H1) >= (L2) && (H1) <= (H2)) || \
- /* condition 3 */ \
- ((L1) <= (L2) && (H1) >= (H2)))
+ (!((L1) > (H2) || (L2) > (H1)))
/* Flags for which hyperslab fragments to compute */
#define H5S_HYPER_COMPUTE_B_NOT_A 0x01
@@ -84,6 +72,18 @@
(curr_span) = saved_next_span; \
} while(0)
+/* Macro to add "skipped" elements to projection during the execution of
+ * H5S__hyper_project_intersect() */
+#define H5S_HYPER_PROJ_INT_ADD_SKIP(UDATA, ADD, ERR) \
+ do { \
+ /* If there are any elements to add, we must add them \
+ * to the projection first before adding skip */ \
+ if((UDATA)->nelem > 0) \
+ if(H5S__hyper_proj_int_build_proj(UDATA) < 0) \
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, ERR, "can't add elements to projected selection") \
+ (UDATA)->skip += (ADD); \
+ } while(0) /* end H5S_HYPER_PROJ_INT_ADD_SKIP() */
+
/******************/
/* Local Typedefs */
@@ -93,6 +93,28 @@
/* (Makes it easier to understand the alloc / free calls) */
typedef hsize_t hbounds_t;
+/* Struct for holding persistent information during iteration for
+ * H5S__hyper_project_intersect() */
+typedef struct {
+ const H5S_hyper_span_t *ds_span[H5S_MAX_RANK]; /* Array of the current spans in the destination space in each dimension */
+ hsize_t ds_low[H5S_MAX_RANK]; /* Array of current low bounds (of iteration) for each element in ds_span */
+ H5S_hyper_span_info_t *ps_span_info[H5S_MAX_RANK]; /* Array of span info structs for projected space during iteration */
+ uint32_t ps_clean_bitmap; /* Bitmap of whether the nth rank has a clean projected space since the last time it was set to 1 */
+ unsigned ss_rank; /* Rank of source space */
+ unsigned ds_rank; /* Rank of destination space */
+ unsigned depth; /* Current depth of iterator in destination space */
+ hsize_t skip; /* Number of elements to skip in projected space */
+ hsize_t nelem; /* Number of elements to add to projected space (after skip) */
+ uint64_t op_gen; /* Operation generation for counting elements */
+} H5S_hyper_project_intersect_ud_t;
+
+/* Assert that H5S_MAX_RANK is <= 32 so our trick with using a 32 bit bitmap
+ * (ps_clean_bitmap) works. If H5S_MAX_RANK increases either increase the size
+ * of ps_clean_bitmap or change the algorithm to use an array. */
+#if H5S_MAX_RANK > 32
+#error H5S_MAX_RANK too large for ps_clean_bitmap field in H5S_hyper_project_intersect_ud_t struct
+#endif
+
/********************/
/* Local Prototypes */
@@ -119,6 +141,8 @@ static herr_t H5S__hyper_clip_spans(H5S_hyper_span_info_t *a_spans,
unsigned ndims, H5S_hyper_span_info_t **a_not_b,
H5S_hyper_span_info_t **a_and_b, H5S_hyper_span_info_t **b_not_a);
static herr_t H5S__hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans);
+static hsize_t H5S__hyper_spans_nelem_helper(H5S_hyper_span_info_t *spans,
+ uint64_t op_gen);
static hsize_t H5S__hyper_spans_nelem(H5S_hyper_span_info_t *spans);
static herr_t H5S__hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans);
static H5S_hyper_span_info_t *H5S__hyper_make_spans(unsigned rank,
@@ -147,6 +171,10 @@ static herr_t H5S__hyper_iter_get_seq_list_opt(H5S_sel_iter_t *iter, size_t maxs
size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len);
static herr_t H5S__hyper_iter_get_seq_list_single(H5S_sel_iter_t *iter, size_t maxseq,
size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off, size_t *len);
+static herr_t H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata);
+static herr_t H5S__hyper_proj_int_iterate(const H5S_hyper_span_info_t *ss_span_info,
+ const H5S_hyper_span_info_t *sis_span_info, hsize_t count, unsigned depth,
+ H5S_hyper_project_intersect_ud_t *udata);
static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride,
hsize_t *count, hsize_t *block, hsize_t clip_size);
static hsize_t H5S__hyper_get_clip_extent_real(const H5S_t *clip_space,
@@ -10442,6 +10470,579 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S__hyper_proj_int_build_proj
+ PURPOSE
+ Secondary iteration routine for H5S__hyper_project_intersection
+ USAGE
+ herr_t H5S__hyper_proj_int_build_proj(udata)
+ H5S_hyper_project_intersect_ud_t *udata; IN/OUT: Persistent shared data for iteration
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Takes the skip and nelem amounts listed in udata and converts them to
+ span trees in the projected space, using the destination space. This
+ is a non-recursive algorithm by necessity, it saves the current state
+ of iteration in udata and resumes in the same location on subsequent
+ calls.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__hyper_proj_int_build_proj(H5S_hyper_project_intersect_ud_t *udata) {
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ HDassert(udata->nelem > 0);
+
+ /*
+ * Skip over skipped elements
+ */
+ if(udata->skip > 0) {
+ /* Work upwards, finishing each span tree before moving up */
+ HDassert(udata->ds_span[udata->depth]);
+ do {
+ /* Check for lowest dimension */
+ if(udata->ds_span[udata->depth]->down) {
+ if(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high) {
+ /* If we will run out of elements to skip in this span,
+ * advance to the first not fully skipped span and break
+ * out of this loop (start moving downwards) */
+ if(udata->skip < H5S__hyper_spans_nelem_helper(udata->ds_span[udata->depth]->down, udata->op_gen)
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ udata->ds_low[udata->depth] += udata->skip / udata->ds_span[udata->depth]->down->u.nelmts;
+ udata->skip %= udata->ds_span[udata->depth]->down->u.nelmts;
+ break;
+ } /* end if */
+
+ /* Skip over this entire span */
+ udata->skip -= udata->ds_span[udata->depth]->down->u.nelmts
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1);
+ } /* end if */
+ } /* end if */
+ else {
+ HDassert(udata->ds_rank - udata->depth == 1);
+
+ /* If we will run out of elements to skip in this span,
+ * skip the remainder of the skipped elements and break out */
+ HDassert(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high);
+ if(udata->skip < (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ udata->ds_low[udata->depth] += udata->skip;
+ udata->skip = 0;
+ break;
+ } /* end if */
+
+ /* Skip over this entire span */
+ udata->skip -= udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1;
+ } /* end else */
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ if(udata->ds_span[udata->depth])
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ else if(udata->depth > 0) {
+ /* If present, append this span tree to the higher dimension's,
+ * and release ownership of it */
+ if(udata->ps_span_info[udata->depth]) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth - 1],
+ udata->ds_rank - udata->depth + 1, udata->ds_low[udata->depth - 1],
+ udata->ds_low[udata->depth - 1],
+ udata->ps_span_info[udata->depth]) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]);
+ udata->ps_span_info[udata->depth] = NULL;
+ } /* end if */
+
+ /* Ran out of spans, move up one dimension */
+ udata->depth--;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth]++;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "insufficient elements in destination selection")
+ } while((udata->skip > 0)
+ || (udata->ds_low[udata->depth] > udata->ds_span[udata->depth]->high));
+
+ /* Work downwards until skip is 0 */
+ HDassert(udata->ds_span[udata->depth]);
+ while(udata->skip > 0) {
+ HDassert(udata->ds_span[udata->depth]->down);
+ udata->depth++;
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth - 1]->down->head;
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ if(udata->ds_span[udata->depth]->down) {
+ do {
+ /* If we will run out of elements to skip in this span,
+ * advance to the first not fully skipped span and
+ * continue down */
+ if(udata->skip < H5S__hyper_spans_nelem_helper(udata->ds_span[udata->depth]->down, udata->op_gen)
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ udata->ds_low[udata->depth] += udata->skip / udata->ds_span[udata->depth]->down->u.nelmts;
+ udata->skip %= udata->ds_span[udata->depth]->down->u.nelmts;
+ break;
+ } /* end if */
+
+ /* Skip over this entire span */
+ udata->skip -= udata->ds_span[udata->depth]->down->u.nelmts
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1);
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ } while(udata->skip > 0);
+ } /* end if */
+ else {
+ do {
+ /* If we will run out of elements to skip in this span,
+ * skip the remainder of the skipped elements */
+ if(udata->skip < (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ udata->ds_low[udata->depth] += udata->skip;
+ udata->skip = 0;
+ break;
+ } /* end if */
+
+ /* Skip over this entire span */
+ udata->skip -= udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1;
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ } while(udata->skip > 0);
+ } /* end else */
+ } /* end while */
+ } /* end if */
+
+ /*
+ * Add requested number of elements to projected space
+ */
+ /* Work upwards, adding all elements of each span tree until it can't fit
+ * all elements */
+ HDassert(udata->ds_span[udata->depth]);
+ do {
+ /* Check for lowest dimension */
+ if(udata->ds_span[udata->depth]->down) {
+ if(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high) {
+ /* If we will run out of elements to add in this span, add
+ * any complete spans, advance to the first not fully added
+ * span, and break out of this loop (start moving downwards)
+ */
+ if(udata->nelem < H5S__hyper_spans_nelem_helper(udata->ds_span[udata->depth]->down, udata->op_gen)
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ if(udata->nelem >= udata->ds_span[udata->depth]->down->u.nelmts) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth],
+ udata->ds_rank - udata->depth, udata->ds_low[udata->depth],
+ udata->ds_low[udata->depth] + (udata->nelem / udata->ds_span[udata->depth]->down->u.nelmts) - 1,
+ udata->ds_span[udata->depth]->down) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->ds_low[udata->depth] += udata->nelem / udata->ds_span[udata->depth]->down->u.nelmts;
+ udata->nelem %= udata->ds_span[udata->depth]->down->u.nelmts;
+ } /* end if */
+ break;
+ } /* end if */
+
+ /* Append span tree for entire span */
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth],
+ udata->ds_rank - udata->depth, udata->ds_low[udata->depth],
+ udata->ds_span[udata->depth]->high,
+ udata->ds_span[udata->depth]->down) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->nelem -= udata->ds_span[udata->depth]->down->u.nelmts
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1);
+ } /* end if */
+ } /* end if */
+ else {
+ HDassert(udata->ds_rank - udata->depth == 1);
+
+ /* If we will run out of elements to add in this span, add the
+ * remainder of the elements and break out */
+ HDassert(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high);
+ if(udata->nelem < (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth], 1,
+ udata->ds_low[udata->depth], udata->ds_low[udata->depth] + udata->nelem - 1, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->ds_low[udata->depth] += udata->nelem;
+ udata->nelem = 0;
+ break;
+ } /* end if */
+
+ /* Append span tree for entire span */
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth], 1,
+ udata->ds_low[udata->depth], udata->ds_span[udata->depth]->high, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->nelem -= udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1;
+ } /* end else */
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ if(udata->ds_span[udata->depth])
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ else if(udata->depth > 0) {
+ /* Append this span tree to the higher dimension's, and release
+ * ownership of it */
+ HDassert(udata->ps_span_info[udata->depth]);
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth - 1],
+ udata->ds_rank - udata->depth + 1, udata->ds_low[udata->depth - 1],
+ udata->ds_low[udata->depth - 1],
+ udata->ps_span_info[udata->depth]) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ H5S__hyper_free_span_info(udata->ps_span_info[udata->depth]);
+ udata->ps_span_info[udata->depth] = NULL;
+
+ /* Ran out of spans, move up one dimension */
+ udata->depth--;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth]++;
+ } /* end if */
+ else {
+ /* We have finished the entire destination span tree. If there are
+ * still elements to add, issue an error. */
+ if(udata->nelem > 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "insufficient elements in destination selection")
+ break;
+ } /* end else */
+ } while((udata->nelem > 0)
+ || (udata->ds_low[udata->depth] > udata->ds_span[udata->depth]->high));
+
+ /* Work downwards until nelem is 0 */
+ HDassert(udata->ds_span[udata->depth] || (udata->nelem == 0));
+ while(udata->nelem > 0) {
+ HDassert(udata->ds_span[udata->depth]->down);
+ udata->depth++;
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth - 1]->down->head;
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ if(udata->ds_span[udata->depth]->down) {
+ do {
+ /* If we will run out of elements to add in this span, add
+ * any complete spans, advance to the first not fully added
+ * span and continue down
+ */
+ HDassert(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high);
+ if(udata->nelem < H5S__hyper_spans_nelem_helper(udata->ds_span[udata->depth]->down, udata->op_gen)
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ if(udata->nelem >= udata->ds_span[udata->depth]->down->u.nelmts) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth],
+ udata->ds_rank - udata->depth, udata->ds_low[udata->depth],
+ udata->ds_low[udata->depth] + (udata->nelem / udata->ds_span[udata->depth]->down->u.nelmts) - 1,
+ udata->ds_span[udata->depth]->down) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->ds_low[udata->depth] += udata->nelem / udata->ds_span[udata->depth]->down->u.nelmts;
+ udata->nelem %= udata->ds_span[udata->depth]->down->u.nelmts;
+ } /* end if */
+ break;
+ } /* end if */
+
+ /* Append span tree for entire span */
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth],
+ udata->ds_rank - udata->depth, udata->ds_low[udata->depth],
+ udata->ds_span[udata->depth]->high,
+ udata->ds_span[udata->depth]->down) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->nelem -= udata->ds_span[udata->depth]->down->u.nelmts
+ * (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1);
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ } while(udata->nelem > 0);
+ } /* end if */
+ else {
+ HDassert(udata->ds_rank - udata->depth == 1);
+ do {
+ /* If we will run out of elements to add in this span, add
+ * the remainder of the elements and break out */
+ HDassert(udata->ds_low[udata->depth] <= udata->ds_span[udata->depth]->high);
+ if(udata->nelem < (udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1)) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth], 1,
+ udata->ds_low[udata->depth], udata->ds_low[udata->depth] + udata->nelem - 1, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->ds_low[udata->depth] += udata->nelem;
+ udata->nelem = 0;
+ break;
+ } /* end if */
+
+ /* Append span tree for entire span */
+ if(H5S__hyper_append_span(&udata->ps_span_info[udata->depth], 1,
+ udata->ds_low[udata->depth], udata->ds_span[udata->depth]->high, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ udata->nelem -= udata->ds_span[udata->depth]->high - udata->ds_low[udata->depth] + 1;
+
+ /* Advance to next span */
+ udata->ds_span[udata->depth] = udata->ds_span[udata->depth]->next;
+ HDassert(udata->ds_span[udata->depth]);
+ udata->ds_low[udata->depth] = udata->ds_span[udata->depth]->low;
+ } while(udata->nelem > 0);
+ } /* end else */
+ } /* end while */
+
+ HDassert(udata->skip == 0);
+ HDassert(udata->nelem == 0);
+
+ /* Mark projected space as changed (for all ranks) */
+ udata->ps_clean_bitmap = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S__hyper_proj_int_build_proj() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__hyper_proj_int_iterate
+ PURPOSE
+ Main iteration routine for H5S__hyper_project_intersection
+ USAGE
+ herr_t H5S__hyper_proj_int_iterate(ss_span_info,sis_span_info,count,depth,udata)
+ const H5S_hyper_span_info_t *ss_span_info; IN: Span tree for source selection
+ const H5S_hyper_span_info_t *sis_span_info; IN: Span tree for source intersect selection
+ hsize_t count; IN: Number of times to compute the intersection of ss_span_info and sis_span_info
+ unsigned depth; IN: Depth of iteration (in terms of rank)
+ H5S_hyper_project_intersect_ud_t *udata; IN/OUT: Persistent shared data for iteration
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Computes the intersection of ss_span_info and sis_span_info and projects it
+ to the projected space (held in udata). It accomplishes this by iterating
+ over both spaces and computing the number of elements to skip (in
+ ss_span_info) and the number of elements to add (the intersection) in a
+ sequential fashion (similar to run length encoding). As necessary, this
+ function both recurses into lower dimensions and calls
+ H5S__hyper_proj_int_build_proj to convert the skip/nelem pairs to the
+ projected span tree.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__hyper_proj_int_iterate(const H5S_hyper_span_info_t *ss_span_info,
+ const H5S_hyper_span_info_t *sis_span_info, hsize_t count, unsigned depth,
+ H5S_hyper_project_intersect_ud_t *udata)
+{
+ const H5S_hyper_span_t *ss_span; /* Current span in source space */
+ const H5S_hyper_span_t *sis_span; /* Current span in source intersect space */
+ hsize_t ss_low; /* Current low bounds of source span */
+ hsize_t sis_low; /* Current low bounds of source intersect span */
+ hsize_t high; /* High bounds of current intersection */
+ hsize_t low; /* Low bounds of current intersection */
+ hsize_t old_skip; /* Value of udata->skip before main loop */
+ hsize_t old_nelem; /* Value of udata->nelem before main loop */
+ hbool_t check_intersect; /* Whether to check for intersecting elements */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check for non-overlapping bounds */
+ check_intersect = TRUE;
+ for(u = 0; u < (udata->ss_rank - depth); u++)
+ if(!H5S_RANGE_OVERLAP(ss_span_info->low_bounds[u],
+ ss_span_info->high_bounds[u],
+ sis_span_info->low_bounds[u],
+ sis_span_info->high_bounds[u])) {
+ check_intersect = FALSE;
+ break;
+ } /* end if */
+
+ /* Only enter main loop if there's something to do */
+ if(check_intersect) {
+ /* Set ps_clean_bitmap */
+ udata->ps_clean_bitmap |= (((uint32_t)1) << depth);
+
+ /* Save old skip and nelem */
+ old_skip = udata->skip;
+ old_nelem = udata->nelem;
+
+ /* Intersect spaces once per count */
+ for(u = 0; u < count; u++) {
+ ss_span = ss_span_info->head;
+ sis_span = sis_span_info->head;
+ HDassert(ss_span && sis_span);
+ ss_low = ss_span->low;
+ sis_low = sis_span->low;
+
+ /* Main loop */
+ do {
+ /* Check if spans overlap */
+ if(H5S_RANGE_OVERLAP(ss_low, ss_span->high,
+ sis_low, sis_span->high)) {
+ high = MIN(ss_span->high, sis_span->high);
+ if(ss_span->down) {
+ /* Add skipped elements if there's a pre-gap */
+ if(ss_low < sis_low) {
+ low = sis_low;
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, H5S__hyper_spans_nelem_helper(ss_span->down, udata->op_gen) * (sis_low - ss_low), FAIL);
+ } /* end if */
+ else
+ low = ss_low;
+
+ /* Recurse into next dimension down */
+ if(H5S__hyper_proj_int_iterate(ss_span->down, sis_span->down, high - low + 1, depth + 1, udata) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't iterate over source selections")
+ } /* end if */
+ else {
+ HDassert(depth == udata->ss_rank - 1);
+
+ /* Add skipped elements if there's a pre-gap */
+ if(ss_low < sis_low) {
+ low = sis_low;
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, sis_low - ss_low, FAIL);
+ } /* end if */
+ else
+ low = ss_low;
+
+ /* Add overlapping elements */
+ udata->nelem += high - low + 1;
+ } /* end else */
+
+ /* Advance spans */
+ if(ss_span->high == sis_span->high) {
+ /* Advance both spans */
+ ss_span = ss_span->next;
+ if(ss_span)
+ ss_low = ss_span->low;
+ sis_span = sis_span->next;
+ if(sis_span)
+ sis_low = sis_span->low;
+ } /* end if */
+ else if(ss_span->high == high) {
+ /* Advance source span */
+ HDassert(ss_span->high < sis_span->high);
+ sis_low = high + 1;
+ ss_span = ss_span->next;
+ if(ss_span)
+ ss_low = ss_span->low;
+ } /* end if */
+ else {
+ /* Advance source intersect span */
+ HDassert(ss_span->high > sis_span->high);
+ ss_low = high + 1;
+ sis_span = sis_span->next;
+ if(sis_span)
+ sis_low = sis_span->low;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Advance spans */
+ if(ss_span->high < sis_low) {
+ /* Add skipped elements */
+ if(ss_span->down)
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, H5S__hyper_spans_nelem_helper(ss_span->down, udata->op_gen) * (ss_span->high - ss_low + 1), FAIL);
+ else
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, ss_span->high - ss_low + 1, FAIL);
+
+ /* Advance source span */
+ ss_span = ss_span->next;
+ if(ss_span)
+ ss_low = ss_span->low;
+ } /* end if */
+ else {
+ /* Advance source intersect span */
+ HDassert(ss_low > sis_span->high);
+ sis_span = sis_span->next;
+ if(sis_span)
+ sis_low = sis_span->low;
+ } /* end else */
+ } /* end else */
+ } while(ss_span && sis_span);
+
+ if(ss_span && !((depth == 0) && (u == count - 1))) {
+ /* Count remaining elements in ss_span_info */
+ if(ss_span->down) {
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, H5S__hyper_spans_nelem_helper(ss_span->down, udata->op_gen) * (ss_span->high - ss_low + 1), FAIL);
+ ss_span = ss_span->next;
+ while(ss_span) {
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, H5S__hyper_spans_nelem_helper(ss_span->down, udata->op_gen) * (ss_span->high - ss_span->low + 1), FAIL);
+ ss_span = ss_span->next;
+ } /* end while */
+ } /* end if */
+ else {
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, ss_span->high - ss_low + 1, FAIL);
+ ss_span = ss_span->next;
+ while(ss_span) {
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, ss_span->high - ss_span->low + 1, FAIL);
+ ss_span = ss_span->next;
+ } /* end while */
+ } /* end else */
+ } /* end if */
+
+ /* Check if the projected space was not changed since we started the
+ * first iteration of the loop, if so we do not need to continue
+ * looping and can just copy the result */
+ if(udata->ps_clean_bitmap & (((uint32_t)1) << depth)) {
+ HDassert(u == 0);
+ if(udata->skip == old_skip) {
+ /* First case: algorithm added only elements */
+ HDassert(udata->nelem >= old_nelem);
+ udata->nelem += (count - 1) * (udata->nelem - old_nelem);
+ } /* end if */
+ else if(udata->nelem == 0) {
+ /* Second case: algorithm added only skip. In this case,
+ * nelem must be 0 since otherwise adding skip would have
+ * triggered a change in the projected space */
+ HDassert(old_nelem == 0);
+ HDassert(udata->skip > old_skip);
+ udata->skip += (count - 1) * (udata->skip - old_skip);
+ } /* end if */
+ else {
+ /* Third case: agorithm added skip and nelem (in that
+ * order). Add the same skip and nelem once for each item
+ * remaining in count. */
+ hsize_t skip_add;
+ hsize_t nelem_add;
+
+ HDassert(udata->nelem > 0);
+ HDassert(udata->skip > old_skip);
+ HDassert(old_nelem == 0);
+
+ skip_add = udata->skip - old_skip;
+ nelem_add = udata->nelem - old_nelem;
+ for(u = 1; u < count; u++) {
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, skip_add, FAIL);
+ udata->nelem += nelem_add;
+ } /* end for */
+ } /* end else */
+
+ /* End loop since we already took care of it */
+ break;
+ } /* end if */
+ } /* end for */
+ } /* end if */
+ else if(depth > 0)
+ /* Just count skipped elements */
+ H5S_HYPER_PROJ_INT_ADD_SKIP(udata, H5S__hyper_spans_nelem_helper((H5S_hyper_span_info_t *)ss_span_info, udata->op_gen) * count, FAIL); /* Casting away const OK -NAF */
+
+ /* Clean up if we are done */
+ if(depth == 0) {
+ /* Add remaining elements */
+ if(udata->nelem > 0)
+ if(H5S__hyper_proj_int_build_proj(udata) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't add elements to projected selection")
+
+ /* Append remaining span trees */
+ for(u = udata->ds_rank - 1; u > 0; u--)
+ if(udata->ps_span_info[u]) {
+ if(H5S__hyper_append_span(&udata->ps_span_info[u - 1],
+ udata->ds_rank - u + 1, udata->ds_low[u - 1],
+ udata->ds_low[u - 1],
+ udata->ps_span_info[u]) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ H5S__hyper_free_span_info(udata->ps_span_info[u]);
+ udata->ps_span_info[u] = NULL;
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S__hyper_proj_int_iterate() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S__hyper_project_intersection
PURPOSE
Projects the intersection of of the selections of src_space and
@@ -10461,7 +11062,9 @@ done:
within the selection of dst_space. The result is placed in the selection
of proj_space. Note src_space, dst_space, and src_intersect_space do not
need to use hyperslab selections, but they cannot use point selections.
- The result is always a hyperslab selection.
+ The result is always a hyperslab or none selection. Note also that
+ proj_space can share some span trees with dst_space, so proj_space
+ must not be subsequently modified if dst_space must be preserved.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
@@ -10471,43 +11074,11 @@ herr_t
H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
const H5S_t *src_intersect_space, H5S_t *proj_space)
{
- hsize_t ss_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for src_space */
- size_t ss_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for src_space */
- size_t ss_nseq; /* Number of sequences for src_space */
- size_t ss_nelem; /* Number of elements for src_space */
- size_t ss_i = (size_t)0; /* Index into offset/length arrays for src_space */
- hbool_t advance_ss = FALSE; /* Whether to advance ss_i on the next iteration */
- H5S_sel_iter_t *ss_iter = NULL; /* Selection iterator for src_space */
- hbool_t ss_iter_init = FALSE; /* Whether ss_iter is initialized */
- hsize_t ss_sel_off = (hsize_t)0; /* Offset within src_space selection */
- hsize_t ds_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for dst_space */
- size_t ds_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for dst_space */
- size_t ds_nseq; /* Number of sequences for dst_space */
- size_t ds_nelem; /* Number of elements for dst_space */
- size_t ds_i = (size_t)0; /* Index into offset/length arrays for dst_space */
- H5S_sel_iter_t *ds_iter = NULL; /* Selection iterator for dst_space */
- hbool_t ds_iter_init = FALSE; /* Whether ds_iter is initialized */
- hsize_t ds_sel_off = (hsize_t)0; /* Offset within dst_space selection */
- hsize_t sis_off[H5S_PROJECT_INTERSECT_NSEQS]; /* Offset array for src_intersect_space */
- size_t sis_len[H5S_PROJECT_INTERSECT_NSEQS]; /* Length array for src_intersect_space */
- size_t sis_nseq; /* Number of sequences for src_intersect_space */
- size_t sis_nelem; /* Number of elements for src_intersect_space */
- size_t sis_i = (size_t)0; /* Index into offset/length arrays for src_intersect_space */
- hbool_t advance_sis = FALSE; /* Whether to advance sis_i on the next iteration */
- H5S_sel_iter_t *sis_iter = NULL; /* Selection iterator for src_intersect_space */
- hbool_t sis_iter_init = FALSE; /* Whether sis_iter is initialized */
- hsize_t int_sel_off; /* Offset within intersected selections (ss/sis and ds/ps) */
- size_t int_len; /* Length of segment in intersected selections */
- hsize_t proj_off; /* Segment offset in proj_space */
- size_t proj_len; /* Segment length in proj_space */
- size_t proj_len_rem; /* Remaining length in proj_space for segment */
- hsize_t proj_down_dims[H5S_MAX_RANK]; /* "Down" dimensions in proj_space */
- H5S_hyper_span_info_t *curr_span_tree[H5S_MAX_RANK]; /* Current span tree being built (in each dimension) */
- hsize_t curr_span_up_dim[H5S_MAX_RANK]; /* "Up" dimensions for current span */
- unsigned proj_rank; /* Rank of proj_space */
- hsize_t low; /* Low value of span */
- size_t nelem; /* Number of elements returned for get_seq_list op */
- unsigned u; /* Local index variable */
+ H5S_hyper_project_intersect_ud_t udata; /* User data for subroutines */
+ const H5S_hyper_span_info_t *ss_span_info;
+ const H5S_hyper_span_info_t *ds_span_info;
+ H5S_hyper_span_info_t *ss_span_info_buf = NULL;
+ H5S_hyper_span_info_t *ds_span_info_buf = NULL;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -10521,280 +11092,88 @@ H5S__hyper_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
/* Assert that src_space and src_intersect_space have same extent and there
* are no point selections */
HDassert(H5S_GET_EXTENT_NDIMS(src_space) == H5S_GET_EXTENT_NDIMS(src_intersect_space));
- HDassert(!HDmemcmp(src_space->extent.size, src_intersect_space->extent.size,
- (size_t)H5S_GET_EXTENT_NDIMS(src_space) * sizeof(src_space->extent.size[0])));
+ HDassert(H5S_GET_SELECT_NPOINTS(src_space) == H5S_GET_SELECT_NPOINTS(dst_space));
HDassert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_POINTS);
HDassert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_POINTS);
- HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) != H5S_SEL_POINTS);
-
- /* Initialize prev_space, curr_span_tree, and curr_span_up_dim */
- HDmemset(curr_span_tree, 0, sizeof(curr_span_tree));
- HDmemset(curr_span_up_dim, 0, sizeof(curr_span_up_dim));
+ HDassert(H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_HYPERSLABS);
- /* Save rank of projected space */
- proj_rank = proj_space->extent.rank;
- HDassert(proj_rank > 0);
+ /* Set up ss_span_info */
+ if(H5S_GET_SELECT_TYPE(src_space) == H5S_SEL_HYPERSLABS) {
+ /* Make certain the selection has a span tree */
+ if(NULL == src_space->select.sel_info.hslab->span_lst)
+ if(H5S__hyper_generate_spans((H5S_t *)src_space) < 0) /* Casting away const OK -NAF */
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "can't construct span tree for source hyperslab selection")
- /* Get numbers of elements */
- ss_nelem = (size_t)H5S_GET_SELECT_NPOINTS(src_space);
- ds_nelem = (size_t)H5S_GET_SELECT_NPOINTS(dst_space);
- sis_nelem = (size_t)H5S_GET_SELECT_NPOINTS(src_intersect_space);
- HDassert(ss_nelem == ds_nelem);
-
- /* Calculate proj_down_dims */
- if(H5VM_array_down(proj_rank, proj_space->extent.size, proj_down_dims) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value")
-
- /* Remove current selection from proj_space */
- if(H5S_SELECT_RELEASE(proj_space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
-
- /* If any selections are empty, skip to the end so "none" is selected */
- if((ss_nelem == 0) || (ds_nelem == 0) || (sis_nelem == 0))
- goto loop_end;
-
- /* Allocate space for the hyperslab selection information (note this sets
- * diminfo_valid to FALSE, diminfo arrays to 0, and span list to NULL) */
- if(NULL == (proj_space->select.sel_info.hslab = H5FL_CALLOC(H5S_hyper_sel_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info")
-
- /* Set selection type */
- proj_space->select.type = H5S_sel_hyper;
-
- /* Set unlim_dim */
- proj_space->select.sel_info.hslab->unlim_dim = -1;
-
- /* Allocate the source selection iterator */
- if(NULL == (ss_iter = H5FL_MALLOC(H5S_sel_iter_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source selection iterator")
-
- /* Initialize source space iterator */
- if(H5S_select_iter_init(ss_iter, src_space, (size_t)1, 0) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- ss_iter_init = TRUE;
-
- /* Get sequence list for source space */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
- ss_nelem -= nelem;
- HDassert(ss_nseq > 0);
-
- /* Allocate the destination selection iterator */
- if(NULL == (ds_iter = H5FL_MALLOC(H5S_sel_iter_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate destination selection iterator")
-
- /* Initialize destination space iterator */
- if(H5S_select_iter_init(ds_iter, dst_space, (size_t)1, 0) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- ds_iter_init = TRUE;
-
- /* Get sequence list for destination space */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- ds_nelem -= nelem;
- HDassert(ds_nseq > 0);
-
- /* Allocate the source intersect space iterator */
- if(NULL == (sis_iter = H5FL_MALLOC(H5S_sel_iter_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate source intersect space iterator")
-
- /* Initialize source intersect space iterator */
- if(H5S_select_iter_init(sis_iter, src_intersect_space, (size_t)1, 0) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- sis_iter_init = TRUE;
-
- /* Get sequence list for source intersect space */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
- sis_nelem -= nelem;
- HDassert(sis_nseq > 0);
-
- /* Loop until we run out of sequences in either the source or source
- * intersect space */
- while(1) {
- while(advance_ss || (ss_off[ss_i] + ss_len[ss_i] <= sis_off[sis_i])) {
- /* Either we finished the current source sequence or the
- * sequences do not intersect. Advance source space. */
- ss_sel_off += (hsize_t)ss_len[ss_i];
- if(++ss_i == ss_nseq) {
- if(ss_nelem > 0) {
- /* Try to grab more sequences from src_space */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(ss_iter, H5S_PROJECT_INTERSECT_NSEQS, ss_nelem, &ss_nseq, &nelem, ss_off, ss_len) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
- HDassert(ss_len[0] > 0);
-
- /* Update ss_nelem */
- HDassert(nelem > 0);
- HDassert(nelem <= ss_nelem);
- ss_nelem -= nelem;
-
- /* Reset source space index */
- ss_i = 0;
- } /* end if */
- else
- /* There are no more sequences in src_space, so we can exit
- * the loop. Use goto instead of break so we exit the outer
- * loop. */
- goto loop_end;
- } /* end if */
+ /* Simply point to existing span tree */
+ ss_span_info = src_space->select.sel_info.hslab->span_lst;
+ } /* end if */
+ else {
+ /* Create temporary span tree from all selection */
+ HDassert(H5S_GET_SELECT_TYPE(src_space) == H5S_SEL_ALL);
- /* Reset advance_ss */
- advance_ss = FALSE;
- } /* end while */
- if(advance_sis || (sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i])) {
- do {
- /* Either we finished the current source intersect sequence or
- * the sequences do not intersect. Advance source intersect
- * space. */
- if(++sis_i == sis_nseq) {
- if(sis_nelem > 0) {
- /* Try to grab more sequences from src_intersect_space
- */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(sis_iter, H5S_PROJECT_INTERSECT_NSEQS, sis_nelem, &sis_nseq, &nelem, sis_off, sis_len) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
- HDassert(sis_len[0] > 0);
+ if(NULL == (ss_span_info_buf = H5S__hyper_make_spans(H5S_GET_EXTENT_NDIMS(src_space),
+ H5S_hyper_zeros_g, H5S_hyper_zeros_g, H5S_hyper_ones_g, src_space->extent.size)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't create span tree for ALL source space")
+ ss_span_info = ss_span_info_buf;
+ } /* end else */
- /* Update ss_nelem */
- HDassert(nelem > 0);
- HDassert(nelem <= sis_nelem);
- sis_nelem -= nelem;
+ /* Set up ds_span_info */
+ if(H5S_GET_SELECT_TYPE(dst_space) == H5S_SEL_HYPERSLABS) {
+ /* Make certain the selection has a span tree */
+ if(NULL == dst_space->select.sel_info.hslab->span_lst)
+ if(H5S__hyper_generate_spans((H5S_t *)dst_space) < 0) /* Casting away const OK -NAF */
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "can't construct span tree for dsetination hyperslab selection")
- /* Reset source space index */
- sis_i = 0;
- } /* end if */
- else
- /* There are no more sequences in src_intersect_space,
- * so we can exit the loop. Use goto instead of break
- * so we exit the outer loop. */
- goto loop_end;
- } /* end if */
- } while(sis_off[sis_i] + sis_len[sis_i] <= ss_off[ss_i]);
-
- /* Reset advance_sis */
- advance_sis = FALSE;
- } /* end if */
- else {
- /* Sequences intersect, add intersection to projected space */
- /* Calculate intersection sequence in terms of offset within source
- * selection and advance any sequences we complete */
- if(ss_off[ss_i] >= sis_off[sis_i])
- int_sel_off = ss_sel_off;
- else
- int_sel_off = sis_off[sis_i] - ss_off[ss_i] + ss_sel_off;
- if((ss_off[ss_i] + (hsize_t)ss_len[ss_i]) <= (sis_off[sis_i]
- + (hsize_t)sis_len[sis_i])) {
- int_len = (size_t)((hsize_t)ss_len[ss_i] + ss_sel_off - int_sel_off);
- advance_ss = TRUE;
- } /* end if */
- else
- int_len = (size_t)(sis_off[sis_i] + (hsize_t)sis_len[sis_i] - ss_off[ss_i] + ss_sel_off - int_sel_off);
- if((ss_off[ss_i] + (hsize_t)ss_len[ss_i]) >= (sis_off[sis_i]
- + (hsize_t)sis_len[sis_i]))
- advance_sis = TRUE;
-
- /* Project intersection sequence to destination selection */
- while(int_len > (size_t)0) {
- while(ds_sel_off + (hsize_t)ds_len[ds_i] <= int_sel_off) {
- /* Intersection is not projected to this destination
- * sequence, advance destination space */
- ds_sel_off += (hsize_t)ds_len[ds_i];
- if(++ds_i == ds_nseq) {
- HDassert(ds_nelem > 0);
-
- /* Try to grab more sequences from dst_space */
- if(H5S_SELECT_ITER_GET_SEQ_LIST(ds_iter, H5S_PROJECT_INTERSECT_NSEQS, ds_nelem, &ds_nseq, &nelem, ds_off, ds_len) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
- HDassert(ds_len[0] > 0);
-
- /* Update ss_nelem */
- HDassert(nelem > 0);
- HDassert(nelem <= ds_nelem);
- ds_nelem -= nelem;
-
- /* Reset source space index */
- ds_i = 0;
- } /* end if */
- } /* end while */
+ /* Simply point to existing span tree */
+ ds_span_info = dst_space->select.sel_info.hslab->span_lst;
+ } /* end if */
+ else {
+ /* Create temporary span tree from all selection */
+ HDassert(H5S_GET_SELECT_TYPE(dst_space) == H5S_SEL_ALL);
- /* Add sequence to projected space */
- HDassert(ds_sel_off <= int_sel_off);
- proj_off = ds_off[ds_i] + int_sel_off - ds_sel_off;
- proj_len = proj_len_rem = (size_t)MIN(int_len,
- (size_t)(ds_sel_off + (hsize_t)ds_len[ds_i] - int_sel_off));
-
- /* Add to span tree */
- while(proj_len_rem > (size_t)0) {
- hsize_t high; /* High value of span */
- size_t span_len; /* Length of span */
-
- /* Append spans in higher dimensions if we're going ouside
- * the plane of the span currently being built (i.e. it's
- * finished being built) */
- /* Check for more than one full row (in every dim) and
- * append multiple spans at once? -NAF */
- for(u = proj_rank - 1; ((u > 0)
- && ((proj_off / proj_down_dims[u - 1])
- != curr_span_up_dim[u - 1])); u--) {
- if(curr_span_tree[u]) {
- /* Append complete lower dimension span tree to
- * current dimension */
- low = curr_span_up_dim[u - 1] % proj_space->extent.size[u - 1];
- if(H5S__hyper_append_span(&curr_span_tree[u - 1], (proj_rank - u) + 1, low, low, curr_span_tree[u]) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ if(NULL == (ds_span_info_buf = H5S__hyper_make_spans(H5S_GET_EXTENT_NDIMS(dst_space),
+ H5S_hyper_zeros_g, H5S_hyper_zeros_g, H5S_hyper_ones_g, dst_space->extent.size)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't create span tree for ALL destination space")
+ ds_span_info = ds_span_info_buf;
+ } /* end else */
- /* Reset lower dimension's span tree and previous
- * span since we just committed it and will start
- * over with a new one */
- H5S__hyper_free_span_info(curr_span_tree[u]);
- curr_span_tree[u] = NULL;
- } /* end if */
+ /* Make certain the source intersect selection has a span tree */
+ if(NULL == src_intersect_space->select.sel_info.hslab->span_lst)
+ if(H5S__hyper_generate_spans((H5S_t *)src_intersect_space) < 0) /* Casting away const OK -NAF */
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "can't construct span tree for source intersect hyperslab selection")
- /* Update curr_span_up_dim */
- curr_span_up_dim[u - 1] = proj_off / proj_down_dims[u - 1];
- } /* end for */
+ /* Initialize udata */
+ HDmemset(&udata, 0, sizeof(udata));
+ udata.ds_span[0] = ds_span_info->head;
+ udata.ds_low[0] = udata.ds_span[0]->low;
+ udata.ss_rank = H5S_GET_EXTENT_NDIMS(src_space);
+ udata.ds_rank = H5S_GET_EXTENT_NDIMS(dst_space);
+ udata.op_gen = H5S__hyper_get_op_gen();
- /* Compute bounds for new span in lowest dimension */
- low = proj_off % proj_space->extent.size[proj_rank - 1];
- span_len = MIN(proj_len_rem,
- (size_t)(proj_space->extent.size[proj_rank - 1]
- - low));
- HDassert(proj_len_rem >= span_len);
- high = (low + (hsize_t)span_len) - (hsize_t)1;
+ /* Iterate over selections and build projected span tree */
+ if(H5S__hyper_proj_int_iterate(ss_span_info, src_intersect_space->select.sel_info.hslab->span_lst, 1, 0, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "selection iteration failed")
- /* Append span in lowest dimension */
- if(H5S__hyper_append_span(&curr_span_tree[proj_rank - 1], 1, low, high, NULL) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ /* Remove current selection from proj_space */
+ if(H5S_SELECT_RELEASE(proj_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
- /* Update remaining offset and length */
- proj_off += (hsize_t)span_len;
- proj_len_rem -= span_len;
- } /* end while */
+ /* Check for elements in projected space */
+ if(udata.ps_span_info[0]) {
+ /* Allocate space for the hyperslab selection information (note this sets
+ * diminfo_valid to FALSE, diminfo arrays to 0, and span list to NULL) */
+ if(NULL == (proj_space->select.sel_info.hslab = H5FL_CALLOC(H5S_hyper_sel_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab info")
- /* Update intersection sequence */
- int_sel_off += (hsize_t)proj_len;
- int_len -= proj_len;
- } /* end while */
- } /* end else */
- } /* end while */
-
-loop_end:
- /* Add remaining spans to span tree */
- for(u = proj_rank - 1; u > 0; u--)
- if(curr_span_tree[u]) {
- /* Append remaining span tree to higher dimension */
- low = curr_span_up_dim[u - 1] % proj_space->extent.size[u - 1];
- if(H5S__hyper_append_span(&curr_span_tree[u - 1], (proj_rank - u) + 1, low, low, curr_span_tree[u]) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTAPPEND, FAIL, "can't allocate hyperslab span")
+ /* Set selection type */
+ proj_space->select.type = H5S_sel_hyper;
- /* Reset span tree */
- H5S__hyper_free_span_info(curr_span_tree[u]);
- curr_span_tree[u] = NULL;
- } /* end if */
+ /* Set unlim_dim */
+ proj_space->select.sel_info.hslab->unlim_dim = -1;
- /* Add span tree to proj_space */
- if(curr_span_tree[0]) {
- proj_space->select.sel_info.hslab->span_lst = curr_span_tree[0];
- curr_span_tree[0] = NULL;
+ /* Set span tree */
+ proj_space->select.sel_info.hslab->span_lst = udata.ps_span_info[0];
+ udata.ps_span_info[0] = NULL;
/* Set the number of elements in current selection */
proj_space->select.num_elem = H5S__hyper_spans_nelem(proj_space->select.sel_info.hslab->span_lst);
@@ -10810,36 +11189,40 @@ loop_end:
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
done:
- /* Release source selection iterator */
- if(ss_iter_init && H5S_SELECT_ITER_RELEASE(ss_iter) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
- if(ss_iter)
- ss_iter = H5FL_FREE(H5S_sel_iter_t, ss_iter);
-
- /* Release destination selection iterator */
- if(ds_iter_init && H5S_SELECT_ITER_RELEASE(ds_iter) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
- if(ds_iter)
- ds_iter = H5FL_FREE(H5S_sel_iter_t, ds_iter);
-
- /* Release source intersect selection iterator */
- if(sis_iter_init && H5S_SELECT_ITER_RELEASE(sis_iter) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
- if(sis_iter)
- sis_iter = H5FL_FREE(H5S_sel_iter_t, sis_iter);
+ /* Free ss_span_info_buf */
+ if(ss_span_info_buf) {
+ H5S__hyper_free_span_info(ss_span_info_buf);
+ ss_span_info_buf = NULL;
+ } /* end if */
+
+ /* Free ds_span_info_buf */
+ if(ds_span_info_buf) {
+ H5S__hyper_free_span_info(ds_span_info_buf);
+ ds_span_info_buf = NULL;
+ } /* end if */
/* Cleanup on error */
if(ret_value < 0) {
- /* Remove current selection from proj_space */
- if(H5S_SELECT_RELEASE(proj_space) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+ unsigned u;
/* Free span trees */
- for(u = 0; u < proj_rank; u++)
- if(curr_span_tree[u])
- H5S__hyper_free_span_info(curr_span_tree[u]);
+ for(u = 0; u < udata.ds_rank; u++)
+ if(udata.ps_span_info[u]) {
+ H5S__hyper_free_span_info(udata.ps_span_info[u]);
+ udata.ps_span_info[u] = NULL;
+ } /* end if */
} /* end if */
+#ifndef NDEBUG
+ /* Verify there are no more span trees */
+ {
+ unsigned u;
+
+ for(u = 0; u < H5S_MAX_RANK; u++)
+ HDassert(!udata.ps_span_info[u]);
+ } /* end block */
+#endif /* NDEBUG */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S__hyper_project_intersection() */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 80b5ea1..6983c93 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -2374,10 +2374,11 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
if(H5S_select_copy(new_space, dst_space, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection")
} /* end if */
- /* If any of the spaces are "none", the projection must also be "none" */
- else if((src_intersect_space->select.type->type == H5S_SEL_NONE)
- || (src_space->select.type->type == H5S_SEL_NONE)
- || (dst_space->select.type->type == H5S_SEL_NONE)) {
+ /* If any of the selections contain no elements, the projection must be
+ * "none" */
+ else if((H5S_GET_SELECT_NPOINTS(src_intersect_space) == 0)
+ || (H5S_GET_SELECT_NPOINTS(src_space) == 0)
+ || (H5S_GET_SELECT_NPOINTS(dst_space) == 0)) {
/* Change to "none" selection */
if(H5S_select_none(new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
@@ -2389,6 +2390,8 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported")
else {
HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS);
+ HDassert(src_space->select.type->type != H5S_SEL_NONE);
+ HDassert(dst_space->select.type->type != H5S_SEL_NONE);
/* Intersecting space is hyperslab selection. Call the hyperslab
* routine to project to another hyperslab selection. */
diff --git a/src/H5VL.c b/src/H5VL.c
index fd45bf8..5c62f6f 100644
--- a/src/H5VL.c
+++ b/src/H5VL.c
@@ -31,8 +31,11 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Iprivate.h" /* IDs */
+#include "H5Pprivate.h" /* Property lists */
#include "H5VLpkg.h" /* Virtual Object Layer */
+/* VOL connectors */
+#include "H5VLnative.h" /* Native VOL connector */
/****************/
/* Local Macros */
@@ -71,6 +74,9 @@
* Purpose: Registers a new VOL connector as a member of the virtual object
* layer class.
*
+ * VIPL_ID is a VOL initialization property list which must be
+ * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
+ *
* Return: Success: A VOL connector ID which is good until the
* library is closed or the connector is
* unregistered.
@@ -99,6 +105,13 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id)
if (cls->wrap_cls.get_wrap_ctx && !cls->wrap_cls.free_wrap_ctx)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector must provide free callback for object wrapping contexts when a get callback is provided")
+ /* Check VOL initialization property list */
+ if(H5P_DEFAULT == vipl_id)
+ vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list")
+
/* Register connector */
if((ret_value = H5VL__register_connector(cls, TRUE, vipl_id)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector")
@@ -114,6 +127,9 @@ done:
* Purpose: Registers a new VOL connector as a member of the virtual object
* layer class.
*
+ * VIPL_ID is a VOL initialization property list which must be
+ * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
+ *
* Return: Success: A VOL connector ID which is good until the
* library is closed or the connector is
* unregistered.
@@ -136,6 +152,13 @@ H5VLregister_connector_by_name(const char *name, hid_t vipl_id)
if (0 == HDstrlen(name))
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "zero-length VOL connector name is disallowed")
+ /* Check VOL initialization property list */
+ if(H5P_DEFAULT == vipl_id)
+ vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list")
+
/* Register connector */
if((ret_value = H5VL__register_connector_by_name(name, TRUE, vipl_id)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector")
@@ -151,6 +174,9 @@ done:
* Purpose: Registers a new VOL connector as a member of the virtual object
* layer class.
*
+ * VIPL_ID is a VOL initialization property list which must be
+ * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
+ *
* Return: Success: A VOL connector ID which is good until the
* library is closed or the connector is
* unregistered.
@@ -171,6 +197,13 @@ H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id)
if(value < 0)
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "negative VOL connector value is disallowed")
+ /* Check VOL initialization property list */
+ if(H5P_DEFAULT == vipl_id)
+ vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list")
+
/* Register connector */
if((ret_value = H5VL__register_connector_by_value(value, TRUE, vipl_id)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector")
@@ -185,9 +218,9 @@ done:
*
* Purpose: Tests whether a VOL class has been registered or not
*
- * Return: >0 if the VOL class has been registered
- * 0 if it is unregistered
- * <0 on error (if the class is not a valid class ID)
+ * Return: >0 if a VOL connector with that name has been registered
+ * 0 if a VOL connector with that name has NOT been registered
+ * <0 on errors
*
* Programmer: Dana Robinson
* June 17, 2017
@@ -216,8 +249,12 @@ done:
*
* Purpose: Retrieves the ID for a registered VOL connector.
*
- * Return: Positive if the VOL class has been registered
- * Negative on error (if the class is not a valid class or not registered)
+ * Return: A valid VOL connector ID if a connector by that name has
+ * been registered. This ID will need to be closed using
+ * H5VLclose().
+ *
+ * H5I_INVALID_HID on error or if a VOL connector of that
+ * name has not been registered.
*
* Programmer: Dana Robinson
* June 17, 2017
@@ -245,7 +282,12 @@ done:
* Function: H5VLget_connector_name
*
* Purpose: Returns the connector name for the VOL associated with the
- * object or file ID
+ * object or file ID.
+ *
+ * This works like other calls where the caller must provide a
+ * buffer of the appropriate size for the library to fill in.
+ * i.e., passing in a NULL pointer for NAME will return the
+ * required size of the buffer.
*
* Return: Success: The length of the connector name
*
@@ -312,6 +354,9 @@ done:
* this VOL connector or files which are already opened under with
* this connector.
*
+ * The native VOL connector cannot be unregistered and attempts
+ * to do so are considered an error.
+ *
* Return: Success: Non-negative
*
* Failure: Negative
@@ -321,6 +366,7 @@ done:
herr_t
H5VLunregister_connector(hid_t vol_id)
{
+ hid_t native_id = H5I_INVALID_HID;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -328,13 +374,23 @@ H5VLunregister_connector(hid_t vol_id)
/* Check arguments */
if(NULL == H5I_object_verify(vol_id, H5I_VOL))
- HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector")
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+
+ /* For the time being, we disallow unregistering the native VOL connector */
+ if(H5I_INVALID_HID == (native_id = H5VL__get_connector_id(H5VL_NATIVE_NAME, FALSE)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to find the native VOL connector ID")
+ if(vol_id == native_id)
+ HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed")
/* The H5VL_class_t struct will be freed by this function */
- if (H5I_dec_app_ref(vol_id) < 0)
+ if(H5I_dec_app_ref(vol_id) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister VOL connector")
done:
+ if(native_id != H5I_INVALID_HID)
+ if(H5I_dec_ref(native_id) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement count on native_id")
+
FUNC_LEAVE_API(ret_value)
} /* end H5VLunregister_connector() */
@@ -344,8 +400,8 @@ done:
*
* Purpose: Compares two connector classes (based on their value field)
*
- * Note: This routine is _only_ for HDF5 VOL connector authors! It is
- * _not_ part of the public API for HDF5 application developers.
+ * Note: This routine is _only_ for HDF5 VOL connector authors! It is
+ * _not_ part of the public API for HDF5 application developers.
*
* Return: Success: Non-negative, *cmp set to a value like strcmp
*
@@ -381,11 +437,11 @@ done:
* Function: H5VLwrap_register
*
* Purpose: Wrap an internal object with a "wrap context" and register an
- * hid_t for the resulting object.
+ * hid_t for the resulting object.
*
- * Note: This routine is mainly targeted toward wrapping objects for
- * iteration routine callbacks (i.e. the callbacks from H5Aiterate*,
- * H5Literate* / H5Lvisit*, and H5Ovisit* ).
+ * Note: This routine is mainly targeted toward wrapping objects for
+ * iteration routine callbacks (i.e. the callbacks from H5Aiterate*,
+ * H5Literate* / H5Lvisit*, and H5Ovisit* ).
*
* Return: Success: Non-negative hid_t for the object.
* Failure: Negative (H5I_INVALID_HID)
@@ -420,10 +476,10 @@ done:
* Function: H5VLobject
*
* Purpose: Retrieve the object pointer associated with an hid_t for a.
- * VOL object.
+ * VOL object.
*
- * Note: This routine is mainly targeted toward unwrapping objects for
- * testing.
+ * Note: This routine is mainly targeted toward unwrapping objects for
+ * testing.
*
* Return: Success: Object pointer
* Failure: NULL
@@ -451,16 +507,16 @@ done:
* Function: H5VLretrieve_lib_state
*
* Purpose: Retrieves a copy of the internal state of the HDF5 library,
- * so that it can be restored later.
+ * so that it can be restored later.
*
- * Note: This routine is _only_ for HDF5 VOL connector authors! It is
- * _not_ part of the public API for HDF5 application developers.
+ * Note: This routine is _only_ for HDF5 VOL connector authors! It is
+ * _not_ part of the public API for HDF5 application developers.
*
* Return: Success: Non-negative, *state set
* Failure: Negative, *state unset
*
- * Programmer: Quincey Koziol
- * Thursday, January 10, 2019
+ * Programmer: Quincey Koziol
+ * Thursday, January 10, 2019
*
*---------------------------------------------------------------------------
*/
@@ -491,14 +547,14 @@ done:
*
* Purpose: Restores the internal state of the HDF5 library.
*
- * Note: This routine is _only_ for HDF5 VOL connector authors! It is
- * _not_ part of the public API for HDF5 application developers.
+ * Note: This routine is _only_ for HDF5 VOL connector authors! It is
+ * _not_ part of the public API for HDF5 application developers.
*
* Return: Success: Non-negative
* Failure: Negative
*
- * Programmer: Quincey Koziol
- * Thursday, January 10, 2019
+ * Programmer: Quincey Koziol
+ * Thursday, January 10, 2019
*
*---------------------------------------------------------------------------
*/
@@ -528,20 +584,20 @@ done:
* Function: H5VLreset_lib_state
*
* Purpose: Resets the internal state of the HDF5 library, undoing the
- * affects of H5VLrestore_lib_state.
+ * affects of H5VLrestore_lib_state.
*
- * Note: This routine is _only_ for HDF5 VOL connector authors! It is
- * _not_ part of the public API for HDF5 application developers.
+ * Note: This routine is _only_ for HDF5 VOL connector authors! It is
+ * _not_ part of the public API for HDF5 application developers.
*
- * Note: This routine must be called as a "pair" with
- * H5VLrestore_lib_state. It can be called before / after /
- * independently of H5VLfree_lib_state.
+ * Note: This routine must be called as a "pair" with
+ * H5VLrestore_lib_state. It can be called before / after /
+ * independently of H5VLfree_lib_state.
*
* Return: Success: Non-negative
* Failure: Negative
*
- * Programmer: Quincey Koziol
- * Saturday, February 23, 2019
+ * Programmer: Quincey Koziol
+ * Saturday, February 23, 2019
*
*---------------------------------------------------------------------------
*/
@@ -568,17 +624,17 @@ done:
*
* Purpose: Free a retrieved library state.
*
- * Note: This routine is _only_ for HDF5 VOL connector authors! It is
- * _not_ part of the public API for HDF5 application developers.
+ * Note: This routine is _only_ for HDF5 VOL connector authors! It is
+ * _not_ part of the public API for HDF5 application developers.
*
- * Note: This routine must be called as a "pair" with
- * H5VLretrieve_lib_state.
+ * Note: This routine must be called as a "pair" with
+ * H5VLretrieve_lib_state.
*
* Return: Success: Non-negative
* Failure: Negative
*
- * Programmer: Quincey Koziol
- * Thursday, January 10, 2019
+ * Programmer: Quincey Koziol
+ * Thursday, January 10, 2019
*
*---------------------------------------------------------------------------
*/
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index 2d1274c..696ccab 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -3041,7 +3041,7 @@ H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_t
arg_started = TRUE;
/* Special treatment of file access check */
- if(specific_type == H5VL_FILE_IS_ACCESSIBLE) {
+ if(specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) {
H5P_genplist_t *plist; /* Property list pointer */
H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
va_list tmp_args; /* argument list passed from the API call */
diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h
index 9b01ca2..62929ee 100644
--- a/src/H5VLconnector.h
+++ b/src/H5VLconnector.h
@@ -408,93 +408,6 @@ extern "C" {
/* Helper routines for VOL connector authors */
H5_DLL void *H5VLobject(hid_t obj_id);
-/* Public wrappers for generic callbacks */
-H5_DLL herr_t H5VLinitialize(hid_t connector_id, hid_t vipl_id);
-H5_DLL herr_t H5VLterminate(hid_t connector_id);
-H5_DLL herr_t H5VLget_cap_flags(hid_t connector_id, unsigned *cap_flags);
-H5_DLL herr_t H5VLget_value(hid_t connector_id, H5VL_class_value_t *conn_value);
-
-/* Public wrappers for info fields and callbacks */
-H5_DLL herr_t H5VLcopy_connector_info(hid_t connector_id, void **dst_vol_info, void *src_vol_info);
-H5_DLL herr_t H5VLcmp_connector_info(int *cmp, hid_t connector_id, const void *info1,
- const void *info2);
-H5_DLL herr_t H5VLfree_connector_info(hid_t connector_id, void *vol_info);
-H5_DLL herr_t H5VLconnector_info_to_str(const void *info, hid_t connector_id, char **str);
-H5_DLL herr_t H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info);
-
-/* Public wrappers for attribute callbacks */
-H5_DLL void *H5VLattr_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req);
-H5_DLL void *H5VLattr_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t aapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLattr_read(void *attr, hid_t connector_id, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLattr_write(void *attr, hid_t connector_id, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLattr_close(void *attr, hid_t connector_id, hid_t dxpl_id, void **req);
-
-/* Public wrappers for dataset callbacks */
-H5_DLL void *H5VLdataset_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
-H5_DLL void *H5VLdataset_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLdataset_read(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf, void **req);
-H5_DLL herr_t H5VLdataset_write(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
-H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdataset_close(void *dset, hid_t connector_id, hid_t dxpl_id, void **req);
-
-/* Public wrappers for file callbacks */
-H5_DLL void *H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
-H5_DLL void *H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLfile_close(void *file, hid_t connector_id, hid_t dxpl_id, void **req);
-
-/* Public wrappers for group callbacks */
-H5_DLL void *H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req);
-H5_DLL void *H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLgroup_close(void *grp, hid_t connector_id, hid_t dxpl_id, void **req);
-
-/* Public wrappers for link callbacks */
-H5_DLL herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1,
- void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id,
- hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1,
- void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id,
- hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLlink_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-
-/* Public wrappers for object callbacks */
-H5_DLL void *H5VLobject_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5I_type_t *opened_type, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name,
- void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name,
- hid_t connector_id, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLobject_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-
-/* Public wrappers for named datatype callbacks */
-H5_DLL void *H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req);
-H5_DLL void *H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req);
-H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
-H5_DLL herr_t H5VLdatatype_close(void *dt, hid_t connector_id, hid_t dxpl_id, void **req);
-
-/* Public wrappers for asynchronous request callbacks */
-H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status);
-H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx);
-H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id);
-H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, va_list arguments);
-H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments);
-H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h
index 5083cb4..9a2bd52 100644
--- a/src/H5VLconnector_passthru.h
+++ b/src/H5VLconnector_passthru.h
@@ -20,7 +20,7 @@
*
* The functionality required to implement such a connector is specialized
* and non-trivial so it has been split into this header in an effort to keep
- * the H5VLpublic_dev.h header easier to understand.
+ * the H5VLconnector.h header easier to understand.
*/
#ifndef _H5VLconnector_passthru_H
@@ -71,6 +71,92 @@ H5_DLL void *H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id,
H5_DLL void *H5VLunwrap_object(void *obj, hid_t connector_id);
H5_DLL herr_t H5VLfree_wrap_ctx(void *wrap_ctx, hid_t connector_id);
+/* Public wrappers for generic callbacks */
+H5_DLL herr_t H5VLinitialize(hid_t connector_id, hid_t vipl_id);
+H5_DLL herr_t H5VLterminate(hid_t connector_id);
+H5_DLL herr_t H5VLget_cap_flags(hid_t connector_id, unsigned *cap_flags);
+H5_DLL herr_t H5VLget_value(hid_t connector_id, H5VL_class_value_t *conn_value);
+
+/* Public wrappers for info fields and callbacks */
+H5_DLL herr_t H5VLcopy_connector_info(hid_t connector_id, void **dst_vol_info, void *src_vol_info);
+H5_DLL herr_t H5VLcmp_connector_info(int *cmp, hid_t connector_id, const void *info1,
+ const void *info2);
+H5_DLL herr_t H5VLfree_connector_info(hid_t connector_id, void *vol_info);
+H5_DLL herr_t H5VLconnector_info_to_str(const void *info, hid_t connector_id, char **str);
+H5_DLL herr_t H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info);
+
+/* Public wrappers for attribute callbacks */
+H5_DLL void *H5VLattr_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req);
+H5_DLL void *H5VLattr_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t aapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLattr_read(void *attr, hid_t connector_id, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLattr_write(void *attr, hid_t connector_id, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLattr_close(void *attr, hid_t connector_id, hid_t dxpl_id, void **req);
+
+/* Public wrappers for dataset callbacks */
+H5_DLL void *H5VLdataset_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
+H5_DLL void *H5VLdataset_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLdataset_read(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf, void **req);
+H5_DLL herr_t H5VLdataset_write(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
+H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdataset_close(void *dset, hid_t connector_id, hid_t dxpl_id, void **req);
+
+/* Public wrappers for file callbacks */
+H5_DLL void *H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
+H5_DLL void *H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLfile_close(void *file, hid_t connector_id, hid_t dxpl_id, void **req);
+
+/* Public wrappers for group callbacks */
+H5_DLL void *H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req);
+H5_DLL void *H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLgroup_close(void *grp, hid_t connector_id, hid_t dxpl_id, void **req);
+
+/* Public wrappers for link callbacks */
+H5_DLL herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1,
+ void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id,
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1,
+ void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id,
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLlink_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+
+/* Public wrappers for object callbacks */
+H5_DLL void *H5VLobject_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5I_type_t *opened_type, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name,
+ void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name,
+ hid_t connector_id, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLobject_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+
+/* Public wrappers for named datatype callbacks */
+H5_DLL void *H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req);
+H5_DLL void *H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments);
+H5_DLL herr_t H5VLdatatype_close(void *dt, hid_t connector_id, hid_t dxpl_id, void **req);
+
+/* Public wrappers for asynchronous request callbacks */
+H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status);
+H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx);
+H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id);
+H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, va_list arguments);
+H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments);
+H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id);
#ifdef __cplusplus
}
diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c
index 8903911..eeaade6 100644
--- a/src/H5VLnative_file.c
+++ b/src/H5VLnative_file.c
@@ -386,10 +386,16 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type,
/* Call private routine */
if((*ret = H5F__is_hdf5(name, fapl_id)) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "error in HDF5 file check")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "error in HDF5 file check")
break;
}
+ /* H5Fdelete */
+ case H5VL_FILE_DELETE:
+ {
+ HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "H5Fdelete() is currently not supported in the native VOL connector")
+ break;
+ }
default:
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
index f0672b2..eecdac2 100644
--- a/src/H5VLpassthru.c
+++ b/src/H5VLpassthru.c
@@ -1737,7 +1737,7 @@ H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type,
/* Re-issue 'file specific' call, using the unwrapped pieces */
ret_value = H5VL_pass_through_file_specific_reissue(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, (int)loc_type, name, child_file->under_object, plist_id);
} /* end if */
- else if(specific_type == H5VL_FILE_IS_ACCESSIBLE) {
+ else if(specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) {
H5VL_pass_through_info_t *info;
hid_t fapl_id, under_fapl_id;
const char *name;
diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h
index 326e65e..12448b6 100644
--- a/src/H5VLpublic.h
+++ b/src/H5VLpublic.h
@@ -34,7 +34,7 @@
* These are H5VL_class_value_t values, NOT hid_t values!
*/
#define H5_VOL_INVALID (-1) /* Invalid ID for VOL connector iD */
-#define H5_VOL_NATIVE 0 /* Native HDF5 file formnat VOL connector */
+#define H5_VOL_NATIVE 0 /* Native HDF5 file format VOL connector */
#define H5_VOL_RESERVED 256 /* VOL connector IDs below this value are reserved for library use */
#define H5_VOL_MAX 65535 /* Maximum VOL connector ID */
diff --git a/src/H5err.txt b/src/H5err.txt
index 4eedc0f..d4edfba 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -134,6 +134,7 @@ MINOR, FILEACC, H5E_NOTHDF5, Not an HDF5 file
MINOR, FILEACC, H5E_BADFILE, Bad file ID accessed
MINOR, FILEACC, H5E_TRUNCATED, File has been truncated
MINOR, FILEACC, H5E_MOUNT, File mount error
+MINOR, FILEACC, H5E_CANTDELETEFILE, Unable to delete file
# Generic low-level file I/O errors
MINOR, FILE, H5E_SEEKERROR, Seek failed
diff --git a/src/H5trace.c b/src/H5trace.c
index 851ec73..ff81ae8 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -2714,6 +2714,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
case H5VL_FILE_GET_INTENT:
HDfprintf(out, "H5VL_FILE_GET_INTENT");
break;
+ case H5VL_FILE_GET_FILENO:
+ HDfprintf(out, "H5VL_FILE_GET_FILENO");
+ break;
case H5VL_FILE_GET_NAME:
HDfprintf(out, "H5VL_FILE_GET_NAME");
break;
@@ -2755,6 +2758,9 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
case H5VL_FILE_IS_ACCESSIBLE:
HDfprintf(out, "H5VL_FILE_IS_ACCESSIBLE");
break;
+ case H5VL_FILE_DELETE:
+ HDfprintf(out, "H5VL_FILE_DELETE");
+ break;
default:
HDfprintf(out, "%ld", (long)specific);
break;
diff --git a/src/Makefile.am b/src/Makefile.am
index 0368739..73a8c83 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,10 +32,18 @@ lib_LTLIBRARIES=libhdf5.la
# Add libtool numbers to the HDF5 library (from config/lt_vers.am)
libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_VERS_AGE) $(AM_LDFLAGS)
+# h5cc needs custom install and uninstall rules, since it may be
+# named h5pcc if hdf5 is being built in parallel mode.
+if BUILD_PARALLEL_CONDITIONAL
+ H5CC_NAME=h5pcc
+else
+ H5CC_NAME=h5cc
+endif
+
# H5Tinit.c and H5lib_settings.c are generated files and should be cleaned.
MOSTLYCLEANFILES=H5Tinit.c H5lib_settings.c
# H5pubconf.h is generated by configure, and should be cleaned.
-DISTCLEANFILES=H5pubconf.h
+DISTCLEANFILES=H5pubconf.h $(H5CC_NAME)
# library sources
libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
@@ -152,6 +160,8 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
settingsdir=$(libdir)
settings_DATA=libhdf5.settings
+bin_SCRIPTS=$(H5CC_NAME)
+
# Number format detection
# The LD_LIBRARY_PATH setting is a kludge.
# Things should have been all set during H5detect making.
@@ -210,4 +220,10 @@ trace: $(libhdf5_la_SOURCES)
fi; \
done
+#install-exec-local:
+# @$(INSTALL) h5cc $(DESTDIR)$(bindir)/$(H5CC_NAME)
+#uninstall-local:
+# @$(RM) $(DESTDIR)$(bindir)/$(H5CC_NAME)
+
include $(top_srcdir)/config/conclude.am
+
diff --git a/src/h5cc.in b/src/h5cc.in
new file mode 100644
index 0000000..9c4e3ca
--- /dev/null
+++ b/src/h5cc.in
@@ -0,0 +1,399 @@
+#! /bin/sh
+##
+# Copyright by The HDF Group.
+# Copyright by the Board of Trustees of the University of Illinois.
+# 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://support.hdfgroup.org/ftp/HDF5/releases.
+# If you do not have access to either file, you may request a copy from
+# help@hdfgroup.org.
+##
+
+# This tool is adapted from the mpicc command of the MPICH Software.
+
+############################################################################
+## ##
+## Things You May Have to Modify: ##
+## ##
+## If the following paths don't point to the place were HDF5 is installed ##
+## on your system (i.e., you received a binary distribution or moved the ##
+## files from the originally installed directory to another directory) ##
+## then modify them accordingly to represent the new paths. ##
+## ##
+############################################################################
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+libdir="@libdir@"
+includedir="@includedir@"
+HL="@HL@"
+
+############################################################################
+## ##
+## Things You Can Modify to Override HDF5 Library Build Components: ##
+## ##
+## (Advanced usage - know what you're doing - you're on your own here.) ##
+## The four variables below can be used to insert paths and flags in ##
+## CPPFLAGS, CFLAGS, LDFLAGS, or LIBS in the h5cc compile line: ##
+## $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS ##
+## $LIBS $clibpath $link_objs $link_args $shared_link ##
+## ##
+## These settings can be overriden by setting HDF5_CFLAGS, ##
+## HDF5_CPPFLAGS, HDF5_LDFLAGS, or HDF5_LIBS in the environment. ##
+## ##
+############################################################################
+CFLAGSBASE=""
+CPPFLAGSBASE=""
+LDFLAGSBASE=""
+LIBSBASE=""
+
+############################################################################
+## ##
+## You shouldn't have to modify anything below this line. ##
+## ##
+############################################################################
+
+# Constants definitions
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+host_os="@host_os@"
+
+prog_name="`basename $0`"
+
+allargs=""
+compile_args=""
+libraries=""
+link_args=""
+link_objs=""
+clibpath=""
+
+do_link="yes"
+do_compile="no"
+dash_o="no"
+dash_c="no"
+get_output_file="no"
+
+SHOW="eval"
+CCBASE="@CC@"
+CLINKERBASE="@CC@"
+
+# CFLAGS, CPPFLAGS and LDFLAGS are reserved for use by the script user.
+# FLAGS brought from the hdf5 build are put in H5BLD_*FLAGS.
+
+# User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's
+# LDFLAGS come just before clibpath, user's LIBS come after $link_objs and
+# before the hdf5 libraries in $link_args, followed by any external library
+# paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in
+# from the hdf5 build. The order of the flags is intended to give precedence
+# to the user's flags.
+H5BLD_CFLAGS="@AM_CFLAGS@ @CFLAGS@"
+H5BLD_CPPFLAGS="@AM_CPPFLAGS@ @CPPFLAGS@"
+H5BLD_LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@"
+H5BLD_LIBS="@LIBS@"
+
+CC="${HDF5_CC:-$CCBASE}"
+CLINKER="${HDF5_CLINKER:-$CLINKERBASE}"
+CFLAGS="${HDF5_CFLAGS:-$CFLAGSBASE}"
+CPPFLAGS="${HDF5_CPPFLAGS:-$CPPFLAGSBASE}"
+LDFLAGS="${HDF5_LDFLAGS:-$LDFLAGSBASE}"
+LIBS="${HDF5_LIBS:-$LIBSBASE}"
+
+# If a static library is available, the default will be to use it. If the only
+# available library is shared, it will be used by default. The user can
+# override either default, although choosing an unavailable library will result
+# in link errors.
+STATIC_AVAILABLE="@enable_static@"
+if test "${STATIC_AVAILABLE}" = "yes"; then
+ USE_SHARED_LIB="${HDF5_USE_SHLIB:-no}"
+else
+ USE_SHARED_LIB="${HDF5_USE_SHLIB:-yes}"
+fi
+
+
+usage() {
+ # A wonderfully informative "usage" message.
+ echo "usage: $prog_name [OPTIONS] <compile line>"
+ echo " OPTIONS:"
+ echo " -help This help message."
+ echo " -echo Show all the shell commands executed"
+ echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/"
+ echo " subdirectories [default: $prefix]"
+ # A wonderfully informative "usage" message.
+ echo "usage: $prog_name [OPTIONS] <compile line>"
+ echo " OPTIONS:"
+ echo " -help This help message."
+ echo " -echo Show all the shell commands executed"
+ echo " -prefix=DIR Prefix directory to find HDF5 lib/ and include/"
+ echo " subdirectories [default: $prefix]"
+ echo " -show Show the commands without executing them"
+ echo " -showconfig Show the HDF5 library configuration summary"
+ echo " -shlib Compile with shared HDF5 libraries [default for hdf5 built"
+ echo " without static libraries]"
+ echo " -noshlib Compile with static HDF5 libraries [default for hdf5 built"
+ echo " with static libraries]"
+ echo " "
+ echo " <compile line> - the normal compile line options for your compiler."
+ echo " $prog_name uses the same compiler you used to compile"
+ echo " HDF5. Check with your compiler's man pages for more"
+ echo " information on which options are needed."
+ echo " "
+ echo " You can override the compiler, linker, and whether or not to use static"
+ echo " or shared libraries to compile your program by setting the following"
+ echo " environment variables accordingly:"
+ echo " "
+ echo " HDF5_CC - use a different C compiler"
+ echo " HDF5_CLINKER - use a different linker"
+ echo " HDF5_USE_SHLIB=[yes|no] - use shared or static version of the HDF5 library"
+ echo " [default: no except when built with only"
+ echo " shared libraries]"
+ echo " "
+ echo " You can also add or change paths and flags to the compile line using"
+ echo " the following environment varibles or by assigning them to their counterparts"
+ echo " in the 'Things You Can Modify to Override...'" section of $prog_name
+ echo " "
+ echo " Variable Current value to be replaced"
+ echo " HDF5_CPPFLAGS \"$CPPFLAGSBASE\""
+ echo " HDF5_CFLAGS \"$CFLAGSBASE\""
+ echo " HDF5_LDFLAGS \"$LDFLAGSBASE\""
+ echo " HDF5_LIBS \"$LIBSBASE\""
+ echo " "
+ echo " Note that adding library paths to HDF5_LDFLAGS where another hdf5 version"
+ echo " is located may link your program with that other hdf5 library version."
+ echo " "
+ exit $EXIT_FAILURE
+}
+
+# Show the configuration summary of the library recorded in the
+# libhdf5.settings file reside in the lib directory.
+showconfigure()
+{
+ cat ${libdir}/libhdf5.settings
+ status=$?
+}
+
+# Main
+status=$EXIT_SUCCESS
+
+if test "$#" = "0"; then
+ # No parameters specified, issue usage statement and exit.
+ usage
+fi
+
+case "$CC" in
+ gcc)
+ kind="gcc"
+ ;;
+ mpicc|mpcc|mpicc_r)
+ # Is this gcc masquarading as an MPI compiler?
+ if test "`${CC} -v 2>&1 | sed -n 2p | cut -c1-3`" = "gcc"; then
+ kind="gcc"
+ else
+ # Nope
+ kind="$host_os"
+ fi
+ ;;
+ *)
+ kind="$host_os"
+ ;;
+esac
+
+for arg in $@ ; do
+ if test "x$get_output_file" = "xyes"; then
+ link_args="$link_args $arg"
+ output_file="$arg"
+ get_output_file="no"
+ continue
+ fi
+
+ case "$arg" in
+ -c)
+ allargs="$allargs $arg"
+ compile_args="$compile_args $arg"
+
+ if test "x$do_link" = "xyes" -a -n "$output_file"; then
+ compile_args="$compile_args -o $output_file"
+ fi
+
+ do_link="no"
+ dash_c="yes"
+ ;;
+ -o)
+ allargs="$allargs $arg"
+ dash_o="yes"
+
+ if test "x$dash_c" = "xyes"; then
+ compile_args="$compile_args $arg"
+ else
+ link_args="$link_args $arg"
+ do_link="yes"
+ get_output_file="yes"
+ fi
+ ;;
+ -E|-M|-MT)
+ allargs="$allargs $arg"
+ compile_args="$compile_args $arg"
+ dash_c="yes"
+ do_link="no"
+ ;;
+ -l*)
+ libraries=" $libraries $arg "
+ allargs="$allargs $arg"
+ ;;
+ -prefix=*)
+ prefix="`expr "$arg" : '-prefix=\(.*\)'`"
+ ;;
+ -echo)
+ set -x
+ ;;
+ -show)
+ SHOW="echo"
+ ;;
+ -showconfig)
+ showconfigure
+ exit $status
+ ;;
+ -shlib)
+ USE_SHARED_LIB="yes"
+ ;;
+ -noshlib)
+ USE_SHARED_LIB="no"
+ ;;
+ -help)
+ usage
+ ;;
+ *\"*)
+ qarg="'"$arg"'"
+ allargs="$allargs $qarg"
+ ;;
+ *\'*)
+ qarg='\"'"$arg"'\"'
+ allargs="$allargs $qarg"
+ ;;
+ *)
+ allargs="$allargs $qarg"
+
+ if test -s "$arg"; then
+ ext=`expr "$arg" : '.*\(\..*\)'`
+
+ if test "x$ext" = "x.c"; then
+ do_compile="yes"
+ compile_args="$compile_args $arg"
+ fname=`basename $arg .c`
+ link_objs="$link_objs $fname.o"
+ elif test "x$ext" = "x.o"; then
+ if test "x$dash_c" = "xyes"; then
+ compile_args="$compile_args $arg"
+ else
+ do_link="yes"
+ link_objs="$link_objs $arg"
+ fi
+ elif test "x$ext" = "x.a"; then
+ # This is an archive that we're linking in
+ libraries=" $libraries $arg "
+ else
+ compile_args="$compile_args $arg"
+ link_args="$link_args $arg"
+ fi
+ else
+ compile_args="$compile_args $arg"
+ link_args="$link_args $arg"
+ fi
+ ;;
+ esac
+done
+
+if test "$dash_c" = "yes" -a "$do_compile" = no -a "$do_link" = no ; then
+ # -c was specified. Force do_compile on.
+ do_compile=yes
+fi
+
+if test "x$do_compile" = "xyes"; then
+ if test "x$dash_c" != "xyes"; then
+ compile_args="-c $compile_args"
+ fi
+
+ $SHOW $CC -I$includedir $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $compile_args
+ status=$?
+
+ if test "$status" != "0"; then
+ exit $status
+ fi
+fi
+
+if test "x$do_link" = "xyes"; then
+ shared_link=""
+# conditionnaly link with the hl library
+ if test "X$HL" = "Xhl"; then
+ libraries=" $libraries -lhdf5_hl -lhdf5 "
+ else
+ libraries=" $libraries -lhdf5 "
+ fi
+ link_args="$link_args -L${libdir}"
+
+ case "$kind" in
+ gcc|linux*)
+ # MacOS X doesn't support the "-Wl,-rpath -Wl," style of linker flags.
+ # It appears to want none of them specified.
+ case "$host_os" in
+ darwin*) flag="" ;;
+ *) flag="-Wl,-rpath -Wl," ;;
+ esac
+ ;;
+ hpux*) flag="-Wl,+b -Wl," ;;
+ freebsd*|solaris*) flag="-R" ;;
+ rs6000*|aix*) flag="-L" ;;
+ sgi) flag="-rpath " ;;
+ *) flag="" ;;
+ esac
+
+ if test -n "$flag"; then
+ shared_link="${flag}${libdir}"
+ fi
+
+ if test "x$USE_SHARED_LIB" != "xyes"; then
+ # The "-lhdf5" & "-lhdf5_hl" flags are in here already...This is a static
+ # compile though, so change it to the static version (.a) of the library.
+ new_libraries=""
+ for lib in $libraries; do
+ case "$lib" in
+ -lhdf5)
+ new_libraries="$new_libraries ${libdir}/libhdf5.a"
+ ;;
+ -lhdf5_hl)
+ new_libraries="$new_libraries ${libdir}/libhdf5_hl.a"
+ ;;
+ *)
+ new_libraries="$new_libraries $lib"
+ ;;
+ esac
+ done
+ libraries="$new_libraries"
+ fi
+
+ for lib in $libraries; do
+ if echo $link_args | grep " $lib " > /dev/null ||
+ echo $link_args | grep " $lib$" > /dev/null; then
+ :
+ else
+ link_args="$link_args $lib "
+ fi
+ done
+
+ # The LIBS are just a bunch of -l* libraries necessary for the HDF5
+ # module. It's okay if they're included twice in the compile line.
+ link_args="$link_args $H5BLD_LDFLAGS $H5BLD_LIBS"
+
+ # User's CPPFLAGS and CFLAGS come after their H5BLD counterparts. User's
+ # LDFLAGS come just before clibpath, user's LIBS come after $link_objs and
+ # before the hdf5 libraries in $link_args, followed by any external library
+ # paths and libraries from AM_LDFLAGS, LDFLAGS, AM_LIBS or LIBS carried in
+ # from the hdf5 build. The order of the flags is intended to give precedence
+ # to the user's flags.
+ $SHOW $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CFLAGS $CFLAGS $LDFLAGS $clibpath $link_objs $LIBS $link_args $shared_link
+ status=$?
+fi
+
+exit $status
diff --git a/src/libhdf5.settings.in b/src/libhdf5.settings.in
index 9d0e29f..37957a2 100644
--- a/src/libhdf5.settings.in
+++ b/src/libhdf5.settings.in
@@ -71,6 +71,8 @@ Features:
Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@
Large Parallel I/O: @LARGE_PARALLEL_IO@
High-level library: @HDF5_HL@
+ Build HDF5 Tests: @HDF5_TESTS@
+ Build HDF5 TOOLS: @HDF5_TOOLS@
Threadsafety: @THREADSAFE@
Default API mapping: @DEFAULT_API_VERSION@
With deprecated public symbols: @DEPRECATED_SYMBOLS@