summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5O.c4
-rw-r--r--test/links.c85
3 files changed, 92 insertions, 0 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 6bd5796..9262fc8 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -153,6 +153,9 @@ Bug Fixes since HDF5-1.8.1
Library
-------
+ - H5Ovisit and H5Ovisit_by_name will now properly terminate when the
+ callback function returns a positive value on the starting object.
+ (NAF - 2008/11/03)
- Fixed an error where a null message could be created that was larger
than could be written to the file. (NAF - 2008/10/23)
- Corrected error with family/split/multi VFD not updating driver info
diff --git a/src/H5O.c b/src/H5O.c
index bf12c3f..acd31fb 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -2810,6 +2810,10 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
if((ret_value = op(obj_id, ".", &oinfo, op_data)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "can't visit objects")
+ /* Check return value of first callback */
+ if(ret_value != H5_ITER_CONT)
+ HGOTO_DONE(ret_value);
+
/* Check for object being a group */
if(oinfo.type == H5O_TYPE_GROUP) {
H5G_loc_t start_loc; /* Location of starting group */
diff --git a/test/links.c b/test/links.c
index d57615a..cfbfde6 100644
--- a/test/links.c
+++ b/test/links.c
@@ -7755,6 +7755,90 @@ error:
/*-------------------------------------------------------------------------
+ * Function: visit_obj_stop_cb
+ *
+ * Purpose: Callback routine for visiting objects in a file
+ *
+ * Return: 1 (H5_ITER_STOP)
+ *
+ * Programmer: Neil Fortner
+ * Sunday, November 2, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+visit_obj_stop_cb(hid_t UNUSED group_id, const char UNUSED *name, const H5O_info_t UNUSED *oinfo,
+ void *_op_data)
+{
+ unsigned *op_data = (unsigned *)_op_data;
+
+ /* Increment the number of visited objects */
+ (*op_data)++;
+
+ return(H5_ITER_STOP);
+} /* end visit_obj_stop_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: obj_visit_stop
+ *
+ * Purpose: Test that the object visiting routine stops iteration
+ * properly on the starting object.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Neil Fortner
+ * Sunday, November 2, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+obj_visit_stop(hid_t fapl, hbool_t new_format)
+{
+ unsigned nvisited; /* User-data for visiting */
+ hid_t fid = -1;
+ herr_t ret; /* Return value */
+
+ if(new_format)
+ TESTING("stopping object iteration (w/new group format)")
+ else
+ TESTING("stopping object iteration")
+
+ /* Construct "interesting" file to visit */
+ if((fid = build_visit_file(fapl)) < 0) TEST_ERROR
+
+ /* Start iteration. The callback should only be called once because it
+ * returns H5_ITER_STOP
+ */
+ nvisited = 0;
+ if((ret = H5Ovisit(fid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb, &nvisited)) < 0)
+ FAIL_STACK_ERROR
+ if(ret != H5_ITER_STOP) TEST_ERROR
+ if(nvisited != 1) TEST_ERROR
+
+ /* Same test with H5Ovisit_by_name */
+ nvisited = 0;
+ if((ret = H5Ovisit_by_name(fid, "/", H5_INDEX_NAME, H5_ITER_INC, visit_obj_stop_cb,
+ &nvisited, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+ if(ret != H5_ITER_STOP) TEST_ERROR
+ if(nvisited != 1) TEST_ERROR
+
+ /* Close file created */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end obj_visit_stop() */
+
+
+/*-------------------------------------------------------------------------
* Function: corder_create_empty
*
* Purpose: Create an empty group with creation order indices
@@ -12286,6 +12370,7 @@ main(void)
nerrors += link_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += obj_visit(my_fapl, new_format) < 0 ? 1 : 0;
nerrors += obj_visit_by_name(my_fapl, new_format) < 0 ? 1 : 0;
+ nerrors += obj_visit_stop(my_fapl, new_format) < 0 ? 1 : 0;
/* Keep this test last, it's testing files that are used above */
/* do not do this for files used by external link tests */