summaryrefslogtreecommitdiffstats
path: root/test/links.c
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2006-08-02 23:41:53 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2006-08-02 23:41:53 (GMT)
commit3e755623cb24eb37c19fa645d74dc46948318253 (patch)
tree66e0a3807f37d50a8d6e5f3469864c604cd837c6 /test/links.c
parent71a4d0e9c48c4e02e5384cd3f6e38a2a530e9d22 (diff)
downloadhdf5-3e755623cb24eb37c19fa645d74dc46948318253.zip
hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.gz
hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.bz2
[svn-r12528] Added User-Defined links to the library.
Users can create external links using H5L_create_external(). These links point to an object in another HDF5 file. Users can alter the behavior of external links or create new kinds of links by registering callbacks using the H5L interface. Added tests, tools support, etc. Also a number of other, minor changes have been made (some restructuring of the H5L interface, for instance). Additional documentation and examples are forthcoming.
Diffstat (limited to 'test/links.c')
-rw-r--r--test/links.c3571
1 files changed, 3427 insertions, 144 deletions
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)
}
+