summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST15
-rwxr-xr-xbin/reconfigure7
-rwxr-xr-xbin/trace2
-rw-r--r--src/H5.c11
-rw-r--r--src/H5D.c119
-rw-r--r--src/H5Dpublic.h3
-rw-r--r--src/H5Edefin.h217
-rw-r--r--src/H5Einit.h713
-rw-r--r--src/H5Epubgen.h384
-rw-r--r--src/H5Eterm.h221
-rw-r--r--src/H5Fmount.c4
-rw-r--r--src/H5G.c213
-rw-r--r--src/H5Gdeprec.c20
-rw-r--r--src/H5Gent.c94
-rw-r--r--src/H5Glink.c72
-rw-r--r--src/H5Gloc.c10
-rw-r--r--src/H5Gname.c7
-rw-r--r--src/H5Gnode.c92
-rw-r--r--src/H5Gobj.c29
-rw-r--r--src/H5Gpkg.h50
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5Gpublic.h30
-rw-r--r--src/H5Gstab.c47
-rw-r--r--src/H5Gtraverse.c272
-rw-r--r--src/H5L.c1156
-rw-r--r--src/H5Lexternal.c314
-rw-r--r--src/H5Lpkg.h7
-rw-r--r--src/H5Lprivate.h16
-rw-r--r--src/H5Lpublic.h108
-rw-r--r--src/H5O.c400
-rw-r--r--src/H5Oattr.c4
-rw-r--r--src/H5Olink.c81
-rw-r--r--src/H5Oprivate.h6
-rw-r--r--src/H5Opublic.h7
-rw-r--r--src/H5Oshared.c8
-rw-r--r--src/H5P.c40
-rw-r--r--src/H5Pgcpl.c2
-rw-r--r--src/H5Plapl.c117
-rw-r--r--src/H5Ppublic.h8
-rw-r--r--src/H5R.c2
-rw-r--r--src/H5T.c15
-rw-r--r--src/H5Tbit.c3
-rw-r--r--src/H5Tcommit.c93
-rw-r--r--src/H5Tpublic.h1
-rw-r--r--src/H5err.txt11
-rw-r--r--src/H5private.h1
-rwxr-xr-xsrc/Makefile.am4
-rw-r--r--src/Makefile.in35
-rw-r--r--test/Makefile.am14
-rw-r--r--test/Makefile.in73
-rw-r--r--test/be_extlink1.h5bin0 -> 1120 bytes
-rw-r--r--test/be_extlink2.h5bin0 -> 2840 bytes
-rw-r--r--test/gen_udlinks.c81
-rw-r--r--test/le_extlink1.h5bin0 -> 1120 bytes
-rw-r--r--test/le_extlink2.h5bin0 -> 2840 bytes
-rw-r--r--test/links.c3571
-rw-r--r--test/mount.c24
-rwxr-xr-xtest/objcopy.c195
-rw-r--r--test/stab.c6
-rw-r--r--test/testhdf5.c1
-rw-r--r--test/testhdf5.h2
-rw-r--r--test/th5o.c601
-rw-r--r--test/titerate.c4
-rw-r--r--test/tmisc.c50
-rw-r--r--test/unlink.c322
-rw-r--r--tools/h5diff/h5diffgentest.c34
-rw-r--r--tools/h5dump/h5dump.c202
-rw-r--r--tools/h5dump/h5dump.h10
-rw-r--r--tools/h5dump/h5dumpgentest.c151
-rw-r--r--tools/h5dump/testh5dump.sh.in4
-rwxr-xr-xtools/h5dump/testh5dumpxml.sh.in2
-rw-r--r--tools/h5jam/h5jam.c1
-rw-r--r--tools/h5jam/h5jamgentest.c345
-rw-r--r--tools/h5ls/h5ls.c65
-rwxr-xr-xtools/h5ls/testh5ls.sh4
-rw-r--r--tools/h5repack/h5repack_copy.c56
-rw-r--r--tools/h5repack/h5repack_list.c3
-rw-r--r--tools/h5repack/h5repack_refs.c6
-rw-r--r--tools/h5repack/testh5repack_dset.c2
-rw-r--r--tools/h5repack/testh5repack_main.c1
-rw-r--r--tools/h5repack/testh5repack_make.c19
-rw-r--r--tools/lib/h5diff.c85
-rw-r--r--tools/lib/h5diff_util.c2
-rw-r--r--tools/lib/h5tools.c162
-rw-r--r--tools/lib/h5tools_ref.c6
-rw-r--r--tools/lib/h5trav.c58
-rw-r--r--tools/misc/h5stat.c3
-rw-r--r--tools/testfiles/file3.h5bin3184 -> 3512 bytes
-rw-r--r--tools/testfiles/tall-1.ddl8
-rw-r--r--tools/testfiles/tall-2.ls2
-rw-r--r--tools/testfiles/tall-2A.ddl8
-rw-r--r--tools/testfiles/tall-2A.h5.xml24
-rw-r--r--tools/testfiles/tall-2B.ddl8
-rw-r--r--tools/testfiles/tall.h5bin11440 -> 9744 bytes
-rw-r--r--tools/testfiles/tall.h5.xml24
-rw-r--r--tools/testfiles/tcontents.ddl4
-rw-r--r--tools/testfiles/textlink.h5bin0 -> 1264 bytes
-rw-r--r--tools/testfiles/textlink.h5.xml10
-rw-r--r--tools/testfiles/tfcontents1.h5bin8424 -> 6696 bytes
-rw-r--r--tools/testfiles/tfcontents2.h5bin976 -> 792 bytes
-rw-r--r--tools/testfiles/tmany.h5bin15160 -> 18896 bytes
-rw-r--r--tools/testfiles/tmany.h5.xml44
-rw-r--r--tools/testfiles/tudlink-1.ddl13
-rw-r--r--tools/testfiles/tudlink-1.ls5
-rw-r--r--tools/testfiles/tudlink-2.ddl9
-rw-r--r--tools/testfiles/tudlink.h5bin0 -> 1120 bytes
-rw-r--r--tools/testfiles/tudlink.h5.xml10
-rw-r--r--tools/testfiles/twithub.h5bin10820 -> 8852 bytes
-rw-r--r--tools/testfiles/twithub513.h5bin12560 -> 10920 bytes
109 files changed, 9339 insertions, 2068 deletions
diff --git a/MANIFEST b/MANIFEST
index 3836030..0417492 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -530,6 +530,7 @@
./src/H5Iprivate.h
./src/H5Ipublic.h
./src/H5L.c
+./src/H5Lexternal.c
./src/H5Lpkg.h
./src/H5Lprivate.h
./src/H5Lpublic.h
@@ -571,6 +572,7 @@
./src/H5Pfapl.c
./src/H5Pfcpl.c
./src/H5Pgcpl.c
+./src/H5Plapl.c
./src/H5Plcpl.c
./src/H5Pocpl.c
./src/H5Ppkg.h
@@ -646,6 +648,8 @@
./test/Makefile.am
./test/Makefile.in
./test/be_data.h5
+./test/be_extlink1.h5
+./test/be_extlink2.h5
./test/big.c
./test/bittests.c
./test/btree2.c
@@ -689,6 +693,7 @@
./test/gen_old_group.c _DO_NOT_DISTRIBUTE_
./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_
./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_
+./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_
./test/getname.c
./test/gheap.c
./test/group_old.h5
@@ -697,6 +702,8 @@
./test/hyperslab.c
./test/istore.c
./test/le_data.h5
+./test/le_extlink1.h5
+./test/le_extlink2.h5
./test/lheap.c
./test/links.c
./test/mergemsg.h5
@@ -724,6 +731,7 @@
./test/testmeta.c
./test/tfile.c
./test/tgenprop.c
+./test/th5o.c
./test/th5s.c
./test/th5s.h5
./test/theap.c
@@ -983,6 +991,8 @@
./tools/testfiles/tempty.ls
./tools/testfiles/tenum.h5
./tools/testfiles/tenum.ddl
+./tools/testfiles/textlink.h5
+./tools/testfiles/textlink.h5.xml
./tools/testfiles/tfamily.ddl
./tools/testfiles/tfamily00000.h5
./tools/testfiles/tfamily00001.h5
@@ -1057,6 +1067,11 @@
./tools/testfiles/tvldtypes5.h5
./tools/testfiles/tvlstr.h5
./tools/testfiles/tvlstr.ddl
+./tools/testfiles/tudlink.h5
+./tools/testfiles/tudlink.h5.xml
+./tools/testfiles/tudlink-1.ddl
+./tools/testfiles/tudlink-2.ddl
+./tools/testfiles/tudlink-1.ls
./tools/testfiles/tattr2.h5
./tools/testfiles/tall-2A.ddl
./tools/testfiles/tall-2B.ddl
diff --git a/bin/reconfigure b/bin/reconfigure
index b82f734..857efe9 100755
--- a/bin/reconfigure
+++ b/bin/reconfigure
@@ -120,4 +120,11 @@ echo
echo " Running trace script:"
bin/trace src/H5*.c || exit 1
+# Run make_error
+# make_error automatically generates the H5E headers that create error message
+# types for HDF5.
+echo
+echo " Running error generation script:"
+bin/make_err src/H5err.txt || exit 1
+
exit 0
diff --git a/bin/trace b/bin/trace
index eb9d95d..73810bf 100755
--- a/bin/trace
+++ b/bin/trace
@@ -51,6 +51,7 @@ $Source = "";
"H5G_obj_t" => "Go",
"H5G_stat_t*" => "Gs",
"H5L_link_t" => "Ll",
+ "unsigned long" => "Lu",
"hsize_t" => "h",
"hssize_t" => "Hs",
"hid_t" => "i",
@@ -87,6 +88,7 @@ $Source = "";
"H5E_auto_t" => "x",
"H5E_walk_t" => "x",
"H5G_iterate_t" => "x",
+ "H5L_link_class_t" => "x",
"H5MM_allocate_t" => "x",
"H5MM_free_t" => "x",
"H5P_cls_create_func_t" => "x",
diff --git a/src/H5.c b/src/H5.c
index d873797..67530e6 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -22,6 +22,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free lists */
#include "H5Ipkg.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5Rpublic.h" /* References */
@@ -135,6 +136,8 @@ H5_init_library(void)
* initialized. The property interface must be initialized before the file
* & dataset interfaces though, in order to provide them with the proper
* property classes.
+ * The link interface needs to be initialized so that link property lists
+ * have their properties registered.
*/
if (H5E_init()<0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface")
@@ -148,6 +151,8 @@ H5_init_library(void)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataset interface")
if (H5AC_init()<0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize metadata caching interface")
+ if (H5L_init()<0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize link interface")
/* Debugging? */
H5_debug_mask("-all");
@@ -1903,7 +1908,10 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
fprintf (out, "H5G_UNKNOWN");
break;
case H5G_LINK:
- fprintf (out, "H5L_LINK");
+ fprintf (out, "H5G_LINK");
+ break;
+ case H5G_UDLINK:
+ fprintf (out, "H5G_UDLINK");
break;
case H5G_GROUP:
fprintf (out, "H5G_GROUP");
@@ -1914,7 +1922,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
case H5G_TYPE:
fprintf (out, "H5G_TYPE");
break;
- case H5G_RESERVED_4:
case H5G_RESERVED_5:
case H5G_RESERVED_6:
case H5G_RESERVED_7:
diff --git a/src/H5D.c b/src/H5D.c
index 70f84ad..073b74d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -228,6 +228,7 @@ H5D_init_interface(void)
H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */
size_t nprops; /* Number of properties */
+ H5P_genclass_t *acc_pclass;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_init_interface)
@@ -428,6 +429,20 @@ H5D_init_interface(void)
if (H5D_get_dxpl_cache_real(H5P_DATASET_XFER_DEFAULT, &H5D_def_dxpl_cache) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve default DXPL info")
+ /* ========== Dataset Access Property Class Initialization ============*/
+ assert(H5P_CLS_DATASET_ACCESS_g!=-1);
+
+ /* Get the pointer to dataset creation class */
+ if(NULL == (acc_pclass = H5I_object(H5P_CLS_DATASET_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
+
+ /* Only register the default property list if it hasn't been created yet */
+ if(H5P_LST_DATASET_ACCESS_g == (-1)) {
+ /* Register the default dataset access property list */
+ if((H5P_LST_DATASET_ACCESS_g = H5P_create_id(acc_pclass))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
+ } /* end if */
+
done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -1213,11 +1228,11 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
if(H5G_loc(dset_id, &dset_loc) <0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to get location for dataset")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get location for dataset")
/* Link the new dataset */
- if( H5L_link(&loc, name, &dset_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to dataset")
+ if( H5L_link(&loc, name, &dset_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to dataset")
ret_value = dset_id;
@@ -1277,7 +1292,7 @@ done:
*/
hid_t
H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id,
- hid_t dcpl_id)
+ hid_t dcpl_id, hid_t dapl_id)
{
H5G_loc_t loc; /* Object location to insert dataset into */
H5D_t *new_dset = NULL; /* New dataset's info */
@@ -1285,7 +1300,7 @@ H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id,
hid_t ret_value; /* Return value */
FUNC_ENTER_API(H5Dcreate_expand, FAIL)
- H5TRACE4("i","iiii",loc_id,type_id,space_id,dcpl_id);
+ H5TRACE5("i","iiiii",loc_id,type_id,space_id,dcpl_id,dapl_id);
/* Check arguments */
if(H5G_loc(loc_id, &loc) < 0)
@@ -1300,6 +1315,13 @@ H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id,
if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID")
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
/* build and open the new dataset */
if(NULL == (new_dset = H5D_create(loc.oloc->file, type_id, space, dcpl_id, H5AC_dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
@@ -1363,7 +1385,7 @@ H5Dopen(hid_t loc_id, const char *name)
H5G_loc_reset(&dset_loc);
/* Find the dataset object */
- if(H5G_loc_find(&loc, name, &dset_loc, dxpl_id) < 0)
+ if(H5G_loc_find(&loc, name, &dset_loc, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
ent_found = TRUE;
@@ -1398,6 +1420,91 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Dopen_expand
+ *
+ * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns
+ * its ID. The dataset should be close when the caller is no
+ * longer interested in it.
+ *
+ * Takes a dataset access property list
+ *
+ * Return: Success: A new dataset ID
+ * Failure: FAIL
+ *
+ * Programmer: James Laird
+ * Thursday, July 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dopen_expand(hid_t loc_id, const char *name, hid_t dapl_id)
+{
+ H5D_t *dset = NULL;
+ H5G_loc_t loc; /* Object location of group */
+ H5G_loc_t dset_loc; /* Object location of dataset */
+ H5G_name_t path; /* Dataset group hier. path */
+ H5O_loc_t oloc; /* Dataset object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */
+ hid_t ret_value;
+
+ FUNC_ENTER_API(H5Dopen_expand, FAIL)
+ H5TRACE3("i","isi",loc_id,name,dapl_id);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == dapl_id)
+ dapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
+
+ /* Set up dataset location to fill in */
+ dset_loc.oloc = &oloc;
+ dset_loc.path = &path;
+ H5G_loc_reset(&dset_loc);
+
+ /* Find the dataset object */
+ if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
+ ent_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&oloc, dxpl_id) != H5G_DATASET)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
+
+ /* Open the dataset */
+ if((dset = H5D_open(&dset_loc, dxpl_id)) == NULL) {
+ ent_found = FALSE; /* Reset this, since H5D_open 'owns' it and then free's it on failure */
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
+ } /* end if */
+
+ /* Register an atom for the dataset */
+ if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
+
+done:
+ if(ret_value < 0) {
+ if(dset != NULL) {
+ if(H5D_close(dset) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
+ } /* end if */
+ else {
+ if(ent_found)
+ H5G_name_free(&path);
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Dclose
*
* Purpose: Closes access to a dataset (DATASET_ID) and releases
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 45b13d8..b44bc8b 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -91,6 +91,7 @@ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim,
H5_DLL hid_t H5Dcreate(hid_t file_id, const char *name, hid_t type_id,
hid_t space_id, hid_t plist_id);
H5_DLL hid_t H5Dopen(hid_t file_id, const char *name);
+H5_DLL hid_t H5Dopen_expand(hid_t file_id, const char *name, hid_t dapl_id);
H5_DLL herr_t H5Dclose(hid_t dset_id);
H5_DLL hid_t H5Dget_space(hid_t dset_id);
H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
@@ -112,7 +113,7 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size);
H5_DLL herr_t H5Ddebug(hid_t dset_id);
H5_DLL hid_t H5Dcreate_expand(hid_t file_id, hid_t type_id,
- hid_t space_id, hid_t plist_id);
+ hid_t space_id, hid_t plist_id, hid_t dapl_id);
#ifdef __cplusplus
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 229a67f..9b14486 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -20,77 +20,47 @@
#define _H5Edefin_H
/* Major error IDs */
-hid_t H5E_DATASET_g = FAIL; /* Dataset */
-hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */
+hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */
+hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */
+hid_t H5E_CACHE_g = FAIL; /* Object cache */
+hid_t H5E_SLIST_g = FAIL; /* Skip Lists */
hid_t H5E_STORAGE_g = FAIL; /* Data storage */
-hid_t H5E_FILE_g = FAIL; /* File accessability */
-hid_t H5E_SYM_g = FAIL; /* Symbol table */
-hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */
-hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */
-hid_t H5E_BTREE_g = FAIL; /* B-Tree node */
-hid_t H5E_REFERENCE_g = FAIL; /* References */
-hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */
+hid_t H5E_ATOM_g = FAIL; /* Object atom */
hid_t H5E_RESOURCE_g = FAIL; /* Resource unavailable */
-hid_t H5E_PLIST_g = FAIL; /* Property lists */
-hid_t H5E_DATATYPE_g = FAIL; /* Datatype */
-hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */
-hid_t H5E_HEAP_g = FAIL; /* Heap */
+hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
hid_t H5E_OHDR_g = FAIL; /* Object header */
-hid_t H5E_ATOM_g = FAIL; /* Object atom */
+hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */
+hid_t H5E_ERROR_g = FAIL; /* Error API */
+hid_t H5E_BTREE_g = FAIL; /* B-Tree node */
hid_t H5E_ATTR_g = FAIL; /* Attribute */
-hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */
+hid_t H5E_PLIST_g = FAIL; /* Property lists */
+hid_t H5E_SYM_g = FAIL; /* Symbol table */
+hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */
+hid_t H5E_HEAP_g = FAIL; /* Heap */
+hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */
+hid_t H5E_FILE_g = FAIL; /* File accessability */
+hid_t H5E_LINK_g = FAIL; /* Links */
+hid_t H5E_DATATYPE_g = FAIL; /* Datatype */
+hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */
hid_t H5E_IO_g = FAIL; /* Low-level I/O */
-hid_t H5E_SLIST_g = FAIL; /* Skip Lists */
+hid_t H5E_DATASET_g = FAIL; /* Dataset */
+hid_t H5E_REFERENCE_g = FAIL; /* References */
hid_t H5E_EFL_g = FAIL; /* External file list */
-hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */
-hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */
-hid_t H5E_ERROR_g = FAIL; /* Error API */
+hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */
+hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */
hid_t H5E_PLINE_g = FAIL; /* Data filters */
-hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
-hid_t H5E_CACHE_g = FAIL; /* Object cache */
/* Minor error IDs */
-/* Generic low-level file I/O errors */
-hid_t H5E_SEEKERROR_g = FAIL; /* Seek failed */
-hid_t H5E_READERROR_g = FAIL; /* Read failed */
-hid_t H5E_WRITEERROR_g = FAIL; /* Write failed */
-hid_t H5E_CLOSEERROR_g = FAIL; /* Close failed */
-hid_t H5E_OVERFLOW_g = FAIL; /* Address overflowed */
-hid_t H5E_FCNTL_g = FAIL; /* File control (fcntl) failed */
-
-/* Resource errors */
-hid_t H5E_NOSPACE_g = FAIL; /* No space available for allocation */
-hid_t H5E_CANTALLOC_g = FAIL; /* Can't allocate space */
-hid_t H5E_CANTCOPY_g = FAIL; /* Unable to copy object */
-hid_t H5E_CANTFREE_g = FAIL; /* Unable to free object */
-hid_t H5E_ALREADYEXISTS_g = FAIL; /* Object already exists */
-hid_t H5E_CANTLOCK_g = FAIL; /* Unable to lock object */
-hid_t H5E_CANTUNLOCK_g = FAIL; /* Unable to unlock object */
-hid_t H5E_CANTGC_g = FAIL; /* Unable to garbage collect */
-hid_t H5E_CANTGETSIZE_g = FAIL; /* Unable to compute size */
-
-/* Heap errors */
-hid_t H5E_CANTRESTORE_g = FAIL; /* Can't restore condition */
-hid_t H5E_CANTCOMPUTE_g = FAIL; /* Can't compute value */
-hid_t H5E_CANTEXTEND_g = FAIL; /* Can't extend heap's space */
-hid_t H5E_CANTATTACH_g = FAIL; /* Can't attach object */
-hid_t H5E_CANTUPDATE_g = FAIL; /* Can't update object */
-
-/* Function entry/exit interface errors */
-hid_t H5E_CANTINIT_g = FAIL; /* Unable to initialize object */
-hid_t H5E_ALREADYINIT_g = FAIL; /* Object already initialized */
-hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */
-
-/* Property list errors */
-hid_t H5E_CANTGET_g = FAIL; /* Can't get value */
-hid_t H5E_CANTSET_g = FAIL; /* Can't set value */
-hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */
+/* System level errors */
+hid_t H5E_SYSERRSTR_g = FAIL; /* System error message */
-/* Free space errors */
-hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */
-hid_t H5E_CANTREVIVE_g = FAIL; /* Can't revive object */
-hid_t H5E_CANTSHRINK_g = FAIL; /* Can't shrink container */
+/* I/O pipeline errors */
+hid_t H5E_NOFILTER_g = FAIL; /* Requested filter is not available */
+hid_t H5E_CALLBACK_g = FAIL; /* Callback failed */
+hid_t H5E_CANAPPLY_g = FAIL; /* Error from filter 'can apply' callback */
+hid_t H5E_SETLOCAL_g = FAIL; /* Error from filter 'set local' callback */
+hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled */
/* Object header related errors */
hid_t H5E_LINKCOUNT_g = FAIL; /* Bad object header link count */
@@ -101,26 +71,37 @@ hid_t H5E_CANTDELETE_g = FAIL; /* Can't delete message */
hid_t H5E_BADITER_g = FAIL; /* Iteration failed */
hid_t H5E_CANTPACK_g = FAIL; /* Can't pack messages */
-/* System level errors */
-hid_t H5E_SYSERRSTR_g = FAIL; /* System error message */
-
-/* I/O pipeline errors */
-hid_t H5E_NOFILTER_g = FAIL; /* Requested filter is not available */
-hid_t H5E_CALLBACK_g = FAIL; /* Callback failed */
-hid_t H5E_CANAPPLY_g = FAIL; /* Error from filter 'can apply' callback */
-hid_t H5E_SETLOCAL_g = FAIL; /* Error from filter 'set local' callback */
-hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled */
+/* Resource errors */
+hid_t H5E_NOSPACE_g = FAIL; /* No space available for allocation */
+hid_t H5E_CANTALLOC_g = FAIL; /* Can't allocate space */
+hid_t H5E_CANTCOPY_g = FAIL; /* Unable to copy object */
+hid_t H5E_CANTFREE_g = FAIL; /* Unable to free object */
+hid_t H5E_ALREADYEXISTS_g = FAIL; /* Object already exists */
+hid_t H5E_CANTLOCK_g = FAIL; /* Unable to lock object */
+hid_t H5E_CANTUNLOCK_g = FAIL; /* Unable to unlock object */
+hid_t H5E_CANTGC_g = FAIL; /* Unable to garbage collect */
+hid_t H5E_CANTGETSIZE_g = FAIL; /* Unable to compute size */
-/* Group related errors */
-hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */
-hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */
-hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */
-hid_t H5E_LINK_g = FAIL; /* Link failure */
-hid_t H5E_SLINK_g = FAIL; /* Symbolic link error */
-hid_t H5E_PATH_g = FAIL; /* Problem with path to object */
+/* Generic low-level file I/O errors */
+hid_t H5E_SEEKERROR_g = FAIL; /* Seek failed */
+hid_t H5E_READERROR_g = FAIL; /* Read failed */
+hid_t H5E_WRITEERROR_g = FAIL; /* Write failed */
+hid_t H5E_CLOSEERROR_g = FAIL; /* Close failed */
+hid_t H5E_OVERFLOW_g = FAIL; /* Address overflowed */
+hid_t H5E_FCNTL_g = FAIL; /* File control (fcntl) failed */
-/* No error */
-hid_t H5E_NONE_MINOR_g = FAIL; /* No error */
+/* B-tree related errors */
+hid_t H5E_NOTFOUND_g = FAIL; /* Object not found */
+hid_t H5E_EXISTS_g = FAIL; /* Object already exists */
+hid_t H5E_CANTENCODE_g = FAIL; /* Unable to encode value */
+hid_t H5E_CANTDECODE_g = FAIL; /* Unable to decode value */
+hid_t H5E_CANTSPLIT_g = FAIL; /* Unable to split node */
+hid_t H5E_CANTREDISTRIBUTE_g = FAIL; /* Unable to redistribute records */
+hid_t H5E_CANTSWAP_g = FAIL; /* Unable to swap records */
+hid_t H5E_CANTINSERT_g = FAIL; /* Unable to insert object */
+hid_t H5E_CANTLIST_g = FAIL; /* Unable to list node */
+hid_t H5E_CANTMODIFY_g = FAIL; /* Unable to modify record */
+hid_t H5E_CANTREMOVE_g = FAIL; /* Unable to remove object */
/* File accessability errors */
hid_t H5E_FILEEXISTS_g = FAIL; /* File already exists */
@@ -133,6 +114,16 @@ hid_t H5E_BADFILE_g = FAIL; /* Bad file ID accessed */
hid_t H5E_TRUNCATED_g = FAIL; /* File has been truncated */
hid_t H5E_MOUNT_g = FAIL; /* File mount error */
+/* No error */
+hid_t H5E_NONE_MINOR_g = FAIL; /* No error */
+
+/* Heap errors */
+hid_t H5E_CANTRESTORE_g = FAIL; /* Can't restore condition */
+hid_t H5E_CANTCOMPUTE_g = FAIL; /* Can't compute value */
+hid_t H5E_CANTEXTEND_g = FAIL; /* Can't extend heap's space */
+hid_t H5E_CANTATTACH_g = FAIL; /* Can't attach object */
+hid_t H5E_CANTUPDATE_g = FAIL; /* Can't update object */
+
/* Object atom related errors */
hid_t H5E_BADATOM_g = FAIL; /* Unable to find atom information (already closed?) */
hid_t H5E_BADGROUP_g = FAIL; /* Unable to find ID group information */
@@ -141,6 +132,44 @@ hid_t H5E_CANTINC_g = FAIL; /* Unable to increment reference count *
hid_t H5E_CANTDEC_g = FAIL; /* Unable to decrement reference count */
hid_t H5E_NOIDS_g = FAIL; /* Out of IDs for group */
+/* Group related errors */
+hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */
+hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */
+hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */
+hid_t H5E_PATH_g = FAIL; /* Problem with path to object */
+
+/* Property list errors */
+hid_t H5E_CANTGET_g = FAIL; /* Can't get value */
+hid_t H5E_CANTSET_g = FAIL; /* Can't set value */
+hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */
+
+/* Function entry/exit interface errors */
+hid_t H5E_CANTINIT_g = FAIL; /* Unable to initialize object */
+hid_t H5E_ALREADYINIT_g = FAIL; /* Object already initialized */
+hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */
+
+/* Datatype conversion errors */
+hid_t H5E_CANTCONVERT_g = FAIL; /* Can't convert datatypes */
+hid_t H5E_BADSIZE_g = FAIL; /* Bad size for object */
+
+/* Link related errors */
+hid_t H5E_TRAVERSE_g = FAIL; /* Link traversal failure */
+hid_t H5E_NLINKS_g = FAIL; /* Too many soft links in path */
+hid_t H5E_NOTREGISTERED_g = FAIL; /* Link class not registered */
+hid_t H5E_CANTMOVE_g = FAIL; /* Move callback returned error */
+
+/* Parallel MPI errors */
+hid_t H5E_MPI_g = FAIL; /* Some MPI function failed */
+hid_t H5E_MPIERRSTR_g = FAIL; /* MPI Error String */
+hid_t H5E_CANTRECV_g = FAIL; /* Can't receive data */
+
+/* Argument errors */
+hid_t H5E_UNINITIALIZED_g = FAIL; /* Information is uinitialized */
+hid_t H5E_UNSUPPORTED_g = FAIL; /* Feature is unsupported */
+hid_t H5E_BADTYPE_g = FAIL; /* Inappropriate type */
+hid_t H5E_BADRANGE_g = FAIL; /* Out of range */
+hid_t H5E_BADVALUE_g = FAIL; /* Bad value */
+
/* Cache related errors */
hid_t H5E_CANTFLUSH_g = FAIL; /* Unable to flush data from cache */
hid_t H5E_CANTSERIALIZE_g = FAIL; /* Unable to serialize data from cache */
@@ -159,10 +188,10 @@ hid_t H5E_CANTDIRTY_g = FAIL; /* Unable to mark metadata as dirty */
hid_t H5E_CANTEXPUNGE_g = FAIL; /* Unable to expunge a metadata cache entry */
hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache entry */
-/* Parallel MPI errors */
-hid_t H5E_MPI_g = FAIL; /* Some MPI function failed */
-hid_t H5E_MPIERRSTR_g = FAIL; /* MPI Error String */
-hid_t H5E_CANTRECV_g = FAIL; /* Can't receive data */
+/* Free space errors */
+hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */
+hid_t H5E_CANTREVIVE_g = FAIL; /* Can't revive object */
+hid_t H5E_CANTSHRINK_g = FAIL; /* Can't shrink container */
/* Dataspace errors */
hid_t H5E_CANTCLIP_g = FAIL; /* Can't clip hyperslab region */
@@ -172,28 +201,4 @@ hid_t H5E_CANTNEXT_g = FAIL; /* Can't move to next iterator location
hid_t H5E_BADSELECT_g = FAIL; /* Invalid selection */
hid_t H5E_CANTCOMPARE_g = FAIL; /* Can't compare objects */
-/* B-tree related errors */
-hid_t H5E_NOTFOUND_g = FAIL; /* Object not found */
-hid_t H5E_EXISTS_g = FAIL; /* Object already exists */
-hid_t H5E_CANTENCODE_g = FAIL; /* Unable to encode value */
-hid_t H5E_CANTDECODE_g = FAIL; /* Unable to decode value */
-hid_t H5E_CANTSPLIT_g = FAIL; /* Unable to split node */
-hid_t H5E_CANTREDISTRIBUTE_g = FAIL; /* Unable to redistribute records */
-hid_t H5E_CANTSWAP_g = FAIL; /* Unable to swap records */
-hid_t H5E_CANTINSERT_g = FAIL; /* Unable to insert object */
-hid_t H5E_CANTLIST_g = FAIL; /* Unable to list node */
-hid_t H5E_CANTMODIFY_g = FAIL; /* Unable to modify record */
-hid_t H5E_CANTREMOVE_g = FAIL; /* Unable to remove object */
-
-/* Argument errors */
-hid_t H5E_UNINITIALIZED_g = FAIL; /* Information is uinitialized */
-hid_t H5E_UNSUPPORTED_g = FAIL; /* Feature is unsupported */
-hid_t H5E_BADTYPE_g = FAIL; /* Inappropriate type */
-hid_t H5E_BADRANGE_g = FAIL; /* Out of range */
-hid_t H5E_BADVALUE_g = FAIL; /* Bad value */
-
-/* Datatype conversion errors */
-hid_t H5E_CANTCONVERT_g = FAIL; /* Can't convert datatypes */
-hid_t H5E_BADSIZE_g = FAIL; /* Bad size for object */
-
#endif /* H5Edefin_H */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index a5a3f18..c62282e 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -23,182 +23,226 @@
/* Major error codes */
/*********************/
-assert(H5E_DATASET_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL)
+assert(H5E_NONE_MAJOR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FUNC_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL)
+assert(H5E_RS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CACHE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_SLIST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_STORAGE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FILE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL)
+assert(H5E_ATOM_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_SYM_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL)
+assert(H5E_RESOURCE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_VFL_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL)
+assert(H5E_FSPACE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_INTERNAL_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL)
+assert(H5E_OHDR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BTREE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "B-Tree node"))==NULL)
+assert(H5E_FUNC_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_REFERENCE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "References"))==NULL)
+assert(H5E_ERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_DATASPACE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataspace"))==NULL)
+assert(H5E_BTREE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "B-Tree node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_RESOURCE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL)
+assert(H5E_ATTR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PLIST_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_DATATYPE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL)
+assert(H5E_SYM_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_RS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL)
+assert(H5E_ARGS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_HEAP_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_OHDR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL)
+assert(H5E_INTERNAL_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ATOM_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL)
+assert(H5E_FILE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ATTR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL)
+assert(H5E_LINK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Links"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_NONE_MAJOR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL)
+assert(H5E_DATATYPE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_TST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_IO_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_SLIST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL)
+assert(H5E_DATASET_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_REFERENCE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "References"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_EFL_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_TST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ARGS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL)
+assert(H5E_VFL_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL)
+assert(H5E_DATASPACE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataspace"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PLINE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data filters"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_PLINE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FSPACE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CACHE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/*********************/
/* Minor error codes */
/*********************/
-/* Generic low-level file I/O errors */
-assert(H5E_SEEKERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Seek failed"))==NULL)
+/* System level errors */
+assert(H5E_SYSERRSTR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "System error message"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_READERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Read failed"))==NULL)
+
+/* I/O pipeline errors */
+assert(H5E_NOFILTER_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Requested filter is not available"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_WRITEERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Write failed"))==NULL)
+assert(H5E_CALLBACK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Callback failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CLOSEERROR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Close failed"))==NULL)
+assert(H5E_CANAPPLY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'can apply' callback"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_OVERFLOW_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Address overflowed"))==NULL)
+assert(H5E_SETLOCAL_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FCNTL_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "File control (fcntl) failed"))==NULL)
+assert(H5E_NOENCODER_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+
+/* Object header related errors */
+assert(H5E_LINKCOUNT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad object header link count"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_VERSION_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Wrong version number"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_ALIGNMENT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Alignment error"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_BADMESG_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unrecognized message"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTDELETE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't delete message"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_BADITER_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTPACK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Resource errors */
@@ -248,153 +292,206 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to compute size"))==NULL)
if((H5E_CANTGETSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* Heap errors */
-assert(H5E_CANTRESTORE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't restore condition"))==NULL)
+/* Generic low-level file I/O errors */
+assert(H5E_SEEKERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Seek failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTCOMPUTE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compute value"))==NULL)
+assert(H5E_READERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Read failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTEXTEND_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't extend heap's space"))==NULL)
+assert(H5E_WRITEERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Write failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTATTACH_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't attach object"))==NULL)
+assert(H5E_CLOSEERROR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Close failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTUPDATE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't update object"))==NULL)
+assert(H5E_OVERFLOW_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Address overflowed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_FCNTL_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "File control (fcntl) failed"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* Function entry/exit interface errors */
-assert(H5E_CANTINIT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to initialize object"))==NULL)
+/* B-tree related errors */
+assert(H5E_NOTFOUND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Object not found"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ALREADYINIT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already initialized"))==NULL)
+assert(H5E_EXISTS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTRELEASE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to release object"))==NULL)
+assert(H5E_CANTENCODE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to encode value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-
-/* Property list errors */
-assert(H5E_CANTGET_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't get value"))==NULL)
+assert(H5E_CANTDECODE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decode value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTSET_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't set value"))==NULL)
+assert(H5E_CANTSPLIT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to split node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_DUPCLASS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class"))==NULL)
+assert(H5E_CANTREDISTRIBUTE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to redistribute records"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-
-/* Free space errors */
-assert(H5E_CANTMERGE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't merge objects"))==NULL)
+assert(H5E_CANTSWAP_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to swap records"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTREVIVE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't revive object"))==NULL)
+assert(H5E_CANTINSERT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTSHRINK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't shrink container"))==NULL)
+assert(H5E_CANTLIST_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to list node"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTMODIFY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to modify record"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTREMOVE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to remove object"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* Object header related errors */
-assert(H5E_LINKCOUNT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad object header link count"))==NULL)
+/* File accessability errors */
+assert(H5E_FILEEXISTS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_VERSION_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Wrong version number"))==NULL)
+assert(H5E_FILEOPEN_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "File already open"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_ALIGNMENT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Alignment error"))==NULL)
+assert(H5E_CANTCREATE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADMESG_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unrecognized message"))==NULL)
+assert(H5E_CANTOPENFILE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to open file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTDELETE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't delete message"))==NULL)
+assert(H5E_CANTCLOSEFILE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to close file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADITER_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL)
+assert(H5E_NOTHDF5_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Not an HDF5 file"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTPACK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL)
+assert(H5E_BADFILE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad file ID accessed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_TRUNCATED_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "File has been truncated"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_MOUNT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "File mount error"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* System level errors */
-assert(H5E_SYSERRSTR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "System error message"))==NULL)
+/* No error */
+assert(H5E_NONE_MINOR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* I/O pipeline errors */
-assert(H5E_NOFILTER_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Requested filter is not available"))==NULL)
+/* Heap errors */
+assert(H5E_CANTRESTORE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't restore condition"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CALLBACK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Callback failed"))==NULL)
+assert(H5E_CANTCOMPUTE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compute value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANAPPLY_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'can apply' callback"))==NULL)
+assert(H5E_CANTEXTEND_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't extend heap's space"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_SETLOCAL_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback"))==NULL)
+assert(H5E_CANTATTACH_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't attach object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_NOENCODER_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL)
+assert(H5E_CANTUPDATE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't update object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+
+/* Object atom related errors */
+assert(H5E_BADATOM_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find atom information (already closed?)"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_BADGROUP_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find ID group information"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTREGISTER_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to register new atom"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTINC_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to increment reference count"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTDEC_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decrement reference count"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_NOIDS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of IDs for group"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Group related errors */
@@ -413,106 +510,122 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Name component is too long"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_COMPLEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_LINK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Link failure"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_SLINK_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Symbolic link error"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_SLINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_PATH_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MINOR, "Problem with path to object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_PATH_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* No error */
-assert(H5E_NONE_MINOR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL)
+/* Property list errors */
+assert(H5E_CANTGET_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't get value"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTSET_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't set value"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_DUPCLASS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* File accessability errors */
-assert(H5E_FILEEXISTS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL)
+/* Function entry/exit interface errors */
+assert(H5E_CANTINIT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to initialize object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_FILEOPEN_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "File already open"))==NULL)
+assert(H5E_ALREADYINIT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already initialized"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTCREATE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create file"))==NULL)
+assert(H5E_CANTRELEASE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to release object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTOPENFILE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to open file"))==NULL)
+
+/* Datatype conversion errors */
+assert(H5E_CANTCONVERT_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't convert datatypes"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTCLOSEFILE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to close file"))==NULL)
+assert(H5E_BADSIZE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad size for object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_NOTHDF5_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Not an HDF5 file"))==NULL)
+
+/* Link related errors */
+assert(H5E_TRAVERSE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Link traversal failure"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_TRAVERSE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADFILE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad file ID accessed"))==NULL)
+assert(H5E_NLINKS_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Too many soft links in path"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NLINKS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_TRUNCATED_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "File has been truncated"))==NULL)
+assert(H5E_NOTREGISTERED_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Link class not registered"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_NOTREGISTERED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_MOUNT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "File mount error"))==NULL)
+assert(H5E_CANTMOVE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Move callback returned error"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* Object atom related errors */
-assert(H5E_BADATOM_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find atom information (already closed?)"))==NULL)
+/* Parallel MPI errors */
+assert(H5E_MPI_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Some MPI function failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADGROUP_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find ID group information"))==NULL)
+assert(H5E_MPIERRSTR_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "MPI Error String"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTREGISTER_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to register new atom"))==NULL)
+assert(H5E_CANTRECV_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't receive data"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTINC_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to increment reference count"))==NULL)
+
+/* Argument errors */
+assert(H5E_UNINITIALIZED_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Information is uinitialized"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTDEC_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decrement reference count"))==NULL)
+assert(H5E_UNSUPPORTED_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Feature is unsupported"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_NOIDS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of IDs for group"))==NULL)
+assert(H5E_BADTYPE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Inappropriate type"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_BADRANGE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of range"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_BADVALUE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad value"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Cache related errors */
@@ -597,21 +710,21 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to resize a metadata cache entr
if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* Parallel MPI errors */
-assert(H5E_MPI_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Some MPI function failed"))==NULL)
+/* Free space errors */
+assert(H5E_CANTMERGE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't merge objects"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_MPIERRSTR_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "MPI Error String"))==NULL)
+assert(H5E_CANTREVIVE_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't revive object"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTRECV_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't receive data"))==NULL)
+assert(H5E_CANTSHRINK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't shrink container"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* Dataspace errors */
@@ -646,100 +759,4 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compare objects"))==NULL)
if((H5E_CANTCOMPARE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-/* B-tree related errors */
-assert(H5E_NOTFOUND_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Object not found"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_EXISTS_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTENCODE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to encode value"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTDECODE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decode value"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTSPLIT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to split node"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTREDISTRIBUTE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to redistribute records"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTSWAP_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to swap records"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTINSERT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert object"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTLIST_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to list node"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTMODIFY_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to modify record"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_CANTREMOVE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to remove object"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-
-/* Argument errors */
-assert(H5E_UNINITIALIZED_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Information is uinitialized"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_UNSUPPORTED_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Feature is unsupported"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADTYPE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Inappropriate type"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADRANGE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of range"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADVALUE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad value"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-
-/* Datatype conversion errors */
-assert(H5E_CANTCONVERT_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't convert datatypes"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-assert(H5E_BADSIZE_g==(-1));
-if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad size for object"))==NULL)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
-if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0)
- HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
-
#endif /* H5Einit_H */
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index 70334fa..7c53b8f 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -23,80 +23,100 @@
/* Major error codes */
/*********************/
-#define H5E_DATASET (H5OPEN H5E_DATASET_g)
-#define H5E_FUNC (H5OPEN H5E_FUNC_g)
+#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g)
+#define H5E_RS (H5OPEN H5E_RS_g)
+#define H5E_CACHE (H5OPEN H5E_CACHE_g)
+#define H5E_SLIST (H5OPEN H5E_SLIST_g)
#define H5E_STORAGE (H5OPEN H5E_STORAGE_g)
-#define H5E_FILE (H5OPEN H5E_FILE_g)
-#define H5E_SYM (H5OPEN H5E_SYM_g)
-#define H5E_VFL (H5OPEN H5E_VFL_g)
-#define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g)
-#define H5E_BTREE (H5OPEN H5E_BTREE_g)
-#define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g)
-#define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g)
+#define H5E_ATOM (H5OPEN H5E_ATOM_g)
#define H5E_RESOURCE (H5OPEN H5E_RESOURCE_g)
-#define H5E_PLIST (H5OPEN H5E_PLIST_g)
-#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g)
-#define H5E_RS (H5OPEN H5E_RS_g)
-#define H5E_HEAP (H5OPEN H5E_HEAP_g)
+#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
#define H5E_OHDR (H5OPEN H5E_OHDR_g)
-#define H5E_ATOM (H5OPEN H5E_ATOM_g)
+#define H5E_FUNC (H5OPEN H5E_FUNC_g)
+#define H5E_ERROR (H5OPEN H5E_ERROR_g)
+#define H5E_BTREE (H5OPEN H5E_BTREE_g)
#define H5E_ATTR (H5OPEN H5E_ATTR_g)
-#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g)
+#define H5E_PLIST (H5OPEN H5E_PLIST_g)
+#define H5E_SYM (H5OPEN H5E_SYM_g)
+#define H5E_ARGS (H5OPEN H5E_ARGS_g)
+#define H5E_HEAP (H5OPEN H5E_HEAP_g)
+#define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g)
+#define H5E_FILE (H5OPEN H5E_FILE_g)
+#define H5E_LINK (H5OPEN H5E_LINK_g)
+#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g)
+#define H5E_TST (H5OPEN H5E_TST_g)
#define H5E_IO (H5OPEN H5E_IO_g)
-#define H5E_SLIST (H5OPEN H5E_SLIST_g)
+#define H5E_DATASET (H5OPEN H5E_DATASET_g)
+#define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g)
#define H5E_EFL (H5OPEN H5E_EFL_g)
-#define H5E_TST (H5OPEN H5E_TST_g)
-#define H5E_ARGS (H5OPEN H5E_ARGS_g)
-#define H5E_ERROR (H5OPEN H5E_ERROR_g)
+#define H5E_VFL (H5OPEN H5E_VFL_g)
+#define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g)
#define H5E_PLINE (H5OPEN H5E_PLINE_g)
-#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
-#define H5E_CACHE (H5OPEN H5E_CACHE_g)
-H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
-H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */
+H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */
+H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */
+H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */
+H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */
H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */
-H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */
-H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */
-H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */
-H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */
-H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */
-H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */
-H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */
+H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */
H5_DLLVAR hid_t H5E_RESOURCE_g; /* Resource unavailable */
-H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */
-H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */
-H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */
-H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */
+H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */
-H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */
+H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */
+H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */
+H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */
H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */
-H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */
+H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */
+H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */
+H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */
+H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */
+H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */
+H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */
+H5_DLLVAR hid_t H5E_LINK_g; /* Links */
+H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */
+H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */
H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */
-H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */
+H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
+H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */
H5_DLLVAR hid_t H5E_EFL_g; /* External file list */
-H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */
-H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */
-H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */
+H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */
+H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */
H5_DLLVAR hid_t H5E_PLINE_g; /* Data filters */
-H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
-H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */
/*********************/
/* Minor error codes */
/*********************/
-/* Generic low-level file I/O errors */
-#define H5E_SEEKERROR (H5OPEN H5E_SEEKERROR_g)
-#define H5E_READERROR (H5OPEN H5E_READERROR_g)
-#define H5E_WRITEERROR (H5OPEN H5E_WRITEERROR_g)
-#define H5E_CLOSEERROR (H5OPEN H5E_CLOSEERROR_g)
-#define H5E_OVERFLOW (H5OPEN H5E_OVERFLOW_g)
-#define H5E_FCNTL (H5OPEN H5E_FCNTL_g)
-H5_DLLVAR hid_t H5E_SEEKERROR_g; /* Seek failed */
-H5_DLLVAR hid_t H5E_READERROR_g; /* Read failed */
-H5_DLLVAR hid_t H5E_WRITEERROR_g; /* Write failed */
-H5_DLLVAR hid_t H5E_CLOSEERROR_g; /* Close failed */
-H5_DLLVAR hid_t H5E_OVERFLOW_g; /* Address overflowed */
-H5_DLLVAR hid_t H5E_FCNTL_g; /* File control (fcntl) failed */
+/* System level errors */
+#define H5E_SYSERRSTR (H5OPEN H5E_SYSERRSTR_g)
+H5_DLLVAR hid_t H5E_SYSERRSTR_g; /* System error message */
+
+/* I/O pipeline errors */
+#define H5E_NOFILTER (H5OPEN H5E_NOFILTER_g)
+#define H5E_CALLBACK (H5OPEN H5E_CALLBACK_g)
+#define H5E_CANAPPLY (H5OPEN H5E_CANAPPLY_g)
+#define H5E_SETLOCAL (H5OPEN H5E_SETLOCAL_g)
+#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g)
+H5_DLLVAR hid_t H5E_NOFILTER_g; /* Requested filter is not available */
+H5_DLLVAR hid_t H5E_CALLBACK_g; /* Callback failed */
+H5_DLLVAR hid_t H5E_CANAPPLY_g; /* Error from filter 'can apply' callback */
+H5_DLLVAR hid_t H5E_SETLOCAL_g; /* Error from filter 'set local' callback */
+H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */
+
+/* Object header related errors */
+#define H5E_LINKCOUNT (H5OPEN H5E_LINKCOUNT_g)
+#define H5E_VERSION (H5OPEN H5E_VERSION_g)
+#define H5E_ALIGNMENT (H5OPEN H5E_ALIGNMENT_g)
+#define H5E_BADMESG (H5OPEN H5E_BADMESG_g)
+#define H5E_CANTDELETE (H5OPEN H5E_CANTDELETE_g)
+#define H5E_BADITER (H5OPEN H5E_BADITER_g)
+#define H5E_CANTPACK (H5OPEN H5E_CANTPACK_g)
+H5_DLLVAR hid_t H5E_LINKCOUNT_g; /* Bad object header link count */
+H5_DLLVAR hid_t H5E_VERSION_g; /* Wrong version number */
+H5_DLLVAR hid_t H5E_ALIGNMENT_g; /* Alignment error */
+H5_DLLVAR hid_t H5E_BADMESG_g; /* Unrecognized message */
+H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */
+H5_DLLVAR hid_t H5E_BADITER_g; /* Iteration failed */
+H5_DLLVAR hid_t H5E_CANTPACK_g; /* Can't pack messages */
/* Resource errors */
#define H5E_NOSPACE (H5OPEN H5E_NOSPACE_g)
@@ -118,91 +138,43 @@ H5_DLLVAR hid_t H5E_CANTUNLOCK_g; /* Unable to unlock object */
H5_DLLVAR hid_t H5E_CANTGC_g; /* Unable to garbage collect */
H5_DLLVAR hid_t H5E_CANTGETSIZE_g; /* Unable to compute size */
-/* Heap errors */
-#define H5E_CANTRESTORE (H5OPEN H5E_CANTRESTORE_g)
-#define H5E_CANTCOMPUTE (H5OPEN H5E_CANTCOMPUTE_g)
-#define H5E_CANTEXTEND (H5OPEN H5E_CANTEXTEND_g)
-#define H5E_CANTATTACH (H5OPEN H5E_CANTATTACH_g)
-#define H5E_CANTUPDATE (H5OPEN H5E_CANTUPDATE_g)
-H5_DLLVAR hid_t H5E_CANTRESTORE_g; /* Can't restore condition */
-H5_DLLVAR hid_t H5E_CANTCOMPUTE_g; /* Can't compute value */
-H5_DLLVAR hid_t H5E_CANTEXTEND_g; /* Can't extend heap's space */
-H5_DLLVAR hid_t H5E_CANTATTACH_g; /* Can't attach object */
-H5_DLLVAR hid_t H5E_CANTUPDATE_g; /* Can't update object */
-
-/* Function entry/exit interface errors */
-#define H5E_CANTINIT (H5OPEN H5E_CANTINIT_g)
-#define H5E_ALREADYINIT (H5OPEN H5E_ALREADYINIT_g)
-#define H5E_CANTRELEASE (H5OPEN H5E_CANTRELEASE_g)
-H5_DLLVAR hid_t H5E_CANTINIT_g; /* Unable to initialize object */
-H5_DLLVAR hid_t H5E_ALREADYINIT_g; /* Object already initialized */
-H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */
-
-/* Property list errors */
-#define H5E_CANTGET (H5OPEN H5E_CANTGET_g)
-#define H5E_CANTSET (H5OPEN H5E_CANTSET_g)
-#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g)
-H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */
-H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */
-H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */
-
-/* Free space errors */
-#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g)
-#define H5E_CANTREVIVE (H5OPEN H5E_CANTREVIVE_g)
-#define H5E_CANTSHRINK (H5OPEN H5E_CANTSHRINK_g)
-H5_DLLVAR hid_t H5E_CANTMERGE_g; /* Can't merge objects */
-H5_DLLVAR hid_t H5E_CANTREVIVE_g; /* Can't revive object */
-H5_DLLVAR hid_t H5E_CANTSHRINK_g; /* Can't shrink container */
-
-/* Object header related errors */
-#define H5E_LINKCOUNT (H5OPEN H5E_LINKCOUNT_g)
-#define H5E_VERSION (H5OPEN H5E_VERSION_g)
-#define H5E_ALIGNMENT (H5OPEN H5E_ALIGNMENT_g)
-#define H5E_BADMESG (H5OPEN H5E_BADMESG_g)
-#define H5E_CANTDELETE (H5OPEN H5E_CANTDELETE_g)
-#define H5E_BADITER (H5OPEN H5E_BADITER_g)
-#define H5E_CANTPACK (H5OPEN H5E_CANTPACK_g)
-H5_DLLVAR hid_t H5E_LINKCOUNT_g; /* Bad object header link count */
-H5_DLLVAR hid_t H5E_VERSION_g; /* Wrong version number */
-H5_DLLVAR hid_t H5E_ALIGNMENT_g; /* Alignment error */
-H5_DLLVAR hid_t H5E_BADMESG_g; /* Unrecognized message */
-H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */
-H5_DLLVAR hid_t H5E_BADITER_g; /* Iteration failed */
-H5_DLLVAR hid_t H5E_CANTPACK_g; /* Can't pack messages */
-
-/* System level errors */
-#define H5E_SYSERRSTR (H5OPEN H5E_SYSERRSTR_g)
-H5_DLLVAR hid_t H5E_SYSERRSTR_g; /* System error message */
-
-/* I/O pipeline errors */
-#define H5E_NOFILTER (H5OPEN H5E_NOFILTER_g)
-#define H5E_CALLBACK (H5OPEN H5E_CALLBACK_g)
-#define H5E_CANAPPLY (H5OPEN H5E_CANAPPLY_g)
-#define H5E_SETLOCAL (H5OPEN H5E_SETLOCAL_g)
-#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g)
-H5_DLLVAR hid_t H5E_NOFILTER_g; /* Requested filter is not available */
-H5_DLLVAR hid_t H5E_CALLBACK_g; /* Callback failed */
-H5_DLLVAR hid_t H5E_CANAPPLY_g; /* Error from filter 'can apply' callback */
-H5_DLLVAR hid_t H5E_SETLOCAL_g; /* Error from filter 'set local' callback */
-H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */
-
-/* Group related errors */
-#define H5E_CANTOPENOBJ (H5OPEN H5E_CANTOPENOBJ_g)
-#define H5E_CANTCLOSEOBJ (H5OPEN H5E_CANTCLOSEOBJ_g)
-#define H5E_COMPLEN (H5OPEN H5E_COMPLEN_g)
-#define H5E_LINK (H5OPEN H5E_LINK_g)
-#define H5E_SLINK (H5OPEN H5E_SLINK_g)
-#define H5E_PATH (H5OPEN H5E_PATH_g)
-H5_DLLVAR hid_t H5E_CANTOPENOBJ_g; /* Can't open object */
-H5_DLLVAR hid_t H5E_CANTCLOSEOBJ_g; /* Can't close object */
-H5_DLLVAR hid_t H5E_COMPLEN_g; /* Name component is too long */
-H5_DLLVAR hid_t H5E_LINK_g; /* Link failure */
-H5_DLLVAR hid_t H5E_SLINK_g; /* Symbolic link error */
-H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */
+/* Generic low-level file I/O errors */
+#define H5E_SEEKERROR (H5OPEN H5E_SEEKERROR_g)
+#define H5E_READERROR (H5OPEN H5E_READERROR_g)
+#define H5E_WRITEERROR (H5OPEN H5E_WRITEERROR_g)
+#define H5E_CLOSEERROR (H5OPEN H5E_CLOSEERROR_g)
+#define H5E_OVERFLOW (H5OPEN H5E_OVERFLOW_g)
+#define H5E_FCNTL (H5OPEN H5E_FCNTL_g)
+H5_DLLVAR hid_t H5E_SEEKERROR_g; /* Seek failed */
+H5_DLLVAR hid_t H5E_READERROR_g; /* Read failed */
+H5_DLLVAR hid_t H5E_WRITEERROR_g; /* Write failed */
+H5_DLLVAR hid_t H5E_CLOSEERROR_g; /* Close failed */
+H5_DLLVAR hid_t H5E_OVERFLOW_g; /* Address overflowed */
+H5_DLLVAR hid_t H5E_FCNTL_g; /* File control (fcntl) failed */
-/* No error */
-#define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g)
-H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */
+/* B-tree related errors */
+#define H5E_NOTFOUND (H5OPEN H5E_NOTFOUND_g)
+#define H5E_EXISTS (H5OPEN H5E_EXISTS_g)
+#define H5E_CANTENCODE (H5OPEN H5E_CANTENCODE_g)
+#define H5E_CANTDECODE (H5OPEN H5E_CANTDECODE_g)
+#define H5E_CANTSPLIT (H5OPEN H5E_CANTSPLIT_g)
+#define H5E_CANTREDISTRIBUTE (H5OPEN H5E_CANTREDISTRIBUTE_g)
+#define H5E_CANTSWAP (H5OPEN H5E_CANTSWAP_g)
+#define H5E_CANTINSERT (H5OPEN H5E_CANTINSERT_g)
+#define H5E_CANTLIST (H5OPEN H5E_CANTLIST_g)
+#define H5E_CANTMODIFY (H5OPEN H5E_CANTMODIFY_g)
+#define H5E_CANTREMOVE (H5OPEN H5E_CANTREMOVE_g)
+H5_DLLVAR hid_t H5E_NOTFOUND_g; /* Object not found */
+H5_DLLVAR hid_t H5E_EXISTS_g; /* Object already exists */
+H5_DLLVAR hid_t H5E_CANTENCODE_g; /* Unable to encode value */
+H5_DLLVAR hid_t H5E_CANTDECODE_g; /* Unable to decode value */
+H5_DLLVAR hid_t H5E_CANTSPLIT_g; /* Unable to split node */
+H5_DLLVAR hid_t H5E_CANTREDISTRIBUTE_g; /* Unable to redistribute records */
+H5_DLLVAR hid_t H5E_CANTSWAP_g; /* Unable to swap records */
+H5_DLLVAR hid_t H5E_CANTINSERT_g; /* Unable to insert object */
+H5_DLLVAR hid_t H5E_CANTLIST_g; /* Unable to list node */
+H5_DLLVAR hid_t H5E_CANTMODIFY_g; /* Unable to modify record */
+H5_DLLVAR hid_t H5E_CANTREMOVE_g; /* Unable to remove object */
/* File accessability errors */
#define H5E_FILEEXISTS (H5OPEN H5E_FILEEXISTS_g)
@@ -224,6 +196,22 @@ H5_DLLVAR hid_t H5E_BADFILE_g; /* Bad file ID accessed */
H5_DLLVAR hid_t H5E_TRUNCATED_g; /* File has been truncated */
H5_DLLVAR hid_t H5E_MOUNT_g; /* File mount error */
+/* No error */
+#define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g)
+H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */
+
+/* Heap errors */
+#define H5E_CANTRESTORE (H5OPEN H5E_CANTRESTORE_g)
+#define H5E_CANTCOMPUTE (H5OPEN H5E_CANTCOMPUTE_g)
+#define H5E_CANTEXTEND (H5OPEN H5E_CANTEXTEND_g)
+#define H5E_CANTATTACH (H5OPEN H5E_CANTATTACH_g)
+#define H5E_CANTUPDATE (H5OPEN H5E_CANTUPDATE_g)
+H5_DLLVAR hid_t H5E_CANTRESTORE_g; /* Can't restore condition */
+H5_DLLVAR hid_t H5E_CANTCOMPUTE_g; /* Can't compute value */
+H5_DLLVAR hid_t H5E_CANTEXTEND_g; /* Can't extend heap's space */
+H5_DLLVAR hid_t H5E_CANTATTACH_g; /* Can't attach object */
+H5_DLLVAR hid_t H5E_CANTUPDATE_g; /* Can't update object */
+
/* Object atom related errors */
#define H5E_BADATOM (H5OPEN H5E_BADATOM_g)
#define H5E_BADGROUP (H5OPEN H5E_BADGROUP_g)
@@ -238,6 +226,68 @@ H5_DLLVAR hid_t H5E_CANTINC_g; /* Unable to increment reference count */
H5_DLLVAR hid_t H5E_CANTDEC_g; /* Unable to decrement reference count */
H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */
+/* Group related errors */
+#define H5E_CANTOPENOBJ (H5OPEN H5E_CANTOPENOBJ_g)
+#define H5E_CANTCLOSEOBJ (H5OPEN H5E_CANTCLOSEOBJ_g)
+#define H5E_COMPLEN (H5OPEN H5E_COMPLEN_g)
+#define H5E_PATH (H5OPEN H5E_PATH_g)
+H5_DLLVAR hid_t H5E_CANTOPENOBJ_g; /* Can't open object */
+H5_DLLVAR hid_t H5E_CANTCLOSEOBJ_g; /* Can't close object */
+H5_DLLVAR hid_t H5E_COMPLEN_g; /* Name component is too long */
+H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */
+
+/* Property list errors */
+#define H5E_CANTGET (H5OPEN H5E_CANTGET_g)
+#define H5E_CANTSET (H5OPEN H5E_CANTSET_g)
+#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g)
+H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */
+H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */
+H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */
+
+/* Function entry/exit interface errors */
+#define H5E_CANTINIT (H5OPEN H5E_CANTINIT_g)
+#define H5E_ALREADYINIT (H5OPEN H5E_ALREADYINIT_g)
+#define H5E_CANTRELEASE (H5OPEN H5E_CANTRELEASE_g)
+H5_DLLVAR hid_t H5E_CANTINIT_g; /* Unable to initialize object */
+H5_DLLVAR hid_t H5E_ALREADYINIT_g; /* Object already initialized */
+H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */
+
+/* Datatype conversion errors */
+#define H5E_CANTCONVERT (H5OPEN H5E_CANTCONVERT_g)
+#define H5E_BADSIZE (H5OPEN H5E_BADSIZE_g)
+H5_DLLVAR hid_t H5E_CANTCONVERT_g; /* Can't convert datatypes */
+H5_DLLVAR hid_t H5E_BADSIZE_g; /* Bad size for object */
+
+/* Link related errors */
+#define H5E_TRAVERSE (H5OPEN H5E_TRAVERSE_g)
+#define H5E_NLINKS (H5OPEN H5E_NLINKS_g)
+#define H5E_NOTREGISTERED (H5OPEN H5E_NOTREGISTERED_g)
+#define H5E_CANTMOVE (H5OPEN H5E_CANTMOVE_g)
+H5_DLLVAR hid_t H5E_TRAVERSE_g; /* Link traversal failure */
+H5_DLLVAR hid_t H5E_NLINKS_g; /* Too many soft links in path */
+H5_DLLVAR hid_t H5E_NOTREGISTERED_g; /* Link class not registered */
+H5_DLLVAR hid_t H5E_CANTMOVE_g; /* Move callback returned error */
+
+/* Parallel MPI errors */
+#define H5E_MPI (H5OPEN H5E_MPI_g)
+#define H5E_MPIERRSTR (H5OPEN H5E_MPIERRSTR_g)
+#define H5E_CANTRECV (H5OPEN H5E_CANTRECV_g)
+H5_DLLVAR hid_t H5E_MPI_g; /* Some MPI function failed */
+H5_DLLVAR hid_t H5E_MPIERRSTR_g; /* MPI Error String */
+H5_DLLVAR hid_t H5E_CANTRECV_g; /* Can't receive data */
+
+/* Argument errors */
+#define H5E_UNINITIALIZED (H5OPEN H5E_UNINITIALIZED_g)
+#define H5E_UNSUPPORTED (H5OPEN H5E_UNSUPPORTED_g)
+#define H5E_BADTYPE (H5OPEN H5E_BADTYPE_g)
+#define H5E_BADRANGE (H5OPEN H5E_BADRANGE_g)
+#define H5E_BADVALUE (H5OPEN H5E_BADVALUE_g)
+H5_DLLVAR hid_t H5E_UNINITIALIZED_g; /* Information is uinitialized */
+H5_DLLVAR hid_t H5E_UNSUPPORTED_g; /* Feature is unsupported */
+H5_DLLVAR hid_t H5E_BADTYPE_g; /* Inappropriate type */
+H5_DLLVAR hid_t H5E_BADRANGE_g; /* Out of range */
+H5_DLLVAR hid_t H5E_BADVALUE_g; /* Bad value */
+
/* Cache related errors */
#define H5E_CANTFLUSH (H5OPEN H5E_CANTFLUSH_g)
#define H5E_CANTSERIALIZE (H5OPEN H5E_CANTSERIALIZE_g)
@@ -272,13 +322,13 @@ H5_DLLVAR hid_t H5E_CANTDIRTY_g; /* Unable to mark metadata as dirty */
H5_DLLVAR hid_t H5E_CANTEXPUNGE_g; /* Unable to expunge a metadata cache entry */
H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry */
-/* Parallel MPI errors */
-#define H5E_MPI (H5OPEN H5E_MPI_g)
-#define H5E_MPIERRSTR (H5OPEN H5E_MPIERRSTR_g)
-#define H5E_CANTRECV (H5OPEN H5E_CANTRECV_g)
-H5_DLLVAR hid_t H5E_MPI_g; /* Some MPI function failed */
-H5_DLLVAR hid_t H5E_MPIERRSTR_g; /* MPI Error String */
-H5_DLLVAR hid_t H5E_CANTRECV_g; /* Can't receive data */
+/* Free space errors */
+#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g)
+#define H5E_CANTREVIVE (H5OPEN H5E_CANTREVIVE_g)
+#define H5E_CANTSHRINK (H5OPEN H5E_CANTSHRINK_g)
+H5_DLLVAR hid_t H5E_CANTMERGE_g; /* Can't merge objects */
+H5_DLLVAR hid_t H5E_CANTREVIVE_g; /* Can't revive object */
+H5_DLLVAR hid_t H5E_CANTSHRINK_g; /* Can't shrink container */
/* Dataspace errors */
#define H5E_CANTCLIP (H5OPEN H5E_CANTCLIP_g)
@@ -294,46 +344,4 @@ H5_DLLVAR hid_t H5E_CANTNEXT_g; /* Can't move to next iterator location */
H5_DLLVAR hid_t H5E_BADSELECT_g; /* Invalid selection */
H5_DLLVAR hid_t H5E_CANTCOMPARE_g; /* Can't compare objects */
-/* B-tree related errors */
-#define H5E_NOTFOUND (H5OPEN H5E_NOTFOUND_g)
-#define H5E_EXISTS (H5OPEN H5E_EXISTS_g)
-#define H5E_CANTENCODE (H5OPEN H5E_CANTENCODE_g)
-#define H5E_CANTDECODE (H5OPEN H5E_CANTDECODE_g)
-#define H5E_CANTSPLIT (H5OPEN H5E_CANTSPLIT_g)
-#define H5E_CANTREDISTRIBUTE (H5OPEN H5E_CANTREDISTRIBUTE_g)
-#define H5E_CANTSWAP (H5OPEN H5E_CANTSWAP_g)
-#define H5E_CANTINSERT (H5OPEN H5E_CANTINSERT_g)
-#define H5E_CANTLIST (H5OPEN H5E_CANTLIST_g)
-#define H5E_CANTMODIFY (H5OPEN H5E_CANTMODIFY_g)
-#define H5E_CANTREMOVE (H5OPEN H5E_CANTREMOVE_g)
-H5_DLLVAR hid_t H5E_NOTFOUND_g; /* Object not found */
-H5_DLLVAR hid_t H5E_EXISTS_g; /* Object already exists */
-H5_DLLVAR hid_t H5E_CANTENCODE_g; /* Unable to encode value */
-H5_DLLVAR hid_t H5E_CANTDECODE_g; /* Unable to decode value */
-H5_DLLVAR hid_t H5E_CANTSPLIT_g; /* Unable to split node */
-H5_DLLVAR hid_t H5E_CANTREDISTRIBUTE_g; /* Unable to redistribute records */
-H5_DLLVAR hid_t H5E_CANTSWAP_g; /* Unable to swap records */
-H5_DLLVAR hid_t H5E_CANTINSERT_g; /* Unable to insert object */
-H5_DLLVAR hid_t H5E_CANTLIST_g; /* Unable to list node */
-H5_DLLVAR hid_t H5E_CANTMODIFY_g; /* Unable to modify record */
-H5_DLLVAR hid_t H5E_CANTREMOVE_g; /* Unable to remove object */
-
-/* Argument errors */
-#define H5E_UNINITIALIZED (H5OPEN H5E_UNINITIALIZED_g)
-#define H5E_UNSUPPORTED (H5OPEN H5E_UNSUPPORTED_g)
-#define H5E_BADTYPE (H5OPEN H5E_BADTYPE_g)
-#define H5E_BADRANGE (H5OPEN H5E_BADRANGE_g)
-#define H5E_BADVALUE (H5OPEN H5E_BADVALUE_g)
-H5_DLLVAR hid_t H5E_UNINITIALIZED_g; /* Information is uinitialized */
-H5_DLLVAR hid_t H5E_UNSUPPORTED_g; /* Feature is unsupported */
-H5_DLLVAR hid_t H5E_BADTYPE_g; /* Inappropriate type */
-H5_DLLVAR hid_t H5E_BADRANGE_g; /* Out of range */
-H5_DLLVAR hid_t H5E_BADVALUE_g; /* Bad value */
-
-/* Datatype conversion errors */
-#define H5E_CANTCONVERT (H5OPEN H5E_CANTCONVERT_g)
-#define H5E_BADSIZE (H5OPEN H5E_BADSIZE_g)
-H5_DLLVAR hid_t H5E_CANTCONVERT_g; /* Can't convert datatypes */
-H5_DLLVAR hid_t H5E_BADSIZE_g; /* Bad size for object */
-
#endif /* H5Epubgen_H */
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index c0d6f56..90c1cdf 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -21,78 +21,48 @@
/* Reset major error IDs */
-H5E_DATASET_g=
-H5E_FUNC_g=
+H5E_NONE_MAJOR_g=
+H5E_RS_g=
+H5E_CACHE_g=
+H5E_SLIST_g=
H5E_STORAGE_g=
-H5E_FILE_g=
-H5E_SYM_g=
-H5E_VFL_g=
-H5E_INTERNAL_g=
-H5E_BTREE_g=
-H5E_REFERENCE_g=
-H5E_DATASPACE_g=
+H5E_ATOM_g=
H5E_RESOURCE_g=
-H5E_PLIST_g=
-H5E_DATATYPE_g=
-H5E_RS_g=
-H5E_HEAP_g=
+H5E_FSPACE_g=
H5E_OHDR_g=
-H5E_ATOM_g=
+H5E_FUNC_g=
+H5E_ERROR_g=
+H5E_BTREE_g=
H5E_ATTR_g=
-H5E_NONE_MAJOR_g=
+H5E_PLIST_g=
+H5E_SYM_g=
+H5E_ARGS_g=
+H5E_HEAP_g=
+H5E_INTERNAL_g=
+H5E_FILE_g=
+H5E_LINK_g=
+H5E_DATATYPE_g=
+H5E_TST_g=
H5E_IO_g=
-H5E_SLIST_g=
+H5E_DATASET_g=
+H5E_REFERENCE_g=
H5E_EFL_g=
-H5E_TST_g=
-H5E_ARGS_g=
-H5E_ERROR_g=
-H5E_PLINE_g=
-H5E_FSPACE_g=
-H5E_CACHE_g= (-1);
+H5E_VFL_g=
+H5E_DATASPACE_g=
+H5E_PLINE_g= (-1);
/* Reset minor error IDs */
-/* Generic low-level file I/O errors */
-H5E_SEEKERROR_g=
-H5E_READERROR_g=
-H5E_WRITEERROR_g=
-H5E_CLOSEERROR_g=
-H5E_OVERFLOW_g=
-H5E_FCNTL_g=
-
-/* Resource errors */
-H5E_NOSPACE_g=
-H5E_CANTALLOC_g=
-H5E_CANTCOPY_g=
-H5E_CANTFREE_g=
-H5E_ALREADYEXISTS_g=
-H5E_CANTLOCK_g=
-H5E_CANTUNLOCK_g=
-H5E_CANTGC_g=
-H5E_CANTGETSIZE_g=
-
-/* Heap errors */
-H5E_CANTRESTORE_g=
-H5E_CANTCOMPUTE_g=
-H5E_CANTEXTEND_g=
-H5E_CANTATTACH_g=
-H5E_CANTUPDATE_g=
-
-/* Function entry/exit interface errors */
-H5E_CANTINIT_g=
-H5E_ALREADYINIT_g=
-H5E_CANTRELEASE_g=
-
-/* Property list errors */
-H5E_CANTGET_g=
-H5E_CANTSET_g=
-H5E_DUPCLASS_g=
+/* System level errors */
+H5E_SYSERRSTR_g=
-/* Free space errors */
-H5E_CANTMERGE_g=
-H5E_CANTREVIVE_g=
-H5E_CANTSHRINK_g=
+/* I/O pipeline errors */
+H5E_NOFILTER_g=
+H5E_CALLBACK_g=
+H5E_CANAPPLY_g=
+H5E_SETLOCAL_g=
+H5E_NOENCODER_g=
/* Object header related errors */
H5E_LINKCOUNT_g=
@@ -103,26 +73,37 @@ H5E_CANTDELETE_g=
H5E_BADITER_g=
H5E_CANTPACK_g=
-/* System level errors */
-H5E_SYSERRSTR_g=
-
-/* I/O pipeline errors */
-H5E_NOFILTER_g=
-H5E_CALLBACK_g=
-H5E_CANAPPLY_g=
-H5E_SETLOCAL_g=
-H5E_NOENCODER_g=
+/* Resource errors */
+H5E_NOSPACE_g=
+H5E_CANTALLOC_g=
+H5E_CANTCOPY_g=
+H5E_CANTFREE_g=
+H5E_ALREADYEXISTS_g=
+H5E_CANTLOCK_g=
+H5E_CANTUNLOCK_g=
+H5E_CANTGC_g=
+H5E_CANTGETSIZE_g=
-/* Group related errors */
-H5E_CANTOPENOBJ_g=
-H5E_CANTCLOSEOBJ_g=
-H5E_COMPLEN_g=
-H5E_LINK_g=
-H5E_SLINK_g=
-H5E_PATH_g=
+/* Generic low-level file I/O errors */
+H5E_SEEKERROR_g=
+H5E_READERROR_g=
+H5E_WRITEERROR_g=
+H5E_CLOSEERROR_g=
+H5E_OVERFLOW_g=
+H5E_FCNTL_g=
-/* No error */
-H5E_NONE_MINOR_g=
+/* B-tree related errors */
+H5E_NOTFOUND_g=
+H5E_EXISTS_g=
+H5E_CANTENCODE_g=
+H5E_CANTDECODE_g=
+H5E_CANTSPLIT_g=
+H5E_CANTREDISTRIBUTE_g=
+H5E_CANTSWAP_g=
+H5E_CANTINSERT_g=
+H5E_CANTLIST_g=
+H5E_CANTMODIFY_g=
+H5E_CANTREMOVE_g=
/* File accessability errors */
H5E_FILEEXISTS_g=
@@ -135,6 +116,16 @@ H5E_BADFILE_g=
H5E_TRUNCATED_g=
H5E_MOUNT_g=
+/* No error */
+H5E_NONE_MINOR_g=
+
+/* Heap errors */
+H5E_CANTRESTORE_g=
+H5E_CANTCOMPUTE_g=
+H5E_CANTEXTEND_g=
+H5E_CANTATTACH_g=
+H5E_CANTUPDATE_g=
+
/* Object atom related errors */
H5E_BADATOM_g=
H5E_BADGROUP_g=
@@ -143,6 +134,44 @@ H5E_CANTINC_g=
H5E_CANTDEC_g=
H5E_NOIDS_g=
+/* Group related errors */
+H5E_CANTOPENOBJ_g=
+H5E_CANTCLOSEOBJ_g=
+H5E_COMPLEN_g=
+H5E_PATH_g=
+
+/* Property list errors */
+H5E_CANTGET_g=
+H5E_CANTSET_g=
+H5E_DUPCLASS_g=
+
+/* Function entry/exit interface errors */
+H5E_CANTINIT_g=
+H5E_ALREADYINIT_g=
+H5E_CANTRELEASE_g=
+
+/* Datatype conversion errors */
+H5E_CANTCONVERT_g=
+H5E_BADSIZE_g=
+
+/* Link related errors */
+H5E_TRAVERSE_g=
+H5E_NLINKS_g=
+H5E_NOTREGISTERED_g=
+H5E_CANTMOVE_g=
+
+/* Parallel MPI errors */
+H5E_MPI_g=
+H5E_MPIERRSTR_g=
+H5E_CANTRECV_g=
+
+/* Argument errors */
+H5E_UNINITIALIZED_g=
+H5E_UNSUPPORTED_g=
+H5E_BADTYPE_g=
+H5E_BADRANGE_g=
+H5E_BADVALUE_g=
+
/* Cache related errors */
H5E_CANTFLUSH_g=
H5E_CANTSERIALIZE_g=
@@ -161,10 +190,10 @@ H5E_CANTDIRTY_g=
H5E_CANTEXPUNGE_g=
H5E_CANTRESIZE_g=
-/* Parallel MPI errors */
-H5E_MPI_g=
-H5E_MPIERRSTR_g=
-H5E_CANTRECV_g=
+/* Free space errors */
+H5E_CANTMERGE_g=
+H5E_CANTREVIVE_g=
+H5E_CANTSHRINK_g=
/* Dataspace errors */
H5E_CANTCLIP_g=
@@ -172,30 +201,6 @@ H5E_CANTCOUNT_g=
H5E_CANTSELECT_g=
H5E_CANTNEXT_g=
H5E_BADSELECT_g=
-H5E_CANTCOMPARE_g=
-
-/* B-tree related errors */
-H5E_NOTFOUND_g=
-H5E_EXISTS_g=
-H5E_CANTENCODE_g=
-H5E_CANTDECODE_g=
-H5E_CANTSPLIT_g=
-H5E_CANTREDISTRIBUTE_g=
-H5E_CANTSWAP_g=
-H5E_CANTINSERT_g=
-H5E_CANTLIST_g=
-H5E_CANTMODIFY_g=
-H5E_CANTREMOVE_g=
-
-/* Argument errors */
-H5E_UNINITIALIZED_g=
-H5E_UNSUPPORTED_g=
-H5E_BADTYPE_g=
-H5E_BADRANGE_g=
-H5E_BADVALUE_g=
-
-/* Datatype conversion errors */
-H5E_CANTCONVERT_g=
-H5E_BADSIZE_g= (-1);
+H5E_CANTCOMPARE_g= (-1);
#endif /* H5Eterm_H */
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index 17014dd..75af431 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -146,7 +146,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child,
*/
if(child->mtab.parent)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "file is already mounted")
- if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0)
+ if(H5G_loc_find(loc, name, &mp_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id)))
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point not found")
@@ -285,7 +285,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
* If we get the root group and the file has a parent in the mount tree,
* then we must have found the mount point.
*/
- if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0)
+ if(H5G_loc_find(loc, name, &mp_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
mp_loc_setup = TRUE;
child = mp_loc.oloc->file;
diff --git a/src/H5G.c b/src/H5G.c
index 2fc408c..4582a0d 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -107,6 +107,7 @@ typedef struct {
typedef struct {
H5G_stat_t *statbuf; /* Stat buffer about object */
hbool_t follow_link; /* Whether we are following a link or not */
+ H5F_t *loc_file; /* Pointer to the file the location is in */
hid_t dxpl_id; /* Dataset transfer property list */
} H5G_trav_ud4_t;
@@ -116,6 +117,14 @@ typedef struct {
hid_t dxpl_id; /* Dataset transfer property list */
} H5G_trav_ud7_t;
+/* User data for path traversal routine for getting external link name */
+typedef struct {
+ hbool_t want_file_name; /* Whether to retrieve file name (or object name) */
+ size_t size; /* Size of user buffer */
+ char *lname; /* User name buffer */
+ size_t name_len; /* Full length of name found */
+} H5G_trav_ud8_t;
+
/* Package variables */
/* Local variables */
@@ -128,13 +137,15 @@ H5FL_DEFINE(H5G_shared_t);
static H5G_t *H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t gapl_id);
static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id);
static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name,
const char *buf, hid_t dxpl_id);
static int H5G_get_comment(H5G_loc_t *loc, const char *name,
size_t bufsize, char *buf, hid_t dxpl_id);
static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
hid_t ocpypl_id, hid_t lcpl_id);
@@ -224,17 +235,17 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint)
/* Create the group */
if(NULL == (grp = H5G_create(file, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
if(H5G_loc(grp_id, &grp_loc) <0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to get location for new group")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get location for new group")
/* Link the group */
- if( H5L_link(&loc, name, &grp_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to group")
+ if( H5L_link(&loc, name, &grp_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to group")
ret_value = grp_id;
@@ -314,14 +325,12 @@ H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
-#ifdef LATER
/* Check the group access property list */
if(H5P_DEFAULT == gapl_id)
gapl_id = H5P_GROUP_ACCESS_DEFAULT;
else
if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
-#endif /* LATER */
if(NULL == (grp = H5G_create(loc.oloc->file, H5AC_dxpl_id, gcpl_id, gapl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
@@ -382,7 +391,7 @@ H5Gopen(hid_t loc_id, const char *name)
H5G_loc_reset(&grp_loc);
/* Find the group object */
- if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
ent_found = TRUE;
@@ -413,6 +422,86 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Gopen_expand
+ *
+ * Purpose: Opens an existing group for modification. When finished,
+ * call H5Gclose() to close it and release resources.
+ *
+ * This function allows the user the pass in a Group Access
+ * Property List, which H5Gopen() does not.
+ *
+ * Return: Success: Object ID of the group.
+ * Failure: FAIL
+ *
+ * Programmer: James Laird
+ * Thursday, July 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id)
+{
+ H5G_t *grp = NULL;
+ H5G_loc_t loc;
+ H5G_loc_t grp_loc; /* Location used to open group */
+ H5G_name_t grp_path; /* Opened object group hier. path */
+ H5O_loc_t grp_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_API(H5Gopen_expand, FAIL);
+ H5TRACE3("i","isi",loc_id,name,gapl_id);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ /* Set up opened group location to fill in */
+ grp_loc.oloc = &grp_oloc;
+ grp_loc.path = &grp_path;
+ H5G_loc_reset(&grp_loc);
+
+ /* Find the group object using the gapl passed in */
+ if(H5G_loc_find(&loc, name, &grp_loc/*out*/, gapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
+ ent_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&grp_oloc, H5AC_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Open the group */
+ if((grp = H5G_open(&grp_loc, H5AC_dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+done:
+ if(ret_value < 0) {
+ if(grp != NULL)
+ H5G_close(grp);
+ else {
+ if(ent_found)
+ H5G_name_free(&grp_path);
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Gclose
*
* Purpose: Closes the specified group. The group ID will no longer be
@@ -442,7 +531,7 @@ H5Gclose(hid_t group_id)
* reaches zero.
*/
if (H5I_dec_ref(group_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group");
done:
FUNC_LEAVE_API(ret_value);
@@ -920,7 +1009,7 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
H5G_loc_reset(&src_loc);
/* Find the source object to copy */
- if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found")
ent_found = TRUE;
@@ -985,7 +1074,7 @@ done:
static herr_t
H5G_init_interface(void)
{
- H5P_genclass_t *crt_pclass, *cpy_pclass;
+ H5P_genclass_t *crt_pclass, *acc_pclass, *cpy_pclass;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface);
@@ -1009,16 +1098,30 @@ H5G_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
+ /* ========== Group Access Property Class Initialization ============*/
+ assert(H5P_CLS_GROUP_ACCESS_g!=-1);
+
+ /* Get the pointer to group creation class */
+ if(NULL == (acc_pclass = H5I_object(H5P_CLS_GROUP_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
+
+ /* Only register the default property list if it hasn't been created yet */
+ if(H5P_LST_GROUP_ACCESS_g == (-1)) {
+ /* Register the default group creation property list */
+ if((H5P_LST_GROUP_ACCESS_g = H5P_create_id(acc_pclass))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
+ } /* end if */
+
/* ========== Object Copy Property Class Initialization ============*/
assert(H5P_CLS_OBJECT_COPY_g!=-1);
- /* Get the pointer to group copy class */
+ /* Get the pointer to group access class */
if(NULL == (cpy_pclass = H5I_object(H5P_CLS_OBJECT_COPY_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
/* Only register the default property list if it hasn't been created yet */
if(H5P_LST_OBJECT_COPY_g == (-1)) {
- /* Register the default group copy property list */
+ /* Register the default group access property list */
if((H5P_LST_OBJECT_COPY_g = H5P_create_id(cpy_pclass))<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
@@ -1241,7 +1344,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
loc->oloc/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
if(1 != H5O_link(loc->oloc, 1, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)")
+ HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
} else {
/*
* Open the root object as a group.
@@ -1736,7 +1839,7 @@ H5G_fileof(H5G_t *grp)
*/
static herr_t
H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1759,17 +1862,11 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno[0]) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno")
- /* Get info for soft link */
- /* (If we don't follow the link, we can retrieve info about the soft link itself) */
- if(!udata->follow_link && lnk && lnk->type == H5L_LINK_SOFT) {
- /* Set object type */
- statbuf->type = H5G_LINK;
+ /* Info for soft and UD links is gotten by H5L_get_linkinfo. If we have
+ * a hard link, follow it and get info on the object */
+ if(udata->follow_link || !lnk ||
+ (lnk->type == H5L_LINK_HARD)) {
- /* Get length of link value */
- statbuf->linklen = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/
- } /* end if */
- /* Get info for hard link */
- else {
/* Get object type */
statbuf->type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id);
if(statbuf->type == H5G_UNKNOWN)
@@ -1796,16 +1893,13 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
/* Get object header information */
if(H5O_get_info(obj_loc->oloc, &(statbuf->ohdr), udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information")
- } /* end else */
+ } /* end if */
} /* end if */
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_get_objinfo_cb() */
@@ -1842,13 +1936,46 @@ H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link,
/* Set up user data for retrieving information */
udata.statbuf = statbuf;
udata.follow_link = follow_link;
+ udata.loc_file = loc->oloc->file;
udata.dxpl_id = dxpl_id;
/* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK),
- H5G_get_objinfo_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK|H5G_TARGET_UDLINK),
+ H5G_get_objinfo_cb, &udata, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
+ /* Assign object type and link length for soft links and UD links */
+ /* The default linklen (for non-links) is 0. */
+ if(statbuf)
+ statbuf->linklen = 0;
+
+ /* If we're pointing at a soft or UD link, get the real link length and type */
+ if(statbuf && follow_link == 0)
+ {
+ H5L_linkinfo_t linfo; /* Link information buffer */
+ herr_t ret;
+
+ /* Get information about link to the object. If this fails, e.g.
+ * because the object is ".", just treat the object as a hard link. */
+ H5E_BEGIN_TRY {
+ ret = H5L_get_linkinfo(loc, name, &linfo, H5P_DEFAULT, dxpl_id);
+ } H5E_END_TRY
+
+ if(ret >=0 && linfo.linkclass != H5L_LINK_HARD)
+ {
+ statbuf->linklen = linfo.u.link_size;
+ if(linfo.linkclass == H5L_LINK_SOFT)
+ {
+ statbuf->type = H5G_LINK;
+ }
+ else /* UD link. H5L_get_linkinfo checked for invalid link classes */
+ {
+ HDassert(linfo.linkclass >= H5L_LINK_UD_MIN && linfo.linkclass <= H5L_LINK_MAX);
+ statbuf->type = H5G_UDLINK;
+ }
+ }
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_get_objinfo() */
@@ -1876,7 +2003,7 @@ H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id
FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment)
/* Get the symbol table entry for the object */
- if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0)
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Remove the previous comment message if any */
@@ -1922,7 +2049,7 @@ H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid
FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment)
/* Get the symbol table entry for the object */
- if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0)
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the message */
@@ -1958,7 +2085,7 @@ done:
*/
static herr_t
H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1973,6 +2100,8 @@ H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H
/* Get file pointer for location */
udata->file = grp_loc->oloc->file;
+ *own_obj_loc = FALSE;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_insertion_file_cb() */
@@ -2016,7 +2145,7 @@ H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
* Look up the name to get the containing group and to make sure the name
* doesn't already exist.
*/
- if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists")
/* Set return value */
@@ -2168,6 +2297,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
H5G_loc_t new_loc; /* Group location of object copied */
hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */
unsigned cpy_option = 0; /* Copy options */
+ hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_copy, FAIL);
@@ -2197,7 +2327,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Insert the new object in the destination file's group */
- if(H5L_link(dst_loc, dst_name, &new_loc, dxpl_id, lcpl_id) < 0)
+ if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link")
entry_inserted = TRUE;
@@ -2209,3 +2339,4 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_copy() */
+
diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c
index 4f2b837..31304b4 100644
--- a/src/H5Gdeprec.c
+++ b/src/H5Gdeprec.c
@@ -52,12 +52,12 @@ H5Glink(hid_t cur_loc_id, H5L_link_t type, const char *cur_name, const char *new
if(type == H5L_LINK_HARD)
{
- if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name, H5P_DEFAULT)) < 0)
+ if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link")
}
else if(type == H5L_LINK_SOFT)
{
- if((ret_value = H5Lcreate_soft(cur_name, cur_loc_id, new_name, H5P_DEFAULT)) < 0)
+ if((ret_value = H5Lcreate_soft(cur_name, cur_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link")
}
else
@@ -86,7 +86,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5L_link_t type,
H5TRACE5("e","isLlis",cur_loc_id,cur_name,type,new_loc_id,new_name);
if(type == H5L_LINK_HARD) {
- if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0)
+ if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, new_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link")
}
else if(type == H5L_LINK_SOFT) {
@@ -95,7 +95,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5L_link_t type,
if(new_loc_id == H5L_SAME_LOC)
new_loc_id = cur_loc_id;
- if((ret_value = H5Lcreate_soft(cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0)
+ if((ret_value = H5Lcreate_soft(cur_name, new_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link")
}
else
@@ -121,7 +121,7 @@ H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name)
FUNC_ENTER_API(H5Gmove, FAIL)
H5TRACE3("e","iss",src_loc_id,src_name,dst_name);
- if((ret_value=H5Lmove(src_loc_id, src_name, H5L_SAME_LOC, dst_name, H5P_DEFAULT)) < 0)
+ if((ret_value=H5Lmove(src_loc_id, src_name, H5L_SAME_LOC, dst_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link")
done:
@@ -143,8 +143,8 @@ herr_t H5Gmove2(hid_t src_loc_id, const char *src_name,
FUNC_ENTER_API(H5Gmove2, FAIL)
- if((ret_value=H5Lmove(src_loc_id, src_name, dst_loc_id, dst_name, H5P_DEFAULT)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link")
+ if((ret_value=H5Lmove(src_loc_id, src_name, dst_loc_id, dst_name, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't move link")
done:
FUNC_LEAVE_API(ret_value)
@@ -166,7 +166,7 @@ H5Gunlink(hid_t loc_id, const char *name)
FUNC_ENTER_API(H5Gunlink, FAIL)
H5TRACE2("e","is",loc_id,name);
- if((ret_value=H5Lunlink(loc_id, name)) < 0)
+ if((ret_value=H5Lunlink(loc_id, name, H5P_DEFAULT)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "Couldn't delete link")
done:
@@ -189,8 +189,8 @@ herr_t H5Gget_linkval(hid_t loc_id, const char *name,
FUNC_ENTER_API(H5Gget_linkval, FAIL)
- if((ret_value=H5Lget_linkval(loc_id, name, size, buf)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "Couldn't get link info")
+ if((ret_value=H5Lget_linkval(loc_id, name, size, buf, H5P_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "couldn't get link info")
done:
FUNC_LEAVE_API(ret_value)
diff --git a/src/H5Gent.c b/src/H5Gent.c
index a8311f0..f242bad 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -183,8 +183,14 @@ H5G_ent_decode(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
UINT32DECODE (*pp, ent->cache.slink.lval_offset);
break;
+ case H5G_CACHED_ULINK:
+ UINT32DECODE (*pp, ent->cache.ulink.udata_size);
+ UINT32DECODE (*pp, ent->cache.ulink.udata_offset);
+ UINT32DECODE (*pp, ent->cache.ulink.link_type);
+ break;
default:
- HDabort();
+ /* Error or unknown type. Bail out. */
+ return -1;
}
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
@@ -296,8 +302,15 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
UINT32ENCODE (*pp, ent->cache.slink.lval_offset);
break;
+ case H5G_CACHED_ULINK:
+ UINT32ENCODE (*pp, ent->cache.ulink.udata_size);
+ UINT32ENCODE (*pp, ent->cache.ulink.udata_offset);
+ UINT32ENCODE (*pp, ent->cache.ulink.link_type);
+ break;
+
default:
- HDabort();
+ /* Unknown cached type. Bail out. */
+ return -1;
}
} else {
H5F_ENCODE_LENGTH(f, *pp, 0);
@@ -457,7 +470,24 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t
break;
default:
- HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ if(lnk->type < H5L_LINK_UD_MIN)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+
+ {
+ size_t udata_offset = (size_t) (-1); /* Offset to data buffer */
+
+ if(lnk->u.ud.size > 0)
+ {
+ if((size_t)(-1) == (udata_offset = H5HL_insert(f, dxpl_id,
+ heap_addr, lnk->u.ud.size, lnk->u.ud.udata)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write user data to local heap")
+ }
+
+ ent->type = H5G_CACHED_ULINK;
+ ent->cache.ulink.udata_size = lnk->u.ud.size;
+ ent->cache.ulink.udata_offset = udata_offset;
+ ent->cache.ulink.link_type = lnk->type;
+ }
} /* end switch */
/* Set the file for the entry */
@@ -544,6 +574,64 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str
HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!");
break;
+ case H5G_CACHED_ULINK:
+ if(ent->cache.ulink.link_type == H5L_LINK_EXTERNAL)
+ {
+ HDfprintf (stream, "External Link\n");
+ HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth,
+ "Cached information:");
+ if(ent->cache.ulink.udata_size > 0)
+ {
+ HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
+ "User data offset:",
+ (unsigned long)(ent->cache.ulink.udata_offset));
+ }
+ HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
+ "User data size:",
+ (unsigned long)(ent->cache.ulink.udata_size));
+ if (heap>0 && H5F_addr_defined(heap)) {
+ const H5HL_t *heap_ptr;
+ char * filename;
+ char * pathname;
+
+ heap_ptr = H5HL_protect(ent->file, dxpl_id, heap);
+ lval = H5HL_offset_into(ent->file, heap_ptr, ent->cache.ulink.udata_offset);
+ if(H5Lunpack_elink_val(lval, &filename, &pathname) < 0) return FAIL;
+
+ HDfprintf (stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth,
+ "External link file name:",
+ lval);
+ HDfprintf (stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth,
+ "External link object name:",
+ pathname);
+ H5HL_unprotect(ent->file, dxpl_id, heap_ptr, heap, H5AC__NO_FLAGS_SET);
+ } else {
+ HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given!");
+ }
+ }
+ else
+ {
+ HDfprintf (stream, "User-defined Link\n");
+ HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth,
+ "Cached information:");
+ HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
+ "Link class:",
+ (unsigned long)(ent->cache.ulink.link_type));
+ if(ent->cache.ulink.udata_size > 0)
+ {
+ HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
+ "User data offset:",
+ (unsigned long)(ent->cache.ulink.udata_offset));
+ }
+ HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth,
+ "User data size:",
+ (unsigned long)(ent->cache.ulink.udata_size));
+ if (heap<=0 || !H5F_addr_defined(heap)) {
+ HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given!");
+ }
+ }
+ break;
+
default:
HDfprintf(stream, "*** Unknown symbol type %d\n", ent->type);
break;
diff --git a/src/H5Glink.c b/src/H5Glink.c
index bf23058..1139e7c 100644
--- a/src/H5Glink.c
+++ b/src/H5Glink.c
@@ -294,7 +294,8 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
HDassert(name);
/* Create link message from object entry */
- HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK);
+ HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK
+ || ent->type == H5G_CACHED_ULINK);
/* XXX: Set character set & creation time for real? */
lnk->cset = H5F_CRT_DEFAULT_CSET;
lnk->ctime = 0;
@@ -302,7 +303,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
HDassert(lnk->name);
switch(ent->type) {
case H5G_NOTHING_CACHED:
- lnk->type = H5G_LINK_HARD;
+ lnk->type = H5L_LINK_HARD;
lnk->u.hard.addr = ent->header;
break;
@@ -310,7 +311,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
{
const char *s; /* Pointer to link value in heap */
- lnk->type = H5G_LINK_SOFT;
+ lnk->type = H5L_LINK_SOFT;
s = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset);
HDassert(s);
@@ -321,6 +322,25 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
}
break;
+ case H5G_CACHED_ULINK:
+ {
+ const char *s; /* Pointer to link name in heap */
+
+ /* Copy link type and udata size from entry info */
+ lnk->type = ent->cache.ulink.link_type;
+ lnk->u.ud.size = ent->cache.ulink.udata_size;
+
+ /* Get pointer to udata in heap */
+ s = H5HL_offset_into(ent->file, heap, ent->cache.ulink.udata_offset);
+ HDassert(s);
+
+ /* Read udata from heap */
+ if(NULL== (lnk->u.ud.udata = H5MM_malloc(lnk->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for user link data")
+ HDmemcpy(lnk->u.ud.udata, s, lnk->u.ud.size);
+ }
+ break;
+
default:
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
} /* end switch */
@@ -454,9 +474,11 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
/* Determine type of object */
- if(ltable.lnks[idx].type == H5G_LINK_SOFT)
+ if(ltable.lnks[idx].type == H5L_LINK_SOFT)
ret_value = H5G_LINK;
- else {
+ else if(ltable.lnks[idx].type >= H5L_LINK_UD_MIN)
+ ret_value = H5G_UDLINK;
+ else if(ltable.lnks[idx].type == H5L_LINK_HARD){
H5O_loc_t tmp_oloc; /* Temporary object location */
/* Build temporary object location */
@@ -466,7 +488,9 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
/* Get the type of the object */
if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type")
- } /* end else */
+ } else{
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type")
+ }/* end else */
done:
/* Release link table */
@@ -501,7 +525,7 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
H5G_link_ud2_t *udata = (H5G_link_ud2_t *)_udata; /* 'User data' passed in */
herr_t ret_value = H5O_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_remove_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_remove_cb)
/* check arguments */
HDassert(lnk);
@@ -509,20 +533,32 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
/* If we've found the right link, get the object type */
if(HDstrcmp(lnk->name, udata->name) == 0) {
- if(lnk->type == H5G_LINK_SOFT)
- *(udata->obj_type) = H5G_LINK;
- else {
- H5O_loc_t tmp_oloc; /* Temporary object location */
+ switch(lnk->type)
+ {
+ case H5L_LINK_HARD:
+ {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = udata->file;
+ tmp_oloc.addr = lnk->u.hard.addr;
+
+ /* Get the type of the object */
+ /* Note: no way to check for error :-( */
+ *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id);
+ }
+ break;
- /* Build temporary object location */
- tmp_oloc.file = udata->file;
- tmp_oloc.addr = lnk->u.hard.addr;
+ case H5L_LINK_SOFT:
+ *(udata->obj_type) = H5G_LINK;
+ break;
- /* Get the type of the object */
- /* Note: no way to check for error :-( */
- *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id);
- } /* end else */
+ default: /* User-defined link */
+ if(lnk->type < H5L_LINK_UD_MIN)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type");
+ *(udata->obj_type) = H5G_UDLINK;
+ }
/* Stop the iteration, we found the correct link */
HGOTO_DONE(H5O_ITER_STOP)
} /* end if */
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
index 4e22357..c022169 100644
--- a/src/H5Gloc.c
+++ b/src/H5Gloc.c
@@ -46,7 +46,8 @@ typedef struct {
/* PRIVATE PROTOTYPES */
static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
+ hbool_t *own_obj_loc/*out*/);
/*-------------------------------------------------------------------------
@@ -283,7 +284,7 @@ done:
*/
static herr_t
H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_loc_ud1_t *udata = (H5G_loc_ud1_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -299,6 +300,7 @@ H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const
* of the group location for the object, or freeing it. - QAK)
*/
H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW);
+ *own_obj_loc = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -319,7 +321,7 @@ done:
*/
herr_t
H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/,
- hid_t dxpl_id)
+ hid_t lapl_id, hid_t dxpl_id)
{
H5G_loc_ud1_t udata; /* User data for traversal callback */
herr_t ret_value = SUCCEED; /* Return value */
@@ -335,7 +337,7 @@ H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/,
udata.loc = obj_loc;
/* Traverse group hierarchy to locate object */
- if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
done:
diff --git a/src/H5Gname.c b/src/H5Gname.c
index d3e1d12..fb2df97 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -936,6 +936,13 @@ H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc,
search_datatype = 1;
break;
+ case H5G_UDLINK:
+ /* User-defined links automatically wipe out names (because it
+ * would be too much work to track them), so there's no point
+ * in searching them.
+ */
+ break;
+
default:
HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not valid object type")
} /* end switch */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index dabb01c..c640a65 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -283,16 +283,23 @@ H5G_node_debug_key (FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidt
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:",
(unsigned)key->offset);
- HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:");
+ if(udata->heap_addr != 0)
+ {
+ HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:");
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
+ if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
- s = H5HL_offset_into(f, heap, key->offset);
- HDfprintf (stream, "%s\n", s);
+ s = H5HL_offset_into(f, heap, key->offset);
+ HDfprintf (stream, "%s\n", s);
- if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
+ if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
+ }
+ else
+ {
+ HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Cannot get name; heap address not specified\n");
+ }
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1242,7 +1249,10 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
if(cmp)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found")
- if(H5G_CACHED_SLINK == sn->entry[idx].type) {
+ switch(sn->entry[idx].type)
+ {
+ case H5G_CACHED_SLINK:
+ {
/* Set the type of the link removed */
*(udata->obj_type) = H5G_LINK;
@@ -1266,7 +1276,42 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.slink.lval_offset, len);
H5E_clear_stack(NULL); /* no big deal */
- } else {
+ }
+ break;
+
+ case H5G_CACHED_ULINK:
+ {
+ size_t ud_data_size = 0; /* User link data size */
+ hbool_t ud_data_found; /* Indicate that the link user data was found */
+
+ /* Set the type of the link removed */
+ *(udata->obj_type) = H5G_UDLINK;
+
+ /* Remove the link user data from the heap */
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
+
+ s = H5HL_offset_into(f, heap, sn->entry[idx].cache.ulink.udata_offset);
+ if(s)
+ {
+ ud_data_found = 1;
+ ud_data_size = sn->entry[idx].cache.ulink.udata_size;
+ }
+ else
+ ud_data_found = 0;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; s = NULL;
+
+ if(ud_data_found)
+ H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.ulink.udata_offset, ud_data_size);
+
+ H5E_clear_stack(NULL); /* no big deal */
+ }
+ break;
+
+ default:
+ {
H5O_loc_t tmp_oloc; /* Temporary object location */
/* Build temporary object location */
@@ -1283,7 +1328,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
if(H5O_link(&tmp_oloc, -1, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to decrement object link count")
} /* end if */
- } /* end else */
+ }
+ } /* end switch */
/* Remove the name from the local heap */
if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
@@ -1372,7 +1418,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
/* Reduce the link count for all entries in this node */
for(idx = 0; idx < sn->nsyms; idx++) {
- if(H5G_CACHED_SLINK != sn->entry[idx].type) {
+ if(!(H5G_CACHED_SLINK == sn->entry[idx].type ||
+ H5G_CACHED_ULINK == sn->entry[idx].type)) {
/* Decrement the reference count, if requested */
if(udata->adj_link) {
HDassert(H5F_addr_defined(sn->entry[idx].header));
@@ -1670,17 +1717,24 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
loc_idx = udata->idx - udata->num_objs;
/* Check for a soft link */
- if(sn->entry[loc_idx].type == H5G_CACHED_SLINK)
+ switch(sn->entry[loc_idx].type)
+ {
+ case H5G_CACHED_SLINK:
udata->type = H5G_LINK;
- /* Must be a hard link */
- else {
+ break;
+ case H5G_CACHED_ULINK:
+ udata->type = H5G_UDLINK;
+ break;
+
+ default:
/* Build temporary object location */
tmp_oloc.file = f;
HDassert(H5F_addr_defined(sn->entry[loc_idx].header));
tmp_oloc.addr = sn->entry[loc_idx].header;
udata->type = H5O_obj_type(&tmp_oloc, dxpl_id);
- } /* end else */
+ break;
+ }
ret_value = H5B_ITER_STOP;
} else {
udata->num_objs += sn->nsyms;
@@ -1997,6 +2051,14 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
lnk.type = H5L_LINK_SOFT;
lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
} /* else if */
+ else if(H5G_CACHED_ULINK == src_ent->type) {
+ /* user-defined link */
+
+ /* Construct link information for eventual insertion */
+ lnk.type = src_ent->cache.ulink.link_type;
+ lnk.u.ud.size = src_ent->cache.ulink.udata_size;
+ lnk.u.ud.udata = H5HL_offset_into(f, heap, src_ent->cache.ulink.udata_offset);
+ } /* else if */
else
HDassert(0 && "Unknown entry type");
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 7b18469..9b61a26 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -35,6 +35,7 @@
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property Lists */
/* Private typedefs */
@@ -424,7 +425,7 @@ H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
/* Increment reference count for object */
if(H5O_link(&obj_oloc, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count")
+ HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "unable to increment hard link count")
} /* end if */
done:
@@ -779,6 +780,10 @@ H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxp
H5MM_xfree(lnk_table[u].name);
if(lnk_table[u].type == H5L_LINK_SOFT)
H5MM_xfree(lnk_table[u].u.soft.name);
+ else if(lnk_table[u].type >= H5L_LINK_UD_MIN) {
+ if(lnk_table[u].u.ud.size > 0)
+ H5MM_xfree(lnk_table[u].u.ud.udata);
+ } /* end if */
} /* end for */
/* Release memory for link table */
@@ -897,7 +902,7 @@ done:
*/
static herr_t
H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_obj_ud2_t *udata = (H5G_obj_ud2_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -918,7 +923,7 @@ H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const
*udata->lnk = *lnk;
HDassert(lnk->name);
udata->lnk->name = H5MM_xstrdup(lnk->name);
- if(lnk->type == H5G_LINK_SOFT)
+ if(lnk->type == H5L_LINK_SOFT)
udata->lnk->u.soft.name = H5MM_xstrdup(lnk->u.soft.name);
#endif /* H5_GROUP_REVISION */
} /* end if */
@@ -933,12 +938,9 @@ H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const
} /* end if */
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_obj_find_cb() */
@@ -959,10 +961,10 @@ done:
*/
herr_t
H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags,
- H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id)
+ H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t lapl_id, hid_t dxpl_id)
{
- H5G_obj_ud2_t udata; /* User data for traversal callback */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5G_obj_ud2_t udata; /* User data for traversal callback */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_obj_find, FAIL)
@@ -970,13 +972,14 @@ H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags,
HDassert(loc && loc->oloc->file);
HDassert(name && *name);
HDassert(obj_oloc);
+ HDassert(H5P_CLS_LINK_ACCESS_g != -1);
/* Set up user data for locating object */
udata.lnk = lnk;
udata.oloc = obj_oloc;
/* Traverse group hierarchy to locate object */
- if(H5G_traverse(loc, name, traverse_flags, H5G_obj_find_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, traverse_flags, H5G_obj_find_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
done:
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index b0d51d2..77eec67 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -36,7 +36,9 @@
#include "H5SLprivate.h" /* Skip lists */
#define H5G_SIZE_HINT 256 /* default root grp size hint */
-#define H5G_NLINKS 16 /*max symlinks to follow per lookup */
+
+/* H5G_NLINKS is deprecated */
+#define H5G_NLINKS H5L_NLINKS_DEF
/*
* Various types of object header information can be cached in a symbol
@@ -49,8 +51,9 @@ typedef enum H5G_type_t {
H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */
H5G_CACHED_STAB = 1, /*symbol table, `stab' */
H5G_CACHED_SLINK = 2, /*symbolic link */
+ H5G_CACHED_ULINK = 3, /*user-defined link */
- H5G_NCACHED = 3 /*THIS MUST BE LAST */
+ H5G_NCACHED = 4 /*THIS MUST BE LAST */
} H5G_type_t;
/*
@@ -69,6 +72,12 @@ typedef union H5G_cache_t {
struct {
size_t lval_offset; /*link value offset */
} slink;
+
+ struct {
+ size_t udata_size; /*size of user data buffer */
+ size_t udata_offset; /*link's user data buffer */
+ H5L_link_t link_type; /*link type ID */
+ } ulink;
} H5G_cache_t;
/*
@@ -232,25 +241,17 @@ typedef struct H5G_bt_it_ud5_t {
} H5G_bt_it_ud5_t;
/* Typedef for path traversal operations */
+/* grp_loc is the location of the group in which the targeted object is located.
+ * name is the last component of the object's name
+ * lnk is the link between the group and the object
+ * obj_loc is the target of the traversal (or NULL if the object doesn't exist)
+ * operator_data is whatever udata was supplied when H5G_traverse was called
+ * own_obj_loc should be set to TRUE if this callback takes ownership of obj_loc,
+ * and FALSE if obj_loc needs to be deleted.
+ */
typedef herr_t (*H5G_traverse_t)(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk/*in*/, H5G_loc_t *obj_loc/*out*/, void *operator_data/*in,out*/);
-
-/* "value" information for a link (as opposed to "name" of link) */
-typedef struct {
- haddr_t addr; /* Address of object linked to */
-} H5G_linkvalue_hard_t;
-
-typedef struct {
- char *name; /* Link value */
-} H5G_linkvalue_soft_t;
-
-typedef struct {
- H5L_link_t type; /* Type of link */
- union {
- H5G_linkvalue_hard_t hard; /* Information for hard link */
- H5G_linkvalue_soft_t soft; /* Information for soft link */
- } u;
-} H5G_linkvalue_t;
+ const H5O_link_t *lnk/*in*/, H5G_loc_t *obj_loc/*out*/, void *operator_data/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
/*
* During name lookups (see H5G_traverse()) we sometimes want information about
@@ -260,7 +261,8 @@ typedef struct {
#define H5G_TARGET_NORMAL 0x0000
#define H5G_TARGET_SLINK 0x0001
#define H5G_TARGET_MOUNT 0x0002
-#define H5G_CRT_INTMD_GROUP 0x0004
+#define H5G_TARGET_UDLINK 0x0004
+#define H5G_CRT_INTMD_GROUP 0x0008
/*
* This is the class identifier to give to the B-tree functions.
@@ -278,7 +280,8 @@ H5_DLL H5G_t *H5G_rootof(H5F_t *f);
H5_DLL const char * H5G_component(const char *name, size_t *size_p);
H5_DLL herr_t H5G_traverse_term_interface(void);
H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name,
- unsigned target, H5G_traverse_t op, void *op_data, hid_t dxpl_id);
+ unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id,
+ hid_t dxpl_id);
/*
* Functions that understand symbol tables but not names. The
@@ -377,7 +380,8 @@ H5_DLL H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name,
H5G_obj_t *obj_type, hid_t dxpl_id);
H5_DLL herr_t H5G_obj_find(H5G_loc_t *loc, const char *name,
- unsigned traverse_flags, H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id);
+ unsigned traverse_flags, H5O_link_t *lnk, H5O_loc_t *obj_oloc,
+ hid_t lapl_id, hid_t dxpl_id);
/*
* These functions operate on group hierarchy names.
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index c1d3320..d4278a4 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -161,7 +161,7 @@ H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size);
*/
H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc);
H5_DLL herr_t H5G_loc_find(H5G_loc_t *loc, const char *name,
- H5G_loc_t *obj_loc/*out*/, hid_t dxpl_id);
+ H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id);
H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc);
H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc);
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index a1583c9..52420e1 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -52,7 +52,7 @@ typedef enum H5G_obj_t {
H5G_DATASET, /* Object is a dataset */
H5G_TYPE, /* Object is a named data type */
H5G_LINK, /* Object is a symbolic link */
- H5G_RESERVED_4, /* Reserved for future use */
+ H5G_UDLINK, /* Object is a user-defined link */
H5G_RESERVED_5, /* Reserved for future use */
H5G_RESERVED_6, /* Reserved for future use */
H5G_RESERVED_7 /* Reserved for future use */
@@ -63,30 +63,6 @@ typedef enum H5G_obj_t {
#define H5G_NUSERTYPES (H5G_NTYPES-H5G_NLIBTYPES)
#define H5G_USERTYPE(X) (8+(X)) /* User defined types */
-#ifdef QAK
-/* Information about an object */
-typedef struct H5G_obj_stat_t {
- haddr_t objno; /* Object number */
- unsigned nlink; /* Number of hard links to object*/
- time_t mtime; /* Modification time */
- H5O_stat_t ohdr; /* Object header information */
-} H5G_obj_stat_t;
-
-typedef struct H5G_slink_stat_t {
- size_t linklen; /* Symbolic link value length */
-} H5G_slink_stat_t;
-
-typedef struct H5G_stat_t {
- unsigned long fileno; /* File number */
- H5T_cset_t cset; /* Character set of link name */
- time_t ctime; /* Creation time */
- H5G_obj_t type; /* Object type */
- union {
- H5G_obj_stat_t obj; /* Information about objects */
- H5G_slink_stat_t slink; /* Information about symbolic links */
- } u;
-} H5G_stat_t;
-#else /* QAK */
/* Information about an object */
typedef struct H5G_stat_t {
unsigned long fileno[2]; /*file number */
@@ -97,7 +73,6 @@ typedef struct H5G_stat_t {
size_t linklen; /*symbolic link value length */
H5O_stat_t ohdr; /* Object header information */
} H5G_stat_t;
-#endif /* QAK */
typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name,
void *op_data);
@@ -112,6 +87,7 @@ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name,
H5_DLL hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint);
H5_DLL hid_t H5Gopen(hid_t loc_id, const char *name);
+H5_DLL hid_t H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id);
H5_DLL herr_t H5Gclose(hid_t group_id);
H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx,
H5G_iterate_t op, void *op_data);
@@ -154,8 +130,10 @@ H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name,
#define H5G_link_t H5L_link_t
#define H5G_SAME_LOC H5L_SAME_LOC
+
#ifdef __cplusplus
}
#endif
#endif
+
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 651ddf3..926aa0e 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -608,8 +608,11 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata)
udata->lnk->ctime = 0;
udata->lnk->name = H5MM_xstrdup(udata->name);
- /* Object is a symbolic link */
- if(H5G_CACHED_SLINK == ent->type) {
+ /* Object is a symbolic or user-defined link */
+ switch(ent->type)
+ {
+ case H5G_CACHED_SLINK:
+ {
const char *s; /* Pointer to link value */
const H5HL_t *heap; /* Pointer to local heap for group */
@@ -628,14 +631,47 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata)
/* Set link type */
udata->lnk->type = H5L_LINK_SOFT;
- } /* end if */
- else {
+ }
+ break;
+
+ case H5G_CACHED_ULINK:
+ {
+ void * s; /* Pointer to heap value */
+ const H5HL_t *heap; /* Pointer to local heap for group */
+ size_t data_size; /* Size of user link data */
+
+ /* Lock the local heap */
+ if(NULL == (heap = H5HL_protect(udata->file, udata->dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
+
+ data_size =ent->cache.ulink.udata_size;
+
+ if(data_size > 0)
+ {
+ s = H5HL_offset_into(udata->file, heap, ent->cache.ulink.udata_offset);
+
+ /* Allocate space for the user data and copy it from the heap */
+ udata->lnk->u.ud.udata = H5MM_malloc(data_size);
+ HDmemcpy(udata->lnk->u.ud.udata, s, data_size);
+ } /* end if */
+
+ /* Release the local heap */
+ if(H5HL_unprotect(udata->file, udata->dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
+
+ /* Set link size and type */
+ udata->lnk->u.ud.size = data_size;
+ udata->lnk->type = ent->cache.ulink.link_type;
+ }
+ break;
+
+ default:
/* Set address of object */
udata->lnk->u.hard.addr = ent->header;
/* Set link type */
udata->lnk->type = H5L_LINK_HARD;
- } /* end else */
+ } /* end switch */
} /* end if */
done:
@@ -697,3 +733,4 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_stab_lookup() */
+
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index c94cd86..03db4d3 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -28,10 +28,12 @@
/* Packages needed by this file... */
#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppublic.h" /* Property Lists */
@@ -51,13 +53,21 @@ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* PRIVATE PROTOTYPES */
static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
+static herr_t H5G_traverse_ud(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id,
+ hid_t dxpl_id);
+static herr_t H5G_traverse_elink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id,
+ hid_t dxpl_id);
static herr_t H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id);
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id,
+ hid_t dxpl_id);
static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/);
static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name,
unsigned target, int *nlinks, H5G_traverse_t op, void *op_data,
- hid_t dxpl_id);
+ hid_t lapl_id, hid_t dxpl_id);
/*-------------------------------------------------------------------------
@@ -103,7 +113,7 @@ H5G_traverse_term_interface(void)
*/
static herr_t
H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -118,18 +128,149 @@ H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H
H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP);
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_traverse_link_cb() */
/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_link_ud
+ *
+ * Purpose: Callback for user-defined link traversal. Sets up a
+ * location ID and passes it to the user traversal callback.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t H5G_traverse_ud(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id,
+ hid_t dxpl_id)
+{
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ hid_t cb_return = -1; /* The ID the user-defined callback returned */
+ H5O_loc_t *new_oloc=NULL;
+ H5F_t *temp_file=NULL;
+ H5F_t *new_file=NULL;
+ H5G_t *grp;
+ H5P_genplist_t *lapl_default;
+ H5P_genplist_t *lapl; /* LAPL with nlinks set */
+ hid_t cur_grp;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_ud)
+
+ /* Sanity check */
+ HDassert(grp_loc);
+ HDassert(lnk);
+ HDassert(lnk->type >= H5L_LINK_UD_MIN);
+ HDassert(obj_loc);
+ HDassert(nlinks);
+
+ /* Reset the object's path information, because we can't detect any changes
+ * in the "path" the user-defined callback takes */
+ H5G_name_free(obj_loc->path);
+
+ /* Get the link class for this type of link. */
+ if(NULL == (link_class = H5L_find_class(lnk->type)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get UD link class")
+
+ /* Set up location for user-defined callback */
+ if((grp = H5G_open(grp_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((cur_grp = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+ /* Record number of soft links left to traverse in the property list.
+ * If no property list exists yet, create one. */
+ if(lapl_id == H5P_DEFAULT)
+ {
+ HDassert(H5P_LINK_ACCESS_DEFAULT != -1);
+ if(NULL == (lapl_default = H5I_object(H5P_LINK_ACCESS_DEFAULT)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get default property list")
+
+ if((lapl_id = H5P_copy_plist(lapl_default)) <0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to copy property list")
+ }
+
+ if(NULL == (lapl = H5I_object(lapl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
+ if(H5P_set(lapl, H5L_NLINKS_NAME, nlinks) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
+
+ /* User-defined callback function */
+ if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
+
+ /* Get the oloc from the ID the user callback returned */
+ switch(H5I_get_type(cb_return))
+ {
+ case H5I_GROUP:
+ if((new_oloc = H5G_oloc(H5I_object(cb_return))) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from group ID")
+ break;
+ case H5I_DATASET:
+ if((new_oloc = H5D_oloc(H5I_object(cb_return))) ==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from dataset ID")
+ break;
+ case H5I_DATATYPE:
+ if((new_oloc = H5T_oloc(H5I_object(cb_return))) ==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from datatype ID")
+ break;
+ case H5I_FILE:
+ if((temp_file = H5I_object(cb_return)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "couldn't get file from ID")
+ if((new_oloc = H5G_oloc(temp_file->shared->root_grp)) ==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get root group location from file ID")
+ break;
+ default:
+ HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL, "not a valid location or object ID")
+ }
+
+ if(H5O_loc_copy(obj_loc->oloc, new_oloc, H5_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+
+ /* The user has given us an open object, but we only want its location. However,
+ * if the object is in another file and we close it, the file will close as well and
+ * clear its information from the location we've just copied.
+ * Thus, we play with the number of open objects in the file to close the object without
+ * closing the file. -JML 5/06*/
+ obj_loc->oloc->file->nopen_objs++;
+ H5Idec_ref(cb_return);
+ HDassert(obj_loc->oloc->file->nopen_objs > 0);
+ obj_loc->oloc->file->nopen_objs--;
+
+done:
+ /* Close location given to callback.
+ * This has the side effect of calling H5F_try_close on grp_loc's file.
+ * If we have a series of external links (file1 to file2 to file3 to
+ * file4), this closes file2 and file3 when we're done traversing
+ * through them (unless they have other IDs holding them open).
+ */
+ if(cur_grp > 0)
+ {
+ if(H5I_object_verify(cur_grp, H5I_GROUP))
+ if(H5I_dec_ref(cur_grp) < 0)
+ HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
+ }
+
+ if(ret_value < 0 && cb_return >= 0)
+ {
+ if(H5I_dec_ref(cb_return) < 0)
+ HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+}
+
+/*-------------------------------------------------------------------------
* Function: H5G_traverse_slink
*
* Purpose: Traverses symbolic link. The link head appears in the group
@@ -149,7 +290,8 @@ done:
*/
static herr_t
H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
- H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id)
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id,
+ hid_t dxpl_id)
{
H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */
H5G_name_t tmp_obj_path; /* Temporary copy of object's path */
@@ -192,7 +334,7 @@ H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
udata.obj_loc = obj_loc;
/* Traverse the link */
- if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
done:
@@ -296,7 +438,7 @@ done:
*/
static herr_t
H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
- int *nlinks, H5G_traverse_t op, void *op_data, hid_t dxpl_id)
+ int *nlinks, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id)
{
H5G_loc_t loc; /* Location of start object */
H5O_loc_t grp_oloc; /* Object loc. for current group */
@@ -305,10 +447,13 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
H5O_loc_t obj_oloc; /* Object found */
H5G_name_t obj_path; /* Path for object found */
H5G_loc_t obj_loc; /* Location of object */
+ H5O_link_t *cb_lnk=NULL; /* Pointer to link info for callback */
+ H5G_loc_t *cb_loc=NULL; /* Pointer to object location for callback */
size_t nchars; /* component name length */
H5O_link_t lnk; /* Link information for object */
hbool_t link_valid = FALSE; /* Flag to indicate that the link information is valid */
hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */
+ hbool_t own_cb_loc=FALSE; /* Flag to indicate that callback took ownership of cb_loc */
hbool_t group_copy = FALSE; /* Flag to indicate that the group entry is copied */
hbool_t last_comp = FALSE; /* Flag to indicate that a component is the last component in the name */
herr_t ret_value = SUCCEED; /* Return value */
@@ -403,7 +548,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
H5O_reset(H5O_LINK_ID, &lnk);
#else /* H5_GROUP_REVISION */
/* Free information for link (but don't free link pointer) */
- if(lnk.type == H5G_LINK_SOFT)
+ if(lnk.type == H5L_LINK_SOFT)
lnk.u.soft.name = H5MM_xfree(lnk.u.soft.name);
lnk.name = H5MM_xfree(lnk.name);
#endif /* H5_GROUP_REVISION */
@@ -417,6 +562,9 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* If the lookup was OK, try traversing soft links and mount points, if allowed */
if(lookup_status >= 0) {
/* Indicate that the link info is valid */
+ HDassert(lnk.type >= H5L_LINK_HARD);
+ if(lnk.type >H5L_LINK_BUILTIN_MAX && lnk.type < H5L_LINK_UD_MIN)
+ HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "unknown link type")
link_valid = TRUE;
/* Build object's group hier. location */
@@ -437,9 +585,21 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
if(H5L_LINK_SOFT == lnk.type &&
(0 == (target & H5G_TARGET_SLINK) || !last_comp)) {
if((*nlinks)-- <= 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "too many links")
- if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_SLINK, FAIL, "symbolic link traversal failed")
+ HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links")
+ if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed")
+ } /* end if */
+
+ /*
+ * If we found an external link then we should follow it. But if this
+ * is the last component of the name and the H5G_TARGET_ELINK bit of
+ * TARGET is set then we don't follow it.
+ */
+ if( lnk.type >= H5L_LINK_UD_MIN && ((0 == (target & H5G_TARGET_UDLINK)) || !last_comp) ) {
+ if((*nlinks)-- <= 0)
+ HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links")
+ if(H5G_traverse_ud(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed")
} /* end if */
/*
@@ -449,9 +609,9 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
*
* (If this link is a hard link, try to perform mount point traversal)
*
- * (Note that the soft link traversal above can change the status of
- * the object (into a hard link), so don't use an 'else' statement
- * here. -QAK)
+ * (Note that the soft and external link traversal above can change
+ * the status of the object (into a hard link), so don't use an 'else'
+ * statement here. -QAK)
*/
if(H5F_addr_defined(obj_loc.oloc->addr) &&
(0 == (target & H5G_TARGET_MOUNT) || !last_comp)) {
@@ -462,25 +622,23 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* Check for last component in name provided */
if(last_comp) {
- H5O_link_t *tmp_lnk; /* Pointer to link info for callback */
- H5G_loc_t *tmp_loc; /* Pointer to object location for callback */
-
/* Set callback parameters appropriately, based on link being found */
if(lookup_status < 0) {
- tmp_lnk = NULL;
- tmp_loc = NULL;
+ cb_lnk = NULL;
+ cb_loc = NULL;
} /* end if */
else {
- tmp_lnk = &lnk;
- tmp_loc = &obj_loc;
+ cb_lnk = &lnk;
+ cb_loc = &obj_loc;
} /* end else */
/* Operator routine will take care of object location, succeed or fail */
obj_loc_valid = FALSE;
/* Call 'operator' routine */
- if((op)(&grp_loc, H5G_comp_g, tmp_lnk, tmp_loc, op_data) < 0)
+ if((op)(&grp_loc, H5G_comp_g, cb_lnk, cb_loc, op_data, &own_cb_loc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CALLBACK, FAIL, "traversal operator failed")
+
HGOTO_DONE(SUCCEED)
} /* end if */
@@ -533,27 +691,54 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
/* If we've fallen through to here, the name must be something like just '.'
* and we should issue the callback on that. -QAK
*/
- /* Reset "group copied" flag */
- /* (callback will take ownership of group location, succeed or fail) */
+ cb_loc = &grp_loc;
+
+ /* Reset "group copied" flag (cb_loc will be freed automatically unless the
+ * callback takes ownership of it) */
HDassert(group_copy);
group_copy = FALSE;
+
/* Call 'operator' routine */
- if((op)(&grp_loc, ".", NULL, &grp_loc, op_data) < 0)
+ if((op)(&grp_loc, ".", NULL, cb_loc, op_data, &own_cb_loc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "traversal operator failed")
+
HGOTO_DONE(SUCCEED)
done:
+ /* If the operator routine didn't take ownership of the location we
+ * passed it (or if there was an error), free it. If it's in a new
+ * file, also try to close its file. */
+ if(!own_cb_loc && cb_loc)
+ {
+ if(cb_loc->oloc->file != grp_loc.oloc->file)
+ {
+ if(H5F_try_close(cb_loc->oloc->file) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close external file opened during traversal")
+ }
+ H5G_loc_free(cb_loc);
+ }
+
/* If the object location is still valid (usually in an error situation), reset it */
if(obj_loc_valid)
+ {
+ if(ret_value < 0)
+ {
+ H5F_try_close(obj_loc.oloc->file);
+ }
H5G_loc_free(&obj_loc);
+ }
+ if(ret_value < 0 && grp_loc.oloc->file)
+ {
+ H5F_try_close(grp_loc.oloc->file);
+ }
/* If there's valid information in the link, reset it */
if(link_valid) {
#ifdef H5_GROUP_REVISION
H5O_reset(H5O_LINK_ID, &lnk);
#else /* H5_GROUP_REVISION */
/* Free information for link (but don't free link pointer) */
- if(lnk.type == H5G_LINK_SOFT)
+ if(lnk.type == H5L_LINK_SOFT)
lnk.u.soft.name = H5MM_xfree(lnk.u.soft.name);
lnk.name = H5MM_xfree(lnk.name);
#endif /* H5_GROUP_REVISION */
@@ -584,10 +769,11 @@ done:
*/
herr_t
H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op,
- void *op_data, hid_t dxpl_id)
+ void *op_data, hid_t lapl_id, hid_t dxpl_id)
{
- int nlinks = H5G_NLINKS; /* Link countdown value */
- herr_t ret_value = SUCCEED; /* Return value */
+ int nlinks; /* Link countdown value */
+ H5P_genplist_t *lapl; /* Property list with value for nlinks */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_traverse, FAIL)
@@ -598,9 +784,23 @@ H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traver
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no starting location")
if(!op)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no operation provided")
+ HDassert(lapl_id >= 0);
+
+ /* Set nlinks value from property list, if it exists */
+ if(lapl_id == H5P_DEFAULT)
+ {
+ nlinks = H5L_NLINKS_DEF;
+ }
+ else
+ {
+ if(NULL == (lapl = H5I_object(lapl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ if(H5P_get(lapl, H5L_NLINKS_NAME, &nlinks) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links")
+ }
/* Go perform "real" traversal */
- if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, dxpl_id) < 0)
+ if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "path traversal failed")
done:
diff --git a/src/H5L.c b/src/H5L.c
index 082681f..ed73380 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -14,7 +14,7 @@
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5G_PACKAGE /*suppress error about including H5Gpkg */
-#define H5L_PACKAGE /*suppress error about including H5Gpkg */
+#define H5L_PACKAGE /*suppress error about including H5Lpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5L_init_interface
@@ -37,35 +37,37 @@
/* User data for path traversal routine for getting link metadata */
typedef struct {
H5L_linkinfo_t *linfo; /* Buffer to return to user */
- hid_t dxpl_id; /* dxpl to use in callback */
+ hid_t dxpl_id; /* dxpl to use in callback */
} H5L_trav_ud1_t;
/* User data for path traversal callback to creating a link */
typedef struct {
- H5F_t *file; /* Pointer to the file */
- hid_t dxpl_id; /* Dataset transfer property list */
- H5G_name_t *path; /* Path to object being linked */
- H5O_link_t *lnk; /* Pointer to link information to insert */
+ H5F_t *file; /* Pointer to the file */
+ hid_t dxpl_id; /* Dataset transfer property list */
+ hid_t lcpl_id; /* Link creation property list */
+ H5G_name_t *path; /* Path to object being linked */
+ H5O_link_t *lnk; /* Pointer to link information to insert */
} H5L_trav_ud3_t;
/* User data for path traversal routine for moving and renaming a link */
typedef struct {
- const char *dst_name; /* Destination name for moving object */
- H5T_cset_t cset; /* Char set for new name */
- H5G_loc_t *dst_loc; /* Destination location for moving object */
- hbool_t copy; /* TRUE if this is a copy operation */
- hid_t dxpl_id; /* dxpl to use in callback */
+ const char *dst_name; /* Destination name for moving object */
+ H5T_cset_t cset; /* Char set for new name */
+ H5G_loc_t *dst_loc; /* Destination location for moving object */
+ hbool_t copy; /* TRUE if this is a copy operation */
+ hid_t lapl_id; /* lapl to use in callback */
+ hid_t dxpl_id; /* dxpl to use in callback */
} H5L_trav_ud4_t;
/* User data for path traversal routine for getting soft link value */
typedef struct {
- size_t size; /* Size of user buffer */
- char *buf; /* User buffer */
+ size_t size; /* Size of user buffer */
+ char *buf; /* User buffer */
} H5L_trav_ud5_t;
/* User data for path traversal routine for removing link (i.e. unlink) */
typedef struct {
- hid_t dxpl_id; /* Dataset transfer property list */
+ hid_t dxpl_id; /* Dataset transfer property list */
} H5L_trav_ud6_t;
/* User data for path traversal routine for retrieving link creation property list */
@@ -75,9 +77,10 @@ typedef struct {
/* User data for path traversal routine for moving and renaming an object */
typedef struct {
- H5F_t *file; /* Pointer to the file */
- H5O_link_t *lnk; /* Pointer to link information to insert */
- hid_t dxpl_id; /* Dataset transfer property list */
+ H5F_t *file; /* Pointer to the file */
+ H5O_link_t *lnk; /* Pointer to link information to insert */
+ hbool_t copy; /* TRUE if this is a copy operation */
+ hid_t dxpl_id; /* Dataset transfer property list */
} H5L_trav_ud10_t;
/* Package variables */
@@ -86,32 +89,196 @@ typedef struct {
/* Private prototypes */
static herr_t H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5L_create_real(H5G_loc_t *link_loc, const char *link_name,
- H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id,
- hid_t lcpl_id);
+ H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, hid_t lcpl_id,
+ hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name,
- H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id);
-static herr_t H5L_create_soft(const char *target_path, H5G_loc_t *loc,
- const char *name, hid_t dxpl_id, hid_t lcpl_id);
+ H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id,
+ hid_t lapl_id, hid_t dxpl_id);
+static herr_t H5L_create_soft(const char *target_path, H5G_loc_t *cur_loc,
+ const char *cur_name, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5L_linkval(H5G_loc_t *loc, const char *name, size_t size,
- char *buf/*out*/, hid_t dxpl_id);
+ char *buf/*out*/, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
-static herr_t H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
+static herr_t H5L_unlink(H5G_loc_t *loc, const char *name, hid_t lapl_id,
+ hid_t dxpl_id);
static herr_t H5L_move(H5G_loc_t *src_loc, const char *src_name,
H5G_loc_t *dst_loc, const char *dst_name, hbool_t copy_flag,
- hid_t lcpl_id, hid_t dxpl_id);
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id);
static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/,
- const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
-static herr_t H5L_get_linkinfo(H5G_loc_t *loc, const char *name,
- H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id);
+ const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name,
- const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
+static int H5L_find_class_idx(H5L_link_t id);
+
+
+/* Information about user-defined links */
+static size_t H5L_table_alloc_g = 0;
+static size_t H5L_table_used_g = 0;
+static H5L_link_class_t *H5L_table_g = NULL;
+
+
+
+#define H5L_MIN_TABLE_SIZE 32 /* Minimum size of the user-defined link type table if it is allocated */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: James Laird
+ * Thursday, July 13, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5L_init(void)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5L_init, FAIL);
+ /* FUNC_ENTER() does all the work */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lregister
+ *
+ * Purpose: Registers a class of user-defined links, or changes the
+ * behavior of an existing class.
+ *
+ * The link class passed in will override any existing link
+ * class for the specified link class ID. It must at least
+ * include a H5L_link_class_t version (which should be
+ * H5L_LINK_CLASS_T_VERS), a link class ID, and a traversal
+ * function.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lregister(const H5L_link_class_t *cls)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Lregister, FAIL)
+ H5TRACE1("e","*x",cls);
+
+ /* Check args */
+ if (cls==NULL)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class")
+
+ /* Check H5L_link_class_t version number; this is where a function to convert
+ * from an outdated version should be called.
+ */
+ if(cls->version != H5L_LINK_CLASS_T_VERS)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5L_link_class_t version number");
+
+ if (cls->id<H5L_LINK_UD_MIN || cls->id>H5L_LINK_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link identification number")
+ if (cls->trav_func==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no traversal function specified")
+
+ /* Do it */
+ if (H5L_register (cls)<0)
+ HGOTO_ERROR (H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register link type")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_find_class_idx
+ *
+ * Purpose: Given a link class ID, return the offset in the global array
+ * that holds all the registered link classes.
+ *
+ * Return: Success: Non-negative index of entry in global
+ * link class table.
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5L_find_class_idx(H5L_link_t id)
+{
+ size_t i; /* Local index variable */
+ int ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_find_class_idx)
+
+ for (i=0; i<H5L_table_used_g; i++)
+ if (H5L_table_g[i].id == id)
+ HGOTO_DONE((int)i)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5L_find_class_idx */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_find_class
+ *
+ * Purpose: Given a link class ID return a pointer to a global struct that
+ * defines the link class.
+ *
+ * Return: Success: Ptr to entry in global link class table.
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+const H5L_link_class_t *
+H5L_find_class(H5L_link_t id)
+{
+ int idx; /* Filter index in global table */
+ H5L_link_class_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5L_find_class, NULL)
+
+ /* Get the index in the global table */
+ if((idx=H5L_find_class_idx(id))<0)
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, NULL, "unable to find link class")
+
+ /* Set return value */
+ ret_value=H5L_table_g+idx;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5L_find_class */
/*-------------------------------------------------------------------------
@@ -130,6 +297,7 @@ static herr_t
H5L_init_interface(void)
{
H5P_genclass_t *crt_pclass;
+ H5P_genclass_t *acc_pclass;
size_t nprops; /* Number of properties */
unsigned intmd_group = H5L_CRT_INTERMEDIATE_GROUP_DEF;
herr_t ret_value = SUCCEED; /* Return value */
@@ -163,12 +331,57 @@ H5L_init_interface(void)
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list")
} /* end if */
+ /* ========== Link Access Property Class Initialization ============*/
+ assert(H5P_CLS_LINK_ACCESS_g!=-1);
+
+ /* Get the pointer to link access class */
+ if(NULL == (acc_pclass = H5I_object(H5P_CLS_LINK_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
+
+ /* Only register the default property list if it hasn't been created yet */
+ if(H5P_LST_LINK_ACCESS_g == (-1)) {
+ /* Register the default link access property list */
+ if((H5P_LST_LINK_ACCESS_g = H5P_create_id(acc_pclass))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default LAPL")
+ } /* end if */
+
+
+ /* Initialize user-defined link classes */
+ if(H5L_register_external() <0)
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register external link class")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
}
/*-------------------------------------------------------------------------
+ * Function: H5L_term_interface
+ *
+ * Purpose: Terminate any resources allocated in H5L_init_interface.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Tuesday, January 24, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5L_term_interface(void)
+{
+ int n=0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_term_interface)
+
+ /* Free the table of link types */
+ H5L_table_g = H5MM_xfree(H5L_table_g);
+ H5L_table_used_g = H5L_table_alloc_g = 0;
+
+ FUNC_LEAVE_NOAPI(n)
+}
+
+/*-------------------------------------------------------------------------
* Function: H5Lmove
*
* Purpose: Renames an object within an HDF5 file and moves it to a new
@@ -187,14 +400,15 @@ done:
*/
herr_t
H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
- const char *dst_name, hid_t lcpl_id)
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t src_loc, *src_loc_p;
H5G_loc_t dst_loc, *dst_loc_p;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lmove, FAIL)
- H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id);
+ H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id,
+ lapl_id);
/* Check arguments */
if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0)
@@ -220,8 +434,8 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name,
- FALSE, lcpl_id, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link")
+ FALSE, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
done:
FUNC_LEAVE_API(ret_value)
@@ -244,14 +458,15 @@ done:
*/
herr_t
H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
- const char *dst_name, hid_t lcpl_id)
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t src_loc, *src_loc_p;
H5G_loc_t dst_loc, *dst_loc_p;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lcopy, FAIL)
- H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id);
+ H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id,
+ lapl_id);
/* Check arguments */
if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0)
@@ -276,8 +491,9 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
- if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link")
+ if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id,
+ lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
done:
FUNC_LEAVE_API(ret_value)
@@ -306,14 +522,15 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id)
+H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id,
+ hid_t lapl_id)
{
H5G_loc_t new_loc;
H5G_loc_t obj_loc;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Llink, FAIL)
- H5TRACE4("e","isii",new_loc_id,new_name,obj_id,lcpl_id);
+ H5TRACE5("e","isiii",new_loc_id,new_name,obj_id,lcpl_id,lapl_id);
/* Check arguments */
if(new_loc_id == H5L_SAME_LOC)
@@ -328,8 +545,8 @@ H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id)
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
- if(H5L_link(&new_loc, new_name, &obj_loc, H5AC_dxpl_id, lcpl_id ) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link")
+ if(H5L_link(&new_loc, new_name, &obj_loc, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
FUNC_LEAVE_API(ret_value)
@@ -356,20 +573,20 @@ done:
*/
herr_t
H5Lcreate_soft(const char *target_path,
- hid_t loc_id, const char *name, hid_t lcpl_id)
+ hid_t cur_loc, const char *cur_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t new_loc, *new_loc_p;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lcreate_soft, FAIL)
- H5TRACE4("e","sisi",target_path,loc_id,name,lcpl_id);
+ H5TRACE5("e","sisii",target_path,cur_loc,cur_name,lcpl_id,lapl_id);
/* Check arguments */
- if(H5G_loc(loc_id, &new_loc) < 0)
+ if(H5G_loc(cur_loc, &new_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!target_path || !*target_path)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no target specified")
- if(!name || !*name)
+ if(!cur_name || !*cur_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified")
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
@@ -377,8 +594,9 @@ H5Lcreate_soft(const char *target_path,
new_loc_p = &new_loc;
- if(H5L_create_soft(target_path, new_loc_p, name, H5AC_dxpl_id, lcpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link")
+ if(H5L_create_soft(target_path, new_loc_p, cur_name,
+ lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
FUNC_LEAVE_API(ret_value)
@@ -403,14 +621,15 @@ done:
*/
herr_t
H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name,
- hid_t new_loc_id, const char *new_name, hid_t lcpl_id)
+ hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t cur_loc, *cur_loc_p;
H5G_loc_t new_loc, *new_loc_p;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lcreate_hard, FAIL)
- H5TRACE5("e","isisi",cur_loc_id,cur_name,new_loc_id,new_name,lcpl_id);
+ H5TRACE6("e","isisii",cur_loc_id,cur_name,new_loc_id,new_name,lcpl_id,
+ lapl_id);
/* Check arguments */
if(cur_loc_id != H5L_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0)
@@ -437,14 +656,66 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name,
else if(cur_loc_p->oloc->file != new_loc_p->oloc->file)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.")
- if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, H5AC_dxpl_id, lcpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link")
+ if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name,
+ lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lcreate_hard() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_ud
+ *
+ * Purpose: Creates a user-defined link of type LINK_TYPE named LINK_NAME
+ * with user-specified data UDATA.
+ *
+ * The format of the information pointed to by UDATA is
+ * defined by the user. UDATA_SIZE holds the size of this buffer.
+ *
+ * LINK_NAME is interpreted relative to LINK_LOC_ID.
+ *
+ * The property list specified by LCPL_ID holds properties used
+ * to create the link.
+ *
+ * The link class of the new link must already be registered
+ * with the library.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Tuesday, December 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_link_t link_type, void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id)
+{
+ H5G_loc_t link_loc;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Lcreate_ud, FAIL)
+ H5TRACE7("e","isLlxzii",link_loc_id,link_name,link_type,udata,udata_size,
+ lcpl_id,lapl_id);
+
+ /* Check arguments */
+ if(H5G_loc(link_loc_id, &link_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!link_name || !*link_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
+
+ /* Create external link */
+ if(H5L_create_ud(&link_loc, link_name, udata, udata_size, link_type,
+ H5G_TARGET_NORMAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Lcreate_ud */
+
+
/*-------------------------------------------------------------------------
* Function: H5Lunlink
*
@@ -463,13 +734,13 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Lunlink(hid_t loc_id, const char *name)
+H5Lunlink(hid_t loc_id, const char *name, hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lunlink, FAIL)
- H5TRACE2("e","is",loc_id,name);
+ H5TRACE3("e","isi",loc_id,name,lapl_id);
/* Check arguments */
if(H5G_loc(loc_id, &loc) < 0)
@@ -478,8 +749,8 @@ H5Lunlink(hid_t loc_id, const char *name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Unlink */
- if(H5L_unlink(&loc, name, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object")
+ if(H5L_unlink(&loc, name, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to unlink object")
done:
FUNC_LEAVE_API(ret_value)
@@ -506,13 +777,14 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/)
+H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/,
+ hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Lget_linkval, FAIL)
- H5TRACE4("e","iszx",loc_id,name,size,buf);
+ H5TRACE5("e","iszxi",loc_id,name,size,buf,lapl_id);
/* Check arguments */
if(H5G_loc(loc_id, &loc))
@@ -521,7 +793,7 @@ H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
/* Get the link value */
- if(H5L_linkval(&loc, name, size, buf, H5AC_ind_dxpl_id) < 0)
+ if(H5L_linkval(&loc, name, size, buf, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value")
done:
@@ -544,12 +816,13 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/)
+H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/,
+ hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(H5Lget_linkinfo, FAIL)
- H5TRACE3("e","isx",loc_id,name,linkbuf);
+ H5TRACE4("e","isxi",loc_id,name,linkbuf,lapl_id);
/* Check arguments */
if(H5G_loc(loc_id, &loc))
@@ -558,7 +831,7 @@ H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
/* Get the creation time */
- if(H5L_get_linkinfo(&loc, name, linkbuf, H5AC_ind_dxpl_id) < 0)
+ if(H5L_get_linkinfo(&loc, name, linkbuf, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info")
done:
@@ -566,6 +839,79 @@ done:
}
+/*-------------------------------------------------------------------------
+ * Function: H5Lunregister
+ *
+ * Purpose: Unregisters a class of user-defined links, preventing them
+ * from being traversed, queried, moved, etc.
+ *
+ * A link class can be re-registered using H5Lregister().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lunregister(H5L_link_t id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Lunregister, FAIL)
+ H5TRACE1("e","Ll",id);
+
+ /* Check args */
+ if (id<0 || id>H5L_LINK_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type")
+
+ /* Do it */
+ if (H5L_unregister (id)<0)
+ HGOTO_ERROR (H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to unregister link type")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lunregister() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lis_registered
+ *
+ * Purpose: Tests whether a user-defined link class has been registered
+ * or not.
+ *
+ * Return: Positive if the link class has been registered
+ * Zero if it is unregistered
+ * Negative on error (if the class is not a valid UD class ID)
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t H5Lis_registered(H5L_link_t id)
+{
+ size_t i; /* Local index variable */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_API(H5Lis_registered, FAIL)
+
+ /* Check args */
+ if(id<0 || id>H5L_LINK_MAX)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type id number")
+
+ /* Is the link class already registered? */
+ for(i=0; i<H5L_table_used_g; i++)
+ if(H5L_table_g[i].id==id) {
+ ret_value=TRUE;
+ break;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+/* end H5Lis_registered */
/*
*-------------------------------------------------------------------------
@@ -576,6 +922,107 @@ done:
*/
/*-------------------------------------------------------------------------
+ * Function: H5L_register
+ *
+ * Purpose: Registers a class of user-defined links, or changes the
+ * behavior of an existing class.
+ *
+ * See H5Lregister for full documentation.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5L_register (const H5L_link_class_t *cls)
+{
+ size_t i;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5L_register, FAIL)
+
+ assert (cls);
+ assert (cls->id>=0 && cls->id<=H5L_LINK_MAX);
+
+ /* Is the link type already registered? */
+ for (i=0; i<H5L_table_used_g; i++)
+ if (H5L_table_g[i].id==cls->id)
+ break;
+
+ /* Filter not already registered */
+ if (i>=H5L_table_used_g) {
+ if (H5L_table_used_g>=H5L_table_alloc_g) {
+ size_t n = MAX(H5L_MIN_TABLE_SIZE, 2*H5L_table_alloc_g);
+ H5L_link_class_t *table = H5MM_realloc(H5L_table_g,
+ n*sizeof(H5L_link_class_t));
+ if (!table)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend link type table")
+ H5L_table_g = table;
+ H5L_table_alloc_g = n;
+ } /* end if */
+
+ /* Initialize */
+ i = H5L_table_used_g++;
+ HDmemcpy(H5L_table_g+i, cls, sizeof(H5L_link_class_t));
+ } /* end if */
+ /* Filter already registered */
+ else {
+ /* Replace old contents */
+ HDmemcpy(H5L_table_g+i, cls, sizeof(H5L_link_class_t));
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5L_register */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_unregister
+ *
+ * Purpose: Unregisters a class of user-defined links.
+ *
+ * See H5Lunregister for full documentation.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5L_unregister (H5L_link_t id)
+{
+ size_t i; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5L_unregister,FAIL)
+
+ assert (id>=0 && id<=H5L_LINK_MAX);
+
+ /* Is the filter already registered? */
+ for (i=0; i<H5L_table_used_g; i++)
+ if (H5L_table_g[i].id==id)
+ break;
+
+ /* Fail if filter not found */
+ if (i>=H5L_table_used_g)
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered")
+
+ /* Remove filter from table */
+ /* Don't worry about shrinking table size (for now) */
+ HDmemmove(&H5L_table_g[i],&H5L_table_g[i+1],sizeof(H5L_link_class_t)*((H5L_table_used_g-1)-i));
+ H5L_table_used_g--;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5L_unregister() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5L_link
*
* Purpose: Creates a link from OBJ_ID to CUR_NAME. See H5Llink() for
@@ -590,7 +1037,7 @@ done:
*/
herr_t
H5L_link(H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc,
- hid_t dxpl_id, hid_t lcpl_id)
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id)
{
H5F_t *file = NULL; /* File link will be in */
H5O_link_t lnk; /* Link to insert */
@@ -614,8 +1061,8 @@ H5L_link(H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc,
lnk.u.hard.addr = obj_loc->oloc->addr;
/* Create the link */
- if( H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, dxpl_id, lcpl_id) <0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object")
+ if( H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, lcpl_id, lapl_id, dxpl_id) <0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -636,9 +1083,13 @@ done:
*/
static herr_t
H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5L_trav_ud3_t *udata = (H5L_trav_ud3_t *)_udata; /* User data passed in */
+ H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */
+ hid_t grp_id = FAIL; /* Id for this group (passed to user callback */
+ H5G_loc_t temp_loc; /* For UD callback */
+ hbool_t temp_loc_init = FALSE;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_link_cb)
@@ -652,7 +1103,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
if(udata->lnk->type == H5L_LINK_HARD) {
/* Check that both objects are in same file */
if(grp_loc->oloc->file->shared != udata->file->shared)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed")
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "interfile hard links are not allowed")
} /* end if */
/* Set the link's name correctly */
@@ -661,7 +1112,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
/* Insert link into group */
if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object")
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link for object")
/* Set object's path if it has been passed in and is not set */
if(udata->path != NULL && udata->path->user_path_r == NULL)
@@ -670,15 +1121,59 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name")
}
+ /* If link is a user-defined link, trigger its creation callback if it has one*/
+ if(udata->lnk->type >= H5L_LINK_UD_MIN)
+ {
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ H5O_loc_t temp_oloc;
+ H5G_name_t temp_path;
+
+ /* Get the link class for this type of link. */
+ if(NULL == (link_class = H5L_find_class(udata->lnk->type)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get class of UD link")
+
+ if(link_class->create_func != NULL)
+ {
+ /* Create a temporary location (or else H5G_open will do a shallow
+ * copy and wipe out grp_loc)
+ */
+ H5G_name_reset(&temp_path);
+ if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+
+ temp_loc.oloc = &temp_oloc;
+ temp_loc.path = &temp_path;
+ temp_loc_init = TRUE;
+
+ /* Set up location for user-defined callback */
+ if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register ID for group")
+
+ if((link_class->create_func)(name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size, H5P_DEFAULT) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link creation callback failed")
+ }
+ }
+
done:
- if(ret_value < 0) {
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
- } /* end if */
+ /* Close the location given to the user callback if it was created */
+ if(grp_id >= 0)
+ {
+ if(H5I_dec_ref(grp_id) <0)
+ HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ }
+ else if(grp != NULL)
+ {
+ if(H5G_close(grp) <0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback")
+ }
+ else if(temp_loc_init)
+ H5G_loc_free(&temp_loc);
+
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_link_cb() */
@@ -706,7 +1201,7 @@ done:
*/
static herr_t
H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path,
- H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id, hid_t lcpl_id)
+ H5F_t *obj_file, H5O_link_t *lnk, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id)
{
char *norm_link_name = NULL; /* Pointer to normalized link name */
unsigned target_flags = H5G_TARGET_NORMAL; /* Flags to pass to group traversal function */
@@ -718,9 +1213,10 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path
FUNC_ENTER_NOAPI_NOINIT(H5L_create_real)
/* Check args */
+ HDassert(lnk);
HDassert(link_loc);
HDassert(link_name && *link_name);
- HDassert(lnk);
+ HDassert(lnk->type >= H5L_LINK_HARD && lnk->type <= H5L_LINK_MAX);
/* Get normalized link name */
if((norm_link_name = H5G_normalize(link_name)) == NULL)
@@ -746,6 +1242,9 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding")
} /* end if */
+ /* Pass the lcpl to the link creation callback */
+ udata.lcpl_id = lcpl_id;
+
/* Fill in common data for the link struct */
lnk->cset = char_encoding;
#ifdef H5_HAVE_GETTIMEOFDAY
@@ -776,7 +1275,7 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path
udata.path = obj_path;
/* Traverse the destination path & create new link */
- if(H5G_traverse(link_loc, link_name, target_flags, H5L_link_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(link_loc, link_name, target_flags, H5L_link_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link")
done:
@@ -802,7 +1301,8 @@ done:
*/
static herr_t
H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name,
- H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id)
+ H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id, hid_t lapl_id,
+ hid_t dxpl_id)
{
char *norm_cur_name = NULL; /* Pointer to normalized current name */
H5F_t *link_file = NULL; /* Pointer to file to link to */
@@ -826,7 +1326,7 @@ H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name,
lnk.type = H5L_LINK_HARD;
/* Get object location for object pointed to */
- if(H5G_obj_find(cur_loc, norm_cur_name, H5G_TARGET_NORMAL, NULL, &obj_oloc, dxpl_id) < 0)
+ if(H5G_obj_find(cur_loc, norm_cur_name, H5G_TARGET_NORMAL, NULL, &obj_oloc, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found")
/* Construct link information for eventual insertion */
@@ -837,8 +1337,9 @@ H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name,
/* Create actual link to the object. Pass in NULL for the path, since this
* function shouldn't change an object's user path. */
- if(H5L_create_real(link_loc, link_name, NULL, link_file, &lnk, dxpl_id, lcpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object")
+ if(H5L_create_real(link_loc, link_name, NULL, link_file, &lnk, lcpl_id,
+ lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
/* Free the normalized path name */
@@ -863,7 +1364,7 @@ done:
*/
static herr_t
H5L_create_soft( const char *target_path, H5G_loc_t *link_loc,
- const char *link_name, hid_t dxpl_id, hid_t lcpl_id)
+ const char *link_name, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id)
{
char *norm_target = NULL; /* Pointer to normalized current name */
H5O_link_t lnk; /* Link to insert */
@@ -885,8 +1386,9 @@ H5L_create_soft( const char *target_path, H5G_loc_t *link_loc,
lnk.u.soft.name = norm_target;
/* Create actual link to the object */
- if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, dxpl_id, lcpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object")
+ if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, lcpl_id,
+ lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
/* Free the normalized target name */
@@ -898,9 +1400,65 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5L_create_ud
+ *
+ * Purpose: Creates a user-defined link. See H5Lcreate_ud for
+ * full documentation.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Friday, May 19, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5L_create_ud(H5G_loc_t *link_loc, const char *link_name, void * ud_data,
+ size_t ud_data_size, H5L_link_t type, unsigned traverse_flags,
+ hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id)
+{
+ H5O_link_t lnk; /* Link to insert */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5L_create_ud)
+
+ /* Check args */
+ HDassert(type >= H5L_LINK_UD_MIN && type <= H5L_LINK_MAX);
+ HDassert(link_loc);
+ HDassert(link_name && *link_name);
+ HDassert(ud_data_size >= 0);
+ HDassert(ud_data_size == 0 || ud_data);
+
+ /* Make sure that this link class is registered */
+ if(H5L_find_class_idx(type) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "link class has not been registered with library")
+
+ /* Fill in UD link-specific information in the link struct*/
+ if(ud_data_size > 0)
+ {
+ lnk.u.ud.udata = H5MM_malloc((size_t) ud_data_size);
+ HDmemcpy(lnk.u.ud.udata, ud_data, (size_t) ud_data_size);
+ }
+ else
+ lnk.u.ud.udata = NULL;
+
+ lnk.u.ud.size = ud_data_size;
+ lnk.type = type;
+
+ /* Create actual link to the object */
+ if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, lcpl_id,
+ lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to register new name for object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5L_create_ud() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5L_linkval_cb
*
- * Purpose: Callback for retrieving soft link value for an object.
+ * Purpose: Callback for retrieving link value or udata.
*
* Return: Non-negative on success/Negative on failure
*
@@ -911,10 +1469,11 @@ done:
*/
static herr_t
H5L_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5L_trav_ud5_t *udata = (H5L_trav_ud5_t *)_udata; /* User data passed in */
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_linkval_cb)
@@ -922,23 +1481,35 @@ H5L_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H
if(lnk == NULL)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
- if(H5L_LINK_SOFT != lnk->type)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link")
-
- /* Copy to output buffer */
- if(udata->size > 0 && udata->buf) {
- HDstrncpy(udata->buf, lnk->u.soft.name, udata->size);
- if(HDstrlen(lnk->u.soft.name) >= udata->size)
- udata->buf[udata->size - 1] = '\0';
- } /* end if */
+ if(H5L_LINK_SOFT == lnk->type)
+ {
+ /* Copy to output buffer */
+ if(udata->size > 0 && udata->buf) {
+ HDstrncpy(udata->buf, lnk->u.soft.name, udata->size);
+ if(HDstrlen(lnk->u.soft.name) >= udata->size)
+ udata->buf[udata->size - 1] = '\0';
+ } /* end if */
+ }
+ else if(lnk->type >= H5L_LINK_UD_MIN)
+ {
+ /* Get the link class for this type of link. It's okay if the class isn't registered, though--we
+ * just can't give any more information about it */
+ link_class = H5L_find_class(lnk->type);
+
+ if(link_class != NULL && link_class->query_func != NULL) {
+ if((link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, udata->buf, udata->size) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query callback returned failure")
+ }
+ else if(udata->buf && udata->size > 0)
+ udata->buf[0] = '\0';
+ }
+ else
+ HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "object is not a symbolic or user-defined link")
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_linkval_cb() */
@@ -947,7 +1518,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5L_linkval
*
- * Purpose: Returns the value of a symbolic link.
+ * Purpose: Returns the value of a symbolic link or the udata for a
+ * user-defined link.
*
* Return: Success: Non-negative, with at most SIZE bytes of the
* link value copied into the BUF buffer. If the
@@ -963,7 +1535,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id)
+H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t lapl_id, hid_t dxpl_id)
{
H5L_trav_ud5_t udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
@@ -975,8 +1547,8 @@ H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid
udata.buf = buf;
/* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_linkval_cb, &udata, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
+ if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L_linkval_cb, &udata, lapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -998,10 +1570,14 @@ done:
*/
static herr_t
H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
+ H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */
+ hid_t grp_id = FAIL; /* Id for this group (passed to user callback */
H5L_trav_ud6_t *udata = (H5L_trav_ud6_t *)_udata; /* User data passed in */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5G_loc_t temp_loc; /* For UD callback */
+ hbool_t temp_loc_init = FALSE;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5L_unlink_cb)
@@ -1011,19 +1587,57 @@ H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSE
/* Check for removing '.' */
if(lnk == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't delete self")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "can't delete self")
+
+ /* If there is a user-defined callback, call it before deleting the link */
+ if(lnk->type >= H5L_LINK_UD_MIN)
+ {
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ H5O_loc_t temp_oloc;
+ H5G_name_t temp_path;
+
+ /* Get the link class for this type of link. */
+ if(NULL == (link_class = H5L_find_class(lnk->type)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class not registered")
+
+ if(link_class->del_func != NULL)
+ {
+ H5G_name_reset(&temp_path);
+
+ if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+
+ temp_loc.oloc = &temp_oloc;
+ temp_loc.path = &temp_path;
+ temp_loc_init = TRUE;
+
+ /* Set up location for user-defined callback */
+ if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+ if((link_class->del_func)(name, grp_id, lnk->u.ud.udata, lnk->u.ud.size) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link deletion callback returned failure")
+ }
+ }
/* Remove the link from the group */
if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from group")
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Close the location given to the user callback if it was created */
+ if(grp_id >= 0)
+ H5I_dec_ref(grp_id);
+ else if(grp != NULL)
+ H5G_close(grp);
+ else if(temp_loc_init)
+ H5G_loc_free(&temp_loc);
+
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_unlink_cb() */
@@ -1042,7 +1656,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
+H5L_unlink(H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id)
{
H5L_trav_ud6_t udata; /* User data for callback */
char *norm_name = NULL; /* Pointer to normalized name */
@@ -1061,7 +1675,7 @@ H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
/* Set up user data for unlink operation */
udata.dxpl_id = dxpl_id;
- if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_unlink_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_unlink_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
done:
@@ -1089,10 +1703,14 @@ done:
*/
static herr_t
H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5L_trav_ud10_t *udata = (H5L_trav_ud10_t *)_udata; /* User data passed in */
H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */
+ H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */
+ hid_t grp_id = FAIL; /* Id for this group (passed to user callback */
+ H5G_loc_t temp_loc; /* For UD callback */
+ hbool_t temp_loc_init = FALSE;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_move_dest_cb)
@@ -1105,25 +1723,78 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *l
if(udata->lnk->type == H5L_LINK_HARD) {
/* Check that both objects are in same file */
if(grp_loc->oloc->file->shared != udata->file->shared)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "moving a link across files is not allowed")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "moving a link across files is not allowed")
} /* end if */
/* Give the object its new name */
/* Casting away const okay -JML */
udata->lnk->name = H5MM_xfree(udata->lnk->name);
- udata->lnk->name=name;
+ udata->lnk->name= (char *)name;
/* Insert the link into the group */
if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object")
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
+ /* If the link was a user-defined link, call its move callback if it has one */
+ if(udata->lnk->type >= H5L_LINK_UD_MIN)
+ {
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ H5O_loc_t temp_oloc;
+ H5G_name_t temp_path;
+
+ /* Get the link class for this type of link. */
+ if(NULL == (link_class = H5L_find_class(udata->lnk->type)))
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered")
+
+ if((!udata->copy && link_class->move_func != NULL) || (udata->copy && link_class->move_func))
+ {
+ /* Create a temporary location (or else H5G_open will do a shallow
+ * copy and wipe out grp_loc)
+ */
+ H5G_name_reset(&temp_path);
+ if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+
+ temp_loc.oloc = &temp_oloc;
+ temp_loc.path = &temp_path;
+ temp_loc_init = TRUE;
+
+ /* Set up location for user-defined callback */
+ if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group ID")
+
+ if(udata->copy)
+ {
+ if((link_class->copy_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD copy callback returned error")
+ }
+ else
+ {
+ if((link_class->move_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD move callback returned error")
+ }
+ }
+ }
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Close the location given to the user callback if it was created */
+ if(grp_id >= 0)
+ {
+ if(H5I_dec_ref(grp_id) <0)
+ HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ }
+ else if(grp != NULL)
+ {
+ if(H5G_close(grp) <0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback")
+ }
+ else if(temp_loc_init)
+ H5G_loc_free(&temp_loc);
+
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
if(dst_name_r)
H5RS_decr(dst_name_r);
@@ -1147,7 +1818,7 @@ done:
*/
static herr_t
H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5L_trav_ud4_t *udata = (H5L_trav_ud4_t *)_udata; /* User data passed in */
H5L_trav_ud10_t udata_out; /* User data for H5L_move_dest_cb traversal */
@@ -1178,21 +1849,24 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
break;
default:
- HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ if(lnk->type < H5L_LINK_UD_MIN)
+ HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unrecognized link type")
+ type = H5G_UDLINK;
} /* end switch */
/* Set up user data for move_dest_cb */
if((udata_out.lnk = H5O_link_copy(lnk, NULL, 0)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy link to be moved");
+ HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link to be moved");
udata_out.lnk->cset = udata->cset;
udata_out.file = grp_loc->oloc->file;
+ udata_out.copy = udata->copy;
udata_out.dxpl_id = udata->dxpl_id;
/* Remember the link's original name (in case it's changed by H5G_name_replace) */
orig_name = H5MM_xstrdup(name);
/* Insert the link into its new location */
- if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->dxpl_id) < 0)
+ if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
/* If this is a move and not a copy operation, change the object's name and remove the old link */
@@ -1214,12 +1888,9 @@ done:
if(orig_name)
H5MM_xfree(orig_name);
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_move_cb() */
@@ -1247,12 +1918,15 @@ done:
*/
static herr_t
H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
- const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t dxpl_id)
+ const char *dst_name, hbool_t copy_flag, hid_t lcpl_id,
+ hid_t lapl_id, hid_t dxpl_id)
{
- unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK; /* Flags to pass to group traversal function */
+ unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK|H5G_TARGET_UDLINK;
H5T_cset_t char_encoding = H5F_CRT_DEFAULT_CSET; /* Character encoding for link */
H5P_genplist_t* lc_plist; /* Link creation property list */
+ H5P_genplist_t* la_plist; /* Link access property list */
H5L_trav_ud4_t udata; /* User data for traversal */
+ hid_t lapl_copy; /* Copy of lapl for this function */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_move)
@@ -1284,15 +1958,29 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding")
} /* end if */
+ /* Copy the link access property list because traversing UD links will
+ * decrease the NLINKS property. HDF5 should have NLINKS traversals to
+ * get to the source and NLINKS more to get to the destination. */
+ if(lapl_id == H5P_DEFAULT) {
+ lapl_copy = lapl_id;
+ }
+ else {
+ if (NULL==(la_plist=H5I_object(lapl_id)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid access PL")
+ if((lapl_copy=H5P_copy_plist(la_plist)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy access properties")
+ }
+
/* Set up user data */
udata.dst_loc = dst_loc;
udata.dst_name= dst_name;
udata.cset = char_encoding;
udata.copy = copy_flag;
+ udata.lapl_id = lapl_copy;
udata.dxpl_id = dxpl_id;
/* Do the move */
- if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT|H5G_TARGET_SLINK, H5L_move_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(src_loc, src_name, target_flags, H5L_move_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link")
done:
@@ -1301,110 +1989,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5L_get_lcpl_cb
- *
- * Purpose: Callback for getting a link's creation property list. This
- * routine gets properties from the link and sets them on the
- * copy of the default property list passed in.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: James Laird
- * Friday, January 27, 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5L_get_lcpl_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/)
-{
- H5L_trav_ud8_t *udata = (H5L_trav_ud8_t *)_udata; /* User data passed in */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5L_get_lcpl_cb)
-
- /* Check if the name in this group resolved to a valid link */
- if(lnk == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
-
- /* Set appropriate character encoding */
- if(H5P_set(udata->lcpl, H5P_CHAR_ENCODING_NAME, &(lnk->cset)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set property value for character encoding")
-
-done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5L_get_lcpl_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5L_get_create_plist
- *
- * Purpose: Returns a copy of the link's creation property list given
- * given a link's location and name.
- *
- * Return: Success: ID of the property list
- *
- * Failure: Negative
- *
- * Programmer: James Laird
- * Friday, January 27, 2006
- *
- *-------------------------------------------------------------------------
- */
-hid_t H5L_get_create_plist(H5G_loc_t *loc, const char* name)
-{
- H5P_genplist_t *plist; /* Default property list */
- H5P_genplist_t *plist_copy; /* Copy of list to be modified */
- hid_t lcpl_id=-1;
- H5L_trav_ud8_t udata; /* User data for traversal */
- char *norm_name = NULL; /* Pointer to normalized name */
- hid_t ret_value;
-
- FUNC_ENTER_NOAPI(H5L_get_create_plist, FAIL)
-
- /* Check arguments */
- HDassert(loc);
- HDassert(name && *name);
-
- /* Get normalized copy of the name */
- if((norm_name = H5G_normalize(name)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name")
-
- /* Get copy of default lcpl */
- if (NULL==(plist=H5I_object(H5P_LST_LINK_CREATE_g)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default LCPL")
- if((lcpl_id=H5P_copy_plist(plist)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties")
- if (NULL==(plist_copy=H5I_object(lcpl_id)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get copy of LCPL")
-
- /* Set up user data */
- udata.lcpl = plist_copy;
-
- if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_get_lcpl_cb, &udata, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
-
- ret_value = lcpl_id;
-
-done:
- /* Free the normalized path name */
- if(norm_name)
- H5MM_xfree(norm_name);
- /* If we've created a new lcpl, close it */
- if(ret_value <0 && lcpl_id >= 0)
- H5P_close(H5I_object(lcpl_id));
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5L_get_create_plist */
-
-
-/*-------------------------------------------------------------------------
* Function: H5L_get_linfo_cb
*
* Purpose: Callback for retrieving a link's metadata
@@ -1418,10 +2002,12 @@ done:
*/
static herr_t
H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5L_trav_ud1_t *udata = (H5L_trav_ud1_t *)_udata; /* User data passed in */
H5L_linkinfo_t *linfo = udata->linfo;
+ const H5L_link_class_t *link_class; /* User-defined link class */
+ ssize_t cb_ret; /* Return value from UD callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_get_linfo_cb)
@@ -1431,31 +2017,49 @@ H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
/* Get information from the link */
- linfo->cset = lnk->cset;
- linfo->ctime = lnk->ctime;
- linfo->linkclass = lnk->type;
-
- switch(lnk->type)
+ if(linfo)
{
- case H5L_LINK_HARD:
- linfo->u.objno = lnk->u.hard.addr;
- break;
-
- case H5L_LINK_SOFT:
- linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/
- break;
-
- default:
- HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "unknown link type");
- }
+ linfo->cset = lnk->cset;
+ linfo->ctime = lnk->ctime;
+ linfo->linkclass = lnk->type;
+
+ switch(lnk->type)
+ {
+ case H5L_LINK_HARD:
+ linfo->u.address = lnk->u.hard.addr;
+ break;
+
+ case H5L_LINK_SOFT:
+ linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/
+ break;
+
+ default:
+ if(lnk->type < H5L_LINK_UD_MIN || lnk->type > H5L_LINK_MAX)
+ HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unknown link class")
+
+ /* User-defined link; call its query function to get the link udata size. */
+ /* Get the link class for this type of link. It's okay if the class
+ * isn't registered, though--we just can't give any more information
+ * about it
+ */
+ link_class = H5L_find_class(lnk->type);
+
+ if(link_class != NULL && link_class->query_func != NULL) {
+ if((cb_ret = (link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, NULL, 0)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure")
+
+ linfo->u.link_size = cb_ret;
+ }
+ else {
+ linfo->u.link_size = 0;
+ }
+ } /* end switch */
+ } /* end if */
done:
- /* Release the group location for the object */
- /* (Group traversal callbacks are responsible for either taking ownership
- * of the group location for the object, or freeing it. - QAK)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_get_linfo_cb() */
@@ -1473,8 +2077,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5L_get_linkinfo(H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id)
+herr_t
+H5L_get_linkinfo(const H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id)
{
H5L_trav_ud1_t udata;
herr_t ret_value = SUCCEED; /* Return value */
@@ -1485,7 +2089,7 @@ H5L_get_linkinfo(H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*
udata.dxpl_id = dxpl_id;
/* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_get_linfo_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_linfo_cb, &udata, lapl_id, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
done:
@@ -1494,7 +2098,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5L get_default_lcpl
+ * Function: H5L_get_default_lcpl
*
* Purpose: Accessor for the default Link Creation Property List
*
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
new file mode 100644
index 0000000..5609658
--- /dev/null
+++ b/src/H5Lexternal.c
@@ -0,0 +1,314 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5L_PACKAGE /*suppress error about including H5Lpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5L_init_extern_interface
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Lpkg.h" /* Links */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Opublic.h" /* File objects */
+#include "H5Ppublic.h" /* Property lists */
+#include "H5Gpkg.h" /* Groups */
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_extern_traverse
+ *
+ * Purpose: Default traversal function for external links. This can
+ * be overridden using H5Lregister().
+ *
+ * Given a filename and path packed into the link udata,
+ * attempts to open an object within an external file.
+ * If the H5L_ELINK_PREFIX_PROP property is set in the
+ * link access property list, appends that prefix to the
+ * filename being opened.
+ *
+ * Return: ID of the opened object on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t H5L_extern_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ hid_t fid;
+ char *file_name;
+ char *obj_name;
+ size_t fname_len;
+ htri_t result;
+ hbool_t fname_alloc = FALSE;
+ hid_t ret_value = -1;
+
+ file_name = (char *) udata;
+ fname_len = strlen(file_name);
+ obj_name = ((char *) udata) + fname_len + 1;
+
+ /* See if the external link prefix property is set */
+ if((result = H5Pexist(lapl_id, H5L_ELINK_PREFIX_PROP)) < 0)
+ goto error;
+
+ /* If so, prepend it to the filename */
+ if(result > 0)
+ {
+ size_t buf_size;
+
+ if(H5Pget_size(lapl_id, H5L_ELINK_PREFIX_PROP, &buf_size) < 0)
+ goto error;
+
+ /* Allocate a buffer to hold the filename plus prefix */
+ file_name = malloc(buf_size + fname_len + 1);
+ fname_alloc = TRUE;
+
+ if(H5Pget(lapl_id, H5L_ELINK_PREFIX_PROP, file_name) < 0)
+ goto error;
+
+ /* Add the external link's filename to the prefix supplied */
+ strcat(file_name, udata);
+ }
+
+ if((fid = H5Fopen(file_name, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
+ goto error;
+ ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */
+ if(H5Fclose(fid) < 0)
+ goto error;
+
+ /* Free file_name if it's been allocated */
+ if(fname_alloc)
+ free(file_name);
+
+ return ret_value;
+
+error:
+ /* Free file_name if it's been allocated */
+ if(fname_alloc)
+ free(file_name);
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_extern_query
+ *
+ * Purpose: Default query function for external links. This can
+ * be overridden using H5Lregister().
+ *
+ * Returns the size of the link's user data. If a buffer of
+ * is provided, copies at most buf_size bytes of the udata
+ * into it.
+ *
+ * Return: Size of buffer on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 10, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static ssize_t H5L_extern_query(const char * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size)
+{
+ size_t ret_value;
+
+ /* If the buffer is NULL, skip writng anything in it and just return
+ * the size needed */
+ if(buf)
+ {
+ if(udata_size < buf_size)
+ buf_size = udata_size;
+
+ /* Copy the udata verbatim up to udata_size*/
+ memcpy(buf, udata, udata_size);
+ }
+
+ ret_value = udata_size;
+ return ret_value;
+}
+
+/* Default External Link link class */
+const H5L_link_class_t H5L_EXTERN_LINK_CLASS[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ H5L_LINK_EXTERNAL, /* Link type id number */
+ "external_link", /* Link name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move callback */
+ NULL, /* Copy callback */
+ H5L_extern_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ H5L_extern_query /* Query callback */
+}};
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5L_init_extern_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5L_init_extern_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5T_init_iterface currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5L_init_extern_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_init_extern_interface)
+
+ FUNC_LEAVE_NOAPI(H5L_init())
+} /* H5L_init_extern_interface() */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_external
+ *
+ * Purpose: Creates an external link from LINK_NAME to OBJ_NAME.
+ *
+ * External links are links to objects in other HDF5 files. They
+ * are allowed to "dangle" like soft links internal to a file.
+ * FILE_NAME is the name of the file that OBJ_NAME is is contained
+ * within. If OBJ_NAME is given as a relative path name, the
+ * path will be relative to the root group of FILE_NAME.
+ * LINK_NAME is interpreted relative to LINK_LOC_ID, which is
+ * either a file ID or a group ID.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 18, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_external(const char *file_name, const char *obj_name,
+ hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id)
+{
+ H5G_loc_t link_loc;
+ char *temp_name = NULL;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Lcreate_external, FAIL)
+ H5TRACE6("e","ssisii",file_name,obj_name,link_loc_id,link_name,lcpl_id,
+ lapl_id);
+
+ /* Check arguments */
+ if(!file_name || !*file_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified")
+ if(!obj_name || !*obj_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified")
+ if(H5G_loc(link_loc_id, &link_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!link_name || !*link_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
+
+ /* Combine the filename and link name into a single buffer to give to the UD link */
+ buf_size = HDstrlen(file_name) + HDstrlen(obj_name) + 2;
+ if(NULL == (temp_name = H5MM_malloc(buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer")
+ HDstrcpy(temp_name, file_name);
+ HDstrcpy(temp_name + (HDstrlen(file_name) + 1), obj_name);
+
+ /* Create an external link */
+ if(H5L_create_ud(&link_loc, link_name, temp_name, buf_size, H5L_LINK_EXTERNAL, H5G_TARGET_NORMAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
+
+done:
+ if(temp_name != NULL)
+ H5MM_free(temp_name);
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Lcreate_external() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5L_register_external
+ *
+ * Purpose: Registers default "External Link" link class.
+ * Use during library initialization or to restore the default
+ * after users change it.
+ *
+ * Return: Non-negative on success/ negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5L_register_external()
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5L_register_external, FAIL)
+
+ if(H5L_register(H5L_EXTERN_LINK_CLASS) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register external link class")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lunpack_elink_path
+ *
+ * Purpose: Given a buffer holding the "link value" from an external link,
+ * gets pointers to the filename and object path within the
+ * link value buffer.
+ *
+ * External link linkvalues are two NULL-terminated strings
+ * one after the other.
+ *
+ * FILENAME and OBJ_PATH will be set to pointers within
+ * ext_linkval unless they are NULL.
+ *
+ * Using this function on strings that aren't external link
+ * udata buffers can result in segmentation faults.
+ *
+ * Return: Non-negative on success/ Negative on failure
+ *
+ * Programmer: James Laird
+ * Monday, July 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lunpack_elink_val(char *ext_linkval, char **filename, char **obj_path)
+{
+ size_t len; /* Length of the filename in the linkval*/
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Lunpack_elink_val, FAIL)
+ H5TRACE3("e","s*s*s",ext_linkval,filename,obj_path);
+
+ if(ext_linkval == NULL )
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an external link linkval buffer")
+
+ if(filename != NULL)
+ *filename = ext_linkval;
+
+ if(obj_path != NULL)
+ {
+ len = HDstrlen(ext_linkval);
+ *obj_path = ext_linkval + len + 1; /* Add one for NULL terminator */
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h
index 04a74f4..8a02791 100644
--- a/src/H5Lpkg.h
+++ b/src/H5Lpkg.h
@@ -30,6 +30,13 @@
/* Get package's private header */
#include "H5Lprivate.h"
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+
+H5_DLL herr_t H5L_create_ud(H5G_loc_t *link_loc, const char *link_name,
+ void * ud_data, size_t ud_data_size, H5L_link_t type,
+ unsigned traverse_flags, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id);
#endif /* _H5Lpkg_H */
diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h
index 78743da..d5cc7d8 100644
--- a/src/H5Lprivate.h
+++ b/src/H5Lprivate.h
@@ -31,13 +31,27 @@
#define H5L_CRT_INTERMEDIATE_GROUP_SIZE sizeof(unsigned)
#define H5L_CRT_INTERMEDIATE_GROUP_DEF 0
+/* Definitions for accessing links */
+#define H5L_NLINKS_NAME "max soft links"
+#define H5L_NLINKS_SIZE sizeof(size_t)
+#define H5L_NLINKS_DEF 16 /*max symlinks to follow per lookup */
/* Functions that understand link messages */
/* forward reference for later use */
struct H5HL_t; /* defined in H5HLprivate.h */
H5_DLL herr_t H5L_link(H5G_loc_t *new_loc, const char *new_name,
- H5G_loc_t *obj_loc, hid_t dxpl, hid_t lcpl_id);
+ H5G_loc_t *obj_loc, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id);
H5_DLL hid_t H5L_get_default_lcpl(void);
+H5_DLL herr_t H5L_get_linkinfo(const H5G_loc_t *loc, const char *name,
+ H5L_linkinfo_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id);
+H5_DLL herr_t H5L_init(void);
+H5_DLL herr_t H5L_register_external(void);
+
+/* User-defined link functions */
+H5_DLL herr_t H5L_register (const H5L_link_class_t *cls);
+H5_DLL herr_t H5L_unregister (H5L_link_t id);
+H5_DLL const H5L_link_class_t *H5L_find_class(H5L_link_t id);
+
#endif /* _H5Lprivate_H */
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index a922908..29dc840 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -34,42 +34,110 @@
extern "C" {
#endif
-/* Types of links */
-typedef enum H5L_link_t {
- H5L_LINK_ERROR = -1,
- H5L_LINK_HARD = 0,
- H5L_LINK_SOFT = 1
-} H5L_link_t;
+/* Link classes.
+ * Values less than 64 are reserved for the HDF5 library's internal use.
+ * Values 64 to 255 are for "user-defined" link types; these types are
+ * defined by HDF5 but their behavior can be overridden by users.
+ * Users who want to create new classes of links should contact the HDF5
+ * development team at hdfhelp@ncsa.uiuc.edu .
+ * These values can never change because they appear in HDF5 files.
+ */
+typedef int H5L_link_t;
+#define H5L_LINK_ERROR (-1)
+#define H5L_LINK_HARD 0
+#define H5L_LINK_SOFT 1
+#define H5L_LINK_BUILTIN_MAX H5L_LINK_SOFT /* Maximum value link value for "built-in" link types */
+#define H5L_LINK_UD_MIN 64 /*link ids at or above this value are "user-defined" link types. */
+#define H5L_LINK_EXTERNAL 64
+#define H5L_LINK_MAX 255 /*maximum link id */
/* Metadata buffer for user query function */
typedef struct H5L_linkinfo_t {
- H5T_cset_t cset; /* Character set of link name */
- time_t ctime; /* Creation time */
- H5L_link_t linkclass; /* Type of link */
+ H5T_cset_t cset; /* Character set of link name */
+ time_t ctime; /* Creation time */
+ H5L_link_t linkclass; /* Type of link */
union {
- haddr_t objno; /* Data stored in a hard link */
- size_t link_size; /* Size of a soft link */
+ haddr_t address; /* Address hard link points to */
+ size_t link_size; /* Size of a soft link or UD link */
} u;
} H5L_linkinfo_t;
#define H5L_SAME_LOC 0
+/* The H5L_link_class_t struct can be used to override the behavior of a
+ * "user-defined" link class. Users should populate the struct with callback
+ * functions defined below.
+ */
+/* Current version of the H5L_link_class_t struct */
+#define H5L_LINK_CLASS_T_VERS (0)
+
+/* Callback prototypes for user-defined links */
+/* Link creation callback */
+typedef herr_t (*H5L_create_func_t)(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id);
+
+/* Callback for when the link is moved */
+typedef herr_t (*H5L_move_func_t)(const char * new_name, hid_t new_loc, void * udata, size_t udata_size);
+
+/* Callback for when the link is moved */
+typedef herr_t (*H5L_copy_func_t)(const char * new_name, hid_t new_loc, void * udata, size_t udata_size);
+
+/* The actual link function, called during traversal */
+typedef herr_t (*H5L_func_t)(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id);
+
+/* Callback for when the link is deleted */
+typedef herr_t (*H5L_delete_func_t)(const char * link_name, hid_t loc_group, void * udata, size_t udata_size);
+
+/* Callback for querying the link */
+/* Returns the size of the buffer needed */
+typedef ssize_t (*H5L_query_func_t)(const char * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size);
+
+/* User-defined link types */
+typedef struct H5L_link_class_t {
+ int version; /* Version number of this struct */
+ H5L_link_t id; /* Link type ID */
+ const char *comment; /* Comment for debugging */
+ H5L_create_func_t create_func; /* Callback during link creation */
+ H5L_move_func_t move_func; /* Callback after moving link */
+ H5L_copy_func_t copy_func; /* Callback after copying link */
+ H5L_func_t trav_func; /* The main traversal function */
+ H5L_delete_func_t del_func; /* Callback for link deletion */
+ H5L_query_func_t query_func; /* Callback for queries */
+} H5L_link_class_t;
+
+#define H5L_ELINK_PREFIX_PROP "elink_prefix"
+
+
+/* Public prototypes */
H5_DLL herr_t H5Llink(hid_t cur_loc_id, const char *cur_name,
- hid_t obj_id, hid_t lcpl_id);
+ hid_t obj_id, hid_t lcpl_id, hid_t lapl_id);
H5_DLL herr_t H5Lmove(hid_t src_loc, const char *src_name, hid_t dst_loc,
- const char *dst_name, hid_t lcpl_id);
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id);
H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc,
- const char *dst_name, hid_t lcpl_id);
+ const char *dst_name, hid_t lcpl_id, hid_t lapl_id);
H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name,
- hid_t dst_loc, const char *dst_name, hid_t lcpl_id);
-H5_DLL herr_t H5Lcreate_soft(const char *target_path, hid_t loc,
- const char *name, hid_t lcpl_id);
-H5_DLL herr_t H5Lunlink(hid_t loc_id, const char *name);
+ hid_t dst_loc, const char *dst_name, hid_t lcpl_id,
+ hid_t lapl_id);
+H5_DLL herr_t H5Lcreate_soft(const char *target_path, hid_t cur_loc,
+ const char *cur_name, hid_t lcpl_id, hid_t lapl_id);
+H5_DLL herr_t H5Lunlink(hid_t loc_id, const char *name, hid_t lapl_id);
H5_DLL herr_t H5Lget_linkval(hid_t loc_id, const char *name, size_t size,
- char *buf/*out*/);
+ char *buf/*out*/, hid_t lapl_id);
H5_DLL herr_t H5Lget_linkinfo(hid_t loc_id, const char *name,
- H5L_linkinfo_t *linkbuf /*out*/);
+ H5L_linkinfo_t *linkbuf /*out*/, hid_t lapl_id);
+
+/* UD link functions */
+H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name,
+ H5L_link_t link_type, void * udata, size_t udata_size, hid_t lcpl_id,
+ hid_t lapl_id);
+H5_DLL herr_t H5Lregister(const H5L_link_class_t *cls);
+H5_DLL herr_t H5Lunregister(H5L_link_t id);
+H5_DLL htri_t H5Lis_registered(H5L_link_t id);
+/* External link functions */
+H5_DLL herr_t H5Lunpack_elink_val(char * ext_linkval/*in*/,
+ char ** filename/*out*/, char** obj_path /*out*/);
+H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name,
+ hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id);
#ifdef __cplusplus
}
diff --git a/src/H5O.c b/src/H5O.c
index e035ed4..878e73a 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -33,6 +33,7 @@
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
#include "H5MFprivate.h" /* File memory management */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
@@ -175,6 +176,8 @@ H5FL_EXTERN(H5O_cont_t);
H5FL_DEFINE_STATIC(H5O_addr_map_t);
/* PRIVATE PROTOTYPES */
+static hid_t H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id);
+static H5O_loc_t * H5O_get_oloc(hid_t id);
static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5O_loc_t *loc/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_msg_class_t *type, void *native);
@@ -229,6 +232,401 @@ static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
/*-------------------------------------------------------------------------
+ * Function: H5Oopen
+ *
+ * Purpose: Opens an object within an HDF5 file.
+ *
+ * This function opens an object in the same way that H5Gopen,
+ * H5Topen, and H5Dopen do. However, H5Oopen doesn't require
+ * the type of object to be known beforehand. This can be
+ * useful in user-defined links, for instance, when only a
+ * path is known.
+ *
+ * The opened object should be closed again with H5Oclose
+ * or H5Gclose, H5Tclose, or H5Dclose.
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id)
+{
+ H5G_loc_t loc;
+ H5G_loc_t obj_loc; /* Location used to open group */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Oopen, FAIL)
+ H5TRACE3("i","isi",loc_id,name,lapl_id);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object's location */
+ if(H5G_loc_find(&loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
+ ent_found = TRUE;
+
+ if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
+
+done:
+ if(ret_value < 0) {
+ if(ent_found)
+ H5G_name_free(&obj_path);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_by_addr
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function opens an object using its address within the
+ * HDF5 file, similar to an HDF5 hard link. The open object
+ * is identical to an object opened with H5Oopen() and should
+ * be closed with H5Oclose() or a type-specific closing
+ * function (such as H5Gclose() ).
+ *
+ * This function is very dangerous if called on an invalid
+ * address. For this reason, H5Oincr_refcount() should be
+ * used to prevent HDF5 from deleting any object that is
+ * referenced by address (e.g. by a user-defined link).
+ * H5Odecr_refcount() should be used when the object is
+ * no longer being referenced by address (e.g. when the UD link
+ * is deleted).
+ *
+ * The address of the HDF5 file on disk has no effect on
+ * H5Oopen_by_addr(), nor does the use of any unusual file
+ * drivers. The "address" is really the offset within the
+ * HDF5 file, and HDF5's file drivers will transparently
+ * map this to an address on disk for the filesystem.
+ *
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
+{
+ H5G_loc_t loc;
+ H5G_loc_t obj_loc; /* Location used to open group */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Oopen_by_addr, FAIL)
+ H5TRACE2("i","ia",loc_id,addr);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+ obj_loc.oloc->addr = addr;
+ obj_loc.oloc->file = loc.oloc->file;
+ H5G_name_reset(obj_loc.path);
+
+ if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
+
+done:
+ if(ret_value < 0) {
+ if(ent_found)
+ H5G_name_free(&obj_path);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oclose
+ *
+ * Purpose: Close an open file object.
+ *
+ * This is the companion to H5Oopen. It is used to close any
+ * open object in an HDF5 file (but not IDs are that not file
+ * objects, such as property lists and dataspaces). It has
+ * the same effect as calling H5Gclose, H5Dclose, or H5Tclose.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oclose(hid_t object_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(H5Oclose, FAIL)
+ H5TRACE1("e","i",object_id);
+
+ /* Get the type of the object and open it in the correct way */
+ switch(H5I_get_type(object_id))
+ {
+ case(H5I_GROUP):
+ case(H5I_DATATYPE):
+ case(H5I_DATASET):
+ if( H5I_object(object_id) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object");
+ if (H5I_dec_ref(object_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object");
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)");
+ break;
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oincr_refcount
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function increments the "hard link" reference count
+ * for an object. It should be used a user-defined link
+ * that references an object by address is deleted. When the
+ * link is deleted, H5Odecr_refcount should be used.
+ *
+ * Return: Success: The object's new refcount
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Oincr_refcount(hid_t object_id)
+{
+ H5O_loc_t *oloc;
+ int ret_value;
+ FUNC_ENTER_API(H5Oincr_refcount, FAIL)
+ H5TRACE1("Is","i",object_id);
+
+ /* Get the object's oloc so we can adjust its link count */
+ if((oloc = H5O_get_oloc(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ ret_value = H5O_link(oloc, 1, H5AC_dxpl_id);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Odecr_refcount
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function decrements the "hard link" reference count
+ * for an object. It should be used when user-defined links
+ * that reference an object by address are deleted, and only
+ * after H5Oincr_refcount has already been used.
+ *
+ * Return: Success: The object's new refcount
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5Odecr_refcount(hid_t object_id)
+{
+ H5O_loc_t *oloc;
+ int ret_value;
+
+ FUNC_ENTER_API(H5Odecr_refcount, FAIL)
+
+ /* Get the object's oloc so we can adjust its link count */
+ if((oloc = H5O_get_oloc(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ ret_value = H5O_link(oloc, -1, H5AC_dxpl_id);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_open_by_loc
+ *
+ * Purpose: Opens an object and returns an ID given its group loction.
+ *
+ * This functions simply invokes H5G_open, H5T_open, or
+ * H5D_open depending on the object type.
+ *
+ * Return: Success: Open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 25 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id)
+{
+ H5G_t *grp = NULL;
+ H5D_t *dset = NULL;
+ H5T_t *type = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5O_open_by_loc, FAIL)
+
+ HDassert(obj_loc);
+
+ /* Get the type of the object and open it in the correct way */
+ switch(H5O_obj_type(obj_loc->oloc, dxpl_id))
+ {
+ case(H5G_GROUP):
+ /* Open the group */
+ if((grp = H5G_open(obj_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ break;
+
+ case(H5G_DATASET):
+ /* Open the group */
+ if((dset = H5D_open(obj_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataset")
+ break;
+
+ case(H5G_TYPE):
+ /* Open the group */
+ if((type = H5T_open(obj_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open datatype")
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "invalid object type")
+ }
+
+done:
+ if(ret_value < 0) {
+ if(grp != NULL)
+ H5G_close(grp);
+ else if(dset != NULL)
+ H5D_close(dset);
+ else if(type != NULL)
+ H5T_close(type);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_oloc
+ *
+ * Purpose: Gets the oloc for an object given its ID.
+ *
+ * Return: Success: Pointer to H5O_loc_t
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * July 25 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5O_loc_t *
+H5O_get_oloc(hid_t object_id)
+{
+ H5G_t *grp = NULL;
+ H5D_t *dset = NULL;
+ H5T_t *type = NULL;
+ H5O_loc_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5O_get_oloc, NULL)
+
+ switch(H5I_get_type(object_id))
+ {
+ case(H5I_GROUP):
+ if((grp = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get group from ID")
+ if((ret_value = H5G_oloc(grp)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from group ID")
+ break;
+
+ case(H5I_DATASET):
+ if((dset = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get dataset from ID")
+ if((ret_value = H5D_oloc(dset)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from dataset ID")
+ break;
+
+ case(H5I_DATATYPE):
+ if((type = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get type from ID")
+ if((ret_value = H5T_oloc(type)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from datatype ID")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, NULL, "invalid object type")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_create
*
* Purpose: Creates a new object header. Allocates space for it and
@@ -1604,7 +2002,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t
/* Increment any links in message */
if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared object link count");
done:
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index f0c15e7..84bb09d 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -589,7 +589,7 @@ H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_l
/* Decrement the reference count on the shared datatype, if requested */
if(adj_link)
if(H5T_link(attr->dt, -1, dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count")
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
} /* end if */
done:
@@ -628,7 +628,7 @@ H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg)
if(H5T_committed(attr->dt)) {
/* Increment the reference count on the shared datatype */
if(H5T_link(attr->dt,1,dxpl_id)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count");
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count");
} /* end if */
done:
diff --git a/src/H5Olink.c b/src/H5Olink.c
index 00a2b92..53fa99e 100644
--- a/src/H5Olink.c
+++ b/src/H5Olink.c
@@ -124,7 +124,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
/* Get the type of the link */
lnk->type = *p++;
- if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_SOFT)
+ if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_MAX)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
/* Get the link creation time from the file */
@@ -165,9 +165,21 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
p += len;
break;
+ /* User-defined linkes */
default:
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
- break;
+ if(lnk->type < H5L_LINK_UD_MIN || lnk->type > H5L_LINK_MAX)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
+
+ /* A UD link. Get the user-supplied data */
+ UINT16DECODE(p, len)
+ lnk->u.ud.size = len;
+ if(len > 0)
+ {
+ if(NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->u.ud.udata, p, len);
+ p += len;
+ }
} /* end switch */
/* Set return value */
@@ -252,8 +264,18 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg)
p += len;
break;
+ /* User-defined links */
default:
- HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT));
+ HDassert(lnk->type >= H5L_LINK_UD_MIN && lnk->type <= H5L_LINK_MAX);
+
+ /* Store the user-supplied data, however long it is */
+ len = (uint16_t)lnk->u.ud.size;
+ UINT16ENCODE(p, len)
+ if(len > 0)
+ {
+ HDmemcpy(p, lnk->u.ud.udata, len);
+ p+=len;
+ }
break;
} /* end switch */
@@ -300,6 +322,14 @@ H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
dest->name = H5MM_xstrdup(lnk->name);
if(lnk->type == H5L_LINK_SOFT)
dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name);
+ else if(lnk->type >= H5L_LINK_UD_MIN) {
+ if(lnk->u.ud.size != 0)
+ {
+ if(NULL == (dest->u.ud.udata = H5MM_malloc(lnk->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(dest->u.ud.udata, lnk->u.ud.udata, lnk->u.ud.size);
+ }
+ }/* end if */
/* Set return value */
ret_value=dest;
@@ -354,8 +384,10 @@ H5O_link_size(const H5F_t *f, const void *_mesg)
HDstrlen(lnk->u.soft.name); /* Link value */
break;
- default:
- HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT));
+ default: /* Default is user-defined link type */
+ HDassert(lnk->type >= H5L_LINK_UD_MIN);
+ ret_value += 2 + /* User-defined data size */
+ lnk->u.ud.size; /* User-defined data */
break;
} /* end switch */
@@ -387,6 +419,12 @@ H5O_link_reset(void *_mesg)
/* Free information for link (but don't free link pointer) */
if(lnk->type == H5L_LINK_SOFT)
lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ else if (lnk->type >= H5L_LINK_UD_MIN) {
+ if(lnk->u.ud.size > 0)
+ {
+ lnk->u.ud.udata = H5MM_xfree(lnk->u.ud.udata);
+ }
+ } /* end if */
lnk->name = H5MM_xfree(lnk->name);
} /* end if */
@@ -561,6 +599,17 @@ H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_
break;
default:
+ if(link_src->type >= H5L_LINK_UD_MIN)
+ {
+ /* Copy the user-defined link's user data */
+ if(link_src->u.ud.size != 0)
+ {
+ if(NULL == (link_dst->u.ud.udata = H5MM_malloc(link_src->u.ud.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(link_dst->u.ud.udata, link_src->u.ud.udata, link_src->u.ud.size);
+ }
+ }
+ else
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unrecognized link type")
} /* end switch */
@@ -610,7 +659,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth);
/* Expand soft link */
- if(H5G_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) {
+ if(H5L_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) {
H5G_stat_t statbuf; /* Information about object pointed to by soft link */
H5G_loc_t grp_loc; /* Group location for parent of soft link */
H5G_name_t grp_path; /* Path for parent of soft link */
@@ -635,10 +684,10 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
#else
link_src->u.hard.addr = statbuf.objno[0];
#endif
- link_src->type = H5G_LINK_HARD;
+ link_src->type = H5L_LINK_HARD;
/* Convert destination link to hard link */
- link_dst->type = H5G_LINK_HARD;
+ link_dst->type = H5L_LINK_HARD;
link_dst->u.soft.name = H5MM_xfree(link_dst->u.soft.name);
} /* end if */
} /* if ((H5G_CACHED_SLINK == src_ent->type)... */
@@ -674,6 +723,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src,
break;
case H5L_LINK_SOFT:
+ case H5L_LINK_EXTERNAL:
HGOTO_DONE(SUCCEED)
break;
@@ -720,7 +770,9 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE *
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Link Type:", (lnk->type == H5L_LINK_HARD ? "Hard" :
- (lnk->type == H5L_LINK_SOFT ? "Soft" : "Unknown")));
+ (lnk->type == H5L_LINK_SOFT ? "Soft" :
+ (lnk->type == H5L_LINK_EXTERNAL ? "External" :
+ (lnk->type >= H5L_LINK_UD_MIN ? "User-defined" : "Unknown")))));
tm = HDlocaltime(&(lnk->ctime));
HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
@@ -744,6 +796,15 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE *
"Link Value:", lnk->u.soft.name);
break;
+ case H5L_LINK_EXTERNAL:
+ {
+ char * objname = (char *) lnk->u.ud.udata + (HDstrlen(lnk->u.ud.udata) + 1);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link File Name:", lnk->u.ud.udata);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Object Name:", objname);
+ }
+
default:
break;
} /* end switch */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 59c2081..07d2468 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -153,6 +153,11 @@ typedef struct H5O_link_soft_t {
char *name; /* Destination name */
} H5O_link_soft_t;
+typedef struct H5O_link_ud_t {
+ void *udata; /* Opaque data supplied by the user */
+ size_t size; /* Size of udata */
+} H5O_link_ud_t;
+
typedef struct H5O_link_t {
H5L_link_t type; /* Type of link */
time_t ctime; /* Time link was createed */
@@ -161,6 +166,7 @@ typedef struct H5O_link_t {
union {
H5O_link_hard_t hard; /* Information for hard links */
H5O_link_soft_t soft; /* Information for soft links */
+ H5O_link_ud_t ud; /* Information for user-defined links */
} u;
} H5O_link_t;
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index e71ff9c..9fe00cb 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -30,6 +30,7 @@
/* Public headers needed by this file */
#include "H5public.h"
+#include "H5Ipublic.h"
typedef struct H5O_stat_t {
hsize_t size; /* Total size of object header in file */
@@ -42,6 +43,12 @@ typedef struct H5O_stat_t {
extern "C" {
#endif
+H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id);
+H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr);
+H5_DLL herr_t H5Oclose(hid_t object_id);
+H5_DLL herr_t H5Oincr_refcount(hid_t object_id);
+H5_DLL herr_t H5Odecr_refcount(hid_t object_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 226f300..367e001 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -155,9 +155,9 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adj
* object header.
*/
if(shared->oloc.file->shared != f->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed")
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "interfile hard links are not allowed")
if((ret_value = H5O_link(&(shared->oloc), adjust, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count")
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -370,7 +370,7 @@ H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link)
/* Decrement the reference count on the shared object, if requested */
if(adj_link)
if(H5O_shared_link_adj(f, dxpl_id, shared, -1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count")
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -406,7 +406,7 @@ H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg)
/* Decrement the reference count on the shared object */
if(H5O_shared_link_adj(f,dxpl_id,shared,1)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count");
done:
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/src/H5P.c b/src/H5P.c
index 9a87b90..5c96586 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -30,6 +30,7 @@
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Ppkg.h" /* Property lists */
@@ -57,6 +58,7 @@ hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL;
hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL;
hid_t H5P_CLS_OBJECT_COPY_g = FAIL;
hid_t H5P_CLS_LINK_CREATE_g = FAIL;
+hid_t H5P_CLS_LINK_ACCESS_g = FAIL;
hid_t H5P_CLS_STRING_CREATE_g = FAIL;
/*
@@ -77,6 +79,7 @@ hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL;
hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL;
hid_t H5P_LST_OBJECT_COPY_g = FAIL;
hid_t H5P_LST_LINK_CREATE_g = FAIL;
+hid_t H5P_LST_LINK_ACCESS_g = FAIL;
/* Track the revision count of a class, to make comparisons faster */
static unsigned H5P_next_rev=0;
@@ -233,6 +236,13 @@ H5P_init_interface(void)
{
H5P_genclass_t *root_class; /* Pointer to root property list class created */
H5P_genclass_t *pclass; /* Pointer to property list class to create */
+ /* Link access property class variables. In sequence, they are,
+ * - Access property list class to modify
+ * - Default value for "user-supplied data"
+ * - Default value for "max number of soft links to traverse"
+ */
+ H5P_genclass_t *lacc_class; /* Pointer to link access property list class created */
+ int nlinks = H5L_NLINKS_DEF;
/* Group creation property class variables. In sequence, they are,
* - Creation property list class to modify
* - Default value for "group info"
@@ -314,6 +324,28 @@ H5P_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
} /* end if */
+ /* Create link property classes (which need to be inherited by later classes */
+ /* Allocate the link access class */
+ HDassert(H5P_CLS_LINK_ACCESS_g == (-1));
+ if(NULL == (lacc_class = H5P_create_class(root_class, "link access", 1, NULL, NULL, NULL, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed")
+
+ /* Register the link access class */
+ if((H5P_CLS_LINK_ACCESS_g = H5I_register(H5I_GENPROP_CLS, lacc_class)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class")
+
+ /* Get the number of properties in the class */
+ if(H5P_get_nprops_pclass(lacc_class, &nprops, FALSE) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties")
+
+ /* Assume that if there are properties in the class, they are the default ones */
+ if(nprops == 0) {
+ /* Register property for number of links traversed */
+ if(H5P_register(lacc_class, H5L_NLINKS_NAME, H5L_NLINKS_SIZE,
+ &nlinks, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ } /* end if */
+
/* Register the group creation and group access property classes */
/* (Register the group property classes before file property classes, so
* file creation property class can inherit from group creation property
@@ -344,7 +376,7 @@ H5P_init_interface(void)
/* Allocate the group access class */
HDassert(H5P_CLS_GROUP_ACCESS_g == (-1));
- if(NULL == (pclass = H5P_create_class(root_class, "group access", 1, NULL, NULL, NULL, NULL, NULL, NULL)))
+ if(NULL == (pclass = H5P_create_class(lacc_class, "group access", 1, NULL, NULL, NULL, NULL, NULL, NULL)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the group access class */
@@ -384,7 +416,7 @@ H5P_init_interface(void)
/* Allocate the dataset access class */
assert(H5P_CLS_DATASET_ACCESS_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"dataset access",1,NULL,NULL,NULL,NULL,NULL,NULL)))
+ if (NULL==(pclass = H5P_create_class (lacc_class,"dataset access",1,NULL,NULL,NULL,NULL,NULL,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the dataset access class */
@@ -424,7 +456,7 @@ H5P_init_interface(void)
/* Allocate the datatype access class */
assert(H5P_CLS_DATATYPE_ACCESS_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"datatype access",1,NULL /*H5T_acs_create*/,NULL,NULL /*H5T_acs_copy*/,NULL,NULL /*H5T_acs_close*/,NULL)))
+ if (NULL==(pclass = H5P_create_class (lacc_class,"datatype access",1,NULL /*H5T_acs_create*/,NULL,NULL /*H5T_acs_copy*/,NULL,NULL /*H5T_acs_close*/,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the datatype access class */
@@ -536,6 +568,7 @@ H5P_term_interface(void)
H5P_LST_ATTRIBUTE_CREATE_g =
H5P_LST_OBJECT_COPY_g =
H5P_LST_LINK_CREATE_g =
+ H5P_LST_LINK_ACCESS_g =
H5P_LST_MOUNT_g = (-1);
} /* end if */
} /* end if */
@@ -561,6 +594,7 @@ H5P_term_interface(void)
H5P_CLS_ATTRIBUTE_CREATE_g =
H5P_CLS_OBJECT_COPY_g =
H5P_CLS_LINK_CREATE_g =
+ H5P_CLS_LINK_ACCESS_g =
H5P_CLS_MOUNT_g = (-1);
} /* end if */
} /* end if */
diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c
index 6e883e5..b78bc2b 100644
--- a/src/H5Pgcpl.c
+++ b/src/H5Pgcpl.c
@@ -292,5 +292,7 @@ H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /*out*/, unsigned
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_est_link_info() */
+
+
#endif /* H5_GROUP_REVISION */
diff --git a/src/H5Plapl.c b/src/H5Plapl.c
new file mode 100644
index 0000000..cfe6b50
--- /dev/null
+++ b/src/H5Plapl.c
@@ -0,0 +1,117 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+/* Private header files */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
+#include "H5Ppkg.h" /* Property lists */
+
+/* Local datatypes */
+
+/* Static function prototypes */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_nlinks
+ *
+ * Purpose: Set the number of soft or UD link traversals allowed before
+ * the library assumes it has found a cycle and aborts the
+ * traversal.
+ *
+ * The limit on soft or UD link traversals is designed to
+ * terminate link traversal if one or more links form a cycle.
+ * However, users may have a file with a legitimate path
+ * formed of a large number of soft or user-defined links.
+ * This property can be used to allow traversal of as many
+ * links as desired.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Friday, July 14, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_nlinks(hid_t plist_id, size_t nlinks)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_nlinks, FAIL)
+ H5TRACE2("e","iz",plist_id,nlinks);
+
+ if(nlinks <= 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of links must be positive");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set number of links */
+ if(H5P_set(plist, H5L_NLINKS_NAME, &nlinks) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_nlinks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_nlinks
+ *
+ * Purpose: Get the number of soft or UD traversals allowed when using
+ * this property list.
+ * Purpose: Gets the number of soft or user-defined links that can be
+ * traversed before a failure occurs.
+ *
+ * Retrieves the current setting for the nlinks property on
+ * the given property list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: James Laird
+ * Friday, July 14, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_nlinks(hid_t plist_id, size_t *nlinks)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pget_nlinks, FAIL)
+ H5TRACE2("e","i*z",plist_id,nlinks);
+
+ if(!nlinks)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer passed in");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get the current number of links */
+ if(H5P_get(plist, H5L_NLINKS_NAME, nlinks) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index b8f5edb..589b30c 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -96,6 +96,7 @@ typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
#define H5P_ATTRIBUTE_CREATE (H5OPEN H5P_CLS_ATTRIBUTE_CREATE_g)
#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_g)
#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_g)
+#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_g)
H5_DLLVAR hid_t H5P_CLS_NO_CLASS_g;
H5_DLLVAR hid_t H5P_CLS_OBJECT_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_FILE_CREATE_g;
@@ -112,6 +113,7 @@ H5_DLLVAR hid_t H5P_CLS_STRING_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_CREATE_g;
H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_g;
H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g;
+H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_g;
/*
* The library created default property lists
@@ -135,6 +137,7 @@ H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g;
#define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_g)
#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_g)
#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_g)
+#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_g)
H5_DLLVAR hid_t H5P_LST_NO_CLASS_g;
H5_DLLVAR hid_t H5P_LST_FILE_CREATE_g;
H5_DLLVAR hid_t H5P_LST_FILE_ACCESS_g;
@@ -149,6 +152,7 @@ H5_DLLVAR hid_t H5P_LST_DATATYPE_ACCESS_g;
H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_CREATE_g;
H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_g;
H5_DLLVAR hid_t H5P_LST_LINK_CREATE_g;
+H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_g;
/* Public functions */
H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name,
@@ -357,8 +361,12 @@ H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /*
H5_DLL herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding);
H5_DLL herr_t H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/);
+
#endif /* H5_GROUP_REVISION */
+H5_DLL herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks);
+H5_DLL herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks);
+
H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd);
H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/);
diff --git a/src/H5R.c b/src/H5R.c
index 0e06384..3a2f35d 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -156,7 +156,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5
H5G_loc_reset(&obj_loc);
/* Find the object */
- if(H5G_loc_find(loc, name, &obj_loc, dxpl_id) < 0)
+ if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found")
obj_found = TRUE;
diff --git a/src/H5T.c b/src/H5T.c
index 744e7f3..44ac21f 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -733,6 +733,7 @@ H5T_init_interface(void)
herr_t status;
unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
H5P_genclass_t *crt_pclass; /* Property list class for datatype creation properties */
+ H5P_genclass_t *acc_pclass; /* Property list class for datatype access properties */
herr_t ret_value=SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5T_init_interface);
@@ -1325,6 +1326,20 @@ H5T_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
+ /* ========== Datatype Access Property Class Initialization ============*/
+ assert(H5P_CLS_DATATYPE_ACCESS_g!=-1);
+
+ /* Get the pointer to dataset access class */
+ if(NULL == (acc_pclass = H5I_object(H5P_CLS_DATATYPE_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
+
+ /* Only register the default property list if it hasn't been created yet */
+ if(H5P_LST_DATATYPE_ACCESS_g == (-1)) {
+ /* Register the default dataset access property list */
+ if((H5P_LST_DATATYPE_ACCESS_g = H5P_create_id(acc_pclass))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
+ } /* end if */
+
done:
/* General cleanup */
if (compound!=NULL)
diff --git a/src/H5Tbit.c b/src/H5Tbit.c
index d298d4c..6ae8836 100644
--- a/src/H5Tbit.c
+++ b/src/H5Tbit.c
@@ -265,7 +265,8 @@ H5T_bit_get_d (uint8_t *buf, size_t offset, size_t size)
break;
default:
- HDabort ();
+ /* Unknown endianness. Bail out. */
+ return -1;
}
/* Set return value */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index e842c78..cccee9e 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -108,13 +108,13 @@ H5Tcommit(hid_t loc_id, const char *name, hid_t type_id)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
if(H5G_loc(type_id, &type_loc) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get committed datatype's location")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get committed datatype's location")
/* Link the type into the group hierarchy */
- if( H5L_link(&loc, name, &type_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0)
+ if( H5L_link(&loc, name, &type_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0)
{
uncommit = TRUE; /* Linking failed, and we need to undo H5T_commit. */
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to type")
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to type")
}
done:
@@ -182,14 +182,12 @@ H5Tcommit_expand(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id)
if(TRUE != H5P_isa_class(tcpl_id, H5P_DATATYPE_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype create property list")
-#ifdef LATER
/* Get correct property list */
if(H5P_DEFAULT == tapl_id)
tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
else
if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
-#endif /* LATER */
/* Commit the type */
if(H5T_commit(loc.oloc->file, type, H5AC_dxpl_id, tcpl_id, tapl_id) < 0)
@@ -384,7 +382,7 @@ H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id)
/* Adjust the link count on the named datatype */
if((ret_value = H5O_link(&(type->oloc), adjust, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, FAIL, "unable to adjust named datatype link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -435,7 +433,7 @@ H5Topen(hid_t loc_id, const char *name)
* Find the named datatype object header and read the datatype message
* from it.
*/
- if(H5G_loc_find(&loc, name, &type_loc/*out*/, dxpl_id) < 0)
+ if(H5G_loc_find(&loc, name, &type_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
obj_found = TRUE;
@@ -466,6 +464,87 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Topen_expand
+ *
+ * Purpose: Opens a named datatype using a Datatype Access Property
+ * List.
+ *
+ * Return: Success: Object ID of the named datatype.
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * Thursday July 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen_expand(hid_t loc_id, const char *name, hid_t tapl_id)
+{
+ H5T_t *type = NULL;
+ H5G_loc_t loc;
+ H5G_name_t path; /* Datatype group hier. path */
+ H5O_loc_t oloc; /* Datatype object location */
+ H5G_loc_t type_loc; /* Group object for datatype */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Topen_expand, FAIL)
+ H5TRACE3("i","isi",loc_id,name,tapl_id);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Get correct property list */
+ if(H5P_DEFAULT == tapl_id)
+ tapl_id = H5P_DATATYPE_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list")
+
+ /* Set up datatype location to fill in */
+ type_loc.oloc = &oloc;
+ type_loc.path = &path;
+ H5G_loc_reset(&type_loc);
+
+ /*
+ * Find the named datatype object header and read the datatype message
+ * from it.
+ */
+ if(H5G_loc_find(&loc, name, &type_loc/*out*/, tapl_id, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
+ obj_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&oloc, dxpl_id) != H5G_TYPE)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a named datatype")
+
+ /* Open it */
+ if((type = H5T_open(&type_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype")
+
+ /* Register the type and return the ID */
+ if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype")
+
+done:
+ if(ret_value < 0) {
+ if(type != NULL)
+ H5T_close(type);
+ else {
+ if(obj_found && H5F_addr_defined(type_loc.oloc->addr))
+ H5G_name_free(type_loc.path);
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_open
*
* Purpose: Open a named datatype.
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 51da42a..44daec2 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -497,6 +497,7 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST64_g;
/* Operations defined on all datatypes */
H5_DLL hid_t H5Topen(hid_t loc_id, const char *name);
+H5_DLL hid_t H5Topen_expand(hid_t loc_id, const char *name, hid_t tapl_id);
H5_DLL hid_t H5Tcreate(H5T_class_t type, size_t size);
H5_DLL hid_t H5Tcopy(hid_t type_id);
H5_DLL herr_t H5Tclose(hid_t type_id);
diff --git a/src/H5err.txt b/src/H5err.txt
index 25accb7..d7b4ac7 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -52,6 +52,7 @@ MAJOR, H5E_IO, Low-level I/O
MAJOR, H5E_FUNC, Function entry/exit
MAJOR, H5E_ATOM, Object atom
MAJOR, H5E_CACHE, Object cache
+MAJOR, H5E_LINK, Links
MAJOR, H5E_BTREE, B-Tree node
MAJOR, H5E_SYM, Symbol table
MAJOR, H5E_HEAP, Heap
@@ -81,6 +82,7 @@ SECTION, FILE, Generic low-level file I/O errors
SECTION, FUNC, Function entry/exit interface errors
SECTION, ATOM, Object atom related errors
SECTION, CACHE, Cache related errors
+SECTION, LINK, Link related errors
SECTION, BTREE, B-tree related errors
SECTION, OHDR, Object header related errors
SECTION, GROUP, Group related errors
@@ -190,8 +192,6 @@ MINOR, OHDR, H5E_CANTPACK, Can't pack messages
MINOR, GROUP, H5E_CANTOPENOBJ, Can't open object
MINOR, GROUP, H5E_CANTCLOSEOBJ, Can't close object
MINOR, GROUP, H5E_COMPLEN, Name component is too long
-MINOR, GROUP, H5E_LINK, Link failure
-MINOR, GROUP, H5E_SLINK, Symbolic link error
MINOR, GROUP, H5E_PATH, Problem with path to object
# Datatype conversion errors
@@ -211,6 +211,13 @@ MINOR, PLIST, H5E_CANTGET, Can't get value
MINOR, PLIST, H5E_CANTSET, Can't set value
MINOR, PLIST, H5E_DUPCLASS, Duplicate class name in parent class
+# Link errors
+MINOR, LINK, H5E_TRAVERSE, Link traversal failure
+MINOR, LINK, H5E_NLINKS, Too many soft links in path
+MINOR, LINK, H5E_NOTREGISTERED, Link class not registered
+MINOR, LINK, H5E_CANTMOVE, Move callback returned error
+
+
# Parallel MPI errors
MINOR, MPI, H5E_MPI, Some MPI function failed
MINOR, MPI, H5E_MPIERRSTR, MPI Error String
diff --git a/src/H5private.h b/src/H5private.h
index c216f92..9dd989d 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1439,6 +1439,7 @@ H5_DLL int H5F_term_interface(void);
H5_DLL int H5FS_term_interface(void);
H5_DLL int H5G_term_interface(void);
H5_DLL int H5I_term_interface(void);
+H5_DLL int H5L_term_interface(void);
H5_DLL int H5P_term_interface(void);
H5_DLL int H5R_term_interface(void);
H5_DLL int H5S_term_interface(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index 55edb50..4b7995d 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,12 +55,12 @@ libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \
H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \
H5HFspace.c H5HFstat.c H5HFtest.c \
H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \
- H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \
+ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \
H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omtime.c \
H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \
H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c \
- H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \
+ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \
H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
H5Sselect.c H5Stest.c \
H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 2cb791f..fe6bfd5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -90,19 +90,20 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \
H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo \
H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \
- H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \
- H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo H5Gloc.lo H5Gname.lo \
- H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \
- H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \
- H5HFdtable.lo H5HFhdr.lo H5HFiblock.lo H5HFint.lo H5HFiter.lo \
- H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HG.lo \
- H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo \
- H5MP.lo H5MPtest.lo H5L.lo H5O.lo H5Oattr.lo H5Obogus.lo \
- H5Ocache.lo H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \
- H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omtime.lo \
- H5Oname.lo H5Onull.lo H5Opline.lo H5Osdspace.lo H5Oshared.lo \
- H5Ostab.lo H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo \
- H5Pfcpl.lo H5Pgcpl.lo H5Plcpl.lo H5Pocpl.lo H5Pstrcpl.lo \
+ H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
+ H5FSsection.lo H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo \
+ H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo \
+ H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo \
+ H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFiblock.lo \
+ H5HFint.lo H5HFiter.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo \
+ H5HFtest.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo \
+ H5I.lo H5MF.lo H5MM.lo H5MP.lo H5MPtest.lo H5L.lo \
+ H5Lexternal.lo H5O.lo H5Oattr.lo H5Obogus.lo H5Ocache.lo \
+ H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \
+ H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omtime.lo H5Oname.lo \
+ H5Onull.lo H5Opline.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \
+ H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \
+ H5Pgcpl.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pstrcpl.lo \
H5Ptest.lo H5R.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Shyper.lo \
H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo \
H5SL.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \
@@ -402,12 +403,12 @@ libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \
H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \
H5HFspace.c H5HFstat.c H5HFtest.c \
H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \
- H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \
+ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \
H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omtime.c \
H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \
H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c \
- H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \
+ H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \
H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
H5Sselect.c H5Stest.c \
H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
@@ -590,8 +591,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FS.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FScache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSdbg.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSsection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@
@@ -627,6 +628,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MM.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MP.Plo@am__quote@
@@ -657,6 +659,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfcpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pgcpl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plapl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plcpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pstrcpl.Plo@am__quote@
diff --git a/test/Makefile.am b/test/Makefile.am
index afadd52..4e7818b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -58,16 +58,14 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta
# --enable-build-all at configure time.
# The gen_old_* files can only be compiled with older versions of the library
# so do not appear in this list.
+BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \
+ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
+ gen_nullspace space_overflow gen_cross gen_udlinks
+
if BUILD_ALL_CONDITIONAL
- BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \
- gen_new_group gen_new_mtime gen_new_super gen_noencoder \
- gen_nullspace space_overflow gen_cross
-else
- BUILD_ALL_PROGS=
+ noinst_PROGRAMS=$(BUILD_ALL_PROGS)
endif
-noinst_PROGRAMS=$(BUILD_ALL_PROGS)
-
# The libh5test library provides common support code for the tests.
noinst_LTLIBRARIES=libh5test.la
libh5test_la_SOURCES=h5test.c testframe.c cache_common.c
@@ -118,7 +116,7 @@ CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5
# Sources for testhdf5 executable
testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \
- th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
+ th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c
include $(top_srcdir)/config/conclude.am
diff --git a/test/Makefile.in b/test/Makefile.in
index 5339b48..7934415 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -31,7 +31,7 @@
#
-SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -60,7 +60,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/config/conclude.am
check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \
err_compat$(EXEEXT) testmeta$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_2)
+@BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2)
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
@@ -85,17 +85,12 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \
fheap$(EXEEXT) btree2$(EXEEXT)
-@BUILD_ALL_CONDITIONAL_TRUE@am__EXEEXT_2 = gen_deflate$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_filters$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_array$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_fill$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_mtime$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_super$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_noencoder$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ space_overflow$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_cross$(EXEEXT)
+am__EXEEXT_2 = gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \
+ gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \
+ gen_new_group$(EXEEXT) gen_new_mtime$(EXEEXT) \
+ gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \
+ gen_nullspace$(EXEEXT) space_overflow$(EXEEXT) \
+ gen_cross$(EXEEXT) gen_udlinks$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
big_SOURCES = big.c
big_OBJECTS = big.$(OBJEXT)
@@ -222,6 +217,10 @@ gen_nullspace_SOURCES = gen_nullspace.c
gen_nullspace_OBJECTS = gen_nullspace.$(OBJEXT)
gen_nullspace_LDADD = $(LDADD)
gen_nullspace_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
+gen_udlinks_SOURCES = gen_udlinks.c
+gen_udlinks_OBJECTS = gen_udlinks.$(OBJEXT)
+gen_udlinks_LDADD = $(LDADD)
+gen_udlinks_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
getname_SOURCES = getname.c
getname_OBJECTS = getname.$(OBJEXT)
getname_LDADD = $(LDADD)
@@ -292,12 +291,12 @@ stream_test_LDADD = $(LDADD)
stream_test_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) tarray.$(OBJEXT) \
tattr.$(OBJEXT) tconfig.$(OBJEXT) tfile.$(OBJEXT) \
- tgenprop.$(OBJEXT) th5s.$(OBJEXT) theap.$(OBJEXT) \
- tid.$(OBJEXT) titerate.$(OBJEXT) tmeta.$(OBJEXT) \
- tmisc.$(OBJEXT) ttime.$(OBJEXT) trefer.$(OBJEXT) \
- trefstr.$(OBJEXT) tselect.$(OBJEXT) tskiplist.$(OBJEXT) \
- ttst.$(OBJEXT) tunicode.$(OBJEXT) tvltypes.$(OBJEXT) \
- tvlstr.$(OBJEXT)
+ tgenprop.$(OBJEXT) th5o.$(OBJEXT) th5s.$(OBJEXT) \
+ theap.$(OBJEXT) tid.$(OBJEXT) titerate.$(OBJEXT) \
+ tmeta.$(OBJEXT) tmisc.$(OBJEXT) ttime.$(OBJEXT) \
+ trefer.$(OBJEXT) trefstr.$(OBJEXT) tselect.$(OBJEXT) \
+ tskiplist.$(OBJEXT) ttst.$(OBJEXT) tunicode.$(OBJEXT) \
+ tvltypes.$(OBJEXT) tvlstr.$(OBJEXT)
testhdf5_OBJECTS = $(am_testhdf5_OBJECTS)
testhdf5_LDADD = $(LDADD)
testhdf5_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
@@ -336,22 +335,24 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \
error_test.c extend.c external.c fheap.c fillval.c flush1.c \
flush2.c gen_cross.c gen_deflate.c gen_filters.c \
gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
- gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \
- gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \
- ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
- space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \
+ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+ mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \
+ set_extent.c space_overflow.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \
+ vfd.c
DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \
cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \
dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
error_test.c extend.c external.c fheap.c fillval.c flush1.c \
flush2.c gen_cross.c gen_deflate.c gen_filters.c \
gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
- gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \
- gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \
- ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
- space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \
+ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+ mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \
+ set_extent.c space_overflow.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \
+ vfd.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -629,7 +630,6 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \
getname vfd ntypes dangle dtransform reserved cross_read \
fheap btree2
-@BUILD_ALL_CONDITIONAL_FALSE@BUILD_ALL_PROGS =
# These programs generate test files for the tests. They don't need to be
# compiled every time we want to test the library. However, putting
@@ -638,9 +638,9 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \
# --enable-build-all at configure time.
# The gen_old_* files can only be compiled with older versions of the library
# so do not appear in this list.
-@BUILD_ALL_CONDITIONAL_TRUE@BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace space_overflow gen_cross
+BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \
+ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
+ gen_nullspace space_overflow gen_cross gen_udlinks
# The libh5test library provides common support code for the tests.
@@ -658,7 +658,7 @@ VFD_LIST = sec2 stdio core split multi family
# Sources for testhdf5 executable
testhdf5_SOURCES = testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \
- th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
+ th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c
@@ -829,6 +829,9 @@ gen_noencoder$(EXEEXT): $(gen_noencoder_OBJECTS) $(gen_noencoder_DEPENDENCIES)
gen_nullspace$(EXEEXT): $(gen_nullspace_OBJECTS) $(gen_nullspace_DEPENDENCIES)
@rm -f gen_nullspace$(EXEEXT)
$(LINK) $(gen_nullspace_LDFLAGS) $(gen_nullspace_OBJECTS) $(gen_nullspace_LDADD) $(LIBS)
+gen_udlinks$(EXEEXT): $(gen_udlinks_OBJECTS) $(gen_udlinks_DEPENDENCIES)
+ @rm -f gen_udlinks$(EXEEXT)
+ $(LINK) $(gen_udlinks_LDFLAGS) $(gen_udlinks_OBJECTS) $(gen_udlinks_LDADD) $(LIBS)
getname$(EXEEXT): $(getname_OBJECTS) $(getname_DEPENDENCIES)
@rm -f getname$(EXEEXT)
$(LINK) $(getname_LDFLAGS) $(getname_OBJECTS) $(getname_LDADD) $(LIBS)
@@ -934,6 +937,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_super.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_noencoder.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_nullspace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_udlinks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getname.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gheap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5test.Plo@am__quote@
@@ -960,6 +964,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmeta.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgenprop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5o.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/theap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tid.Po@am__quote@
diff --git a/test/be_extlink1.h5 b/test/be_extlink1.h5
new file mode 100644
index 0000000..dedd0a5
--- /dev/null
+++ b/test/be_extlink1.h5
Binary files differ
diff --git a/test/be_extlink2.h5 b/test/be_extlink2.h5
new file mode 100644
index 0000000..d6f9921
--- /dev/null
+++ b/test/be_extlink2.h5
Binary files differ
diff --git a/test/gen_udlinks.c b/test/gen_udlinks.c
new file mode 100644
index 0000000..1230ffe
--- /dev/null
+++ b/test/gen_udlinks.c
@@ -0,0 +1,81 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: James Laird <jlaird@hdfgroup.org>
+ * Tuesday, June 6, 2006
+ *
+ * This program creates HDF5 files with user-defined links. These files
+ * should be created on a little-endian and a big-endian machine.
+ * They will be named according to the platform and should
+ * be placed in the hdf5/test directory so that the links test can use them.
+ */
+
+#include "hdf5.h"
+#include <string.h>
+
+#define NAME_LE_1 "le_extlink1.h5"
+#define NAME_LE_2 "le_extlink2.h5"
+#define NAME_BE_1 "be_extlink1.h5"
+#define NAME_BE_2 "be_extlink2.h5"
+#define NAME_BUF_SIZE 25
+
+int
+main (void)
+{
+ hid_t fid1=-1;
+ hid_t fid2=-1;
+ hid_t gid=-1;
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+
+ /* Name the files differently depending on the endianness of this platform */
+
+ switch(H5Tget_order(H5T_NATIVE_INT))
+ {
+ case H5T_ORDER_LE:
+ strcpy(filename1, NAME_LE_1);
+ strcpy(filename2, NAME_LE_2);
+ break;
+ case H5T_ORDER_BE:
+ strcpy(filename1, NAME_BE_1);
+ strcpy(filename2, NAME_BE_2);
+ break;
+ default:
+ goto error;
+ }
+
+ /* Create the two files */
+ if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
+ if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
+
+ /* Create two groups in the second file */
+ if((gid = H5Gcreate(fid2, "group", 0)) < 0) goto error;
+ if((H5Gclose(gid)) < 0) goto error;
+ if((gid = H5Gcreate(fid2, "group/subgroup", 0)) < 0) goto error;
+ if((H5Gclose(gid)) < 0) goto error;
+
+ /* Create an external link in the first file pointing to the group in the second file */
+ if(H5Lcreate_external(filename2, "group", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error;
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+ H5Gclose(gid);
+ } H5E_END_TRY
+ return 1;
+}
diff --git a/test/le_extlink1.h5 b/test/le_extlink1.h5
new file mode 100644
index 0000000..877ba37
--- /dev/null
+++ b/test/le_extlink1.h5
Binary files differ
diff --git a/test/le_extlink2.h5 b/test/le_extlink2.h5
new file mode 100644
index 0000000..d6f9921
--- /dev/null
+++ b/test/le_extlink2.h5
Binary files differ
diff --git a/test/links.c b/test/links.c
index 0e4f680..92f4984 100644
--- a/test/links.c
+++ b/test/links.c
@@ -16,34 +16,23 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Friday, April 10, 1998
*
- * Purpose: Tests hard and soft (symbolic) links.
+ * Purpose: Tests hard, soft (symbolic) & external links.
*/
-#define H5G_PACKAGE /*suppress error about including H5Gpkg */
-
-/* Define this macro to indicate that the testing APIs should be available */
-#define H5G_TESTING
+#include "H5Lprivate.h"
#include "h5test.h"
-#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"links0",
"links1",
"links2",
"links3",
- "links4",
+ "links4a",
+ "links4b",
+ "links4c",
+ "links4d",
"links5",
- "links6",
- "links7",
- "links8",
- "links9",
- "links10",
- "links11",
- "links12",
- "links13",
- "links14",
- "links15",
NULL
};
@@ -51,6 +40,27 @@ const char *FILENAME[] = {
#define NAME_BUF_SIZE 1024
#define MAX_NAME_LEN ((64*1024)+1024)
+/* Link type IDs */
+#define UD_HARD_TYPE 201
+#define UD_CB_TYPE H5L_LINK_MAX
+#define UD_PLIST_TYPE 128
+#define UD_CBFAIL_TYPE UD_PLIST_TYPE
+#define UD_ERROR_TYPE 189
+#define UD_BAD_TYPE1 H5G_LINK_HARD
+#define UD_BAD_TYPE2 (H5L_LINK_UD_MIN - 5)
+#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1)
+
+#define DEST_PROP_NAME "destination_group"
+#define REREG_TARGET_NAME "rereg_target"
+
+#define UD_CB_LINK_NAME "ud_callback_link"
+#define NEW_UD_CB_LINK_NAME "ud_callback_link2"
+#define UD_CB_TARGET "ud_target"
+#define UD_CB_TARGET_LEN 10
+
+#define LE_FILENAME "le_extlink1.h5"
+#define BE_FILENAME "be_extlink1.h5"
+
#define H5L_DIM1 100
#define H5L_DIM2 100
@@ -94,16 +104,16 @@ mklinks(hid_t fapl)
if (H5Dclose (d1)<0) TEST_ERROR;
/* Create a hard link */
- if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a symbolic link */
- if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a symbolic link to something that doesn't exist */
- if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a recursive symbolic link */
- if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Close */
if (H5Sclose (scalar)<0) TEST_ERROR;
@@ -167,22 +177,22 @@ new_links(hid_t fapl)
/* Create links within a file. Both of source and destination use
* H5L_SAME_LOC. Both hard and soft links should fail. */
H5E_BEGIN_TRY {
- if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
H5E_BEGIN_TRY {
- if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Create links across files with hard link. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Create hard link to test H5L_SAME_LOC */
- if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create links to test hard links across different locations */
- if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Close dataspace and files */
if (H5Sclose (scalar)<0) TEST_ERROR;
@@ -274,7 +284,7 @@ cklinks(hid_t fapl)
puts(" expected file location.");
TEST_ERROR;
}
- if (H5Gget_linkval(file, "grp1/soft", sizeof linkval, linkval)<0) TEST_ERROR;
+ if (H5Lget_linkval(file, "grp1/soft", sizeof linkval, linkval, H5P_DEFAULT)<0) TEST_ERROR;
if (HDstrcmp(linkval, "/d1")) {
H5_FAILED();
puts(" Soft link test failed. Wrong link value");
@@ -431,7 +441,7 @@ long_links(hid_t fapl)
TESTING("long names for objects & links");
/* Create files */
- h5_fixname(FILENAME[13], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create group with short name in file (used as target for hard links) */
@@ -444,11 +454,11 @@ long_links(hid_t fapl)
objname[MAX_NAME_LEN] = '\0';
/* Create hard link to existing object */
- if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create soft link to existing object */
objname[0] = 'b';
- if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create group with long name in existing group */
if((gid2=H5Gcreate(gid, objname, (size_t)0))<0) TEST_ERROR;
@@ -495,8 +505,7 @@ static int
toomany(hid_t fapl)
{
hid_t fid = (-1); /* File ID */
- hid_t gid = (-1); /* Group ID */
- hid_t gid2 = (-1); /* Datatype ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
char objname[NAME_BUF_SIZE]; /* Object name */
ssize_t name_len; /* Length of object name */
char filename[NAME_BUF_SIZE];
@@ -509,54 +518,54 @@ toomany(hid_t fapl)
*/
HDassert(H5G_NLINKS == 16);
- /* Create files */
- h5_fixname(FILENAME[14], fapl, filename, sizeof filename);
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create group with short name in file (used as target for hard links) */
if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR;
/* Create chain of hard links to existing object (no limit on #) */
- if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create chain of soft links to existing object (limited) */
- if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Close objects */
if(H5Gclose(gid)<0) TEST_ERROR;
@@ -598,16 +607,14 @@ toomany(hid_t fapl)
if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/soft16")) TEST_ERROR
- /* Create object in external file */
+ /* Create object using soft links */
if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR
- /* Close group in external file */
+ /* Close groups */
if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
- /* Close external object */
- if(H5Gclose(gid) < 0) TEST_ERROR;
-
- /* Close first file */
+ /* Close file */
if(H5Fclose(fid)<0) TEST_ERROR;
PASSED();
@@ -642,7 +649,6 @@ toomany(hid_t fapl)
static int
test_h5l_create(hid_t fapl)
{
- hid_t fapl_id=-1;
hid_t file_id=-1;
hid_t group_id=-1;
hid_t space_id=-1;
@@ -654,13 +660,12 @@ test_h5l_create(hid_t fapl)
int i, n, j;
int wdata[H5L_DIM1][H5L_DIM2];
int rdata[H5L_DIM1][H5L_DIM2];
- TESTING("H5Lcreate");
+ TESTING("H5Llink");
/* Create file */
- fapl_id = h5_fileaccess();
- h5_fixname(FILENAME[3], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[3], fapl, filename, sizeof filename);
- if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create and commit a datatype with no name */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
@@ -672,7 +677,7 @@ test_h5l_create(hid_t fapl)
dims[1] = H5L_DIM2;
if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR;
/* Create a dataset with no name using the committed datatype*/
- if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
/* Verify that we can write to and read from the dataset */
/* Initialize the dataset */
@@ -699,14 +704,14 @@ test_h5l_create(hid_t fapl)
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Link nameless datatype into nameless group */
- if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create LCPL with intermediate group creation flag set */
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
if(H5Pset_create_intermediate_group(lcpl_id, TRUE) <0) TEST_ERROR;
/* Link nameless dataset into nameless group with intermediate group */
- if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
/* Close IDs for dataset and datatype */
if(H5Dclose(dset_id)<0) TEST_ERROR;
@@ -716,7 +721,7 @@ test_h5l_create(hid_t fapl)
if((type_id = H5Topen(group_id, "datatype"))<0) TEST_ERROR;
/* Link nameless group to root group and close the group ID*/
- if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Open dataset through root group and verify its data */
@@ -738,7 +743,6 @@ test_h5l_create(hid_t fapl)
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
if(H5Sclose(space_id)<0) TEST_ERROR;
if(H5Fclose(file_id)<0) TEST_ERROR;
- if(H5Pclose(fapl_id)<0) TEST_ERROR;
PASSED();
return 0;
@@ -750,7 +754,6 @@ error:
H5Pclose(lcpl_id);
H5Sclose(space_id);
H5Fclose(file_id);
- H5Pclose(fapl_id);
} H5E_END_TRY;
return 1;
} /* end test_h5l_create() */
@@ -791,27 +794,27 @@ test_lcpl(hid_t fapl)
/* Create file */
fapl_id = h5_fileaccess();
- h5_fixname(FILENAME[12], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
/* Create and link a group with the default LCPL */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create and commit a datatype with the default LCPL */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "type", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create a dataspace */
@@ -820,12 +823,12 @@ test_lcpl(hid_t fapl)
if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR;
/* Create a dataset using the default LCPL */
- if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
+ if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Dclose(dset_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "dataset", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create a link creation property list with the UTF-8 character encoding */
@@ -834,30 +837,30 @@ test_lcpl(hid_t fapl)
/* Create and link a group with the new LCPL */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/group2", group_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group2", group_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "group2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create and commit a datatype with the new LCPL */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/type2", type_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/type2", type_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "type2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create a dataset using the new LCPL */
- if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id)<0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
+ if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Dclose(dset_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "dataset2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create a new link to the dataset with a different character encoding. */
@@ -865,15 +868,46 @@ test_lcpl(hid_t fapl)
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR;
- if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR;
/* Check that its character encoding is ASCII */
- if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR;
/* Check that the first link's encoding hasn't changed */
- if(H5Lget_linkinfo(file_id, "/dataset2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+
+
+/* JAMES: these tests don't work because the character set encoding is
+ * not stored in the symbol table.
+ * Quincey says this will be fixed someday.
+ */
+#ifdef NOTYET
+ /* Make sure that LCPLs work properly for other API calls: */
+ /* H5Lcreate_soft */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR
+ if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR
+
+ /* H5Lmove */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR
+ if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR;
+
+ /* H5Lcopy */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR;
+ if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+
+ /* H5Lcreate_external */
+ if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+#endif /* NOTYET */
/* Close open IDs */
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
@@ -924,10 +958,10 @@ test_move(hid_t fapl)
TESTING("H5Lmove");
/* Create two new files */
- h5_fixname(FILENAME[8], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
- h5_fixname(FILENAME[9], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
@@ -937,26 +971,26 @@ test_move(hid_t fapl)
if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) TEST_ERROR;
/* Create hard and soft links. */
- if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0)
+ if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
- if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT)<0)
+ if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Move a group within the file. Both of source and destination use
* H5L_SAME_LOC. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT)
+ if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across files. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT)
+ if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across groups in the same file while renaming it. */
- if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -972,7 +1006,7 @@ test_move(hid_t fapl)
} H5E_END_TRY;
/* Use H5Lmove to rename a group without moving it. */
- if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
@@ -982,7 +1016,7 @@ test_move(hid_t fapl)
TEST_ERROR;
/* Use H5Lmove to move a group without renaming it. */
- if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
@@ -992,7 +1026,7 @@ test_move(hid_t fapl)
TEST_ERROR;
/* Move the group while giving long paths. */
- if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0)
+ if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1063,10 +1097,10 @@ test_copy(hid_t fapl)
TESTING("H5Lcopy");
/* Create two new files */
- h5_fixname(FILENAME[8], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
- h5_fixname(FILENAME[9], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
@@ -1076,26 +1110,26 @@ test_copy(hid_t fapl)
if((grp_move=H5Gcreate(grp_1, "group_copy", 0))<0) TEST_ERROR;
/* Create hard and soft links. */
- if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0)
+ if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
- if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT)<0)
+ if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Copy a group within the file. Both of source and destination use
* H5L_SAME_LOC. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT)
+ if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Copy a group across files. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT)
+ if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across groups in the same file while renaming it. */
- if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1111,7 +1145,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Use H5Lcopy to create a group in the same location with a different name. */
- if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
@@ -1126,7 +1160,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Use H5Lcopy to copy to a different location with the same name. */
- if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
@@ -1141,7 +1175,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Copy the group while giving long paths. */
- if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1224,7 +1258,7 @@ test_move_preserves(hid_t fapl_id)
TESTING("moving and copying links preserves their properties");
/* Create file */
- h5_fixname(FILENAME[11], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
@@ -1233,11 +1267,11 @@ test_move_preserves(hid_t fapl_id)
if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR;
/* Create a group with that lcpl */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "group", group_id, lcpl_id) < 0) TEST_ERROR;
+ if(H5Llink(file_id, "group", group_id, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gclose(group_id) < 0) TEST_ERROR;
/* Get the group's link's creation time */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
old_create_time = linfo.ctime;
old_modification_time = statbuf.mtime;
@@ -1251,33 +1285,33 @@ test_move_preserves(hid_t fapl_id)
if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) <0) TEST_ERROR;
/* Get the group's link's creation time. The times should be unchanged */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Create a new link to the group. It should have a different creation time but the same modification time */
- if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group2", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group2", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time == linfo.ctime) TEST_ERROR;
/* Copy the first link to a UTF-8 name. Its creation time and modification time should not change. */
- if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id) <0) TEST_ERROR;
+ if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_copied", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_copied", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_copied", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the link with the default property list. */
- if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_copied2", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_copied2", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_copied2", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
@@ -1286,25 +1320,25 @@ test_move_preserves(hid_t fapl_id)
/* Check that the original link is unchanged */
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the first link to a UTF-8 name. Its creation time and modification time should not change. */
- if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_moved", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_moved", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_moved", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the link again using the default property list. */
- if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_moved_again", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
@@ -1357,7 +1391,7 @@ test_compat(hid_t fapl)
TESTING("backwards compatibility");
/* Create file */
- h5_fixname(FILENAME[15], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
@@ -1439,6 +1473,3222 @@ error:
/*-------------------------------------------------------------------------
+ * Function: external_link_root
+ *
+ * Purpose: Build a file with external link to root group in external file
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 25, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_root(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5G_stat_t sb; /* Object information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+ char *file; /* File from external link */
+ char *path; /* Path from external link */
+
+ TESTING("external link to root");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Check that external links are registered with the library */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+
+ /* Create file with link to first file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Check information for external link */
+ if (H5Gget_objinfo(fid, "ext_link", FALSE, &sb)<0) goto error;
+ if (H5G_UDLINK!=sb.type) {
+ H5_FAILED();
+ puts(" Unexpected object type - should have been an external link");
+ goto error;
+ }
+ if(H5Lget_linkval(fid, "ext_link", sizeof(objname), objname, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lunpack_elink_val(objname, &file, &path) < 0) TEST_ERROR
+ if(HDstrcmp(file, filename1))
+ {
+ H5_FAILED();
+ puts(" External link file name incorrect");
+ goto error;
+ }
+ if(HDstrcmp(path, "/"))
+ {
+ H5_FAILED();
+ puts(" External link path incorrect");
+ goto error;
+ }
+
+ /* Close and re-open file to ensure that data is written to disk */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((fid = H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Fclose (gid2);
+ H5Fclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_root() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_path
+ *
+ * Purpose: Build a file with external link to object down a path in the
+ * external file
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_path(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+
+ TESTING("external link to object on path");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create object down a path */
+ if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Create file with link to first file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/A/B/C", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_mult
+ *
+ * Purpose: Build a file with external link to object that crossed several
+ * external file links
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_mult(hid_t fapl)
+{
+ hid_t fid = (-1), fid2 = (-1); /* File IDs */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE],
+ filename3[NAME_BUF_SIZE],
+ filename4[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("external links across multiple files");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+ h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3);
+ h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4);
+
+ /* Create first file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create object down a path */
+ if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file to point to */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link down a path */
+ if((gid = H5Gcreate(fid, "D", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "D/E", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/A/B/C", gid, "F", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create third file to point to */
+ if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link down a path */
+ if((gid = H5Gcreate(fid, "G", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "G/H", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create external link to object in second file */
+ if(H5Lcreate_external(filename2, "/D/E/F", gid, "I", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Create file with link to third file */
+ if((fid=H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename3, "/G/H/I", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+
+ /* Open an object through external links */
+ if((fid = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) <0) TEST_ERROR
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR
+
+ /* The intermediate files should not stay open. Replace one of them with a new file. */
+ if((fid2=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+ if(H5Fclose(fid2)<0) TEST_ERROR
+
+ /* Open the other with write access and delete the external link in it */
+ if((fid2=H5Fopen(filename3, H5F_ACC_RDWR, fapl))<0) TEST_ERROR
+ if(H5Lunlink(fid2, "G/H/I", H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(H5Fclose(fid2)<0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_mult() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_self
+ *
+ * Purpose: Build a file with external link to itself
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Wednesday, July 12, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_GROUP_REVISION
+static int
+external_link_self(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t lcpl_id = (-1); /* Link Creation Property List ID */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+ char filename3[NAME_BUF_SIZE];
+
+ TESTING("external link to self");
+
+ /* Set up filename */
+ h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[2], fapl, filename2, sizeof filename1);
+ h5_fixname(FILENAME[3], fapl, filename3, sizeof filename1);
+
+ /* Create file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create an lcpl with intermediate group creation set */
+ if((lcpl_id=H5Pcreate(H5P_LINK_CREATE))<0) TEST_ERROR
+ if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR
+
+ /* Create a series of groups within the file: /A/B and /X/Y/Z */
+ if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Llink(fid, "A/B", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Llink(fid, "X/Y", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if(H5Pclose (lcpl_id) <0) TEST_ERROR
+
+ /* Create external link to own root group*/
+ if(H5Lcreate_external(filename1, "/X", fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "A/B/C/")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object through external link */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close created group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close object opened through external link */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Check on object created */
+ if((gid = H5Gopen(fid, "X/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/X/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Complicate things. Use this file as an intermediate file in a chain
+ * of external links that will go: file2 -> file1 -> file1 -> file3
+ */
+
+ /* Create file2 with an external link to file1 */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ if(H5Lcreate_external(filename1, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file2 */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create file3 as a target */
+ if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+ if((gid=H5Gcreate(fid, "end", 0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open file1 and create an extlink pointing to file3 */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if(H5Lcreate_external(filename3, "/", fid, "/X/Y/Z", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file1 */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+ /* Re-open file2 and traverse through file1 (with its recursive extlink) to file3 */
+ if((fid=H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if((gid=H5Gopen(fid, "ext_link/B/C/Y/Z/end")) < 0) TEST_ERROR
+
+ /* Create object through external link */
+ if((gid2 = H5Gcreate(gid, "newer_group", 0)) < 0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open up file3 and make sure the object was created successfully */
+ if((fid=H5Fopen(filename3, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if((gid=H5Gopen(fid, "end/newer_group")) < 0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Fclose (gid2);
+ H5Fclose (gid);
+ H5Pclose (lcpl_id);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_self() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_pingpong
+ *
+ * Purpose: Build a file with external link to object that goes back and
+ * force between two files a couple of times:
+ *
+ * file1:/link1 -> file2: /link2
+ * file2:/link2 -> file1: /link3
+ * file1:/link3 -> file2: /link4
+ * file2:/link4 -> file1: /link5
+ * file1:/link5 -> file2: /link6
+ * file2:/link6 -> file1: /final
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_pingpong(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("external links back and forth");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create final object */
+ if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/final", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "link1")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/final/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/final/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_pingpong() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_toomany
+ *
+ * Purpose: Build a file with too many external links to objects (i.e.
+ * more than H5G_NLINKS. Use a "back & forth" style of
+ * linking (like the "ping pong" test above) to minimize the
+ * number of files involved:
+ *
+ * file1:/link1 -> file2: /link2
+ * file2:/link2 -> file1: /link3
+ * file1:/link3 -> file2: /link4
+ * file2:/link4 -> file1: /link5
+ * file1:/link5 -> file2: /link6
+ * file2:/link6 -> file1: /link7
+ * file1:/link7 -> file2: /link8
+ * file2:/link8 -> file1: /link9
+ * file1:/link9 -> file2: /link10
+ * file2:/link10 -> file1: /link11
+ * file1:/link11 -> file2: /link12
+ * file2:/link12 -> file1: /link13
+ * file1:/link13 -> file2: /link14
+ * file2:/link14 -> file1: /link15
+ * file1:/link15 -> file2: /link16
+ * file2:/link16 -> file1: /link17
+ * file1:/link17 -> file2: /final
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 8, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_toomany(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("too many external links");
+
+ /* Make certain test is valid */
+ /* XXX: should probably make a "generic" test that creates the proper
+ * # of links based on this value - QAK
+ */
+ HDassert(H5G_NLINKS == 16);
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link8", fid, "link7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link10", fid, "link9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link12", fid, "link11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link14", fid, "link13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link16", fid, "link15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/final", fid, "link17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link7", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link9", fid, "link8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link11", fid, "link10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link13", fid, "link12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link15", fid, "link14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link17", fid, "link16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create final object */
+ if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "link1");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "link3")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_toomany() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_dangling
+ *
+ * Purpose: Build a file with "dangling" external links: with both
+ * missing files and missing objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 9, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_dangling(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("dangling external links");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create dangling external links */
+ if(H5Lcreate_external("missing", "/missing", fid, "no_file", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/missing", fid, "no_object", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file (for dangling object test) */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through dangling file external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "no_file");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through dangling object external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "no_object");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_dangling() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_recursive
+ *
+ * Purpose: Build a file with "recursive" external link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 15, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_recursive(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("recursive external links");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create recursive external links */
+ if(H5Lcreate_external(filename1, "/recursive", fid, "recursive", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR;
+
+ /* Open object through dangling file external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "recursive");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for recursive external links.");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_recursive() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_query
+ *
+ * Purpose: Query file & object names for external links, as well as
+ * information from H5Gget_obj_info
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 15, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_query(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char *file_name; /* Name of the file the external link points to */
+ char *object_name; /* Name of the object the external link points to */
+ H5G_stat_t sb; /* Object information */
+ H5L_linkinfo_t li; /* Link information */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE], /* Names of files to externally link across */
+ query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */
+
+
+ TESTING("query aspects of external link");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Get size of buffer for external link */
+ if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR
+ if (H5L_LINK_EXTERNAL != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been an external link");
+ goto error;
+ }
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file to point to */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR
+
+ /* Get size of buffer for external link */
+ if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR
+ if (H5L_LINK_EXTERNAL != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been an external link");
+ goto error;
+ }
+
+ /* Get information for external link. It should be two strings right after each other */
+ if(H5Lget_linkval(fid, "src", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Extract the file and object names from the buffer */
+ if(H5Lunpack_elink_val(query_buf, &file_name, &object_name) < 0) TEST_ERROR
+
+ /* Compare the file and object names */
+ if(strcmp(file_name, filename2)) TEST_ERROR;
+ if(strcmp(object_name, "/dst")) TEST_ERROR
+
+ /* Query information about object that external link points to */
+ if (H5Gget_objinfo(fid, "src", TRUE, &sb)<0) goto error;
+ if (H5G_GROUP != sb.type) {
+ H5_FAILED();
+ puts(" Unexpected object type - should have been a group");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Make sure that passing in NULLs to H5Lunpack_elink_val works */
+ if(H5Lunpack_elink_val(query_buf, NULL, NULL) < 0) TEST_ERROR
+
+ /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */
+ H5E_BEGIN_TRY {
+ if(H5Lunpack_elink_val(NULL, NULL, NULL) >= 0) TEST_ERROR
+ } H5E_END_TRY
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_unlink_compact
+ *
+ * Purpose: Remove an external link (from a compact group)
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_unlink_compact(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("unlinking external link in compact group");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Unlink external link */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Unlink external link */
+ if(H5Gunlink(fid, "src") < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group for external link */
+ if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_unlink_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_unlink_dense
+ *
+ * Purpose: Remove an external link (from a dense group)
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_GROUP_REVISION
+static int
+external_link_unlink_dense(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+ unsigned nmsgs; /* Number of messages in group's header */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking external link in dense group");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR
+
+ /* Create external link */
+ /* (This also covers the case of having an external link in a compact group that's converted to a dense group) */
+ if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != 1) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Create enough objects in the root group to change it into a "dense" group */
+ for(u = 0; u < max_compact; u++) {
+ sprintf(objname, "filler %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group creation property list */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Unlink external link */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Unlink external link */
+ if(H5Gunlink(fid, "src") < 0) TEST_ERROR
+
+ /* Remove enough objects in the root group to change it into a "compact" group */
+ for(u = 0; u < ((max_compact - min_dense) + 1); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != (min_dense - 1)) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group for external link (should be unaffected) */
+ if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_unlink_dense() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_move
+ *
+ * Purpose: Move/rename external link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 5, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_move(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("move external link");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Move external link to different name within same group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Move external link within same group */
+ if(H5Gmove(fid, "src", "src2") < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src2")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Move external link to different group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Create another group, to move the external link into */
+ if((gid = H5Gcreate(fid, "group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Move external link to different group */
+ if(H5Gmove2(fid, "src2", gid, "src3") < 0) TEST_ERROR
+
+ /* Close new group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Move external link back to original group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Move external link back to original location */
+ if(H5Gmove(fid, "/group2/src3", "/src") < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group3", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group3")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_move() */
+
+
+#ifdef H5_GROUP_REVISION
+/*-------------------------------------------------------------------------
+ * Function: external_link_ride
+ *
+ * Purpose: Let an external link "come along for the ride" when a group is
+ * converted between compact & dense forms.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_ride(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+ unsigned nmsgs; /* Number of messages in group's header */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ unsigned u; /* Local index variable */
+
+ TESTING("external link along for the ride");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR
+
+ /* Create enough objects in the root group to change it into a "dense" group */
+ for(u = 0; u < (max_compact + 1); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Create external link */
+ /* (This also covers the case of adding an external link to a dense group) */
+ if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group creation property list */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Remove enough objects to convert group containing external link back into compact form */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Remove enough objects in the root group to change it into a "compact" group */
+ for(u = 0; u < ((max_compact - min_dense) + 3); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != (min_dense - 1)) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(gcpl);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_ride() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ext_link_endian
+ *
+ * Purpose: Check that external links work properly when they are
+ * moved from big-endian to little-endian systems and
+ * vice versa.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+ext_link_endian(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t lapl_id = (-1); /* Prop List ID */
+ char * srcdir = getenv("srcdir"); /* The source directory */
+ char pathbuf[NAME_BUF_SIZE]; /* Path to the files */
+ char namebuf[NAME_BUF_SIZE];
+
+ TESTING("endianness of external links");
+
+ /*
+ * Create the name of the file to open (in case we are using the --srcdir
+ * option and the file is in a different directory from this test).
+ */
+ if (srcdir && ((HDstrlen(srcdir) + 2) < sizeof(pathbuf)) )
+ {
+ HDstrcpy(pathbuf, srcdir);
+ HDstrcat(pathbuf, "/");
+ }
+ else
+ HDstrcpy(pathbuf, "");
+
+ /* Create a link access property list with the path to the srcdir */
+ if((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ if(H5Pinsert(lapl_id, H5L_ELINK_PREFIX_PROP, strlen(pathbuf) + 1, pathbuf,
+ NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR;
+
+ if(HDstrlen(pathbuf) + HDstrlen(LE_FILENAME) >= sizeof(namebuf)) TEST_ERROR;
+
+ HDstrcpy(namebuf, pathbuf);
+ HDstrcat(namebuf, LE_FILENAME);
+
+ /* Test LE file; try to open a group through the external link */
+ if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+ if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR;
+
+ /* Open a group in the external file using that group ID */
+ if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR;
+
+ /* Close the IDs */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ if(HDstrlen(pathbuf) + HDstrlen(BE_FILENAME) >= sizeof(namebuf)) TEST_ERROR;
+
+ HDstrcpy(namebuf, pathbuf);
+ HDstrcat(namebuf, BE_FILENAME);
+
+ /* Test BE file; try to open a group through the external link */
+ if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+ if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR;
+
+ /* Open a group in the external file using that group ID */
+ if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR;
+
+ /* Close the IDs */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: ud_hard_links
+ *
+ * Purpose: Check that the functionality of hard links can be duplicated
+ * with user-defined links.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+/* Callback functions for UD hard links. */
+/* UD_hard_create increments the object's reference count */
+static herr_t UD_hard_create(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t UNUSED lcpl_id)
+{
+ haddr_t addr;
+ hid_t target_obj = -1;
+ herr_t ret_value = 0;
+
+ if(udata_size != sizeof(haddr_t))
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ addr = *((haddr_t *) udata);
+
+ /* Open the object this link points to */
+ target_obj= H5Oopen_by_addr(loc_group, addr);
+ if(target_obj < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ /* Increment the reference count of the target object */
+ if(H5Oincr_refcount(target_obj) < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+done:
+ /* Close the target object if we opened it */
+ if(target_obj >= 0)
+ {
+ switch(H5Iget_type(target_obj))
+ {
+ case H5I_GROUP:
+ if(H5Gclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATASET:
+ if(H5Dclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATATYPE:
+ if(H5Tclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ return ret_value;
+}
+
+/* UD_hard_delete decrements the object's reference count */
+static herr_t UD_hard_delete(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ haddr_t addr;
+ hid_t target_obj = -1;
+ herr_t ret_value = 0;
+
+ if(udata_size != sizeof(haddr_t))
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ addr = *((haddr_t *) udata);
+
+ /* Open the object this link points to */
+ target_obj= H5Oopen_by_addr(loc_group, addr);
+ if(target_obj < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ /* Decrement the reference count of the target object */
+ if(H5Odecr_refcount(target_obj) < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+done:
+ /* Close the target object if we opened it */
+ if(target_obj >= 0)
+ {
+ switch(H5Iget_type(target_obj))
+ {
+ case H5I_GROUP:
+ if(H5Gclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATASET:
+ if(H5Dclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATATYPE:
+ if(H5Tclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ return ret_value;
+}
+
+static hid_t UD_hard_traverse(const char UNUSED *link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t UNUSED lapl_id)
+{
+ haddr_t addr;
+ hid_t ret_value = -1;
+
+ if(udata_size != sizeof(haddr_t))
+ return -1;
+
+ addr = *((haddr_t *) udata);
+
+ ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */
+
+ return ret_value;
+}
+
+const H5L_link_class_t UD_hard_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_HARD_TYPE, /* Link type id number */
+ "UD_hard_link", /* Link class name for debugging */
+ UD_hard_create, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_hard_traverse, /* The actual traversal function */
+ UD_hard_delete, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_hard_links(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ h5_stat_size_t empty_size; /* Size of an empty file */
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("user-defined hard link");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Get the size of the empty file for reference */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR;
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that external links are registered and UD hard links are not */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Register "user-defined hard links" with the library */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are now registered */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Create a group for the UD hard link to point to */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+
+ /* Get address for the group to give to the hard link */
+ if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+
+ /* Create a user-defined "hard link" to the group using the address we got
+ * from H5Lget_linkinfo */
+ if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address), sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close and re-open file to ensure that data is written to disk */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+ /* Open group through UD link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in group */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups*/
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Re-open group without using ud link to check that it was created properly */
+ if((gid = H5Gopen(fid, "group/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/group/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Check that H5Gget_objinfo works on the hard link */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ /* UD hard links have no query function, thus return a "link length" of 0 */
+ if(li.u.link_size != 0) TEST_ERROR
+ if (UD_HARD_TYPE != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been a UD hard link");
+ goto error;
+ }
+
+ /* Unlink the group pointed to by the UD link. It shouldn't be
+ * deleted because of the UD link. */
+ if(H5Gunlink(fid, "/group") < 0) TEST_ERROR;
+
+ /* Ensure we can open the group through the UD link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Unlink the group contained within it. */
+ if(H5Gunlink(gid, "new_group") < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now delete the UD link. This should cause the group to be
+ * deleted, too. */
+ if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* The file should be empty again. */
+ if(empty_size!=h5_get_file_size(filename)) TEST_ERROR;
+
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_hard_links() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ext_link_endian
+ *
+ * Purpose: Check that user defined link types can be unregistered and
+ * reregistered properly.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+ /* A traversal function that ignores any udata and simply opens an object
+ * in the current group named REREG_TARGET_NAME
+ */
+static hid_t UD_rereg_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t UNUSED udata_size, hid_t lapl_id)
+{
+ hid_t ret_value;
+
+ if((ret_value = H5Oopen(cur_group, REREG_TARGET_NAME, lapl_id)) < 0) TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+
+/* This link class has the same ID number as the UD hard links but
+ * has a very different traversal function */
+const H5L_link_class_t UD_rereg_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_HARD_TYPE, /* Link type id number */
+ "UD_reregistered_type", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_rereg_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_link_reregister(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename[NAME_BUF_SIZE];
+ h5_stat_size_t empty_size; /* Size of an empty file */
+
+ TESTING("registering a new class for existing UD links");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Get the size of the empty file for reference */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR;
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that UD hard links are not registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Register "user-defined hard links" with the library */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Point a UD defined hard link to a group in the same way as the previous test */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+ if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address),
+ sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR;
+
+ /* Create a group named REREG_TARGET_NAME in the same group as the ud link */
+ if((gid = H5Gcreate(fid, REREG_TARGET_NAME, 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now unregister UD hard links */
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are no longer registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Verify that we can't traverse the ud link anymore */
+ H5E_BEGIN_TRY {
+ if((gid = H5Gopen(fid, "ud_link")) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Verify that we can't create any new links of this type */
+ H5E_BEGIN_TRY {
+ if(H5Lcreate_ud(fid, "ud_link2", UD_HARD_TYPE, &(li.u.address),
+ sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0)
+ TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register a new kind of link with the same ID number */
+ if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are registered again */
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Open a group through the ud link (now a different class of link).
+ * It should be a different group
+ * than the UD hard link pointed to */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in group */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups*/
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Re-open group without using ud link to check that it was created properly */
+ if((gid = H5Gopen(fid, "rereg_target/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/rereg_target/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Unlink the group pointed to by the UD hard link. It shouldn't be
+ * deleted because the UD link incremented its reference count. */
+ if(H5Gunlink(fid, "/group") < 0) TEST_ERROR;
+
+ /* What a mess! Re-register user-defined links to clean up the
+ * reference counts. We shouldn't actually need to unregister the
+ * other link type */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Ensure we can open the group through the UD link (now that UD hard
+ * links have been registered) */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Delete the UD hard link. This should cause the group to be
+ * deleted, too. */
+ if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR;
+
+ /* Unlink the other two groups so that we can make sure the file is empty */
+ if(H5Gunlink(fid, "/rereg_target/new_group")<0) TEST_ERROR;
+ if(H5Gunlink(fid, REREG_TARGET_NAME)<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* The file should be empty again. */
+ if(empty_size!=h5_get_file_size(filename)) TEST_ERROR;
+
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_link_reregister() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ud_callbacks
+ *
+ * Purpose: Check that all callbacks are called and are given the correct
+ * information.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+/* Callback functions for UD "callback" links. */
+/* Creation callback. Called during move as well. */
+herr_t UD_cb_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id)
+{
+ if(!link_name) TEST_ERROR;
+ if(loc_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+ if(lcpl_id < 0) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+static hid_t UD_cb_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ const char *target = (char *) udata;
+ hid_t ret_value;
+
+ if(!link_name) TEST_ERROR;
+ if(cur_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
+ TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+/* Callback for when the link is moved or renamed */
+herr_t UD_cb_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ const char *target = (char *) udata;
+
+ if(!new_name) TEST_ERROR;
+ if(new_loc < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cb_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ if(!link_name) TEST_ERROR;
+ if(loc_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cb_query(const char * link_name, void * udata, size_t udata_size, void* buf, size_t buf_size)
+{
+ if(!link_name) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ if(buf)
+ {
+ if(buf_size < 16) TEST_ERROR;
+ strcpy(buf, "query succeeded");
+ }
+
+ /* There are 15 characters and a NULL in "query succeeded" */
+ return 16;
+
+error:
+ return -1;
+}
+
+const H5L_link_class_t UD_cb_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CB_TYPE, /* Link type id number */
+ NULL, /* NULL name (to make sure this doesn't break anything */
+ UD_cb_create, /* Creation callback */
+ UD_cb_move, /* Move/rename callback */
+ UD_cb_move, /* Copy callback */
+ UD_cb_traverse, /* The actual traversal function */
+ UD_cb_delete, /* Deletion callback */
+ UD_cb_query /* Query callback */
+}};
+
+static int
+ud_callbacks(fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t lcpl = (-1); /* Link Creation PL */
+ H5G_stat_t sb; /* Object information */
+ H5L_linkinfo_t li; /* Link information */
+ char ud_target_name[] = UD_CB_TARGET; /* Link target name */
+ char filename[NAME_BUF_SIZE];
+ char query_buf[NAME_BUF_SIZE];
+
+ TESTING("user-defined link callbacks");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that registered link classes are, and unregistered ones aren't */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+ if(H5Lis_registered(UD_CB_TYPE) != 0) TEST_ERROR
+
+ /* Hit two birds with one stone: register UD hard links from previous
+ * test to check that having two UD links registered at once presents
+ * no problems. */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Register user-defined link class. This is the one we'll actually
+ * be using. */
+ if(H5Lregister(UD_cb_class) < 0) TEST_ERROR;
+
+ /* Check that registered link classes are, and unregistered ones aren't */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_CB_TYPE) != TRUE) TEST_ERROR
+
+ /* Create a group for the UD link to point to */
+ if((gid = H5Gcreate(fid, UD_CB_TARGET, 0)) <0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. These UD links behave like soft links. */
+ if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Try opening group through UD link */
+ if((gid = H5Gopen(fid, UD_CB_LINK_NAME)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Query the link to test its query callback */
+ if (H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT)<0) TEST_ERROR;
+ if(li.u.link_size != 16) TEST_ERROR;
+ if (UD_CB_TYPE != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been a UD hard link");
+ goto error;
+ }
+
+ /* Fill the query buffer */
+ if(H5Gget_linkval(fid, UD_CB_LINK_NAME, NAME_BUF_SIZE, query_buf) < 0) TEST_ERROR;
+ if(strcmp(query_buf, "query succeeded") != 0) TEST_ERROR;
+
+ /* Move the link */
+ if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR;
+
+ /* Re-open group to ensure that move worked */
+ if((gid = H5Gopen(fid, NEW_UD_CB_LINK_NAME)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Remove UD link */
+ if(H5Gunlink(fid, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR;
+
+
+ /* Test that the callbacks don't work if the link class is not registered */
+
+ /* Create a new link. Just for fun, give it a non-default character
+ * encoding (to test that LAPLs work) */
+ if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
+#ifdef H5_GROUP_REVISION
+ if(H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) TEST_ERROR
+#endif /* H5_GROUP_REVISION */
+ if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, lcpl, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Pclose(lcpl)<0) TEST_ERROR
+
+ /* Check its character encoding */
+#ifdef H5_GROUP_REVISION
+ if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.cset != H5T_CSET_UTF8) TEST_ERROR;
+#endif /* H5_GROUP_REVISION */
+
+ /* Unregister the link class so the library forgets what its callbacks do */
+ if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR;
+
+ /* Now test that each of the callbacks fails */
+ H5E_BEGIN_TRY {
+ if(H5Lcreate_ud(fid, NEW_UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ if((gid = H5Gopen(gid, UD_CB_LINK_NAME)) >= 0) TEST_ERROR;
+ if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* The query callback should NOT fail, but should be unable to give a linklen */
+ if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 0) TEST_ERROR;
+ if(li.linkclass != UD_CB_TYPE) TEST_ERROR;
+ if(H5Gget_objinfo(fid, UD_CB_LINK_NAME, FALSE, &sb) <0) TEST_ERROR;
+ if(sb.type != H5G_UDLINK) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose (lcpl);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_callbacks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: lapl_udata
+ *
+ * Purpose: Check that information can be passed to UD links using the
+ * Link Access Property List.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+UD_plist_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t udata_size, hid_t lapl_id)
+{
+ char target[NAME_BUF_SIZE];
+ hid_t ret_value;
+
+ if(udata_size != 0) TEST_ERROR;
+
+ /* Get the name of the target from the property list. */
+ if(H5Pget(lapl_id, DEST_PROP_NAME, target) < 0) TEST_ERROR;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
+ TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+const H5L_link_class_t UD_plist_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_PLIST_TYPE, /* Link type id number */
+ "UD_plist_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_plist_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+lapl_udata(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t plist_id = (-1); /* Property List ID */
+ char group_a_name[NAME_BUF_SIZE];
+ char group_b_name[NAME_BUF_SIZE];
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("user data passed through lapl");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Register UD link types from previous tests to check that having
+ * multiple types registered at once presents no problems. */
+ if(H5Lregister(UD_cb_class) < 0) TEST_ERROR;
+
+ /* Register the link class. We'll actually be using for this test. */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+
+ /* Another link class from a previous test */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Unregister the first link type registered to make sure this doesn't
+ * break anything. */
+ if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR;
+
+ /* Create two groups for the UD link to point to */
+ if((gid = H5Gcreate(fid, "group_a", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if((gid = H5Gcreate(fid, "group_b", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. These UD links have no udata. */
+ if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create a non-default lapl with a new property pointing to group a*/
+ if((plist_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ strcpy(group_a_name, "group_a");
+ if(H5Pinsert(plist_id, DEST_PROP_NAME, NAME_BUF_SIZE, group_a_name, NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR;
+
+ /* Try opening group through UD link */
+ if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR;
+ if((gid2 = H5Gcreate(gid, "subgroup_a", 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Verify that we can open the new group without using the ud link */
+ if((gid2 = H5Gopen(fid, "/group_a/subgroup_a")) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Now use the same ud link to access group_b */
+ strcpy(group_b_name, "group_b");
+ if(H5Pset(plist_id, DEST_PROP_NAME, group_b_name)<0) TEST_ERROR;
+
+ /* Create a subgroup */
+ if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR;
+ if((gid2 = H5Gcreate(gid, "subgroup_b", 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Verify that we can open the new group without using the ud link */
+ if((gid2 = H5Gopen(fid, "/group_b/subgroup_b")) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Close property list */
+ if(H5Pclose(plist_id) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose (plist_id);
+ H5Gclose (gid);
+ H5Gclose (gid2);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end lapl_udata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ud_link_errors
+ *
+ * Purpose: Create error conditions in callbacks and ensure that the
+ * errors propagate correctly.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t UD_cbsucc_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id)
+{
+ /* Check to make sure that this "soft link" has a target */
+ if(udata_size < 1 || !udata)
+ return -1;
+
+ return 0;
+}
+static hid_t UD_cbsucc_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ const char *target = (char *) udata;
+ hid_t ret_value;
+
+ if(!target) goto error;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) goto error;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+/* Failure callback for when the link is moved or renamed */
+herr_t UD_cbfail_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ /* This traversal function will always fail. */
+ return -1;
+}
+/* SuccessCallback for when the link is moved or renamed */
+herr_t UD_cbsucc_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ /* This traversal function will always succeed. */
+ return 0;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cbsucc_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ /* This callback will always succeed */
+ return 0;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cbfail_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ /* This traversal function will always fail. */
+ /* Note: un-deletable links are in general a very bad idea! */
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbfail_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will always fail. */
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbfail_on_write_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will return a buffer size,
+ * but will fail when a buffer is passed in ("writing to the buffer"
+ * fails
+ */
+
+ if(buf != NULL)
+ return -1;
+
+ return 0;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbsucc_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will return a buffer size,
+ * but will fail when a buffer is passed in ("writing to the buffer"
+ * fails
+ */
+
+ if(buf != NULL && buf_size >= 8)
+ strcpy(buf, "succeed");
+
+ return 8;
+}
+
+/* This class is full of failing callbacks */
+const H5L_link_class_t UD_cbfail_class1[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link1", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbfail_move, /* Move/rename callback */
+ UD_cbfail_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbfail_delete, /* Deletion callback */
+ UD_cbfail_query /* Query callback */
+}};
+
+/* This class is has two failing callbacks, move and query */
+const H5L_link_class_t UD_cbfail_class2[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link2", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbfail_move, /* Move/rename callback */
+ UD_cbsucc_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbsucc_delete, /* Deletion callback */
+ UD_cbfail_on_write_query /* Query callback */
+}};
+
+/* All of these callbacks will succeed */
+const H5L_link_class_t UD_cbfail_class3[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link3", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbsucc_move, /* Move/rename callback */
+ UD_cbsucc_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbsucc_delete, /* Deletion callback */
+ UD_cbsucc_query /* Query callback */
+}};
+
+/* Link classes that are invalid for various reasons */
+const H5L_link_class_t UD_error1_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_ERROR_TYPE, /* Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ NULL, /* This class has no traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error2_class[1] = {{
+ UD_BAD_VERS, /* Invalid H5L_link_class_t version */
+ UD_ERROR_TYPE, /* Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error3_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_BAD_TYPE1, /* Invalid Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error4_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_BAD_TYPE2, /* Invalid Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_link_errors(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char group_name[NAME_BUF_SIZE];
+ char filename[NAME_BUF_SIZE];
+ char query_buf[NAME_BUF_SIZE];
+ H5L_linkinfo_t li; /* Link information */
+
+ TESTING("user-defined link error conditions");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Try to register some invalid link classes */
+ H5E_BEGIN_TRY {
+ if(H5Lregister(UD_error1_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error2_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error3_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error4_class) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register the UD plist class. */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+ /* Now register the first class we'll be using.
+ * It has the same ID as the plist class, and should replace it. */
+ if(H5Lregister(UD_cbfail_class1) < 0) TEST_ERROR;
+
+ /* Create a group for the UD link to point to */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. */
+ strcpy(group_name, "/group");
+ if(H5Lcreate_ud(fid, "/ud_link", UD_CBFAIL_TYPE, &group_name, strlen(group_name) + 1, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open the group through the ud link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now test that each of the callbacks will cause a failure if it returns -1 */
+ H5E_BEGIN_TRY {
+ /* The create callback will fail if we pass in no udata */
+ if(H5Lcreate_ud(fid, "fail", UD_CBFAIL_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ /* The move and copy callbacks will fail */
+ if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR;
+ if(H5Lcopy(fid, "ud_link", fid, "copy_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ /* The traversal callback will fail if we remove its target */
+ if(H5Gunlink(fid, "group") < 0) TEST_ERROR;
+ if((gid = H5Gopen(gid, "ud_link")) >= 0) TEST_ERROR;
+ /* The deletion callback will always fail */
+ if(H5Gunlink(fid, "ud_link") >= 0) TEST_ERROR;
+ /* The query callback will fail */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Now use a class with different callback functions */
+ if(H5Lregister(UD_cbfail_class2) < 0) TEST_ERROR;
+
+ /* Moving should still fail, but copying will succeed */
+ H5E_BEGIN_TRY {
+ if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR
+ } H5E_END_TRY
+ if(H5Lcopy(fid, "ud_link", fid, "copy_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* The query callback will succeed when we only want to get the size of the buffer... */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 0) TEST_ERROR;
+ /* ...but fail when we try to write data to the buffer itself*/
+ H5E_BEGIN_TRY {
+ if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) >=0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register a new class */
+ if(H5Lregister(UD_cbfail_class3) < 0) TEST_ERROR;
+
+ /* Now querying should succeed */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 8) TEST_ERROR;
+ if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) <0) TEST_ERROR;
+ if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR;
+
+ /* Moving and copying should both succeed */
+ if(H5Gmove(fid, "copy_succ", "move_succ") < 0) TEST_ERROR
+ if(H5Lcopy(fid, "ud_link", fid, "copy_succ2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Delete link (this callback should work now) */
+ if(H5Gunlink(fid, "ud_link") <0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: lapl_nlinks
+ *
+ * Purpose: Check that the maximum number of soft links can be adjusted
+ * by the user using the Link Access Property List.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+lapl_nlinks(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t plist = (-1); /* lapl ID */
+ hid_t tid = (-1), sid = (-1), did = (-1); /* Other IDs */
+ hid_t gapl = (-1), dapl = (-1), tapl = (-1); /* Other property lists */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename[NAME_BUF_SIZE];
+ size_t nlinks; /* nlinks for H5Pset_nlinks */
+ hsize_t dims[2];
+
+ TESTING("adjusting nlinks with LAPL");
+
+ /* Make certain test is valid */
+ /* XXX: should probably make a "generic" test that creates the proper
+ * # of links based on this value - QAK
+ */
+ HDassert(H5G_NLINKS == 16);
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create group with short name in file (used as target for links) */
+ if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR;
+
+ /* Create chain of soft links to existing object (limited) */
+ if(H5Glink2(fid, "final", H5G_LINK_SOFT, fid, "soft1") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft1", H5G_LINK_SOFT, fid, "soft2") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft2", H5G_LINK_SOFT, fid, "soft3") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft3", H5G_LINK_SOFT, fid, "soft4") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft4", H5G_LINK_SOFT, fid, "soft5") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft5", H5G_LINK_SOFT, fid, "soft6") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft6", H5G_LINK_SOFT, fid, "soft7") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft7", H5G_LINK_SOFT, fid, "soft8") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft8", H5G_LINK_SOFT, fid, "soft9") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft9", H5G_LINK_SOFT, fid, "soft10") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft10", H5G_LINK_SOFT, fid, "soft11") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft11", H5G_LINK_SOFT, fid, "soft12") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft12", H5G_LINK_SOFT, fid, "soft13") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft13", H5G_LINK_SOFT, fid, "soft14") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft14", H5G_LINK_SOFT, fid, "soft15") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft15", H5G_LINK_SOFT, fid, "soft16") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft16", H5G_LINK_SOFT, fid, "soft17") < 0) TEST_ERROR;
+
+ /* Close objects */
+ if(H5Gclose(gid)<0) TEST_ERROR;
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Open file */
+ if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Create LAPL with higher-than-usual nlinks value */
+ /* Create a non-default lapl with udata set to point to the first group */
+ if((plist = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ nlinks = 20;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Ensure that nlinks was set successfully */
+ nlinks = 0;
+ if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR
+ if(nlinks != 20) TEST_ERROR
+
+ /* Open object through what is normally too many soft links using
+ * new property list */
+ if((gid = H5Oopen(fid, "soft17", plist)) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/soft17")) TEST_ERROR
+
+ /* Create group using soft link */
+ if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Set nlinks to a smaller number */
+ nlinks = 4;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Ensure that nlinks was set successfully */
+ nlinks = 0;
+ if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR;
+ if(nlinks != 4) TEST_ERROR;
+
+ /* Try opening through what is now too many soft links */
+ H5E_BEGIN_TRY {
+ gid = H5Oopen(fid, "soft5", plist);
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through lesser soft link */
+ if((gid = H5Oopen(fid, "soft4", plist)) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/soft4")) TEST_ERROR
+
+
+ /* Test other functions that should use a LAPL */
+ nlinks = 20;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Try copying and moving when both src and dst cotain many soft links
+ * using a non-default LAPL
+ */
+ if(H5Lcopy(fid, "soft17", fid, "soft17/newer_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR
+ if(H5Lmove(fid, "soft17/newer_soft", fid, "soft17/newest_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Llink */
+ if(H5Llink(fid, "soft17/link_to_group", gid, H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Lcreate_hard and H5Lcreate_soft */
+ if(H5Lcreate_hard(fid, "soft17", fid, "soft17/link2_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR
+ if(H5Lcreate_soft("/soft4", fid, "soft17/soft_link", H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Lunlink */
+ if(H5Lunlink(fid, "soft17/soft_link", plist) < 0) TEST_ERROR
+
+ /* H5Lget_linkval and H5Lget_linkinfo */
+ if(H5Lget_linkval(fid, "soft17", 0, NULL, plist) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(fid, "soft17", NULL, plist) < 0) TEST_ERROR
+
+ /* H5Lcreate_external and H5Lcreate_ud */
+ if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) <0) TEST_ERROR
+ if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR
+ if(H5Lcreate_ud(fid, "soft17/udlink", UD_HARD_TYPE, NULL, 0, H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* Close plist */
+ if(H5Pclose(plist) < 0) TEST_ERROR;
+
+
+ /* Create a datatype and dataset as targets inside the group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit(gid, "datatype", tid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ dims[0] = 2;
+ dims[1] = 2;
+ if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
+ if((did = H5Dcreate(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR;
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Try to open the objects using too many symlinks with default *APLs */
+ H5E_BEGIN_TRY {
+ if((gid = H5Gopen_expand(fid, "soft17", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ if((tid = H5Topen_expand(fid, "soft17/datatype", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ if((did = H5Dopen_expand(fid, "soft17/dataset", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ } H5E_END_TRY
+
+ /* Create property lists with nlinks set */
+ if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
+ if((tapl = H5Pcreate(H5P_DATATYPE_ACCESS)) < 0) TEST_ERROR
+ if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR
+
+ nlinks = 20;
+ if(H5Pset_nlinks(gapl, nlinks) < 0) TEST_ERROR
+ if(H5Pset_nlinks(tapl, nlinks) < 0) TEST_ERROR
+ if(H5Pset_nlinks(dapl, nlinks) < 0) TEST_ERROR
+
+ /* We should now be able to use these property lists to open each kind
+ * of object.
+ */
+ if((gid = H5Gopen_expand(fid, "soft17", gapl)) <0) TEST_ERROR
+ if((tid = H5Topen_expand(fid, "soft17/datatype", tapl)) <0) TEST_ERROR
+ if((did = H5Dopen_expand(fid, "soft17/dataset", dapl)) <0) TEST_ERROR
+
+ /* Close objects */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close plists */
+ if(H5Pclose(gapl) < 0) TEST_ERROR;
+ if(H5Pclose(tapl) < 0) TEST_ERROR;
+ if(H5Pclose(dapl) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose(gapl);
+ H5Pclose(dapl);
+ H5Pclose(tapl);
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Tclose(tid);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Pclose(plist);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end lapl_nlinks() */
+
+/*-------------------------------------------------------------------------
+ * Function: objinfo_linkclass
+ *
+ * Purpose: Check that the link class is returned correctly when queried.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+linkinfo(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t tid = (-1); /* Type ID */
+ hid_t sid = (-1), did = -(1); /* Dataspace and dataset IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("linkclass field in H5Gget_objinfo");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Register a couple of user-defined link classes with the library */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+
+ /* Create an object of each type */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
+ if(H5Tcommit(fid, "datatype", tid) < 0) TEST_ERROR;
+ if((gid = H5Gcreate(fid, "group", 0)) < 0) TEST_ERROR;
+ if(H5Glink(fid, H5G_LINK_SOFT, "group", "softlink") < 0) TEST_ERROR;
+
+ if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR;
+ if((did = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+ if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external("file_name", "obj_path", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close all objects */
+ if(H5Tclose(tid) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Dclose(did) < 0) TEST_ERROR;
+
+ /* Make sure that linkclass is correct when objects are queried */
+ if(H5Lget_linkinfo(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+
+ if(H5Lget_linkinfo(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_EXTERNAL) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5G_LINK_SOFT) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != UD_PLIST_TYPE) TEST_ERROR;
+
+ /* Ensure that passing a NULL pointer doesn't cause an error */
+ if(H5Lget_linkinfo(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Tclose (tid);
+ H5Dclose (did);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_hard_links() */
+
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test links
@@ -1467,7 +4717,6 @@ main(void)
if (HDstrcmp(envval, "core") && HDstrcmp(envval, "split")) {
h5_reset();
fapl = h5_fileaccess();
-
/* The tests... */
nerrors += mklinks(fapl) < 0 ? 1 : 0;
nerrors += cklinks(fapl) < 0 ? 1 : 0;
@@ -1488,6 +4737,39 @@ main(void)
#endif
nerrors += test_compat(fapl);
+ nerrors += external_link_root(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_path(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_mult(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_self(fapl) < 0 ? 1 : 0;
+#endif
+ nerrors += external_link_pingpong(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_toomany(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_dangling(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_recursive(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_query(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_unlink_compact(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_unlink_dense(fapl) < 0 ? 1 : 0;
+#endif /* H5_GROUP_REVISION */
+ nerrors += external_link_move(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_ride(fapl) < 0 ? 1 : 0;
+#endif /* H5_GROUP_REVISION */
+ nerrors += ext_link_endian(fapl) < 0 ? 1 : 0;
+
+ /* These tests assume that external links are a form of UD links,
+ * so assume that everything that passed for external links
+ * above has already been tested for UD links.
+ */
+ nerrors += ud_hard_links(fapl) < 0 ? 1 : 0;
+ nerrors += ud_link_reregister(fapl) < 0 ? 1 : 0;
+ nerrors += ud_callbacks(fapl) < 0 ? 1 : 0;
+ nerrors += ud_link_errors(fapl) < 0 ? 1 : 0;
+ nerrors += lapl_udata(fapl) < 0 ? 1 : 0;
+ nerrors += lapl_nlinks(fapl) < 0 ? 1 : 0;
+ nerrors += linkinfo(fapl) < 0 ? 1 : 0;
+
/* Results */
if (nerrors) {
printf("***** %d LINK TEST%s FAILED! *****\n",
@@ -1505,3 +4787,4 @@ main(void)
}
+
diff --git a/test/mount.c b/test/mount.c
index 8e5a903..cfd99dc 100644
--- a/test/mount.c
+++ b/test/mount.c
@@ -71,8 +71,8 @@ setup(hid_t fapl)
if (H5Gclose(H5Gcreate(file, "/mnt1/file1", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_unlink", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_move_a", (size_t)0))<0) goto error;
- if (H5Glink(file, H5G_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error;
- if (H5Glink(file, H5G_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error;
+ if (H5Glink(file, H5L_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error;
+ if (H5Glink(file, H5L_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error;
if (H5Fclose(file)<0) goto error;
/* file 2 */
@@ -486,9 +486,9 @@ test_move(hid_t fapl)
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
/* First rename an object in the mounted file, then try it across files */
- if (H5Gmove(file1, "/mnt1/rename_a/x", "/mnt1/rename_b/y")<0) goto error;
+ if (H5Lmove(file1, "/mnt1/rename_a/x", H5L_SAME_LOC, "/mnt1/rename_b/y", H5P_DEFAULT, H5P_DEFAULT)<0) goto error;
H5E_BEGIN_TRY {
- status = H5Gmove(file1, "/mnt1/rename_b/y", "/y");
+ status = H5Lmove(file1, "/mnt1/rename_b/y", H5L_SAME_LOC, "/y", H5P_DEFAULT, H5P_DEFAULT);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -796,7 +796,7 @@ test_mvmpt(hid_t fapl)
if (H5Fmount(file1, "/mnt_move_a", file2, H5P_DEFAULT)<0) TEST_ERROR
/* Rename the mount point */
- if (H5Gmove(file1, "/mnt_move_a", "/mnt_move_b")<0) TEST_ERROR
+ if (H5Lmove(file1, "/mnt_move_a", H5L_SAME_LOC, "/mnt_move_b", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR
/* Access something under the new name */
if (H5Gget_objinfo(file1, "/mnt_move_b/file2", TRUE, NULL)<0) TEST_ERROR
@@ -854,7 +854,7 @@ test_interlink(hid_t fapl)
/* Try an interfile hard link directly */
H5E_BEGIN_TRY {
- status = H5Glink(file1, H5G_LINK_HARD, "/mnt1/file2", "/file2");
+ status = H5Glink(file1, H5L_LINK_HARD, "/mnt1/file2", "/file2");
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -864,7 +864,7 @@ test_interlink(hid_t fapl)
/* Try an interfile hard link by renaming something */
H5E_BEGIN_TRY {
- status = H5Gmove(file1, "/mnt1/file2", "/file2");
+ status = H5Lmove(file1, "/mnt1/file2", H5L_SAME_LOC, "/file2", H5P_DEFAULT, H5P_DEFAULT);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -1108,9 +1108,9 @@ test_mount_after_close(hid_t fapl)
TEST_ERROR
if((gidABM = H5Gcreate(gidAB , "M", (size_t)0)) < 0) /* Mount point */
TEST_ERROR
- if(H5Glink(gidAB, H5G_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */
+ if(H5Glink(gidAB, H5L_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */
TEST_ERROR
- if(H5Glink(gidAB, H5G_LINK_SOFT, "/A", "T") < 0) /* Soft link */
+ if(H5Glink(gidAB, H5L_LINK_SOFT, "/A", "T") < 0) /* Soft link */
TEST_ERROR
/* Close groups and file */
@@ -1144,7 +1144,7 @@ test_mount_after_close(hid_t fapl)
TEST_ERROR
if((did = H5Dcreate(gidXY, "D", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0)
TEST_ERROR
- if(H5Glink(gidX, H5G_LINK_SOFT, "./Y", "T") < 0) /* Soft link */
+ if(H5Glink(gidX, H5L_LINK_SOFT, "./Y", "T") < 0) /* Soft link */
TEST_ERROR
/* Write data to the dataset. */
@@ -1450,7 +1450,7 @@ test_mount_after_unmount(hid_t fapl)
/* Rename object in file #3 that is "disconnected" from name hiearchy */
/* (It is "disconnected" because it's parent file has been unmounted) */
- if(H5Gmove2(gidAMX,"M/Y",gidAMX,"M/Z") < 0)
+ if(H5Lmove(gidAMX,"M/Y",gidAMX,"M/Z", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR
/* Close group in file #3 */
@@ -3686,7 +3686,7 @@ test_symlink(hid_t fapl)
TEST_ERROR
/* Create soft link to mounted object */
- if(H5Glink(fid1, H5G_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */
+ if(H5Glink(fid1, H5L_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */
TEST_ERROR
if(H5Fclose(fid1) < 0)
diff --git a/test/objcopy.c b/test/objcopy.c
index a96d5b0..7efef50 100755
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -25,6 +25,7 @@
const char *FILENAME[] = {
"objcopy_src",
"objcopy_dst",
+ "objcopy_ext",
NULL
};
@@ -63,6 +64,7 @@ const char *FILENAME[] = {
#define NAME_LINK_HARD "/g_links/hard_link_to_dataset_simple"
#define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple"
#define NAME_LINK_SOFT2 "/g_links2/soft_link_to_dataset_simple"
+#define NAME_LINK_EXTERN "/g_links/external_link_to_dataset_simple"
#define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere"
#define NAME_LINK_SOFT_DANGLE2 "/g_links2/soft_link_to_nowhere"
@@ -817,6 +819,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
H5G_obj_t objtype2; /* Type of object in group */
H5G_stat_t objstat; /* Object info */
H5G_stat_t objstat2; /* Object info */
+ H5L_linkinfo_t linfo; /* Link information */
+ H5L_linkinfo_t linfo2; /* Link information */
hid_t oid, oid2; /* IDs of objects within group */
/* Loop over contents of groups */
@@ -835,12 +839,16 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
if(H5Gget_objinfo(gid, objname, FALSE, &objstat) < 0) TEST_ERROR;
if(H5Gget_objinfo(gid2, objname2, FALSE, &objstat2) < 0) TEST_ERROR;
if(objstat.type != objstat2.type) TEST_ERROR;
- if(objstat.type != H5G_LINK) {
+ if(objstat.type != H5G_LINK && objstat.type != H5G_UDLINK) {
if(objstat.nlink != objstat2.nlink) TEST_ERROR;
if(objstat.ohdr.nmesgs != objstat2.ohdr.nmesgs) TEST_ERROR;
if(objstat.ohdr.nchunks != objstat2.ohdr.nchunks) TEST_ERROR;
} /* end if */
+ /* Get link info */
+ if(H5Lget_linkinfo(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR;
+
/* Check for object already having been compared */
if(addr_lookup(&objstat))
continue;
@@ -855,8 +863,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
char linkname2[NAME_BUF_SIZE]; /* Link value */
/* Check link values */
- if(H5Gget_linkval(gid, objname, NAME_BUF_SIZE, linkname) < 0) TEST_ERROR;
- if(H5Gget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2, H5P_DEFAULT) < 0) TEST_ERROR;
if(HDstrcmp(linkname, linkname2)) TEST_ERROR;
}
break;
@@ -900,6 +908,24 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
if(H5Tclose(oid2) < 0) TEST_ERROR;
break;
+ case H5G_UDLINK:
+ {
+ char linkval[NAME_BUF_SIZE]; /* Link value */
+ char linkval2[NAME_BUF_SIZE]; /* Link value */
+
+ /* Check that both links are the same type and the same size */
+ if(linfo.linkclass != linfo2.linkclass) TEST_ERROR;
+ if(linfo.u.link_size != linfo2.u.link_size) TEST_ERROR;
+
+ /* Get link udata */
+ if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkval, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkval2, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Compare link udata */
+ if(HDmemcmp(linkval, linkval2, objstat.linklen)) TEST_ERROR;
+ }
+ break;
+
default:
HDassert(0 && "Unknown type of object");
break;
@@ -4102,7 +4128,7 @@ test_copy_group_loop(hid_t fapl)
if ( (gid_sub2 = H5Gcreate(gid, NAME_GROUP_SUB_SUB, (size_t)0)) < 0) TEST_ERROR;
/* Create link to top group */
- if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
+ if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
/* close sub sub group */
if( H5Gclose(gid_sub2) < 0) TEST_ERROR;
@@ -4223,13 +4249,13 @@ test_copy_group_wide_loop(hid_t fapl)
if ( (gid_sub2 = H5Gcreate(gid_sub, objname, (size_t)0)) < 0) TEST_ERROR;
/* Create link to top group */
- if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
+ if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
/* Create link to sub-group */
- if ( H5Glink2(gid_sub, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR;
+ if ( H5Glink2(gid_sub, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR;
/* Create link to self :-) */
- if ( H5Glink2(gid_sub2, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR;
+ if ( H5Glink2(gid_sub2, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR;
/* close sub sub group */
if( H5Gclose(gid_sub2) < 0) TEST_ERROR;
@@ -4364,13 +4390,16 @@ test_copy_group_links(hid_t fapl)
if (H5Dclose(did) < 0) TEST_ERROR;
/* make a hard link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR;
/* make a soft link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
/* make a soft link to nowhere */
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+
+ /* make a dangling external link */
+ if (H5Lcreate_external("filename", "obj_name", fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* close the group */
if ( H5Gclose(gid) < 0) TEST_ERROR;
@@ -4496,7 +4525,7 @@ test_copy_soft_link(hid_t fapl)
if (H5Dclose(did) < 0) TEST_ERROR;
/* make a soft link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
/* close the group */
if ( H5Gclose(gid) < 0) TEST_ERROR;
@@ -4555,6 +4584,141 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_ext_link
+ *
+ * Purpose: Create an external link in SRC file and copy it to DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: James Laird
+ * Friday, June 16, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_ext_link(hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ hid_t gid = -1; /* Group ID */
+ hsize_t dim2d[2];
+ int buf[DIM_SIZE_1][DIM_SIZE_2];
+ int i, j;
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ char ext_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Gcopy(): object through external link");
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ for (j=0; j<DIM_SIZE_2; j++)
+ buf[i][j] = 10000 + 100*i+j;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+ h5_fixname(FILENAME[2], fapl, ext_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if ( (fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* create group at the SRC file */
+ if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
+
+ /* attach attributes to the group */
+ if ( test_copy_attach_attributes(gid, H5T_NATIVE_INT) < 0) TEST_ERROR;
+
+ /* Set dataspace dimensions */
+ dim2d[0]=DIM_SIZE_1;
+ dim2d[1]=DIM_SIZE_2;
+
+ /* create dataspace */
+ if ( (sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR;
+
+ /* add a dataset to the group */
+ if ( (did = H5Dcreate(fid_src, NAME_LINK_DATASET, H5T_NATIVE_INT, sid, H5P_DEFAULT) ) < 0) TEST_ERROR;
+ if ( H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR;
+
+ /* close dataspace */
+ if ( H5Sclose(sid) < 0) TEST_ERROR;
+ /* close the dataset */
+ if (H5Dclose(did) < 0) TEST_ERROR;
+ /* close the group */
+ if ( H5Gclose(gid) < 0) TEST_ERROR;
+
+
+ /* create file to hold external links to the src file */
+ if ( (fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* create group in the external file */
+ if ( (gid = H5Gcreate(fid_ext, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
+
+ /* Create an external link to the dataset */
+ if ( H5Lcreate_external(src_filename, NAME_LINK_DATASET, fid_ext, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* close the group and file */
+ if ( H5Gclose(gid) < 0) TEST_ERROR;
+ if (H5Fclose(fid_ext) < 0) TEST_ERROR;
+
+ /* open the "extern" file with read-only */
+ if ( (fid_ext = H5Fopen(ext_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+
+ /* create destination file */
+ if ( (fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if ( H5Gclose(H5Gcreate(fid_dst, NAME_GROUP_UNCOPIED, (size_t)0)) < 0) TEST_ERROR;
+
+ /* copy the dataset from SRC to DST */
+ if ( H5Gcopy(fid_ext, NAME_LINK_EXTERN, fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* open the dataset through the external link */
+ if ( (did = H5Dopen(fid_ext, NAME_LINK_EXTERN)) < 0) TEST_ERROR;
+
+ /* open the destination dataset */
+ if ( (did2 = H5Dopen(fid_dst, NAME_DATASET_SIMPLE)) < 0) TEST_ERROR;
+
+ /* Check if the datasets are equal */
+ if ( compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR;
+
+ /* close the destination dataset */
+ if ( H5Dclose(did2) < 0) TEST_ERROR;
+
+ /* close the source dataset */
+ if ( H5Dclose(did) < 0) TEST_ERROR;
+
+ /* close the SRC file */
+ if ( H5Fclose(fid_src) < 0) TEST_ERROR;
+
+ /* close the EXT file */
+ if ( H5Fclose(fid_ext) < 0) TEST_ERROR;
+
+ /* close the DST file */
+ if ( H5Fclose(fid_dst) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Sclose(sid);
+ H5Dclose(did2);
+ H5Dclose(did);
+ H5Gclose(gid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_ext_link */
+
+
+/*-------------------------------------------------------------------------
* Function: test_copy_exist
*
* Purpose: Create a simple dataset in SRC file and copy it onto an
@@ -6197,14 +6361,14 @@ test_copy_option(hid_t fapl, unsigned flag, hbool_t crt_intermediate_grp, const
if ((flag & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0) {
/* Create group to copy */
if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
if ( H5Gclose(gid) < 0) TEST_ERROR;
/* Create group to compare with */
if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK2, (size_t)0)) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR;
if ( H5Gclose(gid) < 0) TEST_ERROR;
}
@@ -6396,6 +6560,7 @@ main(void)
nerrors += test_copy_group_wide_loop(fapl);
nerrors += test_copy_group_links(fapl);
nerrors += test_copy_soft_link(fapl);
+ nerrors += test_copy_ext_link(fapl);
nerrors += test_copy_exist(fapl);
nerrors += test_copy_path(fapl);
nerrors += test_copy_same_file_named_datatype(fapl);
diff --git a/test/stab.c b/test/stab.c
index 2562423..b684f9e 100644
--- a/test/stab.c
+++ b/test/stab.c
@@ -330,7 +330,7 @@ lifecycle(hid_t fapl)
/* Create group for testing lifecycle */
if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* Query group creation property settings */
if(H5Pget_local_heap_size_hint(gcpl, &lheap_size_hint) < 0) TEST_ERROR;
@@ -789,7 +789,7 @@ no_compact(hid_t fapl)
/* Create group for testing lifecycle */
if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* Close GCPL */
if(H5Pclose(gcpl) < 0) TEST_ERROR;
@@ -920,7 +920,7 @@ gcpl_on_root(hid_t fapl)
/* Create a group and intermediate groups, to check if root group settings are inherited */
if((gid2 = H5Gcreate_expand(gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid, lcpl)) < 0) TEST_ERROR
+ if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid2, lcpl, H5P_DEFAULT)) < 0) TEST_ERROR
/* Close LCPL */
if(H5Pclose(lcpl) < 0) TEST_ERROR;
diff --git a/test/testhdf5.c b/test/testhdf5.c
index 925b8f8..eadc2bd 100644
--- a/test/testhdf5.c
+++ b/test/testhdf5.c
@@ -50,6 +50,7 @@ main(int argc, char *argv[])
AddTest("skiplist", test_skiplist, NULL, "Skip Lists", NULL);
AddTest("refstr", test_refstr, NULL, "Reference Counted Strings", NULL);
AddTest("file", test_file, cleanup_file, "Low-Level File I/O", NULL);
+ AddTest("objects", test_h5o, cleanup_file, "Generic Object Functions", NULL);
AddTest("h5s", test_h5s, cleanup_h5s, "Dataspaces", NULL);
AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL);
AddTest("select", test_select, cleanup_select, "Selections", NULL);
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 2274b78..b4f1342 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -127,6 +127,7 @@ void test_tst(void);
void test_heap(void);
void test_refstr(void);
void test_file(void);
+void test_h5o(void);
void test_h5t(void);
void test_h5s(void);
void test_h5d(void);
@@ -148,6 +149,7 @@ void test_unicode(void);
/* Prototypes for the cleanup routines */
void cleanup_metadata(void);
void cleanup_file(void);
+void cleanup_h5o(void);
void cleanup_h5s(void);
void cleanup_attr(void);
void cleanup_select(void);
diff --git a/test/th5o.c b/test/th5o.c
new file mode 100644
index 0000000..fde15c7
--- /dev/null
+++ b/test/th5o.c
@@ -0,0 +1,601 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/***********************************************************
+*
+* Test program: th5o
+*
+* Test public H5O functions for accessing
+*
+*************************************************************/
+
+#include "testhdf5.h"
+
+/*#include "H5private.h"
+#include "H5Bprivate.h"
+#include "H5Sprivate.h"
+#include "H5Pprivate.h"
+*/
+
+#define TEST_FILENAME "th5o_file"
+
+#define RANK 2
+#define DIM0 5
+#define DIM1 10
+
+/****************************************************************
+**
+** test_h5o_open(): Test H5Oopen function.
+**
+****************************************************************/
+static void
+test_h5o_open(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ hsize_t dims[RANK];
+ H5I_type_t id_type; /* Type of IDs returned from H5Oopen */
+ hsize_t num_objs=-1; /* Number of objects in the group */
+ H5T_class_t type_class; /* Class of the datatype */
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Now make sure that H5Oopen can open all three types of objects */
+ grp = H5Oopen(fid, "group", H5P_DEFAULT);
+ CHECK(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
+ CHECK(dtype, FAIL, "H5Oopen");
+ /* Check that we can use the group as a valid location */
+ dset = H5Oopen(grp, "/dataset", H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Oopen");
+
+ /* Make sure that each is the right kind of ID */
+ id_type = H5Iget_type(grp);
+ VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
+ id_type = H5Iget_type(dtype);
+ VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
+ id_type = H5Iget_type(dset);
+ VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
+
+ /* Do something more complex with each of the IDs to make sure they "work" */
+ ret = H5Gget_num_objs(grp, &num_objs);
+ CHECK(ret, FAIL, "H5Gget_num_objs");
+ VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */
+
+ type_class = H5Tget_class(dtype);
+ VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
+
+ dspace = H5Dget_space(dset);
+ CHECK(dspace, FAIL, "H5Dget_space");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Trying to open objects with bogus names should fail gracefully */
+ H5E_BEGIN_TRY {
+ grp = H5Oopen(fid, "bogus_group", H5P_DEFAULT);
+ VERIFY(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/bogus_datatype", H5P_DEFAULT);
+ VERIFY(dtype, FAIL, "H5Oopen");
+ dset = H5Oopen(fid, "/bogus_dataset", H5P_DEFAULT);
+ VERIFY(dset, FAIL, "H5Oopen");
+ } H5E_END_TRY
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Trying to open an object with a bogus file ID should fail */
+ H5E_BEGIN_TRY {
+ dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
+ VERIFY(dset, FAIL, "H5Oopen");
+ } H5E_END_TRY
+} /* test_h5o_open() */
+
+
+
+/****************************************************************
+**
+** test_h5o_close(): Test H5Oclose function.
+**
+****************************************************************/
+static void
+test_h5o_close(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ hsize_t dims[RANK];
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group and close it with H5Oclose */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ VERIFY(H5Iget_type(grp), H5I_GROUP, "H5Iget_type");
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Attempting to close the data space with H5Oclose should fail */
+ H5E_BEGIN_TRY {
+ ret = H5Oclose(dspace);
+ VERIFY(ret, FAIL, "H5Oclose");
+ } H5E_END_TRY
+ /* Close the dataspace for real */
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Make sure that H5Oclose can close objects opened with H5Oopen */
+ grp = H5Oopen(fid, "group", H5P_DEFAULT);
+ CHECK(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
+ CHECK(dtype, FAIL, "H5Oopen");
+ dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Oopen");
+
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Make sure H5Oclose can close objects opened with H5*open */
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "group/datatype");
+ CHECK(dtype, FAIL, "H5Topen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Dopen");
+
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+}
+
+
+/****************************************************************
+**
+** test_h5o_open_by_addr(): Test H5Oopen_by_addr function.
+**
+****************************************************************/
+static void
+test_h5o_open_by_addr(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ H5L_linkinfo_t li; /* Buffer for H5Lget_linkinfo */
+ haddr_t grp_addr; /* Addresses for objects */
+ haddr_t dset_addr;
+ haddr_t dtype_addr;
+ hsize_t dims[RANK];
+ H5I_type_t id_type; /* Type of IDs returned from H5Oopen */
+ hsize_t num_objs=-1; /* Number of objects in the group */
+ H5T_class_t type_class; /* Class of the datatype */
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Get address for each object */
+ ret = H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ grp_addr = li.u.address;
+ ret = H5Lget_linkinfo(fid, "group/datatype", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ dtype_addr = li.u.address;
+ ret = H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ dset_addr = li.u.address;
+
+ /* Now make sure that H5Oopen_by_addr can open all three types of objects */
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ CHECK(grp, FAIL, "H5Oopen_by_addr");
+ dtype = H5Oopen_by_addr(fid, dtype_addr);
+ CHECK(dtype, FAIL, "H5Oopen_by_addr");
+ /* Check that we can use the group ID as a valid location */
+ dset = H5Oopen_by_addr(grp, dset_addr);
+ CHECK(dset, FAIL, "H5Oopen_by_addr");
+
+ /* Make sure that each is the right kind of ID */
+ id_type = H5Iget_type(grp);
+ VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
+ id_type = H5Iget_type(dtype);
+ VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
+ id_type = H5Iget_type(dset);
+ VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
+
+ /* Do something more complex with each of the IDs to make sure they "work" */
+ ret = H5Gget_num_objs(grp, &num_objs);
+ CHECK(ret, FAIL, "H5Gget_num_objs");
+ VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */
+
+ type_class = H5Tget_class(dtype);
+ VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
+
+ dspace = H5Dget_space(dset);
+ CHECK(dspace, FAIL, "H5Dget_space");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Try giving some bogus values to H5O_open_by_addr. */
+ /* Try to open an object with a bad address */
+ grp_addr += 20;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ /* For instance, an objectno smaller than the end of the file's superblock should
+ * trigger an error */
+ grp_addr = 10;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ /* Likewise, an objectno larger than the size of the file should fail */
+ grp_addr = 0;
+ grp_addr = 1000000000;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Also, trying to open an object without a valid location should fail */
+ H5E_BEGIN_TRY{
+ dtype = H5Oopen_by_addr(fid, dtype_addr);
+ }H5E_END_TRY
+ VERIFY(dtype, FAIL, "H5Oopen_by_addr");
+} /* test_h5o_open_by_addr() */
+
+
+/****************************************************************
+**
+** test_h5o_refcount(): Test H5O refcounting functions.
+**
+****************************************************************/
+static void
+test_h5o_refcount(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ H5G_stat_t sb; /* Statbuffer for H5Gget_objinfo */
+ hsize_t dims[RANK];
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Get ref counts for each object. They should all be 1, since each object has a hard link. */
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Increment each object's reference count. */
+ ret = H5Oincr_refcount(grp);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+
+ /* Get ref counts for each object. They should all be 2 now. */
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+
+ /* Decrement the reference counts and check that they decrease back to 1. */
+ ret = H5Odecr_refcount(grp);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Increment the reference counts and then close the file to make sure the increment is permanant */
+ ret = H5Oincr_refcount(grp);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open the file and check that the reference counts were really incremented */
+ fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "datatype");
+ CHECK(dtype, FAIL, "H5Gopen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Gopen");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+
+ /* Decrement the reference counts and close the file */
+ ret = H5Odecr_refcount(grp);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open the file and check that the reference counts were really decremented */
+ fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "datatype");
+ CHECK(dtype, FAIL, "H5Gopen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Gopen");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Make sure that bogus IDs return errors properly */
+ H5E_BEGIN_TRY {
+ ret = H5Oincr_refcount(grp);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Odecr_refcount(grp);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ } H5E_END_TRY
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* test_h5o_refcount() */
+
+
+/****************************************************************
+**
+** test_h5o(): Main H5O (generic object) testing routine.
+**
+****************************************************************/
+void
+test_h5o(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Objects\n"));
+
+ test_h5o_open(); /* Test generic open function */
+ test_h5o_open_by_addr(); /* Test opening objects by address */
+ test_h5o_close(); /* Test generic close function */
+ test_h5o_refcount(); /* Test incrementing and decrementing reference count */
+} /* test_h5o() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_h5o
+ *
+ * Purpose: Cleanup temporary test files
+ *
+ * Return: none
+ *
+ * Programmer: James Laird
+ * June 3, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_h5o(void)
+{
+ remove(TEST_FILENAME);
+}
diff --git a/test/titerate.c b/test/titerate.c
index 0c41ce6..4850db0 100644
--- a/test/titerate.c
+++ b/test/titerate.c
@@ -854,10 +854,10 @@ static void test_links(void)
CHECK(gid1, FAIL, "H5Gcreate");
/* create soft and hard links to the group "/g1". */
- ret = H5Glink (gid, H5G_LINK_SOFT, "something", "softlink");
+ ret = H5Glink (gid, H5L_LINK_SOFT, "something", "softlink");
CHECK(ret, FAIL, "H5Glink");
- ret = H5Glink (gid, H5G_LINK_HARD, "/g1", "hardlink");
+ ret = H5Glink (gid, H5L_LINK_HARD, "/g1", "hardlink");
CHECK(ret, FAIL, "H5Glink");
ret = H5Gget_num_objs(gid, &nobjs);
diff --git a/test/tmisc.c b/test/tmisc.c
index cc4d7b2..b89a9a6 100644
--- a/test/tmisc.c
+++ b/test/tmisc.c
@@ -2850,6 +2850,7 @@ test_misc18(void)
#else /* H5_HAVE_LARGE_HSIZET */
VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Create second dataset */
did2 = H5Dcreate(fid, MISC18_DSET2_NAME, H5T_STD_U32LE, sid, H5P_DEFAULT);
@@ -2866,6 +2867,7 @@ test_misc18(void)
#else /* H5_HAVE_LARGE_HSIZET */
VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Loop creating attributes on each dataset, flushing them to the file each time */
for(u=0; u<10; u++) {
@@ -2905,6 +2907,7 @@ test_misc18(void)
VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo");
VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Get object information for dataset #2 now */
ret = H5Gget_objinfo(fid,MISC18_DSET2_NAME,0,&statbuf);
@@ -2920,6 +2923,7 @@ test_misc18(void)
VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo");
VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Close second dataset */
ret = H5Dclose(did2);
@@ -3844,7 +3848,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
/* Query that the name of the new group is correct */
@@ -3870,7 +3874,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3880,7 +3884,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(group_id, "B03/grp/", tmp_id, create_id);
+ status = H5Llink(group_id, "B03/grp/", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3890,7 +3894,7 @@ test_misc23(void)
if ( (tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id)) < 0)
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3900,7 +3904,7 @@ test_misc23(void)
if ( (tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id)) < 0)
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3924,50 +3928,50 @@ test_misc23(void)
CHECK(status, FAIL, "H5Pset_create_intermediate_group");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(group_id, "B08/dset", tmp_id, create_id);
+ status = H5Llink(group_id, "B08/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
@@ -4002,7 +4006,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4015,7 +4019,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4028,7 +4032,7 @@ test_misc23(void)
status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id);
+ status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4041,7 +4045,7 @@ test_misc23(void)
status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4054,7 +4058,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4110,13 +4114,13 @@ test_misc24(void)
CHECK(ret, FAIL, "H5Tcommit");
/* Create soft links to the objects created */
- ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5G_LINK_SOFT, file_id, MISC24_GROUP_LINK);
+ ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5L_LINK_SOFT, file_id, MISC24_GROUP_LINK);
CHECK(ret, FAIL, "H5Glink2");
- ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5G_LINK_SOFT, file_id, MISC24_DATASET_LINK);
+ ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5L_LINK_SOFT, file_id, MISC24_DATASET_LINK);
CHECK(ret, FAIL, "H5Glink2");
- ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5G_LINK_SOFT, file_id, MISC24_DATATYPE_LINK);
+ ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5L_LINK_SOFT, file_id, MISC24_DATATYPE_LINK);
CHECK(ret, FAIL, "H5Glink2");
/* Close IDs for objects */
diff --git a/test/unlink.c b/test/unlink.c
index d86e4eb..1ad3790 100644
--- a/test/unlink.c
+++ b/test/unlink.c
@@ -19,8 +19,14 @@
* Purpose: Test H5Gunlink().
*/
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+/* Define this macro to indicate that the testing APIs should be available */
+#define H5G_TESTING
+
#include <time.h>
#include "h5test.h"
+#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"unlink",
@@ -33,6 +39,7 @@ const char *FILENAME[] = {
"resurrect_type",
"resurrect_group",
"unlink_chunked",
+ "full_group",
NULL
};
@@ -68,6 +75,9 @@ const char *FILENAME[] = {
#define SLASHES_SOFTLINK_NAME "Soft///"
#define SLASHES_SOFTLINK2_NAME "Soft2///"
#define SLASHES_ROOTLINK_NAME "Root///"
+#define FULL_GROUP_NUM_KEEP 2
+#define FULL_GROUP_NUM_DELETE_COMPACT 2
+#define FULL_GROUP_NUM_DELETE_DENSE 16
/*-------------------------------------------------------------------------
@@ -170,7 +180,7 @@ test_many(hid_t file)
TESTING("forward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
@@ -182,7 +192,7 @@ test_many(hid_t file)
TESTING("backward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=how_many-1; i>=0; --i) {
sprintf(name, "obj_%05d", i);
@@ -194,7 +204,7 @@ test_many(hid_t file)
TESTING("inward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=0; i<how_many; i++) {
if (i%2) {
@@ -210,7 +220,7 @@ test_many(hid_t file)
TESTING("outward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=how_many-1; i>=0; --i) {
if (i%2) {
@@ -259,7 +269,7 @@ test_symlink(hid_t file)
/* Create a test group and symlink */
if ((work=H5Gcreate(file, "/test_symlink", 0))<0) TEST_ERROR;
- if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link")<0) TEST_ERROR;
+ if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link")<0) TEST_ERROR;
if (H5Gunlink(work, "link")<0) TEST_ERROR;
/* Cleanup */
@@ -310,7 +320,7 @@ test_rename(hid_t file)
/* Try renaming a symlink */
TESTING("symlink renaming");
- if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link_one")<0) goto error;
+ if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link_one")<0) goto error;
if (H5Gmove(work, "link_one", "link_two")<0) goto error;
PASSED();
@@ -368,9 +378,9 @@ test_new_move(void)
if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) goto error;
/* Create hard and soft links. */
- if(H5Glink2(grp_1, "group_move", H5G_LINK_HARD, H5G_SAME_LOC, "hard")<0)
+ if(H5Glink2(grp_1, "group_move", H5L_LINK_HARD, H5G_SAME_LOC, "hard")<0)
goto error;
- if(H5Glink2(grp_1, "/group1/group_move", H5G_LINK_SOFT, grp_2, "soft")<0)
+ if(H5Glink2(grp_1, "/group1/group_move", H5L_LINK_SOFT, grp_2, "soft")<0)
goto error;
/* Move a group within the file. Both of source and destination use
@@ -1357,22 +1367,22 @@ test_link_slashes(void)
if(H5Gclose(gid2)<0) TEST_ERROR;
/* Create a hard link to the nested group */
- if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
/* Create a soft link with a relative path to the nested group */
- if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR;
/* Create a soft link with the full path to the nested group */
- if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR;
/* Create a soft link to the root group */
- if(H5Glink2(gid, "////", H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, "////", H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR;
/* Close the group */
if(H5Gclose(gid)<0) TEST_ERROR;
/* Create a hard link to the existing group */
- if(H5Glink2(fid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(fid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
/* Close the file */
if(H5Fclose(fid)<0) TEST_ERROR;
@@ -1861,7 +1871,7 @@ test_resurrect_dataset(void)
if(H5Iget_name(d, NULL, 0) != 0) TEST_ERROR;
/* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(d, ".", H5G_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR;
+ if(H5Glink2(d, ".", H5L_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR;
/* Close things */
if(H5Dclose(d)<0) TEST_ERROR;
@@ -1934,7 +1944,7 @@ test_resurrect_datatype(void)
if(H5Iget_name(type, NULL, 0) != 0) TEST_ERROR;
/* Re-link the datatype to the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(type, ".", H5G_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR;
+ if(H5Glink2(type, ".", H5L_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR;
/* Close things */
if(H5Tclose(type)<0) TEST_ERROR;
@@ -2003,7 +2013,7 @@ test_resurrect_group(void)
if(H5Iget_name(group, NULL, 0) != 0) TEST_ERROR;
/* Re-link the group into the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(group, ".", H5G_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR;
+ if(H5Glink2(group, ".", H5L_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR;
/* Close things */
if(H5Gclose(group)<0) TEST_ERROR;
@@ -2121,6 +2131,269 @@ error:
return 1;
} /* end test_unlink_chunked_dataset() */
+#ifdef H5_GROUP_REVISION
+
+/*-------------------------------------------------------------------------
+ * Function: test_full_group_compact
+ *
+ * Purpose: Test deleting a compact group which still has valid objects in it
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_full_group_compact(void)
+{
+ hid_t fapl_id = -1;
+ hid_t file_id = -1;
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ H5G_stat_t sb; /* Stat buffer for object */
+ char objname[128]; /* Buffer for name of objects to create */
+ char objname2[128]; /* Buffer for name of objects to create */
+ char filename[1024]; /* Buffer for filename */
+ off_t keep_size; /* Size of the file with objects to keep */
+ off_t file_size; /* Size of each file created */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking non-empty compact group");
+
+ /* Create file */
+ fapl_id = h5_fileaccess();
+ h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename);
+
+ /* Create the file */
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR
+
+ /* Create group to link objects to */
+ if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create several objects to link to */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "keep %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Close group with objects to keep */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Get the size of the file with only the objects to keep */
+ if((keep_size = h5_get_file_size(filename)) == 0) TEST_ERROR
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Create group to delete */
+ if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error;
+
+ /* Create external link (doesn't matter if it dangles) */
+ if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create soft link (doesn't matter if it dangles) */
+ if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR
+
+ /* Create hard links to objects in group to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ sprintf(objname2, "keep %u\n", u);
+ if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Create several objects to delete */
+ for(u = 0; u < FULL_GROUP_NUM_DELETE_COMPACT; u++) {
+ sprintf(objname, "delete %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) != TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close group with objects to delete */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 2) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Delete the full group */
+ if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 1) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Get the size of the file */
+ if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR
+
+ /* Verify the file is correct size */
+ if(file_size != keep_size) TEST_ERROR
+
+ /* Close the file access property list */
+ if(H5Pclose(fapl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(file_id);
+ H5Pclose(fapl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_full_group_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_full_group_dense
+ *
+ * Purpose: Test deleting a dense group which still has valid objects in it
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_full_group_dense(void)
+{
+ hid_t fapl_id = -1;
+ hid_t file_id = -1;
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ H5G_stat_t sb; /* Stat buffer for object */
+ char objname[128]; /* Buffer for name of objects to create */
+ char objname2[128]; /* Buffer for name of objects to create */
+ char filename[1024]; /* Buffer for filename */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking non-empty dense group");
+
+ /* Create file */
+ fapl_id = h5_fileaccess();
+ h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename);
+
+ /* Create the file */
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR
+
+ /* Create group to link objects to */
+ if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create several objects to link to */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "keep %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Close group with objects to keep */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Create group to delete */
+ if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error;
+
+ /* Create external link (doesn't matter if it dangles) */
+ if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create soft link (doesn't matter if it dangles) */
+ if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR
+
+ /* Create hard links to objects in group to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ sprintf(objname2, "keep %u\n", u);
+ if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Create several objects to delete */
+ for(u = 0; u < FULL_GROUP_NUM_DELETE_DENSE; u++) {
+ sprintf(objname, "delete %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group with objects to delete */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 2) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Delete the full group */
+ if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 1) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Close the file access property list */
+ if(H5Pclose(fapl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(file_id);
+ H5Pclose(fapl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_full_group_dense() */
+#endif /* H5_GROUP_REVISION */
+
/*-------------------------------------------------------------------------
* Function: main
@@ -2209,13 +2482,20 @@ main(void)
/* Test unlinking chunked datasets */
nerrors += test_unlink_chunked_dataset();
- /* Close */
- if (H5Pclose(fapl2)<0) TEST_ERROR;
- if (H5Fclose(file)<0) TEST_ERROR;
- if (nerrors) {
- printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S");
+#ifdef H5_GROUP_REVISION
+ /* Test unlinked groups which still have objects in them */
+ nerrors += test_full_group_compact();
+ nerrors += test_full_group_dense();
+#endif /* H5_GROUP_REVISION */
+
+ /* Close */
+ if (H5Pclose(fapl2)<0) TEST_ERROR;
+ if (H5Fclose(file)<0) TEST_ERROR;
+ if (nerrors) {
+ printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S");
exit(1);
}
+
puts("All unlink tests passed.");
h5_cleanup(FILENAME, fapl);
}
diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c
index 11459a4..1811b9d 100644
--- a/tools/h5diff/h5diffgentest.c
+++ b/tools/h5diff/h5diffgentest.c
@@ -42,6 +42,26 @@
#define FILE8 "file8.h5"
+#define MY_LINKCLASS 187
+/* A UD link traversal function. Shouldn't actually be called. */
+static hid_t UD_traverse(UNUSED const char * link_name, UNUSED hid_t cur_group,
+ UNUSED void * udata, UNUSED size_t udata_size, UNUSED hid_t lapl_id)
+{
+return -1;
+}
+const H5L_link_class_t UD_link_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ MY_LINKCLASS, /* Link type id number */
+ "UD link class", /* name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+
/*-------------------------------------------------------------------------
* Function: write_attr
*
@@ -2153,7 +2173,7 @@ int test_basic(const char *file1,
* Function: test_basic
*
* Purpose: Compare different HDF5 types (H5G_obj_t):
- * H5G_DATASET, H5G_TYPE, H5G_GROUP, H5G_LINK
+ * H5G_DATASET, H5G_TYPE, H5G_GROUP, H5G_LINK, H5G_UDLINK
*
*-------------------------------------------------------------------------
*/
@@ -2222,8 +2242,16 @@ int test_types(const char *file1,
*-------------------------------------------------------------------------
*/
- status = H5Glink(fid1, H5G_LINK_SOFT, "g1", "l1");
- status = H5Glink(fid1, H5G_LINK_SOFT, "g2", "l2");
+ status = H5Glink(fid1, H5L_LINK_SOFT, "g1", "l1");
+ status = H5Glink(fid1, H5L_LINK_SOFT, "g2", "l2");
+
+/*-------------------------------------------------------------------------
+ * H5G_UDLINK
+ *-------------------------------------------------------------------------
+ */
+ H5Lcreate_external("filename", "objname", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
+ H5Lregister(UD_link_class);
+ H5Lcreate_ud(fid1, "ud_link", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
/*-------------------------------------------------------------------------
* Close
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index 4bd388a..7a49950 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -271,6 +271,10 @@ static const h5dump_header_t standardformat = {
"", /*dataend */
SOFTLINK, /*softlinkbegin */
"", /*softlinkend */
+ EXTLINK, /*extlinkbegin */
+ "", /*extlinkend */
+ UDLINK, /*udlinkbegin */
+ "", /*udlinkend */
SUBSET, /*subsettingbegin */
"", /*subsettingend */
START, /*startbegin */
@@ -300,6 +304,10 @@ static const h5dump_header_t standardformat = {
"}", /*datablockend */
"{", /*softlinkblockbegin */
"}", /*softlinkblockend */
+ "{", /*extlinkblockbegin */
+ "}", /*extlinkblockend */
+ "{", /*udlinkblockbegin */
+ "}", /*udlinkblockend */
"{", /*strblockbegin */
"}", /*strblockend */
"{", /*enumblockbegin */
@@ -1398,6 +1406,7 @@ dump_all(hid_t group, const char *name, void * op_data)
hid_t obj;
char *obj_path = NULL; /* Full path of object */
H5G_stat_t statbuf;
+ H5L_linkinfo_t linfo; /* Link information */
herr_t ret = SUCCEED;
/* Stat the object */
@@ -1407,6 +1416,12 @@ dump_all(hid_t group, const char *name, void * op_data)
ret = FAIL;
goto done;
} /* end if */
+ if(H5Lget_linkinfo(group, name, &linfo, H5P_DEFAULT) < 0) {
+ error_msg(progname, "unable to get object information\n");
+ d_status = EXIT_FAILURE;
+ ret = FAIL;
+ goto done;
+ } /* end if */
if (*(int *)op_data != H5G_UNKNOWN && statbuf.type != *(int *) op_data)
goto done;
@@ -1433,7 +1448,7 @@ dump_all(hid_t group, const char *name, void * op_data)
indentation(indent + COL);
}
- if (H5Gget_linkval(group, name, statbuf.linklen, targbuf) < 0) {
+ if (H5Lget_linkval(group, name, statbuf.linklen, targbuf, H5P_DEFAULT) < 0) {
error_msg(progname, "unable to get link value\n");
d_status = EXIT_FAILURE;
ret = FAIL;
@@ -1516,7 +1531,128 @@ dump_all(hid_t group, const char *name, void * op_data)
HDfree(targbuf);
break;
}
+ case H5G_UDLINK:
+ {
+ indentation(indent);
+ switch(linfo.linkclass)
+ {
+ case H5L_LINK_EXTERNAL:
+ {
+ char *targbuf;
+ char *filename;
+ char *targname;
+ targbuf = HDmalloc(statbuf.linklen);
+ HDassert(targbuf);
+ if (!doxml) {
+ begin_obj(dump_header_format->extlinkbegin, name,
+ dump_header_format->extlinkblockbegin);
+ }
+ if (H5Lget_linkval(group, name, statbuf.linklen, targbuf, H5P_DEFAULT) < 0) {
+ error_msg(progname, "unable to get external link value\n");
+ d_status = EXIT_FAILURE;
+ ret = FAIL;
+ } else {
+ if(H5Lunpack_elink_val(targbuf, &filename, &targname) < 0) {
+ error_msg(progname, "unable to unpack external link value\n");
+ d_status = EXIT_FAILURE;
+ ret = FAIL;
+ } else {
+ if (!doxml) {
+ indentation(indent + COL);
+ printf("LINKCLASS %d\n", linfo.linkclass);
+ indentation(indent + COL);
+ printf("TARGETFILE \"%s\"\n", filename);
+ indentation(indent + COL);
+ printf("TARGETPATH \"%s\"\n", targname);
+ }
+ else /* XML */
+ {
+ char linkxid[100];
+ char parentxid[100];
+ char *t_name = xml_escape_the_name(name);
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_obj_path = xml_escape_the_name(obj_path);
+ char *t_filename = xml_escape_the_name(filename);
+ char *t_targname = xml_escape_the_name(targname);
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(t_obj_path, linkxid, sizeof(linkxid), 1);
+ xml_name_to_XID(prefix, parentxid, sizeof(parentxid), 1);
+
+ printf("<%sExternalLink LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "TargetFilename=\"%s\" "
+ "TargetPath=\"%s\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />\n",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ filename, /* TargetFilename */
+ targname, /* TargetPath*/
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(t_filename);
+ HDfree(t_targname);
+ HDfree(t_obj_path);
+ }
+ }
+ }
+ if (!doxml) {
+ end_obj(dump_header_format->extlinkend,
+ dump_header_format->extlinkblockend);
+ }
+ HDfree(targbuf);
+ }
+ break;
+ default:
+ if (!doxml) {
+ begin_obj(dump_header_format->udlinkbegin, name,
+ dump_header_format->udlinkblockbegin);
+ indentation(indent + COL);
+ }
+ if (!doxml) {
+ printf("LINKCLASS %d\n", linfo.linkclass);
+ }
+ else /* XML */
+ {
+ char linkxid[100];
+ char parentxid[100];
+ char *t_name = xml_escape_the_name(name);
+ char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/");
+ char *t_obj_path = xml_escape_the_name(obj_path);
+
+ /* Create OBJ-XIDs for the parent and object */
+ xml_name_to_XID(t_obj_path, linkxid, sizeof(linkxid), 1);
+ xml_name_to_XID(prefix, parentxid, sizeof(parentxid), 1);
+ printf("<%sUserDefined LinkName=\"%s\" "
+ "OBJ-XID=\"%s\" "
+ "H5SourcePath=\"%s\" "
+ "LinkClass=\"%d\" "
+ "Parents=\"%s\" H5ParentPaths=\"%s\" />\n",
+ xmlnsprefix,
+ t_name, /* LinkName */
+ linkxid, /* OBJ-XID */
+ t_obj_path, /* H5SourcePath */
+ linfo.linkclass, /* LinkClass */
+ parentxid, /* Parents */
+ t_prefix); /* H5ParentPaths */
+ HDfree(t_prefix);
+ HDfree(t_name);
+ HDfree(t_obj_path);
+ }
+ if (!doxml) {
+ indentation(indent);
+ end_obj(dump_header_format->udlinkend,
+ dump_header_format->udlinkblockend);
+ }
+ }
+ break;
+ }
case H5G_GROUP:
if ((obj = H5Gopen(group, name)) < 0) {
error_msg(progname, "unable to dump group \"%s\"\n", name);
@@ -2003,7 +2139,7 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_ai)
/* Print all the values. */
if (obj_data == DATASET_DATA) {
- hid_t f_type = H5Dget_type(obj_id);
+ hid_t f_type = H5Dget_type(obj_id);
char string_prefix[64];
h5tool_format_t string_dataformat;
@@ -2683,7 +2819,7 @@ set_output_file(const char *fname, int is_bin)
else
rawdatastream = NULL;
}
-
+
/* binary output */
if (is_bin)
{
@@ -2699,7 +2835,7 @@ set_output_file(const char *fname, int is_bin)
return 0;
}
}
-
+
return -1;
}
@@ -3044,7 +3180,7 @@ handle_groups(hid_t fid, char *group, void UNUSED * data)
/*-------------------------------------------------------------------------
* Function: handle_links
*
- * Purpose: Handle the links from the command.
+ * Purpose: Handle soft or UD links from the command.
*
* Return: void
*
@@ -3059,18 +3195,24 @@ static void
handle_links(hid_t fid, char *links, void UNUSED * data)
{
H5G_stat_t statbuf;
+ H5L_linkinfo_t linfo;
+ char * elink_file;
+ char * elink_path;
if (H5Gget_objinfo(fid, links, FALSE, &statbuf) < 0) {
error_msg(progname, "unable to get obj info from \"%s\"\n", links);
d_status = EXIT_FAILURE;
- } else if (statbuf.type == H5G_LINK) {
+ } else if (H5Lget_linkinfo(fid, links, &linfo, H5P_DEFAULT) < 0) {
+ error_msg(progname, "unable to get link info from \"%s\"\n", links);
+ d_status = EXIT_FAILURE;
+ } else if (statbuf.type == H5G_LINK) { /* Soft link */
char *buf = HDmalloc(statbuf.linklen);
begin_obj(dump_header_format->softlinkbegin, links,
dump_header_format->softlinkblockbegin);
indentation(COL);
- if (H5Gget_linkval(fid, links, statbuf.linklen, buf) >= 0) {
+ if (H5Lget_linkval(fid, links, statbuf.linklen, buf, H5P_DEFAULT) >= 0) {
printf("LINKTARGET \"%s\"\n", buf);
} else {
error_msg(progname, "h5dump error: unable to get link value for \"%s\"\n",
@@ -3080,7 +3222,45 @@ handle_links(hid_t fid, char *links, void UNUSED * data)
end_obj(dump_header_format->softlinkend,
dump_header_format->softlinkblockend);
-
+ HDfree(buf);
+ } else if (statbuf.type == H5G_UDLINK) { /* User-defined link */
+ char *buf = HDmalloc(statbuf.linklen);
+ begin_obj(dump_header_format->udlinkbegin, links,
+ dump_header_format->udlinkblockbegin);
+ indentation(COL);
+ switch(linfo.linkclass) {
+ case H5L_LINK_EXTERNAL:
+ begin_obj(dump_header_format->extlinkbegin, links,
+ dump_header_format->extlinkblockbegin);
+ if (H5Lget_linkval(fid, links, statbuf.linklen, buf, H5P_DEFAULT) >= 0) {
+ if(H5Lunpack_elink_val(buf, &elink_file, &elink_path)>=0) {
+ indentation(COL);
+ printf("LINKCLASS %d\n", linfo.linkclass);
+ indentation(COL);
+ printf("TARGETFILE \"%s\"\n", elink_file);
+ indentation(COL);
+ printf("TARGETPATH \"%s\"\n", elink_path);
+ } else {
+ error_msg(progname, "h5dump error: unable to unpack external link value for \"%s\"\n",
+ links);
+ d_status = EXIT_FAILURE;
+ }
+ } else {
+ error_msg(progname, "h5dump error: unable to get external link value for \"%s\"\n",
+ links);
+ d_status = EXIT_FAILURE;
+ }
+ end_obj(dump_header_format->extlinkend,
+ dump_header_format->extlinkblockend);
+ break;
+ default:
+ begin_obj(dump_header_format->udlinkbegin, links,
+ dump_header_format->udlinkblockbegin);
+ indentation(COL);
+ printf("LINKCLASS %d\n", linfo.linkclass);
+ end_obj(dump_header_format->udlinkend,
+ dump_header_format->udlinkblockend);
+ }
HDfree(buf);
} else {
error_msg(progname, "\"%s\" is not a link\n", links);
@@ -5054,7 +5234,8 @@ xml_dump_group(hid_t gid, const char *name)
H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
xtype = H5G_LINK;
H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
-
+ xtype = H5G_UDLINK;
+ H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
}
free(t_name);
free(grpxid);
@@ -5114,7 +5295,8 @@ xml_dump_group(hid_t gid, const char *name)
H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
xtype = H5G_LINK;
H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
-
+ xtype = H5G_UDLINK;
+ H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype);
}
indent -= COL;
diff --git a/tools/h5dump/h5dump.h b/tools/h5dump/h5dump.h
index dbc5de9..08aa527 100644
--- a/tools/h5dump/h5dump.h
+++ b/tools/h5dump/h5dump.h
@@ -45,6 +45,8 @@
#define S_SIMPLE "SIMPLE"
#define S_NULL "NULL"
#define SOFTLINK "SOFTLINK"
+#define EXTLINK "EXTERNAL_LINK"
+#define UDLINK "USERDEFINED_LINK"
#define STORAGELAYOUT "STORAGELAYOUT"
#define START "START"
#define STRIDE "STRIDE"
@@ -91,6 +93,10 @@ typedef struct h5dump_header_t {
const char *dataend;
const char *softlinkbegin;
const char *softlinkend;
+ const char *extlinkbegin;
+ const char *extlinkend;
+ const char *udlinkbegin;
+ const char *udlinkend;
const char *subsettingbegin;
const char *subsettingend;
const char *startbegin;
@@ -120,6 +126,10 @@ typedef struct h5dump_header_t {
const char *datablockend;
const char *softlinkblockbegin;
const char *softlinkblockend;
+ const char *extlinkblockbegin;
+ const char *extlinkblockend;
+ const char *udlinkblockbegin;
+ const char *udlinkblockend;
const char *strblockbegin;
const char *strblockend;
const char *enumblockbegin;
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index 89652f2..3a5272a 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -79,7 +79,8 @@
#define FILE50 "taindices.h5"
#define FILE51 "tlonglinks.h5"
#define FILE52 "tldouble.h5"
-
+#define FILE53 "textlink.h5"
+#define FILE54 "tudlink.h5"
@@ -120,6 +121,27 @@ const H5Z_class_t H5Z_MYFILTER[1] = {{
}};
+/* A UD link traversal function. Shouldn't actually be called. */
+static hid_t UD_traverse(UNUSED const char * link_name, UNUSED hid_t cur_group,
+ UNUSED void * udata, UNUSED size_t udata_size, UNUSED hid_t lapl_id)
+{
+return -1;
+}
+
+#define MY_LINKCLASS 187
+
+const H5L_link_class_t UD_link_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ MY_LINKCLASS, /* Link type id number */
+ "UD link class", /* name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
#define LENSTR 50
#define LENSTR2 11
@@ -403,8 +425,8 @@ static void gent_softlink(void)
fid = H5Fcreate(FILE4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
root = H5Gopen (fid, "/");
- H5Glink (root, H5G_LINK_SOFT, "somevalue", "slink1");
- H5Glink (root, H5G_LINK_SOFT, "linkvalue", "slink2");
+ H5Glink (root, H5L_LINK_SOFT, "somevalue", "slink1");
+ H5Glink (root, H5L_LINK_SOFT, "linkvalue", "slink2");
H5Gclose(root);
H5Fclose(fid);
@@ -441,19 +463,48 @@ static void gent_hardlink(void)
H5Dclose(dataset);
group = H5Gcreate (fid, "/g1", 0);
- H5Glink (group, H5G_LINK_HARD, "/dset1", "dset2");
+ H5Glink (group, H5L_LINK_HARD, "/dset1", "dset2");
H5Gclose(group);
group = H5Gcreate (fid, "/g2", 0);
- H5Glink (group, H5G_LINK_HARD, "/dset1", "dset3");
+ H5Glink (group, H5L_LINK_HARD, "/dset1", "dset3");
H5Gclose(group);
group = H5Gopen(fid, "/g1");
- H5Glink (group, H5G_LINK_HARD, "/g2", "g1.1");
+ H5Glink (group, H5L_LINK_HARD, "/g2", "g1.1");
H5Gclose(group);
H5Fclose(fid);
}
+static void gent_extlink(void)
+{
+ hid_t fid;
+
+ /* This external link will dangle, but that's okay */
+ fid = H5Fcreate(FILE53, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ H5Lcreate_external("filename", "objname", fid, "extlink1", H5P_DEFAULT, H5P_DEFAULT);
+ H5Lcreate_external("anotherfile", "anotherobj", fid, "extlink2", H5P_DEFAULT, H5P_DEFAULT);
+
+ H5Fclose(fid);
+}
+
+static void gent_udlink(void)
+{
+ hid_t fid;
+ char buf[4];
+
+ H5Lregister(UD_link_class);
+
+ /* This ud link will dangle, but that's okay */
+ fid = H5Fcreate(FILE54, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ H5Lcreate_ud(fid, "udlink1", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
+ strcpy(buf, "foo");
+ H5Lcreate_ud(fid, "udlink2", MY_LINKCLASS, buf, 4, H5P_DEFAULT, H5P_DEFAULT);
+
+ H5Fclose(fid);
+}
+
+
/*
/
/ | \ \
@@ -830,9 +881,9 @@ static void gent_compound_dt2(void) { /* test compound data type */
/ : g1 g2 attr1 attr2
g1 : g1.1 g1.2
g1.1 : dset1.1.1(attr1, attr2) dset1.1.2
-g1.2 : g1.2.1
+g1.2 : g1.2.1 extlink
g1.2.1 : slink
-g2 : dset2.1 dset2.2
+g2 : dset2.1 dset2.2 udlink
*/
@@ -926,9 +977,12 @@ float dset2_1[10], dset2_2[3][5];
H5Gclose(group);
+ /* external link */
+ H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT);
+
/* soft link */
group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
- H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
+ H5Glink (group, H5L_LINK_SOFT, "somevalue", "slink");
H5Gclose(group);
group = H5Gopen (fid, "/g2");
@@ -956,6 +1010,10 @@ float dset2_1[10], dset2_2[3][5];
H5Gclose(group);
+ /* user-defined link */
+ H5Lregister(UD_link_class);
+ H5Lcreate_ud(fid, "/g2/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
+
H5Fclose(fid);
}
@@ -981,8 +1039,8 @@ hid_t fid, group;
group = H5Gcreate (fid, "/g2", 0);
H5Gclose(group);
- H5Glink(fid, H5G_LINK_HARD, "/g2", "/g1/g1.1");
- H5Glink(fid, H5G_LINK_HARD, "/g1", "/g2/g2.1");
+ H5Glink(fid, H5L_LINK_HARD, "/g2", "/g1/g1.1");
+ H5Glink(fid, H5L_LINK_HARD, "/g1", "/g2/g2.1");
H5Fclose(fid);
}
@@ -1001,10 +1059,10 @@ hid_t fid, group;
H5Gclose(group);
/* create path from object at /g1 to object at /g2 and name it g1.1 */
- H5Glink (fid, H5G_LINK_HARD, "/g2", "/g1/g1.1");
+ H5Glink (fid, H5L_LINK_HARD, "/g2", "/g1/g1.1");
/* create path from object at /g2 to object at /g1 and name it g2.1 */
- H5Glink (fid, H5G_LINK_SOFT, "/g1", "/g2/g2.1");
+ H5Glink (fid, H5L_LINK_SOFT, "/g1", "/g2/g2.1");
H5Fclose(fid);
@@ -1012,13 +1070,13 @@ hid_t fid, group;
/*
/
- | | | \ \ \
- g1 g2 g3 g4 g5 g6
- / \ | | \ \ \
- g1.1 g1.2 slink2 link3 dset2 slink4 dset3
- | | (g1) (dset2) (dset3)
- dset1 link1
- (dset1)
+ | | | \ \ \ \ \
+ g1 g2 g3 g4 g5 g6 g7 g8
+ / \ | | \ \ \ \ \
+ g1.1 g1.2 slink2 link3 dset2 slink4 dset3 slink5 elink
+ | | (g1) (dset2) (dset3) (elink) udlink
+ dset1 link1 slink6
+ (dset1) (udlink)
*/
static void gent_many(void) {
@@ -1043,6 +1101,7 @@ static void gent_many(void) {
hsize_t dim[4];
int idx[4] = {0,1,2,3}; /* normal indicies */
const int perm[4] = {0,1,2,3}; /* the 0'th and the 3'rd indices are permuted */
+ herr_t ret;
fid = H5Fcreate(FILE12, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
@@ -1150,11 +1209,11 @@ static void gent_many(void) {
H5Gclose(group);
group = H5Gcreate (fid, "/g1/g1.2", 0);
- H5Glink (group, H5G_LINK_HARD, "/g1/g1.1/dset1", "link1");
+ H5Glink (group, H5L_LINK_HARD, "/g1/g1.1/dset1", "link1");
H5Gclose(group);
group = H5Gcreate (fid, "/g2", 0);
- H5Glink (group, H5G_LINK_SOFT, "/g1", "slink2");
+ H5Glink (group, H5L_LINK_SOFT, "/g1", "slink2");
H5Gclose(group);
group = H5Gcreate (fid, "/g3", 0);
@@ -1178,7 +1237,7 @@ static void gent_many(void) {
H5Gclose(group);
group = H5Gopen(fid, "/g3");
- H5Glink (group, H5G_LINK_HARD, "/g4/dset2", "link3");
+ H5Glink (group, H5L_LINK_HARD, "/g4/dset2", "link3");
H5Gclose(group);
group = H5Gcreate (fid, "/g5", 0);
@@ -1201,10 +1260,26 @@ static void gent_many(void) {
H5Gclose(group);
group = H5Gopen(fid, "/g5");
- H5Glink (group, H5G_LINK_SOFT, "/g6/dset3", "slink4");
+ H5Glink (group, H5L_LINK_SOFT, "/g6/dset3", "slink4");
H5Gclose(group);
H5Pclose(create_plist);
+ group = H5Gcreate (fid, "/g7", 0);
+ H5Gclose(group);
+ group = H5Gcreate (fid, "/g8", 0);
+ H5Gclose(group);
+
+ /* Create dangling external and UD links */
+ H5Lcreate_external("somefile", "somepath", fid, "/g8/elink", H5P_DEFAULT, H5P_DEFAULT);
+ H5Lregister(UD_link_class);
+ H5Lcreate_ud(fid, "/g8/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
+
+ /* Create links to external and UD links */
+ ret= H5Glink (fid, H5L_LINK_SOFT, "/g8/elink", "/g7/slink5");
+ HDassert(ret >= 0);
+ ret= H5Glink (fid, H5L_LINK_SOFT, "/g8/udlink", "/g7/slink6");
+ HDassert(ret >= 0);
+
H5Fclose(fid);
}
@@ -4927,42 +5002,48 @@ static void gent_fcontents(void)
/* hard link to "dset" */
gid1 = H5Gcreate (fid, "/g1", 0);
- H5Glink (gid1, H5G_LINK_HARD, "/dset", "dset1");
+ H5Glink (gid1, H5L_LINK_HARD, "/dset", "dset1");
H5Gclose(gid1);
/* hard link to "dset" */
gid1 = H5Gcreate (fid, "/g2", 0);
- H5Glink (gid1, H5G_LINK_HARD, "/dset", "dset2");
+ H5Glink (gid1, H5L_LINK_HARD, "/dset", "dset2");
H5Gclose(gid1);
/* hard link to "g2" */
gid1 = H5Gopen(fid, "/g1");
- H5Glink (gid1, H5G_LINK_HARD, "/g2", "g1.1");
+ H5Glink (gid1, H5L_LINK_HARD, "/g2", "g1.1");
H5Gclose(gid1);
/* hard link to "dset" */
- ret=H5Glink (fid, H5G_LINK_HARD, "/dset", "dset3");
+ ret=H5Glink (fid, H5L_LINK_HARD, "/dset", "dset3");
assert(ret>=0);
/* hard link to "dset" */
- ret=H5Glink (fid, H5G_LINK_HARD, "/dset", "dset4");
+ ret=H5Glink (fid, H5L_LINK_HARD, "/dset", "dset4");
assert(ret>=0);
/* soft link to itself */
- ret=H5Glink (fid, H5G_LINK_SOFT, "mylink", "mylink");
+ ret=H5Glink (fid, H5L_LINK_SOFT, "mylink", "mylink");
assert(ret>=0);
/* soft link to "dset" */
- ret=H5Glink (fid, H5G_LINK_SOFT, "/dset", "softlink");
+ ret=H5Glink (fid, H5L_LINK_SOFT, "/dset", "softlink");
assert(ret>=0);
+ /* dangling external link */
+ ret=H5Lcreate_external("fname", "oname", fid, "extlink", H5P_DEFAULT, H5P_DEFAULT);
+ assert(ret>=0);
+ /* dangling udlink */
+ ret=H5Lcreate_ud(fid, "udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
+ assert(ret>=0);
/*-------------------------------------------------------------------------
* datatypes
@@ -5397,11 +5478,11 @@ static void gent_longlinks(void)
objname[F51_MAX_NAME_LEN] = '\0';
/* Create hard link to existing object */
- assert(H5Glink2(fid, "grp1", H5G_LINK_HARD, fid, objname) >= 0);
+ assert(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT) >= 0);
/* Create soft link to existing object */
objname[0] = 'b';
- assert(H5Glink2(fid, "grp1", H5G_LINK_SOFT, fid, objname) >= 0);
+ assert(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT) >= 0);
/* Create group with long name in existing group */
gid2=H5Gcreate(gid, objname, (size_t)0);
@@ -5444,7 +5525,7 @@ static int gent_ldouble(void)
if ((tid = H5Tcopy(H5T_NATIVE_LDOUBLE))<0)
goto error;
- if ((size = H5Tget_size(tid))<0)
+ if ((size = H5Tget_size(tid))==0)
goto error;
if ((did = H5Dcreate(fid, "dset", tid, sid, H5P_DEFAULT))<0)
@@ -5483,6 +5564,8 @@ int main(void)
gent_softlink();
gent_dataset();
gent_hardlink();
+ gent_extlink();
+ gent_udlink();
gent_compound_dt();
gent_all();
gent_loop();
diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in
index 783634c..3f40976 100644
--- a/tools/h5dump/testh5dump.sh.in
+++ b/tools/h5dump/testh5dump.sh.in
@@ -125,10 +125,12 @@ TOOLTEST tattr-3.ddl --header -a /attr2 --attribute=/attr tattr.h5
# test for displaying attributes in shared datatype (also in group and dataset)
TOOLTEST tnamed_dtype_attr.ddl tnamed_dtype_attr.h5
-# test for displaying soft links
+# test for displaying soft links and user-defined links
TOOLTEST tslink-1.ddl tslink.h5
+TOOLTEST tudlink-1.ddl tudlink.h5
# test for displaying the selected link
TOOLTEST tslink-2.ddl -l slink2 tslink.h5
+TOOLTEST tudlink-2.ddl -l udlink2 tudlink.h5
# tests for hard links
TOOLTEST thlink-1.ddl thlink.h5
diff --git a/tools/h5dump/testh5dumpxml.sh.in b/tools/h5dump/testh5dumpxml.sh.in
index 21db71a..490832e 100755
--- a/tools/h5dump/testh5dumpxml.sh.in
+++ b/tools/h5dump/testh5dumpxml.sh.in
@@ -118,6 +118,8 @@ TOOLTEST tcompound_complex.h5.xml --xml tcompound_complex.h5
TOOLTEST tobjref.h5.xml --xml tobjref.h5
TOOLTEST topaque.h5.xml --xml topaque.h5
TOOLTEST tslink.h5.xml --xml tslink.h5
+TOOLTEST tudlink.h5.xml --xml tudlink.h5
+TOOLTEST textlink.h5.xml --xml textlink.h5
TOOLTEST tstr.h5.xml --xml tstr.h5
TOOLTEST tstr2.h5.xml --xml tstr2.h5
TOOLTEST tref.h5.xml --xml tref.h5
diff --git a/tools/h5jam/h5jam.c b/tools/h5jam/h5jam.c
index 5e4d885..afa9ffa 100644
--- a/tools/h5jam/h5jam.c
+++ b/tools/h5jam/h5jam.c
@@ -15,7 +15,6 @@
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
-
#ifdef H5_HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/tools/h5jam/h5jamgentest.c b/tools/h5jam/h5jamgentest.c
index a3a99ca..dd80c29 100644
--- a/tools/h5jam/h5jamgentest.c
+++ b/tools/h5jam/h5jamgentest.c
@@ -65,6 +65,8 @@ char pattern[11] = "abcdefghij";
*/
+#define BUF_SIZE 1024
+
#define LENSTR 50
#define LENSTR2 11
@@ -118,158 +120,63 @@ typedef struct s1_t {
/* VL string datatype name */
#define VLSTR_TYPE "vl_string_type"
+/* A UD link traversal function. Shouldn't actually be called. */
+static hid_t UD_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+return -1;
+}
+#define MY_LINKCLASS 187
+const H5L_link_class_t UD_link_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ MY_LINKCLASS, /* Link type id number */
+ "UD link class", /* name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ UD_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
-/*
+
+/* gent_ub
+ with no ub, identical to gent_all from h5dumpgentest.c
+
+ FILENAME is the name of the file to create
+ UB_SIZE is the size the buffer should be
+ UB_FILL characters will be set to the PATTERN array,
+ the rest of the user block will be NULL.
/ : g1 g2 attr1 attr2
g1 : g1.1 g1.2
g1.1 : dset1.1.1(attr1, attr2) dset1.1.2
-g1.2 : g1.2.1
+g1.2 : g1.2.1 extlink
g1.2.1 : slink
-g2 : dset2.1 dset2.2
+g2 : dset2.1 dset2.2 udlink
*/
-
-static void gent_all(void) {
-hid_t fid, group, attr, dataset, space;
-hsize_t dims[2];
-int data[2][2], dset1[10][10], dset2[20];
-char buf[60];
-int i, j;
-float dset2_1[10], dset2_2[3][5];
-
- fid = H5Fcreate(FILE7, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
-
- /* create groups */
- group = H5Gcreate (fid, "/g1", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g2", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.1", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.2", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0);
- H5Gclose(group);
-
- /* root attributes */
- group = H5Gopen (fid, "/");
-
- dims[0] = 10;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "abcdefghi");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- dims[0] = 2; dims[1] = 2;
- space = H5Screate_simple(2, dims, NULL);
- attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT);
- data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
- H5Awrite(attr, H5T_NATIVE_INT, data);
- H5Sclose(space);
- H5Aclose(attr);
-
- H5Gclose(group);
-
- group = H5Gopen (fid, "/g1/g1.1");
-
- /* dset1.1.1 */
- dims[0] = 10; dims[1] = 10;
- space = H5Screate_simple(2, dims, NULL);
- dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT);
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10; j++)
- dset1[i][j] = j*i;
- H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
- H5Sclose(space);
-
- /* attributes of dset1.1.1 */
- dims[0] = 27;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "1st attribute of dset1.1.1");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- dims[0] = 27;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "2nd attribute of dset1.1.1");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- H5Dclose(dataset);
-
- /* dset1.1.2 */
- dims[0] = 20;
- space = H5Screate_simple(1, dims, NULL);
- dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT);
- for (i = 0; i < 20; i++)
- dset2[i] = i;
- H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
- H5Sclose(space);
- H5Dclose(dataset);
-
- H5Gclose(group);
-
- /* soft link */
- group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
- H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
- H5Gclose(group);
-
- group = H5Gopen (fid, "/g2");
-
- /* dset2.1 */
- dims[0] = 10;
- space = H5Screate_simple(1, dims, NULL);
- dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT);
- for (i = 0; i < 10; i++)
- dset2_1[i] = (float)(i*0.1+1);
- H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
- H5Sclose(space);
- H5Dclose(dataset);
-
- /* dset2.2 */
- dims[0] = 3; dims[1] = 5;
- space = H5Screate_simple(2, dims, NULL);
- dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT);
- for (i = 0; i < 3; i++)
- for (j = 0; j < 5; j++)
- dset2_2[i][j] = (float)((i+1)*j*0.1);
- H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
- H5Sclose(space);
- H5Dclose(dataset);
-
- H5Gclose(group);
-
- H5Fclose(fid);
-
-}
-
-static void gent_withub(void) {
+static void gent_ub(const char * filename, int ub_size, int ub_fill) {
hid_t fid, group, attr, dataset, space;
hid_t create_plist;
hsize_t dims[2];
int data[2][2], dset1[10][10], dset2[20];
-char buf[512];
+char buf[BUF_SIZE];
int i, j;
-unsigned u;
float dset2_1[10], dset2_2[3][5];
int fd;
char *bp;
- create_plist = H5Pcreate(H5P_FILE_CREATE);
- H5Pset_userblock(create_plist,(hsize_t)512);
- fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
+ if(ub_size > 0)
+ {
+ create_plist = H5Pcreate(H5P_FILE_CREATE);
+ H5Pset_userblock(create_plist,(hsize_t)ub_size);
+ fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
+ }
+ else
+ {
+ fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ }
/* create groups */
group = H5Gcreate (fid, "/g1", 0);
@@ -351,153 +258,12 @@ char *bp;
H5Gclose(group);
- /* soft link */
- group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
- H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
- H5Gclose(group);
-
- group = H5Gopen (fid, "/g2");
-
- /* dset2.1 */
- dims[0] = 10;
- space = H5Screate_simple(1, dims, NULL);
- dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT);
- for (i = 0; i < 10; i++)
- dset2_1[i] = (float)(i*0.1+1);
- H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1);
- H5Sclose(space);
- H5Dclose(dataset);
-
- /* dset2.2 */
- dims[0] = 3; dims[1] = 5;
- space = H5Screate_simple(2, dims, NULL);
- dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT);
- for (i = 0; i < 3; i++)
- for (j = 0; j < 5; j++)
- dset2_2[i][j] = (float)((i+1)*j*0.1);
- H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2);
- H5Sclose(space);
- H5Dclose(dataset);
-
- H5Gclose(group);
-
- H5Fclose(fid);
-
-
- fd = HDopen(FILE8,O_RDWR, 0);
- if (fd < 0) {
- /* panic */
- }
- /* fill buf with pattern */
- memset(buf,'\0',512);
- bp = buf;
- for (u = 0; u < strlen(pattern); u++) {
- *bp++ = pattern[u%10];
- }
-
- HDwrite(fd,buf,512);
-
- close(fd);
-}
-
-static void gent_withub513(void) {
-hid_t fid, group, attr, dataset, space;
-hid_t create_plist;
-hsize_t dims[2];
-int data[2][2], dset1[10][10], dset2[20];
-char buf[1023];
-int i, j;
-float dset2_1[10], dset2_2[3][5];
-int fd;
-char *bp;
-
- create_plist = H5Pcreate(H5P_FILE_CREATE);
- H5Pset_userblock(create_plist,(hsize_t)1024);
- fid = H5Fcreate(FILE9, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT);
-
- /* create groups */
- group = H5Gcreate (fid, "/g1", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g2", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.1", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.2", 0);
- H5Gclose(group);
-
- group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0);
- H5Gclose(group);
-
- /* root attributes */
- group = H5Gopen (fid, "/");
-
- dims[0] = 10;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "abcdefghi");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- dims[0] = 2; dims[1] = 2;
- space = H5Screate_simple(2, dims, NULL);
- attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT);
- data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3;
- H5Awrite(attr, H5T_NATIVE_INT, data);
- H5Sclose(space);
- H5Aclose(attr);
-
- H5Gclose(group);
-
- group = H5Gopen (fid, "/g1/g1.1");
-
- /* dset1.1.1 */
- dims[0] = 10; dims[1] = 10;
- space = H5Screate_simple(2, dims, NULL);
- dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT);
- for (i = 0; i < 10; i++)
- for (j = 0; j < 10; j++)
- dset1[i][j] = j*i;
- H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1);
- H5Sclose(space);
-
- /* attributes of dset1.1.1 */
- dims[0] = 27;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "1st attribute of dset1.1.1");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- dims[0] = 27;
- space = H5Screate_simple(1, dims, NULL);
- attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT);
- sprintf(buf, "2nd attribute of dset1.1.1");
- H5Awrite(attr, H5T_NATIVE_SCHAR, buf);
- H5Sclose(space);
- H5Aclose(attr);
-
- H5Dclose(dataset);
-
- /* dset1.1.2 */
- dims[0] = 20;
- space = H5Screate_simple(1, dims, NULL);
- dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT);
- for (i = 0; i < 20; i++)
- dset2[i] = i;
- H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2);
- H5Sclose(space);
- H5Dclose(dataset);
-
- H5Gclose(group);
+ /* external link */
+ H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT);
/* soft link */
group = H5Gopen (fid, "/g1/g1.2/g1.2.1");
- H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink");
+ H5Glink (group, H5L_LINK_SOFT, "somevalue", "slink");
H5Gclose(group);
group = H5Gopen (fid, "/g2");
@@ -525,23 +291,32 @@ char *bp;
H5Gclose(group);
+ /* user-defined link */
+ H5Lregister(UD_link_class);
+ H5Lcreate_ud(fid, "/g2/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT);
+
H5Fclose(fid);
+ /* If a user block is being used, write to it here */
+ if(ub_size > 0)
+ {
+ HDassert(ub_size < BUF_SIZE);
- fd = HDopen(FILE9,O_RDWR, 0);
+ fd = HDopen(filename,O_RDWR, 0);
if (fd < 0) {
/* panic */
}
/* fill buf with pattern */
- memset(buf,'\0',1024);
+ memset(buf,'\0',ub_size);
bp = buf;
- for (i = 0; i < 513; i++) {
+ for (i = 0; i < ub_fill; i++) {
*bp++ = pattern[i%10];
}
- HDwrite(fd,buf,1024);
+ HDwrite(fd,buf,ub_size);
close(fd);
+ }
}
static void
@@ -636,9 +411,9 @@ create_binfile(UBBIN4,512);
create_binfile(UBBIN5,513);
*/
- gent_all();
- gent_withub();
- gent_withub513();
+ gent_ub(FILE7, 0, 0);
+ gent_ub(FILE8, 512, strlen(pattern));
+ gent_ub(FILE9, 1024, 513);
return 0;
}
diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c
index d279ea3..9a51ce2 100644
--- a/tools/h5ls/h5ls.c
+++ b/tools/h5ls/h5ls.c
@@ -1710,7 +1710,7 @@ datatype_list2(hid_t type, const char UNUSED *name)
/*-------------------------------------------------------------------------
- * Function: link_open
+ * Function: slink_open
*
* Purpose: This gets called to open a symbolic link. Since symbolic
* links don't correspond to actual objects we simply print the
@@ -1729,11 +1729,11 @@ datatype_list2(hid_t type, const char UNUSED *name)
*-------------------------------------------------------------------------
*/
static hid_t
-link_open(hid_t location, const char *name)
+slink_open(hid_t location, const char *name)
{
char buf[64];
- if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1;
+ if (H5Lget_linkval (location, name, sizeof(buf), buf, H5P_DEFAULT)<0) return -1;
if (NULL==HDmemchr(buf, 0, sizeof(buf))) {
strcpy(buf+sizeof(buf)-4, "...");
}
@@ -1741,6 +1741,59 @@ link_open(hid_t location, const char *name)
return 0;
}
+/*-------------------------------------------------------------------------
+ * Function: udlink_open
+ *
+ * Purpose: This gets called to open a user-defined link. Since these
+ * links don't correspond to actual objects we simply print a message
+ * and return failure.
+ *
+ * Return: Success: 0 - an invalid object but successful return
+ * of this function.
+ *
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+udlink_open(hid_t location, const char *name)
+{
+ H5L_linkinfo_t linfo;
+ char * buf = NULL;
+ char * filename = NULL;
+ char * path = NULL;
+
+ if(H5Lget_linkinfo(location, name, &linfo, H5P_DEFAULT) < 0) return -1;
+
+ switch(linfo.linkclass)
+ {
+ /* For external links, try to display info for the object it points to */
+ case H5L_LINK_EXTERNAL:
+ if ((buf = HDmalloc(linfo.u.link_size))==NULL) goto error;
+ if (H5Lget_linkval (location, name, sizeof(buf), buf, H5P_DEFAULT)<0) goto error;
+
+ if(H5Lunpack_elink_val(buf, &filename, &path) < 0) goto error;
+ fputs("file: ", stdout);
+ fputs(filename, stdout);
+ fputs(" path: ", stdout);
+ fputs(path, stdout);
+ break;
+
+ default:
+ fputs("cannot follow UD links", stdout);
+ }
+ return 0;
+
+error:
+ if(buf)
+ HDfree(buf);
+ return -1;
+}
/*-------------------------------------------------------------------------
@@ -1828,7 +1881,7 @@ list (hid_t group, const char *name, void *_iter)
/* Show detailed information about the object, beginning with information
* which is common to all objects. */
- if (verbose_g>0 && H5G_LINK!=sb.type) {
+ if (verbose_g>0 && H5G_LINK!=sb.type && H5G_UDLINK!=sb.type) {
if (sb.type>=0)
H5Aiterate(obj, NULL, list_attr, NULL);
printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", sb.fileno[0], objno);
@@ -2063,7 +2116,9 @@ main (int argc, const char *argv[])
NULL, group_list2);
DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose,
NULL, datatype_list2);
- DISPATCH(H5G_LINK, "-> ", link_open, NULL,
+ DISPATCH(H5G_LINK, "-> ", slink_open, NULL,
+ NULL, NULL);
+ DISPATCH(H5G_UDLINK, "-> ", udlink_open, NULL,
NULL, NULL);
#if 0
diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh
index 37581f7..c9aa901 100755
--- a/tools/h5ls/testh5ls.sh
+++ b/tools/h5ls/testh5ls.sh
@@ -118,6 +118,10 @@ TOOLTEST tdset-1.ls -w80 -r -d tdset.h5
# test for displaying soft links
TOOLTEST tslink-1.ls -w80 -r tslink.h5
+# test for displaying external and user-defined links
+TOOLTEST textlink-1.ls -w80 -r textlink.h5
+TOOLTEST tudlink-1.ls -w80 -r tudlink.h5
+
# tests for hard links
TOOLTEST thlink-1.ls -w80 thlink.h5
diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c
index dee6c3f..e59b6d0 100644
--- a/tools/h5repack/h5repack_copy.c
+++ b/tools/h5repack/h5repack_copy.c
@@ -264,17 +264,17 @@ int do_copy_objects(hid_t fidin,
trav_table_t *travt,
pack_opt_t *options) /* repack options */
{
- hid_t grp_in; /* group ID */
- hid_t grp_out; /* group ID */
- hid_t dset_in; /* read dataset ID */
- hid_t dset_out; /* write dataset ID */
- hid_t type_in; /* named type ID */
- hid_t type_out; /* named type ID */
- hid_t dcpl_id; /* dataset creation property list ID */
- hid_t dcpl_out; /* dataset creation property list ID */
- hid_t space_id; /* space ID */
- hid_t ftype_id; /* file data type ID */
- hid_t mtype_id; /* memory data type ID */
+ hid_t grp_in=-1; /* group ID */
+ hid_t grp_out=-1; /* group ID */
+ hid_t dset_in=-1; /* read dataset ID */
+ hid_t dset_out=-1; /* write dataset ID */
+ hid_t type_in=-1; /* named type ID */
+ hid_t type_out=-1; /* named type ID */
+ hid_t dcpl_id=-1; /* dataset creation property list ID */
+ hid_t dcpl_out=-1; /* dataset creation property list ID */
+ hid_t space_id=-1; /* space ID */
+ hid_t ftype_id=-1; /* file data type ID */
+ hid_t mtype_id=-1; /* memory data type ID */
size_t msize; /* memory size of memory type */
void *buf=NULL; /* data buffer */
hsize_t nelmts; /* number of elements in dataset */
@@ -561,30 +561,18 @@ int do_copy_objects(hid_t fidin,
/*-------------------------------------------------------------------------
* H5G_LINK
+ * H5G_UDLINK
+ *
+ * Only handles external links; H5Lcopy will fail for other UD link types
+ * since we don't have creation or copy callbacks for them.
*-------------------------------------------------------------------------
*/
case H5G_LINK:
+ case H5G_UDLINK:
{
- H5G_stat_t statbuf;
- char *targbuf=NULL;
-
- if (H5Gget_objinfo(fidin,travt->objs[i].name,FALSE,&statbuf)<0)
- goto error;
-
- targbuf = malloc(statbuf.linklen);
-
- if (H5Gget_linkval(fidin,travt->objs[i].name,statbuf.linklen,targbuf)<0)
- goto error;
-
- if (H5Glink(fidout,
- H5G_LINK_SOFT,
- targbuf, /* current name of object */
- travt->objs[i].name /* new name of object */
- )<0)
- goto error;
-
- free(targbuf);
+ if(H5Lcopy(fidin, travt->objs[i].name,fidout, travt->objs[i].name, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ goto error;
if (options->verbose)
printf(FORMAT_OBJ,"link",travt->objs[i].name );
@@ -592,6 +580,14 @@ int do_copy_objects(hid_t fidin,
}
break;
+/*-------------------------------------------------------------------------
+ *-------------------------------------------------------------------------
+ */
+ {
+
+ }
+ break;
+
default:
goto error;
}
diff --git a/tools/h5repack/h5repack_list.c b/tools/h5repack/h5repack_list.c
index 05156d4..5622811 100644
--- a/tools/h5repack/h5repack_list.c
+++ b/tools/h5repack/h5repack_list.c
@@ -198,6 +198,9 @@ void print_objlist(const char *filename,
case H5G_LINK:
printf(" %-10s %s\n", "link", info[i].name );
break;
+ case H5G_UDLINK:
+ printf(" %-10s %s\n", "User defined link", info[i].name );
+ break;
default:
printf(" %-10s %s\n", "User defined object", info[i].name );
break;
diff --git a/tools/h5repack/h5repack_refs.c b/tools/h5repack/h5repack_refs.c
index 6e3156b..4884e04 100644
--- a/tools/h5repack/h5repack_refs.c
+++ b/tools/h5repack/h5repack_refs.c
@@ -93,7 +93,7 @@ int do_copy_refobjs(hid_t fidin,
for ( j=0; j<travt->objs[i].nlinks; j++)
{
H5Glink(fidout,
- H5G_LINK_HARD,
+ H5L_LINK_HARD,
travt->objs[i].name,
travt->objs[i].links[j].new_name);
}
@@ -339,7 +339,7 @@ int do_copy_refobjs(hid_t fidin,
{
for ( j=0; j<travt->objs[i].nlinks; j++){
H5Glink(fidout,
- H5G_LINK_HARD,
+ H5L_LINK_HARD,
travt->objs[i].name,
travt->objs[i].links[j].new_name);
}
@@ -384,10 +384,12 @@ int do_copy_refobjs(hid_t fidin,
/*-------------------------------------------------------------------------
* H5G_LINK
+ * H5G_UDLINK
*-------------------------------------------------------------------------
*/
case H5G_LINK:
+ case H5G_UDLINK:
/*nothing to do */
break;
diff --git a/tools/h5repack/testh5repack_dset.c b/tools/h5repack/testh5repack_dset.c
index c345028..ca0f0ca 100644
--- a/tools/h5repack/testh5repack_dset.c
+++ b/tools/h5repack/testh5repack_dset.c
@@ -128,7 +128,7 @@ void write_dset_in(hid_t loc_id,
/* create hard link */
- status = H5Glink(loc_id, H5G_LINK_HARD, "string", "string_link");
+ status = H5Glink(loc_id, H5L_LINK_HARD, "string", "string_link");
/*-------------------------------------------------------------------------
* H5T_BITFIELD
diff --git a/tools/h5repack/testh5repack_main.c b/tools/h5repack/testh5repack_main.c
index 58a7c2a..5299cd4 100644
--- a/tools/h5repack/testh5repack_main.c
+++ b/tools/h5repack/testh5repack_main.c
@@ -1170,7 +1170,6 @@ if (szip_can_encode) {
SKIPPED();
#endif
-
/*-------------------------------------------------------------------------
* end
*-------------------------------------------------------------------------
diff --git a/tools/h5repack/testh5repack_make.c b/tools/h5repack/testh5repack_make.c
index 43b68b1..a74d466 100644
--- a/tools/h5repack/testh5repack_make.c
+++ b/tools/h5repack/testh5repack_make.c
@@ -259,7 +259,14 @@ int make_all_objects(hid_t loc_id)
*-------------------------------------------------------------------------
*/
- H5Glink(loc_id, H5G_LINK_SOFT, "dset", "link");
+ H5Glink(loc_id, H5L_LINK_SOFT, "dset", "link");
+
+/*-------------------------------------------------------------------------
+ * H5G_UDLINK
+ *-------------------------------------------------------------------------
+ */
+ /* Create an external link. Other UD links are not supported by h5repack */
+ H5Lcreate_external("file", "path", loc_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT);
/*-------------------------------------------------------------------------
* write a series of datasetes
@@ -350,11 +357,11 @@ int make_hlinks(hid_t loc_id)
if (write_dset(loc_id,2,dims,"dset",H5T_NATIVE_INT,buf)<0)
return -1;
- if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link1 to dset")<0)
+ if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link1 to dset")<0)
return -1;
- if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link2 to dset")<0)
+ if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link2 to dset")<0)
return -1;
- if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link3 to dset")<0)
+ if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link3 to dset")<0)
return -1;
@@ -370,9 +377,9 @@ int make_hlinks(hid_t loc_id)
if ((group3_id = H5Gcreate(group2_id,"g3",0))<0)
return -1;
- if (H5Glink2(loc_id, "g1", H5G_LINK_HARD, group2_id, "link1 to g1")<0)
+ if (H5Glink2(loc_id, "g1", H5L_LINK_HARD, group2_id, "link1 to g1")<0)
return -1;
- if (H5Glink2(group1_id, "g2", H5G_LINK_HARD, group3_id, "link1 to g2")<0)
+ if (H5Glink2(group1_id, "g2", H5L_LINK_HARD, group3_id, "link1 to g2")<0)
return -1;
H5Gclose(group1_id);
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c
index e8c546e..4fed814 100644
--- a/tools/lib/h5diff.c
+++ b/tools/lib/h5diff.c
@@ -870,6 +870,7 @@ hsize_t diff_compare (hid_t file1_id,
* H5G_DATASET Object is a dataset
* H5G_TYPE Object is a named data type
* H5G_LINK Object is a symbolic link
+ * H5G_UDLINK Object is a user-defined link
*
* Return: Number of differences found
*
@@ -1067,6 +1068,90 @@ hsize_t diff (hid_t file1_id,
}
break;
+ /*-------------------------------------------------------------------------
+ * H5G_UDLINK
+ *-------------------------------------------------------------------------
+ */
+ case H5G_UDLINK:
+ {
+ char *buf1 = NULL;
+ char *buf2 = NULL;
+ H5L_linkinfo_t li1;
+ H5L_linkinfo_t li2;
+
+ if (H5Lget_linkinfo (file1_id, path1, &li1, H5P_DEFAULT) < 0)
+ goto out;
+ if (H5Lget_linkinfo (file1_id, path1, &li2, H5P_DEFAULT) < 0)
+ goto out;
+
+ /* Only external links will have a query function registered */
+ if(li1.linkclass == H5L_LINK_EXTERNAL && li2.linkclass == H5L_LINK_EXTERNAL)
+ {
+ buf1 = HDmalloc (li1.u.link_size);
+ buf2 = HDmalloc (li2.u.link_size);
+
+ if (H5Lget_linkval (file1_id, path1, li1.u.link_size, buf1, H5P_DEFAULT) < 0)
+ {
+ HDfree (buf1); HDfree (buf2);
+ goto out;
+ }
+ if (H5Lget_linkval (file2_id, path2, li2.u.link_size, buf2, H5P_DEFAULT) < 0)
+ {
+ HDfree (buf1); HDfree (buf2);
+ goto out;
+ }
+
+ /* If the buffers are the same size, compare them */
+ if(li1.u.link_size == li2.u.link_size)
+ {
+ if (H5Lget_linkval (file1_id, path1, li1.u.link_size, buf1, H5P_DEFAULT) < 0)
+ {
+ HDfree (buf1); HDfree (buf2);
+ goto out;
+ }
+ if (H5Lget_linkval (file2_id, path2, li2.u.link_size, buf2, H5P_DEFAULT) < 0)
+ {
+ HDfree (buf1); HDfree (buf2);
+ goto out;
+ }
+ ret = HDmemcmp (buf1, buf2, li1.u.link_size);
+ }
+ else
+ ret = 1;
+
+ /* if "buf1" != "buf2" then the links are "different" */
+ nfound = (ret != 0) ? 1 : 0;
+
+ if (print_objname (options, nfound))
+ parallel_print("External Link: <%s> and <%s>\n", path1, path2);
+ }
+ else
+ {
+ /* If one or both of these links isn't an external link, we can only
+ * compare information from H5Lget_linkinfo since we don't have a query
+ * function registered for them. */
+
+ /* If the link classes or the buffer length are not the
+ * same, the links are "different"
+ */
+ if((li1.linkclass != li2.linkclass) || (li1.u.link_size != li2.u.link_size))
+ nfound = 1;
+ else
+ nfound = 0;
+
+ if (print_objname (options, nfound))
+ parallel_print("User-defined Link: <%s> and <%s>\n", path1, path2);
+ }
+
+ /* always print the number of differences found in verbose mode */
+ if (options->m_verbose)
+ print_found(nfound);
+
+ HDfree (buf1);
+ HDfree (buf2);
+ }
+ break;
+
default:
nfound = 0;
if (options->m_verbose)
diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c
index c2c0659..4997c0c 100644
--- a/tools/lib/h5diff_util.c
+++ b/tools/lib/h5diff_util.c
@@ -269,6 +269,8 @@ get_type(int type)
return("H5G_TYPE");
case H5G_LINK:
return("H5G_LINK");
+ case H5G_UDLINK:
+ return("H5G_UDLINK");
default:
return("user defined type");
}
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index a4ccf63..cb62c71 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -594,12 +594,12 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai
/* Setup */
memset(&buffer, 0, sizeof(h5tools_str_t));
size = H5Tget_size(type);
-
+
if (info->line_ncols > 0)
ncols = info->line_ncols;
-
+
h5tools_simple_prefix(stream, info, ctx, (hsize_t)0, 0);
-
+
for (i = 0; i < nelmts; i++, ctx->cur_elmt++, elmt_counter++) {
/* Render the element */
h5tools_str_reset(&buffer);
@@ -1340,7 +1340,7 @@ void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims)
*
*-------------------------------------------------------------------------
*/
-static
+static
int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem)
{
unsigned char *mem = (unsigned char*)_mem;
@@ -1349,7 +1349,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem)
size = H5Tget_size(tid);
- for (i = 0; i < nelmts; i++)
+ for (i = 0; i < nelmts; i++)
{
if (render_bin_output(stream,tid,mem + i * size)<0)
{
@@ -1357,7 +1357,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem)
return FAIL;
}
}
-
+
return SUCCEED;
}
@@ -1377,7 +1377,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem)
*
*-------------------------------------------------------------------------
*/
-static
+static
int render_bin_output(FILE *stream, hid_t tid, void *_mem)
{
#if 0
@@ -1407,88 +1407,88 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH);
}
#endif
-
+
size = H5Tget_size(tid);
-
- if (H5Tequal(tid, H5T_NATIVE_FLOAT))
+
+ if (H5Tequal(tid, H5T_NATIVE_FLOAT))
{
memcpy(&tempfloat, mem, sizeof(float));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%g ", tempfloat);
#else
- if (1 != fwrite(&tempfloat, size, 1, stream))
+ if (1 != fwrite(&tempfloat, size, 1, stream))
return FAIL;
#endif
- }
- else if (H5Tequal(tid, H5T_NATIVE_DOUBLE))
+ }
+ else if (H5Tequal(tid, H5T_NATIVE_DOUBLE))
{
memcpy(&tempdouble, mem, sizeof(double));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%g ", tempdouble);
#else
- if (1 != fwrite(&tempdouble, size, 1, stream))
+ if (1 != fwrite(&tempdouble, size, 1, stream))
return FAIL;
#endif
- }
+ }
#if H5_SIZEOF_LONG_DOUBLE !=0
- else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE))
+ else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE))
{
memcpy(&templdouble, mem, sizeof(long double));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%Lf ", templdouble);
#else
- if (1 != fwrite(&templdouble, size, 1, stream))
+ if (1 != fwrite(&templdouble, size, 1, stream))
return FAIL;
#endif
}
#endif
- else if (H5T_STRING == H5Tget_class(tid))
+ else if (H5T_STRING == H5Tget_class(tid))
{
unsigned int i;
H5T_str_t pad;
char *s;
-
+
pad = H5Tget_strpad(tid);
-
- if(H5Tis_variable_str(tid))
+
+ if(H5Tis_variable_str(tid))
{
s = *(char**)mem;
if(s!=NULL)
size = HDstrlen(s);
}
- else
+ else
{
s = mem;
size = H5Tget_size(tid);
}
- for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++)
+ for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++)
{
memcpy(&tempuchar, &s[i], sizeof(unsigned char));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%d", tempuchar);
#else
- if (1 != fwrite(&tempuchar, size, 1, stream))
+ if (1 != fwrite(&tempuchar, size, 1, stream))
return FAIL;
#endif
} /* i */
}
- else if (H5Tequal(tid, H5T_NATIVE_INT))
+ else if (H5Tequal(tid, H5T_NATIVE_INT))
{
memcpy(&tempint, mem, sizeof(int));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%d ", tempint);
#else
- if (1 != fwrite(&tempint, size, 1, stream))
+ if (1 != fwrite(&tempint, size, 1, stream))
return FAIL;
#endif
}
- else if (H5Tequal(tid, H5T_NATIVE_UINT))
+ else if (H5Tequal(tid, H5T_NATIVE_UINT))
{
memcpy(&tempuint, mem, sizeof(unsigned int));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%u ", tempuint);
#else
- if (1 != fwrite(&tempuint, size, 1, stream))
+ if (1 != fwrite(&tempuint, size, 1, stream))
return FAIL;
#endif
}
@@ -1498,17 +1498,17 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%d ", tempschar);
#else
- if (1 != fwrite(&tempschar, size, 1, stream))
+ if (1 != fwrite(&tempschar, size, 1, stream))
return FAIL;
#endif
- }
+ }
else if (H5Tequal(tid, H5T_NATIVE_UCHAR))
{
memcpy(&tempuchar, mem, sizeof(unsigned char));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%u ", tempuchar);
#else
- if (1 != fwrite(&tempuchar, size, 1, stream))
+ if (1 != fwrite(&tempuchar, size, 1, stream))
return FAIL;
#endif
}
@@ -1518,7 +1518,7 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%d ", tempshort);
#else
- if (1 != fwrite(&tempshort, size, 1, stream))
+ if (1 != fwrite(&tempshort, size, 1, stream))
return FAIL;
#endif
}
@@ -1528,7 +1528,7 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%u ", tempushort);
#else
- if (1 != fwrite(&tempushort, size, 1, stream))
+ if (1 != fwrite(&tempushort, size, 1, stream))
return FAIL;
#endif
}
@@ -1538,27 +1538,27 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%ld ", templong);
#else
- if (1 != fwrite(&templong, size, 1, stream))
+ if (1 != fwrite(&templong, size, 1, stream))
return FAIL;
#endif
- }
+ }
else if (H5Tequal(tid, H5T_NATIVE_ULONG))
{
memcpy(&tempulong, mem, sizeof(unsigned long));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%lu ", tempulong);
#else
- if (1 != fwrite(&tempulong, size, 1, stream))
+ if (1 != fwrite(&tempulong, size, 1, stream))
return FAIL;
#endif
- }
+ }
else if (H5Tequal(tid, H5T_NATIVE_LLONG))
{
memcpy(&templlong, mem, sizeof(long_long));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, fmt_llong, templlong);
#else
- if (1 != fwrite(&templlong, size, 1, stream))
+ if (1 != fwrite(&templlong, size, 1, stream))
return FAIL;
#endif
}
@@ -1568,29 +1568,29 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, fmt_ullong, tempullong);
#else
- if (1 != fwrite(&tempullong, size, 1, stream))
+ if (1 != fwrite(&tempullong, size, 1, stream))
return FAIL;
#endif
}
- else if (H5Tequal(tid, H5T_NATIVE_HSSIZE))
+ else if (H5Tequal(tid, H5T_NATIVE_HSSIZE))
{
- if (sizeof(hssize_t) == sizeof(int))
+ if (sizeof(hssize_t) == sizeof(int))
{
memcpy(&tempint, mem, sizeof(int));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%d ", tempint);
#else
- if (1 != fwrite(&tempint, size, 1, stream))
+ if (1 != fwrite(&tempint, size, 1, stream))
return FAIL;
#endif
}
- else if (sizeof(hssize_t) == sizeof(long))
+ else if (sizeof(hssize_t) == sizeof(long))
{
memcpy(&templong, mem, sizeof(long));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%ld ", templong);
#else
- if (1 != fwrite(&templong, size, 1, stream))
+ if (1 != fwrite(&templong, size, 1, stream))
return FAIL;
#endif
}
@@ -1600,30 +1600,30 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, fmt_llong, templlong);
#else
- if (1 != fwrite(&templlong, size, 1, stream))
+ if (1 != fwrite(&templlong, size, 1, stream))
return FAIL;
#endif
}
- }
- else if (H5Tequal(tid, H5T_NATIVE_HSIZE))
+ }
+ else if (H5Tequal(tid, H5T_NATIVE_HSIZE))
{
- if (sizeof(hsize_t) == sizeof(int))
+ if (sizeof(hsize_t) == sizeof(int))
{
memcpy(&tempuint, mem, sizeof(unsigned int));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%u ", tempuint);
#else
- if (1 != fwrite(&tempuint, size, 1, stream))
+ if (1 != fwrite(&tempuint, size, 1, stream))
return FAIL;
#endif
}
- else if (sizeof(hsize_t) == sizeof(long))
+ else if (sizeof(hsize_t) == sizeof(long))
{
memcpy(&tempulong, mem, sizeof(unsigned long));
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%lu ", tempulong);
#else
- if (1 != fwrite(&tempulong, size, 1, stream))
+ if (1 != fwrite(&tempulong, size, 1, stream))
return FAIL;
#endif
}
@@ -1633,57 +1633,57 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, fmt_ullong, tempullong);
#else
- if (1 != fwrite(&tempullong, size, 1, stream))
+ if (1 != fwrite(&tempullong, size, 1, stream))
return FAIL;
#endif
}
}
- else if (H5Tget_class(tid) == H5T_COMPOUND)
+ else if (H5Tget_class(tid) == H5T_COMPOUND)
{
unsigned j;
hid_t memb;
unsigned nmembs;
size_t offset;
-
+
nmembs = H5Tget_nmembers(tid);
-
- for (j = 0; j < nmembs; j++)
+
+ for (j = 0; j < nmembs; j++)
{
offset = H5Tget_member_offset(tid, j);
memb = H5Tget_member_type(tid, j);
-
+
if (render_bin_output(stream,memb,mem + offset)<0)
return FAIL;
-
+
H5Tclose(memb);
}
}
- else if (H5Tget_class(tid) == H5T_ENUM)
+ else if (H5Tget_class(tid) == H5T_ENUM)
{
unsigned int i;
- if (1==size)
+ if (1==size)
{
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "0x%02x", mem[0]);
#else
- if (1 != fwrite(&mem[0], size, 1, stream))
+ if (1 != fwrite(&mem[0], size, 1, stream))
return FAIL;
#endif
- }
- else
+ }
+ else
{
for (i = 0; i < size; i++)
{
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%s%02x", i?":":"", mem[i]);
#else
- if (1 != fwrite(&mem[i], sizeof(char), 1, stream))
+ if (1 != fwrite(&mem[i], sizeof(char), 1, stream))
return FAIL;
#endif
} /*i*/
}/*else 1 */
}
- else if (H5Tget_class(tid) == H5T_ARRAY)
+ else if (H5Tget_class(tid) == H5T_ARRAY)
{
int k, ndims;
hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts;
@@ -1703,63 +1703,63 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem)
temp_nelmts *= dims[k];
nelmts = (size_t)temp_nelmts;
}
-
+
/* dump the array element */
- for (i = 0; i < nelmts; i++)
+ for (i = 0; i < nelmts; i++)
{
if (render_bin_output(stream,memb,mem + i * size)<0)
return FAIL;
}
-
+
H5Tclose(memb);
}
- else if (H5Tget_class(tid) == H5T_VLEN)
+ else if (H5Tget_class(tid) == H5T_VLEN)
{
unsigned int i;
hsize_t nelmts;
hid_t memb;
-
+
/* get the VL sequences's base datatype for each element */
memb = H5Tget_super(tid);
size = H5Tget_size(memb);
-
+
/* Get the number of sequence elements */
nelmts = ((hvl_t *)mem)->len;
-
- for (i = 0; i < nelmts; i++)
+
+ for (i = 0; i < nelmts; i++)
{
/* dump the array element */
if (render_bin_output(stream,memb,((char *)(((hvl_t *)mem)->p)) + i * size)<0)
return FAIL;
- }
+ }
H5Tclose(memb);
}
- else
+ else
{
size_t i;
- if (1==size)
+ if (1==size)
{
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "0x%02x", mem[0]);
#else
- if (1 != fwrite(&mem[0], size, 1, stream))
+ if (1 != fwrite(&mem[0], size, 1, stream))
return FAIL;
#endif
- }
- else
+ }
+ else
{
for (i = 0; i < size; i++)
{
#ifdef DEBUG_H5DUMP_BIN
fprintf(stream, "%s%02x", i?":":"", mem[i]);
#else
- if (1 != fwrite(&mem[i], sizeof(char), 1, stream))
+ if (1 != fwrite(&mem[i], sizeof(char), 1, stream))
return FAIL;
#endif
} /*i*/
}/*else 1 */
}
-
+
return SUCCEED;
}
diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c
index f49cb07..5d6cfae 100644
--- a/tools/lib/h5tools_ref.c
+++ b/tools/lib/h5tools_ref.c
@@ -171,6 +171,12 @@ ref_path_table_lookup(const char *thepath)
if(H5Gget_objinfo(thefile, thepath, TRUE, &sb)<0)
/* fatal error ? */
return HADDR_UNDEF;
+ } else if(sb.type == H5G_UDLINK)
+ {
+ /* UD links can't be followed, so they always "dangle" like
+ * soft links.
+ */
+ return HADDR_UNDEF;
} /* end if */
objno = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long)));
diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c
index f5c6e91..2ff927c 100644
--- a/tools/lib/h5trav.c
+++ b/tools/lib/h5trav.c
@@ -462,7 +462,7 @@ static int traverse( hid_t loc_id,
*/
case H5G_LINK:
- {
+ {
/* increment */
inserted_objs++;
@@ -489,9 +489,60 @@ static int traverse( hid_t loc_id,
break;
+ /*-------------------------------------------------------------------------
+ * H5G_UDLINK
+ *-------------------------------------------------------------------------
+ */
+
+ case H5G_UDLINK:
+ {
+ H5L_linkinfo_t linkbuf;
+
+ /* increment */
+ inserted_objs++;
+
+ /* add object to table */
+ trav_table_add(HADDR_UNDEF, path, H5G_UDLINK, table );
+
+ /* Get type of link */
+ H5E_BEGIN_TRY {
+
+ /* get link class info */
+ H5Lget_linkinfo( loc_id, path, &linkbuf, H5P_DEFAULT);
+ } H5E_END_TRY;
+
+ if(linkbuf.linkclass == H5L_LINK_EXTERNAL)
+ {
+ if (statbuf.linklen>0)
+ {
+ char *targbuf;
+ char *objname;
+
+ targbuf = HDmalloc(statbuf.linklen);
+ assert(targbuf);
+ H5Gget_linkval(loc_id,path,statbuf.linklen,targbuf);
+ H5Lunpack_elink_val(targbuf, NULL, &objname);
+ if (print)
+ printf(" %-10s %s -> %s %s\n", "ext link", path, targbuf, objname);
+ free(targbuf);
+ }
+ else
+ {
+ if (print)
+ printf(" %-10s %s ->\n", "udlink", path);
+ }
+ }
+ else /* Unknown user-defined type */
+ {
+ if (print)
+ printf(" %-10s %s ->\n", "UD link type", path);
+ }
+ }
+ break;
+
default:
- HDfprintf(stderr, "traverse: Unknown object!\n");
+ HDfprintf(stderr, "traverse: Unknown object %d!\n", type); /* JAMES */
return (-1);
break;
@@ -548,6 +599,9 @@ void h5trav_printinfo(int nobjs, trav_info_t *travi)
case H5G_LINK:
printf(" %-10s %s\n", "link", travi[i].name );
break;
+ case H5G_UDLINK:
+ printf(" %-10s %s\n", "User defined link", travi[i].name );
+ break;
default:
printf(" %-10s %s\n", "User defined object", travi[i].name );
break;
diff --git a/tools/misc/h5stat.c b/tools/misc/h5stat.c
index 4855e68..5d0f23b 100644
--- a/tools/misc/h5stat.c
+++ b/tools/misc/h5stat.c
@@ -608,7 +608,8 @@ printf("walk: fullname = %s\n", fullname);
break;
case H5G_LINK:
- /* Gather statistics about this type of object */
+ case H5G_UDLINK:
+ /* Gather statistics about links and UD links */
iter->uniq_links++;
break;
diff --git a/tools/testfiles/file3.h5 b/tools/testfiles/file3.h5
index 4750ce9..a9eff83 100644
--- a/tools/testfiles/file3.h5
+++ b/tools/testfiles/file3.h5
Binary files differ
diff --git a/tools/testfiles/tall-1.ddl b/tools/testfiles/tall-1.ddl
index 2fd5494..6069293 100644
--- a/tools/testfiles/tall-1.ddl
+++ b/tools/testfiles/tall-1.ddl
@@ -64,6 +64,11 @@ GROUP "/" {
}
}
GROUP "g1.2" {
+ EXTERNAL_LINK "extlink" {
+ LINKCLASS 64
+ TARGETFILE "somefile"
+ TARGETPATH "somepath"
+}
GROUP "g1.2.1" {
SOFTLINK "slink" {
LINKTARGET "somevalue"
@@ -88,6 +93,9 @@ GROUP "/" {
(2,0): 0, 0.3, 0.6, 0.9, 1.2
}
}
+ USERDEFINED_LINK "udlink" {
+ LINKCLASS 187
+ }
}
}
}
diff --git a/tools/testfiles/tall-2.ls b/tools/testfiles/tall-2.ls
index e1b0bcf..5513214 100644
--- a/tools/testfiles/tall-2.ls
+++ b/tools/testfiles/tall-2.ls
@@ -15,6 +15,7 @@
Data:
(0) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
/g1/g1.2 Group
+/g1/g1.2/extlink -> file: somefile path: somepath
/g1/g1.2/g1.2.1 Group
/g1/g1.2/g1.2.1/slink -> somevalue
/g2 Group
@@ -25,3 +26,4 @@
Data:
(0,0) 0, 0.1, 0.2, 0.3, 0.4, 0, 0.2, 0.4, 0.6, 0.8, 0, 0.3, 0.6, 0.9,
(2,4) 1.2
+/g2/udlink -> cannot follow UD links
diff --git a/tools/testfiles/tall-2A.ddl b/tools/testfiles/tall-2A.ddl
index 604c307..b16feb8 100644
--- a/tools/testfiles/tall-2A.ddl
+++ b/tools/testfiles/tall-2A.ddl
@@ -48,6 +48,11 @@ GROUP "/" {
}
}
GROUP "g1.2" {
+ EXTERNAL_LINK "extlink" {
+ LINKCLASS 64
+ TARGETFILE "somefile"
+ TARGETPATH "somepath"
+}
GROUP "g1.2.1" {
SOFTLINK "slink" {
LINKTARGET "somevalue"
@@ -64,6 +69,9 @@ GROUP "/" {
DATATYPE H5T_IEEE_F32BE
DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) }
}
+ USERDEFINED_LINK "udlink" {
+ LINKCLASS 187
+ }
}
}
}
diff --git a/tools/testfiles/tall-2A.h5.xml b/tools/testfiles/tall-2A.h5.xml
index e83f0b3..586afb5 100644
--- a/tools/testfiles/tall-2A.h5.xml
+++ b/tools/testfiles/tall-2A.h5.xml
@@ -3,7 +3,7 @@ Expected output for 'h5dump --xml -A tall.h5'
#############################
<?xml version="1.0" encoding="UTF-8"?>
<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd">
-<hdf5:RootGroup OBJ-XID="xid_928" H5Path="/">
+<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
<hdf5:Attribute Name="attr1">
<hdf5:Dataspace>
<hdf5:SimpleDataspace Ndims="1">
@@ -40,9 +40,9 @@ Expected output for 'h5dump --xml -A tall.h5'
</hdf5:DataFromFile>
</hdf5:Data>
</hdf5:Attribute>
- <hdf5:Group Name="g1" OBJ-XID="xid_1576" H5Path="/g1" Parents="xid_928" H5ParentPaths="/" >
- <hdf5:Group Name="g1.1" OBJ-XID="xid_3200" H5Path="/g1/g1.1" Parents="xid_1576" H5ParentPaths="/g1" >
- <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5200" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_3200" H5ParentPaths="/g1/g1.1">
+ <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Group Name="g1.1" OBJ-XID="xid_2512" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5432" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_2512" H5ParentPaths="/g1/g1.1">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -102,7 +102,7 @@ Expected output for 'h5dump --xml -A tall.h5'
<hdf5:NoData/>
</hdf5:Data>
</hdf5:Dataset>
- <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_5800" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_3200" H5ParentPaths="/g1/g1.1">
+ <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_8272" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_2512" H5ParentPaths="/g1/g1.1">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -126,14 +126,15 @@ Expected output for 'h5dump --xml -A tall.h5'
</hdf5:Data>
</hdf5:Dataset>
</hdf5:Group>
- <hdf5:Group Name="g1.2" OBJ-XID="xid_4176" H5Path="/g1/g1.2" Parents="xid_1576" H5ParentPaths="/g1" >
- <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4824" H5Path="/g1/g1.2/g1.2.1" Parents="xid_4176" H5ParentPaths="/g1/g1.2" >
- <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4824" H5ParentPaths="/g1/g1.2/g1.2.1" />
+ <hdf5:Group Name="g1.2" OBJ-XID="xid_3536" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4232" H5Path="/g1/g1.2/g1.2.1" Parents="xid_3536" H5ParentPaths="/g1/g1.2" >
+ <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4232" H5ParentPaths="/g1/g1.2/g1.2.1" />
</hdf5:Group>
+ <hdf5:ExternalLink LinkName="extlink" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g1/g1.2/extlink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_3536" H5ParentPaths="/g1/g1.2" />
</hdf5:Group>
</hdf5:Group>
- <hdf5:Group Name="g2" OBJ-XID="xid_2552" H5Path="/g2" Parents="xid_928" H5ParentPaths="/" >
- <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8520" H5Path= "/g2/dset2.1" Parents="xid_2552" H5ParentPaths="/g2">
+ <hdf5:Group Name="g2" OBJ-XID="xid_1816" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8872" H5Path= "/g2/dset2.1" Parents="xid_1816" H5ParentPaths="/g2">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -156,7 +157,7 @@ Expected output for 'h5dump --xml -A tall.h5'
<hdf5:NoData/>
</hdf5:Data>
</hdf5:Dataset>
- <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9120" H5Path= "/g2/dset2.2" Parents="xid_2552" H5ParentPaths="/g2">
+ <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9472" H5Path= "/g2/dset2.2" Parents="xid_1816" H5ParentPaths="/g2">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -180,6 +181,7 @@ Expected output for 'h5dump --xml -A tall.h5'
<hdf5:NoData/>
</hdf5:Data>
</hdf5:Dataset>
+ <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g2/udlink" LinkClass="187" Parents="xid_1816" H5ParentPaths="/g2" />
</hdf5:Group>
</hdf5:RootGroup>
</hdf5:HDF5-File>
diff --git a/tools/testfiles/tall-2B.ddl b/tools/testfiles/tall-2B.ddl
index 4969987..002156e 100644
--- a/tools/testfiles/tall-2B.ddl
+++ b/tools/testfiles/tall-2B.ddl
@@ -44,6 +44,11 @@ GROUP "/" {
}
}
GROUP "g1.2" {
+ EXTERNAL_LINK "extlink" {
+ LINKCLASS 64
+ TARGETFILE "somefile"
+ TARGETPATH "somepath"
+}
GROUP "g1.2.1" {
SOFTLINK "slink" {
LINKTARGET "somevalue"
@@ -60,6 +65,9 @@ GROUP "/" {
DATATYPE H5T_IEEE_F32BE
DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) }
}
+ USERDEFINED_LINK "udlink" {
+ LINKCLASS 187
+ }
}
}
}
diff --git a/tools/testfiles/tall.h5 b/tools/testfiles/tall.h5
index 2bc4993..0ed5ed2 100644
--- a/tools/testfiles/tall.h5
+++ b/tools/testfiles/tall.h5
Binary files differ
diff --git a/tools/testfiles/tall.h5.xml b/tools/testfiles/tall.h5.xml
index 22e6f51..ce740fe 100644
--- a/tools/testfiles/tall.h5.xml
+++ b/tools/testfiles/tall.h5.xml
@@ -3,7 +3,7 @@ Expected output for 'h5dump --xml tall.h5'
#############################
<?xml version="1.0" encoding="UTF-8"?>
<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd">
-<hdf5:RootGroup OBJ-XID="xid_928" H5Path="/">
+<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
<hdf5:Attribute Name="attr1">
<hdf5:Dataspace>
<hdf5:SimpleDataspace Ndims="1">
@@ -40,9 +40,9 @@ Expected output for 'h5dump --xml tall.h5'
</hdf5:DataFromFile>
</hdf5:Data>
</hdf5:Attribute>
- <hdf5:Group Name="g1" OBJ-XID="xid_1576" H5Path="/g1" Parents="xid_928" H5ParentPaths="/" >
- <hdf5:Group Name="g1.1" OBJ-XID="xid_3200" H5Path="/g1/g1.1" Parents="xid_1576" H5ParentPaths="/g1" >
- <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5200" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_3200" H5ParentPaths="/g1/g1.1">
+ <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Group Name="g1.1" OBJ-XID="xid_2512" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5432" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_2512" H5ParentPaths="/g1/g1.1">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -113,7 +113,7 @@ Expected output for 'h5dump --xml tall.h5'
</hdf5:DataFromFile>
</hdf5:Data>
</hdf5:Dataset>
- <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_5800" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_3200" H5ParentPaths="/g1/g1.1">
+ <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_8272" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_2512" H5ParentPaths="/g1/g1.1">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -139,14 +139,15 @@ Expected output for 'h5dump --xml tall.h5'
</hdf5:Data>
</hdf5:Dataset>
</hdf5:Group>
- <hdf5:Group Name="g1.2" OBJ-XID="xid_4176" H5Path="/g1/g1.2" Parents="xid_1576" H5ParentPaths="/g1" >
- <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4824" H5Path="/g1/g1.2/g1.2.1" Parents="xid_4176" H5ParentPaths="/g1/g1.2" >
- <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4824" H5ParentPaths="/g1/g1.2/g1.2.1" />
+ <hdf5:Group Name="g1.2" OBJ-XID="xid_3536" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4232" H5Path="/g1/g1.2/g1.2.1" Parents="xid_3536" H5ParentPaths="/g1/g1.2" >
+ <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4232" H5ParentPaths="/g1/g1.2/g1.2.1" />
</hdf5:Group>
+ <hdf5:ExternalLink LinkName="extlink" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g1/g1.2/extlink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_3536" H5ParentPaths="/g1/g1.2" />
</hdf5:Group>
</hdf5:Group>
- <hdf5:Group Name="g2" OBJ-XID="xid_2552" H5Path="/g2" Parents="xid_928" H5ParentPaths="/" >
- <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8520" H5Path= "/g2/dset2.1" Parents="xid_2552" H5ParentPaths="/g2">
+ <hdf5:Group Name="g2" OBJ-XID="xid_1816" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8872" H5Path= "/g2/dset2.1" Parents="xid_1816" H5ParentPaths="/g2">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -171,7 +172,7 @@ Expected output for 'h5dump --xml tall.h5'
</hdf5:DataFromFile>
</hdf5:Data>
</hdf5:Dataset>
- <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9120" H5Path= "/g2/dset2.2" Parents="xid_2552" H5ParentPaths="/g2">
+ <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9472" H5Path= "/g2/dset2.2" Parents="xid_1816" H5ParentPaths="/g2">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -199,6 +200,7 @@ Expected output for 'h5dump --xml tall.h5'
</hdf5:DataFromFile>
</hdf5:Data>
</hdf5:Dataset>
+ <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g2/udlink" LinkClass="187" Parents="xid_1816" H5ParentPaths="/g2" />
</hdf5:Group>
</hdf5:RootGroup>
</hdf5:HDF5-File>
diff --git a/tools/testfiles/tcontents.ddl b/tools/testfiles/tcontents.ddl
index 43afb9d..935ff8c 100644
--- a/tools/testfiles/tcontents.ddl
+++ b/tools/testfiles/tcontents.ddl
@@ -3,11 +3,12 @@ Expected output for 'h5dump -n tfcontents1.h5'
#############################
HDF5 "tfcontents1.h5" {
FILE_CONTENTS {
- datatype /#5696
+ datatype /#6056
dataset /dset
dataset /dset3 -> /dset
dataset /dset4 -> /dset
dataset /dsetmytype2
+ ext link /extlink -> fname oname
group /g1
dataset /g1/dset1 -> /dset
group /g1/g1.1
@@ -16,5 +17,6 @@ FILE_CONTENTS {
link /mylink -> mylink
datatype /mytype
link /softlink -> /dset
+ UD link type /udlink ->
}
}
diff --git a/tools/testfiles/textlink.h5 b/tools/testfiles/textlink.h5
new file mode 100644
index 0000000..a851011
--- /dev/null
+++ b/tools/testfiles/textlink.h5
Binary files differ
diff --git a/tools/testfiles/textlink.h5.xml b/tools/testfiles/textlink.h5.xml
new file mode 100644
index 0000000..fe6f68a
--- /dev/null
+++ b/tools/testfiles/textlink.h5.xml
@@ -0,0 +1,10 @@
+#############################
+Expected output for 'h5dump --xml textlink.h5'
+#############################
+<?xml version="1.0" encoding="UTF-8"?>
+<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd">
+<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
+ <hdf5:ExternalLink LinkName="extlink1" OBJ-XID="xid_18446744073709551614" H5SourcePath="/extlink1" TargetFilename="filename" TargetPath="objname" Parents="xid_96" H5ParentPaths="/" />
+ <hdf5:ExternalLink LinkName="extlink2" OBJ-XID="xid_18446744073709551613" H5SourcePath="/extlink2" TargetFilename="anotherfile" TargetPath="anotherobj" Parents="xid_96" H5ParentPaths="/" />
+</hdf5:RootGroup>
+</hdf5:HDF5-File>
diff --git a/tools/testfiles/tfcontents1.h5 b/tools/testfiles/tfcontents1.h5
index a7cf2d3..8b043fb 100644
--- a/tools/testfiles/tfcontents1.h5
+++ b/tools/testfiles/tfcontents1.h5
Binary files differ
diff --git a/tools/testfiles/tfcontents2.h5 b/tools/testfiles/tfcontents2.h5
index 216a885..1df0779 100644
--- a/tools/testfiles/tfcontents2.h5
+++ b/tools/testfiles/tfcontents2.h5
Binary files differ
diff --git a/tools/testfiles/tmany.h5 b/tools/testfiles/tmany.h5
index 271f13a..0422f93 100644
--- a/tools/testfiles/tmany.h5
+++ b/tools/testfiles/tmany.h5
Binary files differ
diff --git a/tools/testfiles/tmany.h5.xml b/tools/testfiles/tmany.h5.xml
index 60ccb08..1f7fa70 100644
--- a/tools/testfiles/tmany.h5.xml
+++ b/tools/testfiles/tmany.h5.xml
@@ -3,10 +3,10 @@ Expected output for 'h5dump --xml tmany.h5'
#############################
<?xml version="1.0" encoding="UTF-8"?>
<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd">
-<hdf5:RootGroup OBJ-XID="xid_696" H5Path="/">
- <hdf5:Group Name="g1" OBJ-XID="xid_1344" H5Path="/g1" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:Group Name="g1.1" OBJ-XID="xid_2320" H5Path="/g1/g1.1" Parents="xid_1344" H5ParentPaths="/g1" >
- <hdf5:Dataset Name="dset1" OBJ-XID="xid_2696" H5Path= "/g1/g1.1/dset1" Parents="xid_2320" H5ParentPaths="/g1/g1.1">
+<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
+ <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Group Name="g1.1" OBJ-XID="xid_1816" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Dataset Name="dset1" OBJ-XID="xid_2840" H5Path= "/g1/g1.1/dset1" Parents="xid_1816" H5ParentPaths="/g1/g1.1">
<hdf5:StorageLayout>
<hdf5:ChunkedLayout Ndims="1">
<hdf5:ChunkDimension DimSize="2" />
@@ -265,17 +265,17 @@ Expected output for 'h5dump --xml tmany.h5'
</hdf5:Data>
</hdf5:Dataset>
</hdf5:Group>
- <hdf5:Group Name="g1.2" OBJ-XID="xid_5832" H5Path="/g1/g1.2" Parents="xid_1344" H5ParentPaths="/g1" >
- <hdf5:Dataset Name="link1" OBJ-XID="xid_2696-1" H5Path="/g1/g1.2/link1" Parents="xid_5832" H5ParentPaths="/g1/g1.2">
- <hdf5:DatasetPtr OBJ-XID="xid_2696" H5Path="/g1/g1.2/link1"/>
+ <hdf5:Group Name="g1.2" OBJ-XID="xid_6040" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" >
+ <hdf5:Dataset Name="link1" OBJ-XID="xid_2840-1" H5Path="/g1/g1.2/link1" Parents="xid_6040" H5ParentPaths="/g1/g1.2">
+ <hdf5:DatasetPtr OBJ-XID="xid_2840" H5Path="/g1/g1.2/link1"/>
</hdf5:Dataset>
</hdf5:Group>
</hdf5:Group>
- <hdf5:Group Name="g2" OBJ-XID="xid_6808" H5Path="/g2" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:SoftLink LinkName="slink2" OBJ-XID="xid_1344" H5SourcePath="/g2/slink2" TargetPath="/g1" TargetObj="xid_1344" Parents="xid_6808" H5ParentPaths="/g2" />
+ <hdf5:Group Name="g2" OBJ-XID="xid_6520" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:SoftLink LinkName="slink2" OBJ-XID="xid_792" H5SourcePath="/g2/slink2" TargetPath="/g1" TargetObj="xid_792" Parents="xid_6520" H5ParentPaths="/g2" />
</hdf5:Group>
- <hdf5:Group Name="g3" OBJ-XID="xid_7784" H5Path="/g3" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:Dataset Name="link3" OBJ-XID="xid_8480" H5Path= "/g3/link3" Parents="xid_7784" H5ParentPaths="/g3">
+ <hdf5:Group Name="g3" OBJ-XID="xid_10160" H5Path="/g3" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Dataset Name="link3" OBJ-XID="xid_11552" H5Path= "/g3/link3" Parents="xid_10160" H5ParentPaths="/g3">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -311,16 +311,16 @@ Expected output for 'h5dump --xml tmany.h5'
</hdf5:Data>
</hdf5:Dataset>
</hdf5:Group>
- <hdf5:Group Name="g4" OBJ-XID="xid_8432" H5Path="/g4" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:Dataset Name="dset2" OBJ-XID="xid_8480-2" H5Path="/g4/dset2" Parents="xid_8432" H5ParentPaths="/g4">
- <hdf5:DatasetPtr OBJ-XID="xid_8480" H5Path="/g4/dset2"/>
+ <hdf5:Group Name="g4" OBJ-XID="xid_10856" H5Path="/g4" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Dataset Name="dset2" OBJ-XID="xid_11552-2" H5Path="/g4/dset2" Parents="xid_10856" H5ParentPaths="/g4">
+ <hdf5:DatasetPtr OBJ-XID="xid_11552" H5Path="/g4/dset2"/>
</hdf5:Dataset>
</hdf5:Group>
- <hdf5:Group Name="g5" OBJ-XID="xid_10248" H5Path="/g5" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:SoftLink LinkName="slink4" OBJ-XID="xid_10944" H5SourcePath="/g5/slink4" TargetPath="/g6/dset3" TargetObj="xid_10944" Parents="xid_10248" H5ParentPaths="/g5" />
+ <hdf5:Group Name="g5" OBJ-XID="xid_8512" H5Path="/g5" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:SoftLink LinkName="slink4" OBJ-XID="xid_15872" H5SourcePath="/g5/slink4" TargetPath="/g6/dset3" TargetObj="xid_15872" Parents="xid_8512" H5ParentPaths="/g5" />
</hdf5:Group>
- <hdf5:Group Name="g6" OBJ-XID="xid_10896" H5Path="/g6" Parents="xid_696" H5ParentPaths="/" >
- <hdf5:Dataset Name="dset3" OBJ-XID="xid_10944" H5Path= "/g6/dset3" Parents="xid_10896" H5ParentPaths="/g6">
+ <hdf5:Group Name="g6" OBJ-XID="xid_8560" H5Path="/g6" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:Dataset Name="dset3" OBJ-XID="xid_15872" H5Path= "/g6/dset3" Parents="xid_8560" H5ParentPaths="/g6">
<hdf5:StorageLayout>
<hdf5:ContiguousLayout/>
</hdf5:StorageLayout>
@@ -356,5 +356,13 @@ Expected output for 'h5dump --xml tmany.h5'
</hdf5:Data>
</hdf5:Dataset>
</hdf5:Group>
+ <hdf5:Group Name="g7" OBJ-XID="xid_12688" H5Path="/g7" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:SoftLink LinkName="slink5" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g7/slink5" TargetPath="/g8/elink" Parents="xid_12688" H5ParentPaths="/g7" />
+ <hdf5:SoftLink LinkName="slink6" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g7/slink6" TargetPath="/g8/udlink" Parents="xid_12688" H5ParentPaths="/g7" />
+ </hdf5:Group>
+ <hdf5:Group Name="g8" OBJ-XID="xid_720" H5Path="/g8" Parents="xid_96" H5ParentPaths="/" >
+ <hdf5:ExternalLink LinkName="elink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g8/elink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_720" H5ParentPaths="/g8" />
+ <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551611" H5SourcePath="/g8/udlink" LinkClass="187" Parents="xid_720" H5ParentPaths="/g8" />
+ </hdf5:Group>
</hdf5:RootGroup>
</hdf5:HDF5-File>
diff --git a/tools/testfiles/tudlink-1.ddl b/tools/testfiles/tudlink-1.ddl
new file mode 100644
index 0000000..5f76c40
--- /dev/null
+++ b/tools/testfiles/tudlink-1.ddl
@@ -0,0 +1,13 @@
+#############################
+Expected output for 'h5dump tudlink.h5'
+#############################
+HDF5 "tudlink.h5" {
+GROUP "/" {
+ USERDEFINED_LINK "udlink1" {
+ LINKCLASS 187
+ }
+ USERDEFINED_LINK "udlink2" {
+ LINKCLASS 187
+ }
+}
+}
diff --git a/tools/testfiles/tudlink-1.ls b/tools/testfiles/tudlink-1.ls
new file mode 100644
index 0000000..e83fce7
--- /dev/null
+++ b/tools/testfiles/tudlink-1.ls
@@ -0,0 +1,5 @@
+#############################
+ output for 'h5ls -w80 -r tudlink.h5'
+#############################
+/udlink1 -> cannot follow UD links
+/udlink2 -> cannot follow UD links
diff --git a/tools/testfiles/tudlink-2.ddl b/tools/testfiles/tudlink-2.ddl
new file mode 100644
index 0000000..9ae3a54
--- /dev/null
+++ b/tools/testfiles/tudlink-2.ddl
@@ -0,0 +1,9 @@
+#############################
+Expected output for 'h5dump -l udlink2 tudlink.h5'
+#############################
+HDF5 "tudlink.h5" {
+USERDEFINED_LINK "udlink2" {
+ USERDEFINED_LINK "udlink2" {
+ LINKCLASS 187
+}
+}
diff --git a/tools/testfiles/tudlink.h5 b/tools/testfiles/tudlink.h5
new file mode 100644
index 0000000..3b10447
--- /dev/null
+++ b/tools/testfiles/tudlink.h5
Binary files differ
diff --git a/tools/testfiles/tudlink.h5.xml b/tools/testfiles/tudlink.h5.xml
new file mode 100644
index 0000000..aa5fb6c
--- /dev/null
+++ b/tools/testfiles/tudlink.h5.xml
@@ -0,0 +1,10 @@
+#############################
+Expected output for 'h5dump --xml tudlink.h5'
+#############################
+<?xml version="1.0" encoding="UTF-8"?>
+<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd">
+<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/">
+ <hdf5:UserDefined LinkName="udlink1" OBJ-XID="xid_18446744073709551614" H5SourcePath="/udlink1" LinkClass="187" Parents="xid_96" H5ParentPaths="/" />
+ <hdf5:UserDefined LinkName="udlink2" OBJ-XID="xid_18446744073709551613" H5SourcePath="/udlink2" LinkClass="187" Parents="xid_96" H5ParentPaths="/" />
+</hdf5:RootGroup>
+</hdf5:HDF5-File>
diff --git a/tools/testfiles/twithub.h5 b/tools/testfiles/twithub.h5
index 105319f..2176034 100644
--- a/tools/testfiles/twithub.h5
+++ b/tools/testfiles/twithub.h5
Binary files differ
diff --git a/tools/testfiles/twithub513.h5 b/tools/testfiles/twithub513.h5
index 8b6a2e2..fbb872a 100644
--- a/tools/testfiles/twithub513.h5
+++ b/tools/testfiles/twithub513.h5
Binary files differ