summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am14
-rw-r--r--test/Makefile.in73
-rw-r--r--test/be_extlink1.h5bin0 -> 1120 bytes
-rw-r--r--test/be_extlink2.h5bin0 -> 2840 bytes
-rw-r--r--test/gen_udlinks.c81
-rw-r--r--test/le_extlink1.h5bin0 -> 1120 bytes
-rw-r--r--test/le_extlink2.h5bin0 -> 2840 bytes
-rw-r--r--test/links.c3571
-rw-r--r--test/mount.c24
-rwxr-xr-xtest/objcopy.c195
-rw-r--r--test/stab.c6
-rw-r--r--test/testhdf5.c1
-rw-r--r--test/testhdf5.h2
-rw-r--r--test/th5o.c601
-rw-r--r--test/titerate.c4
-rw-r--r--test/tmisc.c50
-rw-r--r--test/unlink.c322
17 files changed, 4682 insertions, 262 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index afadd52..4e7818b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -58,16 +58,14 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta
# --enable-build-all at configure time.
# The gen_old_* files can only be compiled with older versions of the library
# so do not appear in this list.
+BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \
+ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
+ gen_nullspace space_overflow gen_cross gen_udlinks
+
if BUILD_ALL_CONDITIONAL
- BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \
- gen_new_group gen_new_mtime gen_new_super gen_noencoder \
- gen_nullspace space_overflow gen_cross
-else
- BUILD_ALL_PROGS=
+ noinst_PROGRAMS=$(BUILD_ALL_PROGS)
endif
-noinst_PROGRAMS=$(BUILD_ALL_PROGS)
-
# The libh5test library provides common support code for the tests.
noinst_LTLIBRARIES=libh5test.la
libh5test_la_SOURCES=h5test.c testframe.c cache_common.c
@@ -118,7 +116,7 @@ CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5
# Sources for testhdf5 executable
testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \
- th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
+ th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c
include $(top_srcdir)/config/conclude.am
diff --git a/test/Makefile.in b/test/Makefile.in
index 5339b48..7934415 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -31,7 +31,7 @@
#
-SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -60,7 +60,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/config/conclude.am
check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \
err_compat$(EXEEXT) testmeta$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_2)
+@BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2)
subdir = test
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
@@ -85,17 +85,12 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \
fheap$(EXEEXT) btree2$(EXEEXT)
-@BUILD_ALL_CONDITIONAL_TRUE@am__EXEEXT_2 = gen_deflate$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_filters$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_array$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_fill$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_mtime$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_super$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_noencoder$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ space_overflow$(EXEEXT) \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_cross$(EXEEXT)
+am__EXEEXT_2 = gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \
+ gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \
+ gen_new_group$(EXEEXT) gen_new_mtime$(EXEEXT) \
+ gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \
+ gen_nullspace$(EXEEXT) space_overflow$(EXEEXT) \
+ gen_cross$(EXEEXT) gen_udlinks$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
big_SOURCES = big.c
big_OBJECTS = big.$(OBJEXT)
@@ -222,6 +217,10 @@ gen_nullspace_SOURCES = gen_nullspace.c
gen_nullspace_OBJECTS = gen_nullspace.$(OBJEXT)
gen_nullspace_LDADD = $(LDADD)
gen_nullspace_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
+gen_udlinks_SOURCES = gen_udlinks.c
+gen_udlinks_OBJECTS = gen_udlinks.$(OBJEXT)
+gen_udlinks_LDADD = $(LDADD)
+gen_udlinks_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
getname_SOURCES = getname.c
getname_OBJECTS = getname.$(OBJEXT)
getname_LDADD = $(LDADD)
@@ -292,12 +291,12 @@ stream_test_LDADD = $(LDADD)
stream_test_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) tarray.$(OBJEXT) \
tattr.$(OBJEXT) tconfig.$(OBJEXT) tfile.$(OBJEXT) \
- tgenprop.$(OBJEXT) th5s.$(OBJEXT) theap.$(OBJEXT) \
- tid.$(OBJEXT) titerate.$(OBJEXT) tmeta.$(OBJEXT) \
- tmisc.$(OBJEXT) ttime.$(OBJEXT) trefer.$(OBJEXT) \
- trefstr.$(OBJEXT) tselect.$(OBJEXT) tskiplist.$(OBJEXT) \
- ttst.$(OBJEXT) tunicode.$(OBJEXT) tvltypes.$(OBJEXT) \
- tvlstr.$(OBJEXT)
+ tgenprop.$(OBJEXT) th5o.$(OBJEXT) th5s.$(OBJEXT) \
+ theap.$(OBJEXT) tid.$(OBJEXT) titerate.$(OBJEXT) \
+ tmeta.$(OBJEXT) tmisc.$(OBJEXT) ttime.$(OBJEXT) \
+ trefer.$(OBJEXT) trefstr.$(OBJEXT) tselect.$(OBJEXT) \
+ tskiplist.$(OBJEXT) ttst.$(OBJEXT) tunicode.$(OBJEXT) \
+ tvltypes.$(OBJEXT) tvlstr.$(OBJEXT)
testhdf5_OBJECTS = $(am_testhdf5_OBJECTS)
testhdf5_LDADD = $(LDADD)
testhdf5_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
@@ -336,22 +335,24 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \
error_test.c extend.c external.c fheap.c fillval.c flush1.c \
flush2.c gen_cross.c gen_deflate.c gen_filters.c \
gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
- gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \
- gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \
- ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
- space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \
+ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+ mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \
+ set_extent.c space_overflow.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \
+ vfd.c
DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \
cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \
dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
error_test.c extend.c external.c fheap.c fillval.c flush1.c \
flush2.c gen_cross.c gen_deflate.c gen_filters.c \
gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
- gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \
- gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \
- ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
- space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+ gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \
+ getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+ mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \
+ set_extent.c space_overflow.c stab.c stream_test.c \
+ $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \
+ vfd.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -629,7 +630,6 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \
getname vfd ntypes dangle dtransform reserved cross_read \
fheap btree2
-@BUILD_ALL_CONDITIONAL_FALSE@BUILD_ALL_PROGS =
# These programs generate test files for the tests. They don't need to be
# compiled every time we want to test the library. However, putting
@@ -638,9 +638,9 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \
# --enable-build-all at configure time.
# The gen_old_* files can only be compiled with older versions of the library
# so do not appear in this list.
-@BUILD_ALL_CONDITIONAL_TRUE@BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
-@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace space_overflow gen_cross
+BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \
+ gen_new_group gen_new_mtime gen_new_super gen_noencoder \
+ gen_nullspace space_overflow gen_cross gen_udlinks
# The libh5test library provides common support code for the tests.
@@ -658,7 +658,7 @@ VFD_LIST = sec2 stdio core split multi family
# Sources for testhdf5 executable
testhdf5_SOURCES = testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \
- th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
+ th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \
tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c
@@ -829,6 +829,9 @@ gen_noencoder$(EXEEXT): $(gen_noencoder_OBJECTS) $(gen_noencoder_DEPENDENCIES)
gen_nullspace$(EXEEXT): $(gen_nullspace_OBJECTS) $(gen_nullspace_DEPENDENCIES)
@rm -f gen_nullspace$(EXEEXT)
$(LINK) $(gen_nullspace_LDFLAGS) $(gen_nullspace_OBJECTS) $(gen_nullspace_LDADD) $(LIBS)
+gen_udlinks$(EXEEXT): $(gen_udlinks_OBJECTS) $(gen_udlinks_DEPENDENCIES)
+ @rm -f gen_udlinks$(EXEEXT)
+ $(LINK) $(gen_udlinks_LDFLAGS) $(gen_udlinks_OBJECTS) $(gen_udlinks_LDADD) $(LIBS)
getname$(EXEEXT): $(getname_OBJECTS) $(getname_DEPENDENCIES)
@rm -f getname$(EXEEXT)
$(LINK) $(getname_LDFLAGS) $(getname_OBJECTS) $(getname_LDADD) $(LIBS)
@@ -934,6 +937,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_super.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_noencoder.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_nullspace.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_udlinks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getname.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gheap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5test.Plo@am__quote@
@@ -960,6 +964,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmeta.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgenprop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5o.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/theap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tid.Po@am__quote@
diff --git a/test/be_extlink1.h5 b/test/be_extlink1.h5
new file mode 100644
index 0000000..dedd0a5
--- /dev/null
+++ b/test/be_extlink1.h5
Binary files differ
diff --git a/test/be_extlink2.h5 b/test/be_extlink2.h5
new file mode 100644
index 0000000..d6f9921
--- /dev/null
+++ b/test/be_extlink2.h5
Binary files differ
diff --git a/test/gen_udlinks.c b/test/gen_udlinks.c
new file mode 100644
index 0000000..1230ffe
--- /dev/null
+++ b/test/gen_udlinks.c
@@ -0,0 +1,81 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: James Laird <jlaird@hdfgroup.org>
+ * Tuesday, June 6, 2006
+ *
+ * This program creates HDF5 files with user-defined links. These files
+ * should be created on a little-endian and a big-endian machine.
+ * They will be named according to the platform and should
+ * be placed in the hdf5/test directory so that the links test can use them.
+ */
+
+#include "hdf5.h"
+#include <string.h>
+
+#define NAME_LE_1 "le_extlink1.h5"
+#define NAME_LE_2 "le_extlink2.h5"
+#define NAME_BE_1 "be_extlink1.h5"
+#define NAME_BE_2 "be_extlink2.h5"
+#define NAME_BUF_SIZE 25
+
+int
+main (void)
+{
+ hid_t fid1=-1;
+ hid_t fid2=-1;
+ hid_t gid=-1;
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+
+ /* Name the files differently depending on the endianness of this platform */
+
+ switch(H5Tget_order(H5T_NATIVE_INT))
+ {
+ case H5T_ORDER_LE:
+ strcpy(filename1, NAME_LE_1);
+ strcpy(filename2, NAME_LE_2);
+ break;
+ case H5T_ORDER_BE:
+ strcpy(filename1, NAME_BE_1);
+ strcpy(filename2, NAME_BE_2);
+ break;
+ default:
+ goto error;
+ }
+
+ /* Create the two files */
+ if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
+ if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error;
+
+ /* Create two groups in the second file */
+ if((gid = H5Gcreate(fid2, "group", 0)) < 0) goto error;
+ if((H5Gclose(gid)) < 0) goto error;
+ if((gid = H5Gcreate(fid2, "group/subgroup", 0)) < 0) goto error;
+ if((H5Gclose(gid)) < 0) goto error;
+
+ /* Create an external link in the first file pointing to the group in the second file */
+ if(H5Lcreate_external(filename2, "group", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error;
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+ H5Gclose(gid);
+ } H5E_END_TRY
+ return 1;
+}
diff --git a/test/le_extlink1.h5 b/test/le_extlink1.h5
new file mode 100644
index 0000000..877ba37
--- /dev/null
+++ b/test/le_extlink1.h5
Binary files differ
diff --git a/test/le_extlink2.h5 b/test/le_extlink2.h5
new file mode 100644
index 0000000..d6f9921
--- /dev/null
+++ b/test/le_extlink2.h5
Binary files differ
diff --git a/test/links.c b/test/links.c
index 0e4f680..92f4984 100644
--- a/test/links.c
+++ b/test/links.c
@@ -16,34 +16,23 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Friday, April 10, 1998
*
- * Purpose: Tests hard and soft (symbolic) links.
+ * Purpose: Tests hard, soft (symbolic) & external links.
*/
-#define H5G_PACKAGE /*suppress error about including H5Gpkg */
-
-/* Define this macro to indicate that the testing APIs should be available */
-#define H5G_TESTING
+#include "H5Lprivate.h"
#include "h5test.h"
-#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"links0",
"links1",
"links2",
"links3",
- "links4",
+ "links4a",
+ "links4b",
+ "links4c",
+ "links4d",
"links5",
- "links6",
- "links7",
- "links8",
- "links9",
- "links10",
- "links11",
- "links12",
- "links13",
- "links14",
- "links15",
NULL
};
@@ -51,6 +40,27 @@ const char *FILENAME[] = {
#define NAME_BUF_SIZE 1024
#define MAX_NAME_LEN ((64*1024)+1024)
+/* Link type IDs */
+#define UD_HARD_TYPE 201
+#define UD_CB_TYPE H5L_LINK_MAX
+#define UD_PLIST_TYPE 128
+#define UD_CBFAIL_TYPE UD_PLIST_TYPE
+#define UD_ERROR_TYPE 189
+#define UD_BAD_TYPE1 H5G_LINK_HARD
+#define UD_BAD_TYPE2 (H5L_LINK_UD_MIN - 5)
+#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1)
+
+#define DEST_PROP_NAME "destination_group"
+#define REREG_TARGET_NAME "rereg_target"
+
+#define UD_CB_LINK_NAME "ud_callback_link"
+#define NEW_UD_CB_LINK_NAME "ud_callback_link2"
+#define UD_CB_TARGET "ud_target"
+#define UD_CB_TARGET_LEN 10
+
+#define LE_FILENAME "le_extlink1.h5"
+#define BE_FILENAME "be_extlink1.h5"
+
#define H5L_DIM1 100
#define H5L_DIM2 100
@@ -94,16 +104,16 @@ mklinks(hid_t fapl)
if (H5Dclose (d1)<0) TEST_ERROR;
/* Create a hard link */
- if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a symbolic link */
- if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a symbolic link to something that doesn't exist */
- if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a recursive symbolic link */
- if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT)<0) TEST_ERROR;
+ if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Close */
if (H5Sclose (scalar)<0) TEST_ERROR;
@@ -167,22 +177,22 @@ new_links(hid_t fapl)
/* Create links within a file. Both of source and destination use
* H5L_SAME_LOC. Both hard and soft links should fail. */
H5E_BEGIN_TRY {
- if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
H5E_BEGIN_TRY {
- if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Create links across files with hard link. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR;
+ if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Create hard link to test H5L_SAME_LOC */
- if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create links to test hard links across different locations */
- if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Close dataspace and files */
if (H5Sclose (scalar)<0) TEST_ERROR;
@@ -274,7 +284,7 @@ cklinks(hid_t fapl)
puts(" expected file location.");
TEST_ERROR;
}
- if (H5Gget_linkval(file, "grp1/soft", sizeof linkval, linkval)<0) TEST_ERROR;
+ if (H5Lget_linkval(file, "grp1/soft", sizeof linkval, linkval, H5P_DEFAULT)<0) TEST_ERROR;
if (HDstrcmp(linkval, "/d1")) {
H5_FAILED();
puts(" Soft link test failed. Wrong link value");
@@ -431,7 +441,7 @@ long_links(hid_t fapl)
TESTING("long names for objects & links");
/* Create files */
- h5_fixname(FILENAME[13], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create group with short name in file (used as target for hard links) */
@@ -444,11 +454,11 @@ long_links(hid_t fapl)
objname[MAX_NAME_LEN] = '\0';
/* Create hard link to existing object */
- if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create soft link to existing object */
objname[0] = 'b';
- if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create group with long name in existing group */
if((gid2=H5Gcreate(gid, objname, (size_t)0))<0) TEST_ERROR;
@@ -495,8 +505,7 @@ static int
toomany(hid_t fapl)
{
hid_t fid = (-1); /* File ID */
- hid_t gid = (-1); /* Group ID */
- hid_t gid2 = (-1); /* Datatype ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
char objname[NAME_BUF_SIZE]; /* Object name */
ssize_t name_len; /* Length of object name */
char filename[NAME_BUF_SIZE];
@@ -509,54 +518,54 @@ toomany(hid_t fapl)
*/
HDassert(H5G_NLINKS == 16);
- /* Create files */
- h5_fixname(FILENAME[14], fapl, filename, sizeof filename);
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create group with short name in file (used as target for hard links) */
if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR;
/* Create chain of hard links to existing object (no limit on #) */
- if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create chain of soft links to existing object (limited) */
- if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* Close objects */
if(H5Gclose(gid)<0) TEST_ERROR;
@@ -598,16 +607,14 @@ toomany(hid_t fapl)
if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/soft16")) TEST_ERROR
- /* Create object in external file */
+ /* Create object using soft links */
if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR
- /* Close group in external file */
+ /* Close groups */
if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
- /* Close external object */
- if(H5Gclose(gid) < 0) TEST_ERROR;
-
- /* Close first file */
+ /* Close file */
if(H5Fclose(fid)<0) TEST_ERROR;
PASSED();
@@ -642,7 +649,6 @@ toomany(hid_t fapl)
static int
test_h5l_create(hid_t fapl)
{
- hid_t fapl_id=-1;
hid_t file_id=-1;
hid_t group_id=-1;
hid_t space_id=-1;
@@ -654,13 +660,12 @@ test_h5l_create(hid_t fapl)
int i, n, j;
int wdata[H5L_DIM1][H5L_DIM2];
int rdata[H5L_DIM1][H5L_DIM2];
- TESTING("H5Lcreate");
+ TESTING("H5Llink");
/* Create file */
- fapl_id = h5_fileaccess();
- h5_fixname(FILENAME[3], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[3], fapl, filename, sizeof filename);
- if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create and commit a datatype with no name */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
@@ -672,7 +677,7 @@ test_h5l_create(hid_t fapl)
dims[1] = H5L_DIM2;
if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR;
/* Create a dataset with no name using the committed datatype*/
- if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
/* Verify that we can write to and read from the dataset */
/* Initialize the dataset */
@@ -699,14 +704,14 @@ test_h5l_create(hid_t fapl)
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
/* Link nameless datatype into nameless group */
- if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
/* Create LCPL with intermediate group creation flag set */
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
if(H5Pset_create_intermediate_group(lcpl_id, TRUE) <0) TEST_ERROR;
/* Link nameless dataset into nameless group with intermediate group */
- if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
/* Close IDs for dataset and datatype */
if(H5Dclose(dset_id)<0) TEST_ERROR;
@@ -716,7 +721,7 @@ test_h5l_create(hid_t fapl)
if((type_id = H5Topen(group_id, "datatype"))<0) TEST_ERROR;
/* Link nameless group to root group and close the group ID*/
- if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Open dataset through root group and verify its data */
@@ -738,7 +743,6 @@ test_h5l_create(hid_t fapl)
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
if(H5Sclose(space_id)<0) TEST_ERROR;
if(H5Fclose(file_id)<0) TEST_ERROR;
- if(H5Pclose(fapl_id)<0) TEST_ERROR;
PASSED();
return 0;
@@ -750,7 +754,6 @@ error:
H5Pclose(lcpl_id);
H5Sclose(space_id);
H5Fclose(file_id);
- H5Pclose(fapl_id);
} H5E_END_TRY;
return 1;
} /* end test_h5l_create() */
@@ -791,27 +794,27 @@ test_lcpl(hid_t fapl)
/* Create file */
fapl_id = h5_fileaccess();
- h5_fixname(FILENAME[12], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
/* Create and link a group with the default LCPL */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create and commit a datatype with the default LCPL */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "type", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create a dataspace */
@@ -820,12 +823,12 @@ test_lcpl(hid_t fapl)
if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR;
/* Create a dataset using the default LCPL */
- if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT)<0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
+ if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Dclose(dset_id)<0) TEST_ERROR;
/* Check that its character encoding is the default */
- if(H5Lget_linkinfo(file_id, "dataset", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create a link creation property list with the UTF-8 character encoding */
@@ -834,30 +837,30 @@ test_lcpl(hid_t fapl)
/* Create and link a group with the new LCPL */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/group2", group_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/group2", group_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "group2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create and commit a datatype with the new LCPL */
if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
- if(H5Llink(file_id, "/type2", type_id, lcpl_id)<0) TEST_ERROR;
+ if(H5Llink(file_id, "/type2", type_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "type2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create a dataset using the new LCPL */
- if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id)<0) TEST_ERROR;
+ if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
+ if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Dclose(dset_id)<0) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
- if(H5Lget_linkinfo(file_id, "dataset2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Create a new link to the dataset with a different character encoding. */
@@ -865,15 +868,46 @@ test_lcpl(hid_t fapl)
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR;
- if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR;
/* Check that its character encoding is ASCII */
- if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR;
/* Check that the first link's encoding hasn't changed */
- if(H5Lget_linkinfo(file_id, "/dataset2", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+
+
+/* JAMES: these tests don't work because the character set encoding is
+ * not stored in the symbol table.
+ * Quincey says this will be fixed someday.
+ */
+#ifdef NOTYET
+ /* Make sure that LCPLs work properly for other API calls: */
+ /* H5Lcreate_soft */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR
+ if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR
+
+ /* H5Lmove */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR
+ if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR;
+
+ /* H5Lcopy */
+ if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR;
+ if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+
+ /* H5Lcreate_external */
+ if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
+#endif /* NOTYET */
/* Close open IDs */
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
@@ -924,10 +958,10 @@ test_move(hid_t fapl)
TESTING("H5Lmove");
/* Create two new files */
- h5_fixname(FILENAME[8], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
- h5_fixname(FILENAME[9], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
@@ -937,26 +971,26 @@ test_move(hid_t fapl)
if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) TEST_ERROR;
/* Create hard and soft links. */
- if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0)
+ if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
- if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT)<0)
+ if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Move a group within the file. Both of source and destination use
* H5L_SAME_LOC. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT)
+ if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across files. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT)
+ if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across groups in the same file while renaming it. */
- if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -972,7 +1006,7 @@ test_move(hid_t fapl)
} H5E_END_TRY;
/* Use H5Lmove to rename a group without moving it. */
- if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
@@ -982,7 +1016,7 @@ test_move(hid_t fapl)
TEST_ERROR;
/* Use H5Lmove to move a group without renaming it. */
- if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
@@ -992,7 +1026,7 @@ test_move(hid_t fapl)
TEST_ERROR;
/* Move the group while giving long paths. */
- if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0)
+ if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1063,10 +1097,10 @@ test_copy(hid_t fapl)
TESTING("H5Lcopy");
/* Create two new files */
- h5_fixname(FILENAME[8], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
- h5_fixname(FILENAME[9], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
@@ -1076,26 +1110,26 @@ test_copy(hid_t fapl)
if((grp_move=H5Gcreate(grp_1, "group_copy", 0))<0) TEST_ERROR;
/* Create hard and soft links. */
- if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0)
+ if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
- if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT)<0)
+ if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Copy a group within the file. Both of source and destination use
* H5L_SAME_LOC. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT)
+ if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Copy a group across files. Should fail. */
H5E_BEGIN_TRY {
- if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT)
+ if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)
!=FAIL) TEST_ERROR;
} H5E_END_TRY;
/* Move a group across groups in the same file while renaming it. */
- if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1111,7 +1145,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Use H5Lcopy to create a group in the same location with a different name. */
- if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
@@ -1126,7 +1160,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Use H5Lcopy to copy to a different location with the same name. */
- if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
@@ -1141,7 +1175,7 @@ test_copy(hid_t fapl)
TEST_ERROR;
/* Copy the group while giving long paths. */
- if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0)
+ if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
@@ -1224,7 +1258,7 @@ test_move_preserves(hid_t fapl_id)
TESTING("moving and copying links preserves their properties");
/* Create file */
- h5_fixname(FILENAME[11], fapl_id, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR;
@@ -1233,11 +1267,11 @@ test_move_preserves(hid_t fapl_id)
if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR;
/* Create a group with that lcpl */
if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR;
- if(H5Llink(file_id, "group", group_id, lcpl_id) < 0) TEST_ERROR;
+ if(H5Llink(file_id, "group", group_id, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gclose(group_id) < 0) TEST_ERROR;
/* Get the group's link's creation time */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
old_create_time = linfo.ctime;
old_modification_time = statbuf.mtime;
@@ -1251,33 +1285,33 @@ test_move_preserves(hid_t fapl_id)
if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) <0) TEST_ERROR;
/* Get the group's link's creation time. The times should be unchanged */
- if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Create a new link to the group. It should have a different creation time but the same modification time */
- if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group2", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group2", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time == linfo.ctime) TEST_ERROR;
/* Copy the first link to a UTF-8 name. Its creation time and modification time should not change. */
- if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id) <0) TEST_ERROR;
+ if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_copied", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_copied", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_copied", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the link with the default property list. */
- if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_copied2", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_copied2", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_copied2", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
@@ -1286,25 +1320,25 @@ test_move_preserves(hid_t fapl_id)
/* Check that the original link is unchanged */
if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the first link to a UTF-8 name. Its creation time and modification time should not change. */
- if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_moved", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_moved", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_moved", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is UTF-8 */
if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR;
/* Move the link again using the default property list. */
- if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT) <0) TEST_ERROR;
+ if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "group_moved_again", TRUE, &statbuf) <0) TEST_ERROR;
if(old_modification_time != statbuf.mtime) TEST_ERROR;
- if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo) <0) TEST_ERROR;
+ if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
@@ -1357,7 +1391,7 @@ test_compat(hid_t fapl)
TESTING("backwards compatibility");
/* Create file */
- h5_fixname(FILENAME[15], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
@@ -1439,6 +1473,3222 @@ error:
/*-------------------------------------------------------------------------
+ * Function: external_link_root
+ *
+ * Purpose: Build a file with external link to root group in external file
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 25, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_root(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5G_stat_t sb; /* Object information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+ char *file; /* File from external link */
+ char *path; /* Path from external link */
+
+ TESTING("external link to root");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Check that external links are registered with the library */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+
+ /* Create file with link to first file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Check information for external link */
+ if (H5Gget_objinfo(fid, "ext_link", FALSE, &sb)<0) goto error;
+ if (H5G_UDLINK!=sb.type) {
+ H5_FAILED();
+ puts(" Unexpected object type - should have been an external link");
+ goto error;
+ }
+ if(H5Lget_linkval(fid, "ext_link", sizeof(objname), objname, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Lunpack_elink_val(objname, &file, &path) < 0) TEST_ERROR
+ if(HDstrcmp(file, filename1))
+ {
+ H5_FAILED();
+ puts(" External link file name incorrect");
+ goto error;
+ }
+ if(HDstrcmp(path, "/"))
+ {
+ H5_FAILED();
+ puts(" External link path incorrect");
+ goto error;
+ }
+
+ /* Close and re-open file to ensure that data is written to disk */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((fid = H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Fclose (gid2);
+ H5Fclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_root() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_path
+ *
+ * Purpose: Build a file with external link to object down a path in the
+ * external file
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_path(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+
+ TESTING("external link to object on path");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create object down a path */
+ if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Create file with link to first file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/A/B/C", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_mult
+ *
+ * Purpose: Build a file with external link to object that crossed several
+ * external file links
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_mult(hid_t fapl)
+{
+ hid_t fid = (-1), fid2 = (-1); /* File IDs */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE],
+ filename3[NAME_BUF_SIZE],
+ filename4[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("external links across multiple files");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+ h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3);
+ h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4);
+
+ /* Create first file to point to */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create object down a path */
+ if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file to point to */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link down a path */
+ if((gid = H5Gcreate(fid, "D", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "D/E", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename1, "/A/B/C", gid, "F", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create third file to point to */
+ if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link down a path */
+ if((gid = H5Gcreate(fid, "G", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if((gid = H5Gcreate(fid, "G/H", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create external link to object in second file */
+ if(H5Lcreate_external(filename2, "/D/E/F", gid, "I", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Create file with link to third file */
+ if((fid=H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external link to object in first file */
+ if(H5Lcreate_external(filename3, "/G/H/I", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close second file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+
+ /* Open an object through external links */
+ if((fid = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) <0) TEST_ERROR
+ if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR
+
+ /* The intermediate files should not stay open. Replace one of them with a new file. */
+ if((fid2=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+ if(H5Fclose(fid2)<0) TEST_ERROR
+
+ /* Open the other with write access and delete the external link in it */
+ if((fid2=H5Fopen(filename3, H5F_ACC_RDWR, fapl))<0) TEST_ERROR
+ if(H5Lunlink(fid2, "G/H/I", H5P_DEFAULT) < 0) TEST_ERROR
+
+ if(H5Fclose(fid2)<0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_mult() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_self
+ *
+ * Purpose: Build a file with external link to itself
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Wednesday, July 12, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_GROUP_REVISION
+static int
+external_link_self(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t lcpl_id = (-1); /* Link Creation Property List ID */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE];
+ char filename2[NAME_BUF_SIZE];
+ char filename3[NAME_BUF_SIZE];
+
+ TESTING("external link to self");
+
+ /* Set up filename */
+ h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[2], fapl, filename2, sizeof filename1);
+ h5_fixname(FILENAME[3], fapl, filename3, sizeof filename1);
+
+ /* Create file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create an lcpl with intermediate group creation set */
+ if((lcpl_id=H5Pcreate(H5P_LINK_CREATE))<0) TEST_ERROR
+ if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR
+
+ /* Create a series of groups within the file: /A/B and /X/Y/Z */
+ if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Llink(fid, "A/B", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Llink(fid, "X/Y", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ if(H5Pclose (lcpl_id) <0) TEST_ERROR
+
+ /* Create external link to own root group*/
+ if(H5Lcreate_external(filename1, "/X", fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "A/B/C/")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object through external link */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close created group */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close object opened through external link */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Check on object created */
+ if((gid = H5Gopen(fid, "X/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/X/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Complicate things. Use this file as an intermediate file in a chain
+ * of external links that will go: file2 -> file1 -> file1 -> file3
+ */
+
+ /* Create file2 with an external link to file1 */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ if(H5Lcreate_external(filename1, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file2 */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create file3 as a target */
+ if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+ if((gid=H5Gcreate(fid, "end", 0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open file1 and create an extlink pointing to file3 */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if(H5Lcreate_external(filename3, "/", fid, "/X/Y/Z", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file1 */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+ /* Re-open file2 and traverse through file1 (with its recursive extlink) to file3 */
+ if((fid=H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if((gid=H5Gopen(fid, "ext_link/B/C/Y/Z/end")) < 0) TEST_ERROR
+
+ /* Create object through external link */
+ if((gid2 = H5Gcreate(gid, "newer_group", 0)) < 0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open up file3 and make sure the object was created successfully */
+ if((fid=H5Fopen(filename3, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ if((gid=H5Gopen(fid, "end/newer_group")) < 0) TEST_ERROR
+
+ /* Cleanup */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Fclose (gid2);
+ H5Fclose (gid);
+ H5Pclose (lcpl_id);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_self() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_pingpong
+ *
+ * Purpose: Build a file with external link to object that goes back and
+ * force between two files a couple of times:
+ *
+ * file1:/link1 -> file2: /link2
+ * file2:/link2 -> file1: /link3
+ * file1:/link3 -> file2: /link4
+ * file2:/link4 -> file1: /link5
+ * file1:/link5 -> file2: /link6
+ * file2:/link6 -> file1: /final
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 26, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_pingpong(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("external links back and forth");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create final object */
+ if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/final", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "link1")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object (lets first file close) */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file again and check on object created */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Open object created through external link */
+ if((gid = H5Gopen(fid, "/final/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/final/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_pingpong() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_toomany
+ *
+ * Purpose: Build a file with too many external links to objects (i.e.
+ * more than H5G_NLINKS. Use a "back & forth" style of
+ * linking (like the "ping pong" test above) to minimize the
+ * number of files involved:
+ *
+ * file1:/link1 -> file2: /link2
+ * file2:/link2 -> file1: /link3
+ * file1:/link3 -> file2: /link4
+ * file2:/link4 -> file1: /link5
+ * file1:/link5 -> file2: /link6
+ * file2:/link6 -> file1: /link7
+ * file1:/link7 -> file2: /link8
+ * file2:/link8 -> file1: /link9
+ * file1:/link9 -> file2: /link10
+ * file2:/link10 -> file1: /link11
+ * file1:/link11 -> file2: /link12
+ * file2:/link12 -> file1: /link13
+ * file1:/link13 -> file2: /link14
+ * file2:/link14 -> file1: /link15
+ * file1:/link15 -> file2: /link16
+ * file2:/link16 -> file1: /link17
+ * file1:/link17 -> file2: /final
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 8, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_toomany(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("too many external links");
+
+ /* Make certain test is valid */
+ /* XXX: should probably make a "generic" test that creates the proper
+ * # of links based on this value - QAK
+ */
+ HDassert(H5G_NLINKS == 16);
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link8", fid, "link7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link10", fid, "link9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link12", fid, "link11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link14", fid, "link13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/link16", fid, "link15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/final", fid, "link17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create external links for chain */
+ if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link7", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link9", fid, "link8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link11", fid, "link10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link13", fid, "link12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link15", fid, "link14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename1, "/link17", fid, "link16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create final object */
+ if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "link1");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "link3")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_toomany() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_dangling
+ *
+ * Purpose: Build a file with "dangling" external links: with both
+ * missing files and missing objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 9, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_dangling(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("dangling external links");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create dangling external links */
+ if(H5Lcreate_external("missing", "/missing", fid, "no_file", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external(filename2, "/missing", fid, "no_object", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file (for dangling object test) */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Open object through dangling file external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "no_file");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through dangling object external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "no_object");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_dangling() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_recursive
+ *
+ * Purpose: Build a file with "recursive" external link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 15, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_recursive(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("recursive external links");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+
+ /* Create first file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create recursive external links */
+ if(H5Lcreate_external(filename1, "/recursive", fid, "recursive", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ /* Open file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR;
+
+ /* Open object through dangling file external link */
+ H5E_BEGIN_TRY {
+ gid = H5Gopen(fid, "recursive");
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for recursive external links.");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_recursive() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_query
+ *
+ * Purpose: Query file & object names for external links, as well as
+ * information from H5Gget_obj_info
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 15, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_query(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char *file_name; /* Name of the file the external link points to */
+ char *object_name; /* Name of the object the external link points to */
+ H5G_stat_t sb; /* Object information */
+ H5L_linkinfo_t li; /* Link information */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE], /* Names of files to externally link across */
+ query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */
+
+
+ TESTING("query aspects of external link");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Get size of buffer for external link */
+ if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR
+ if (H5L_LINK_EXTERNAL != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been an external link");
+ goto error;
+ }
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Create second file to point to */
+ if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR
+
+
+ /* Open first file */
+ if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR
+
+ /* Get size of buffer for external link */
+ if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR
+ if (H5L_LINK_EXTERNAL != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been an external link");
+ goto error;
+ }
+
+ /* Get information for external link. It should be two strings right after each other */
+ if(H5Lget_linkval(fid, "src", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Extract the file and object names from the buffer */
+ if(H5Lunpack_elink_val(query_buf, &file_name, &object_name) < 0) TEST_ERROR
+
+ /* Compare the file and object names */
+ if(strcmp(file_name, filename2)) TEST_ERROR;
+ if(strcmp(object_name, "/dst")) TEST_ERROR
+
+ /* Query information about object that external link points to */
+ if (H5Gget_objinfo(fid, "src", TRUE, &sb)<0) goto error;
+ if (H5G_GROUP != sb.type) {
+ H5_FAILED();
+ puts(" Unexpected object type - should have been a group");
+ goto error;
+ }
+
+ /* Close first file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Make sure that passing in NULLs to H5Lunpack_elink_val works */
+ if(H5Lunpack_elink_val(query_buf, NULL, NULL) < 0) TEST_ERROR
+
+ /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */
+ H5E_BEGIN_TRY {
+ if(H5Lunpack_elink_val(NULL, NULL, NULL) >= 0) TEST_ERROR
+ } H5E_END_TRY
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_unlink_compact
+ *
+ * Purpose: Remove an external link (from a compact group)
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_unlink_compact(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("unlinking external link in compact group");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Unlink external link */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Unlink external link */
+ if(H5Gunlink(fid, "src") < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group for external link */
+ if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_unlink_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_unlink_dense
+ *
+ * Purpose: Remove an external link (from a dense group)
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_GROUP_REVISION
+static int
+external_link_unlink_dense(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+ unsigned nmsgs; /* Number of messages in group's header */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking external link in dense group");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR
+
+ /* Create external link */
+ /* (This also covers the case of having an external link in a compact group that's converted to a dense group) */
+ if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != 1) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Create enough objects in the root group to change it into a "dense" group */
+ for(u = 0; u < max_compact; u++) {
+ sprintf(objname, "filler %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group creation property list */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Unlink external link */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Unlink external link */
+ if(H5Gunlink(fid, "src") < 0) TEST_ERROR
+
+ /* Remove enough objects in the root group to change it into a "compact" group */
+ for(u = 0; u < ((max_compact - min_dense) + 1); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != (min_dense - 1)) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group for external link (should be unaffected) */
+ if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_unlink_dense() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: external_link_move
+ *
+ * Purpose: Move/rename external link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 5, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_move(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+
+ TESTING("move external link");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create external link */
+ if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+
+/* Move external link to different name within same group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Move external link within same group */
+ if(H5Gmove(fid, "src", "src2") < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src2")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Move external link to different group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Create another group, to move the external link into */
+ if((gid = H5Gcreate(fid, "group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Move external link to different group */
+ if(H5Gmove2(fid, "src2", gid, "src3") < 0) TEST_ERROR
+
+ /* Close new group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Move external link back to original group */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Move external link back to original location */
+ if(H5Gmove(fid, "/group2/src3", "/src") < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group3", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group3")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_move() */
+
+
+#ifdef H5_GROUP_REVISION
+/*-------------------------------------------------------------------------
+ * Function: external_link_ride
+ *
+ * Purpose: Let an external link "come along for the ride" when a group is
+ * converted between compact & dense forms.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+external_link_ride(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gcpl = (-1); /* Group creation property list ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename1[NAME_BUF_SIZE],
+ filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */
+ unsigned nmsgs; /* Number of messages in group's header */
+ unsigned max_compact; /* Maximum # of links to store in group compactly */
+ unsigned min_dense; /* Minimum # of links to store in group "densely" */
+ unsigned u; /* Local index variable */
+
+ TESTING("external link along for the ride");
+
+ /* Set up filenames */
+ h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2);
+
+ /* Create first file, with external link to object in second file */
+ if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR
+
+ /* Query the group creation properties */
+ if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR
+ if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR
+
+ /* Create enough objects in the root group to change it into a "dense" group */
+ for(u = 0; u < (max_compact + 1); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Create external link */
+ /* (This also covers the case of adding an external link to a dense group) */
+ if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group creation property list */
+ if(H5Pclose(gcpl) < 0) TEST_ERROR
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Create second file to point to */
+ if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
+
+ /* Create object to link to */
+ if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+/* Remove enough objects to convert group containing external link back into compact form */
+
+ /* Open first file */
+ if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open root group */
+ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR
+
+ /* Remove enough objects in the root group to change it into a "compact" group */
+ for(u = 0; u < ((max_compact - min_dense) + 3); u++) {
+ sprintf(objname, "filler %u\n", u);
+ if(H5Gunlink(gid, objname) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on root group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR;
+ if(nmsgs != (min_dense - 1)) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close root group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open object through external link */
+ if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR
+
+ /* Check name */
+ if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in external file */
+ if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close group in external file */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+
+ /* Close external object */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close first file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ /* Open second file */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Open group created through external link */
+ if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close file */
+ if(H5Fclose(fid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(gcpl);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end external_link_ride() */
+#endif /* H5_GROUP_REVISION */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ext_link_endian
+ *
+ * Purpose: Check that external links work properly when they are
+ * moved from big-endian to little-endian systems and
+ * vice versa.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+ext_link_endian(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t lapl_id = (-1); /* Prop List ID */
+ char * srcdir = getenv("srcdir"); /* The source directory */
+ char pathbuf[NAME_BUF_SIZE]; /* Path to the files */
+ char namebuf[NAME_BUF_SIZE];
+
+ TESTING("endianness of external links");
+
+ /*
+ * Create the name of the file to open (in case we are using the --srcdir
+ * option and the file is in a different directory from this test).
+ */
+ if (srcdir && ((HDstrlen(srcdir) + 2) < sizeof(pathbuf)) )
+ {
+ HDstrcpy(pathbuf, srcdir);
+ HDstrcat(pathbuf, "/");
+ }
+ else
+ HDstrcpy(pathbuf, "");
+
+ /* Create a link access property list with the path to the srcdir */
+ if((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ if(H5Pinsert(lapl_id, H5L_ELINK_PREFIX_PROP, strlen(pathbuf) + 1, pathbuf,
+ NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR;
+
+ if(HDstrlen(pathbuf) + HDstrlen(LE_FILENAME) >= sizeof(namebuf)) TEST_ERROR;
+
+ HDstrcpy(namebuf, pathbuf);
+ HDstrcat(namebuf, LE_FILENAME);
+
+ /* Test LE file; try to open a group through the external link */
+ if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+ if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR;
+
+ /* Open a group in the external file using that group ID */
+ if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR;
+
+ /* Close the IDs */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ if(HDstrlen(pathbuf) + HDstrlen(BE_FILENAME) >= sizeof(namebuf)) TEST_ERROR;
+
+ HDstrcpy(namebuf, pathbuf);
+ HDstrcat(namebuf, BE_FILENAME);
+
+ /* Test BE file; try to open a group through the external link */
+ if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+ if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR;
+
+ /* Open a group in the external file using that group ID */
+ if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR;
+
+ /* Close the IDs */
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: ud_hard_links
+ *
+ * Purpose: Check that the functionality of hard links can be duplicated
+ * with user-defined links.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+/* Callback functions for UD hard links. */
+/* UD_hard_create increments the object's reference count */
+static herr_t UD_hard_create(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t UNUSED lcpl_id)
+{
+ haddr_t addr;
+ hid_t target_obj = -1;
+ herr_t ret_value = 0;
+
+ if(udata_size != sizeof(haddr_t))
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ addr = *((haddr_t *) udata);
+
+ /* Open the object this link points to */
+ target_obj= H5Oopen_by_addr(loc_group, addr);
+ if(target_obj < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ /* Increment the reference count of the target object */
+ if(H5Oincr_refcount(target_obj) < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+done:
+ /* Close the target object if we opened it */
+ if(target_obj >= 0)
+ {
+ switch(H5Iget_type(target_obj))
+ {
+ case H5I_GROUP:
+ if(H5Gclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATASET:
+ if(H5Dclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATATYPE:
+ if(H5Tclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ return ret_value;
+}
+
+/* UD_hard_delete decrements the object's reference count */
+static herr_t UD_hard_delete(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ haddr_t addr;
+ hid_t target_obj = -1;
+ herr_t ret_value = 0;
+
+ if(udata_size != sizeof(haddr_t))
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ addr = *((haddr_t *) udata);
+
+ /* Open the object this link points to */
+ target_obj= H5Oopen_by_addr(loc_group, addr);
+ if(target_obj < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+ /* Decrement the reference count of the target object */
+ if(H5Odecr_refcount(target_obj) < 0)
+ {
+ ret_value = -1;
+ goto done;
+ }
+
+done:
+ /* Close the target object if we opened it */
+ if(target_obj >= 0)
+ {
+ switch(H5Iget_type(target_obj))
+ {
+ case H5I_GROUP:
+ if(H5Gclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATASET:
+ if(H5Dclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ case H5I_DATATYPE:
+ if(H5Tclose(target_obj) <0)
+ ret_value = -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ return ret_value;
+}
+
+static hid_t UD_hard_traverse(const char UNUSED *link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t UNUSED lapl_id)
+{
+ haddr_t addr;
+ hid_t ret_value = -1;
+
+ if(udata_size != sizeof(haddr_t))
+ return -1;
+
+ addr = *((haddr_t *) udata);
+
+ ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */
+
+ return ret_value;
+}
+
+const H5L_link_class_t UD_hard_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_HARD_TYPE, /* Link type id number */
+ "UD_hard_link", /* Link class name for debugging */
+ UD_hard_create, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_hard_traverse, /* The actual traversal function */
+ UD_hard_delete, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_hard_links(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ h5_stat_size_t empty_size; /* Size of an empty file */
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("user-defined hard link");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Get the size of the empty file for reference */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR;
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that external links are registered and UD hard links are not */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Register "user-defined hard links" with the library */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are now registered */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Create a group for the UD hard link to point to */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+
+ /* Get address for the group to give to the hard link */
+ if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR;
+
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+
+ /* Create a user-defined "hard link" to the group using the address we got
+ * from H5Lget_linkinfo */
+ if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address), sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close and re-open file to ensure that data is written to disk */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+ /* Open group through UD link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in group */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups*/
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Re-open group without using ud link to check that it was created properly */
+ if((gid = H5Gopen(fid, "group/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/group/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Check that H5Gget_objinfo works on the hard link */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR
+ /* UD hard links have no query function, thus return a "link length" of 0 */
+ if(li.u.link_size != 0) TEST_ERROR
+ if (UD_HARD_TYPE != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been a UD hard link");
+ goto error;
+ }
+
+ /* Unlink the group pointed to by the UD link. It shouldn't be
+ * deleted because of the UD link. */
+ if(H5Gunlink(fid, "/group") < 0) TEST_ERROR;
+
+ /* Ensure we can open the group through the UD link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Unlink the group contained within it. */
+ if(H5Gunlink(gid, "new_group") < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now delete the UD link. This should cause the group to be
+ * deleted, too. */
+ if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* The file should be empty again. */
+ if(empty_size!=h5_get_file_size(filename)) TEST_ERROR;
+
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_hard_links() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ext_link_endian
+ *
+ * Purpose: Check that user defined link types can be unregistered and
+ * reregistered properly.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+ /* A traversal function that ignores any udata and simply opens an object
+ * in the current group named REREG_TARGET_NAME
+ */
+static hid_t UD_rereg_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t UNUSED udata_size, hid_t lapl_id)
+{
+ hid_t ret_value;
+
+ if((ret_value = H5Oopen(cur_group, REREG_TARGET_NAME, lapl_id)) < 0) TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+
+/* This link class has the same ID number as the UD hard links but
+ * has a very different traversal function */
+const H5L_link_class_t UD_rereg_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_HARD_TYPE, /* Link type id number */
+ "UD_reregistered_type", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_rereg_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_link_reregister(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename[NAME_BUF_SIZE];
+ h5_stat_size_t empty_size; /* Size of an empty file */
+
+ TESTING("registering a new class for existing UD links");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Get the size of the empty file for reference */
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+ if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR;
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that UD hard links are not registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Register "user-defined hard links" with the library */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Point a UD defined hard link to a group in the same way as the previous test */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+ if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address),
+ sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR;
+
+ /* Create a group named REREG_TARGET_NAME in the same group as the ud link */
+ if((gid = H5Gcreate(fid, REREG_TARGET_NAME, 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now unregister UD hard links */
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are no longer registered */
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ /* Verify that we can't traverse the ud link anymore */
+ H5E_BEGIN_TRY {
+ if((gid = H5Gopen(fid, "ud_link")) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Verify that we can't create any new links of this type */
+ H5E_BEGIN_TRY {
+ if(H5Lcreate_ud(fid, "ud_link2", UD_HARD_TYPE, &(li.u.address),
+ sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0)
+ TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register a new kind of link with the same ID number */
+ if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR;
+
+ /* Check that UD hard links are registered again */
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Open a group through the ud link (now a different class of link).
+ * It should be a different group
+ * than the UD hard link pointed to */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(name_len != 0) TEST_ERROR
+
+ /* Create object in group */
+ if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups*/
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Re-open group without using ud link to check that it was created properly */
+ if((gid = H5Gopen(fid, "rereg_target/new_group")) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/rereg_target/new_group")) TEST_ERROR
+
+ /* Close opened object */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Unlink the group pointed to by the UD hard link. It shouldn't be
+ * deleted because the UD link incremented its reference count. */
+ if(H5Gunlink(fid, "/group") < 0) TEST_ERROR;
+
+ /* What a mess! Re-register user-defined links to clean up the
+ * reference counts. We shouldn't actually need to unregister the
+ * other link type */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+
+ /* Ensure we can open the group through the UD link (now that UD hard
+ * links have been registered) */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Delete the UD hard link. This should cause the group to be
+ * deleted, too. */
+ if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR;
+
+ /* Unlink the other two groups so that we can make sure the file is empty */
+ if(H5Gunlink(fid, "/rereg_target/new_group")<0) TEST_ERROR;
+ if(H5Gunlink(fid, REREG_TARGET_NAME)<0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* The file should be empty again. */
+ if(empty_size!=h5_get_file_size(filename)) TEST_ERROR;
+
+ if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid2);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_link_reregister() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ud_callbacks
+ *
+ * Purpose: Check that all callbacks are called and are given the correct
+ * information.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+/* Callback functions for UD "callback" links. */
+/* Creation callback. Called during move as well. */
+herr_t UD_cb_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id)
+{
+ if(!link_name) TEST_ERROR;
+ if(loc_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+ if(lcpl_id < 0) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+static hid_t UD_cb_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ const char *target = (char *) udata;
+ hid_t ret_value;
+
+ if(!link_name) TEST_ERROR;
+ if(cur_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
+ TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+/* Callback for when the link is moved or renamed */
+herr_t UD_cb_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ const char *target = (char *) udata;
+
+ if(!new_name) TEST_ERROR;
+ if(new_loc < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cb_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ if(!link_name) TEST_ERROR;
+ if(loc_group < 0) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ return 0;
+
+error:
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cb_query(const char * link_name, void * udata, size_t udata_size, void* buf, size_t buf_size)
+{
+ if(!link_name) TEST_ERROR;
+ if(udata_size > 0 && !udata) TEST_ERROR;
+
+ if(strcmp(link_name, UD_CB_LINK_NAME)) TEST_ERROR;
+ if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR;
+ if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR;
+
+ if(buf)
+ {
+ if(buf_size < 16) TEST_ERROR;
+ strcpy(buf, "query succeeded");
+ }
+
+ /* There are 15 characters and a NULL in "query succeeded" */
+ return 16;
+
+error:
+ return -1;
+}
+
+const H5L_link_class_t UD_cb_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CB_TYPE, /* Link type id number */
+ NULL, /* NULL name (to make sure this doesn't break anything */
+ UD_cb_create, /* Creation callback */
+ UD_cb_move, /* Move/rename callback */
+ UD_cb_move, /* Copy callback */
+ UD_cb_traverse, /* The actual traversal function */
+ UD_cb_delete, /* Deletion callback */
+ UD_cb_query /* Query callback */
+}};
+
+static int
+ud_callbacks(fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t lcpl = (-1); /* Link Creation PL */
+ H5G_stat_t sb; /* Object information */
+ H5L_linkinfo_t li; /* Link information */
+ char ud_target_name[] = UD_CB_TARGET; /* Link target name */
+ char filename[NAME_BUF_SIZE];
+ char query_buf[NAME_BUF_SIZE];
+
+ TESTING("user-defined link callbacks");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Check that registered link classes are, and unregistered ones aren't */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR
+ if(H5Lis_registered(UD_CB_TYPE) != 0) TEST_ERROR
+
+ /* Hit two birds with one stone: register UD hard links from previous
+ * test to check that having two UD links registered at once presents
+ * no problems. */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Register user-defined link class. This is the one we'll actually
+ * be using. */
+ if(H5Lregister(UD_cb_class) < 0) TEST_ERROR;
+
+ /* Check that registered link classes are, and unregistered ones aren't */
+ if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR
+ if(H5Lis_registered(UD_CB_TYPE) != TRUE) TEST_ERROR
+
+ /* Create a group for the UD link to point to */
+ if((gid = H5Gcreate(fid, UD_CB_TARGET, 0)) <0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. These UD links behave like soft links. */
+ if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Try opening group through UD link */
+ if((gid = H5Gopen(fid, UD_CB_LINK_NAME)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Query the link to test its query callback */
+ if (H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT)<0) TEST_ERROR;
+ if(li.u.link_size != 16) TEST_ERROR;
+ if (UD_CB_TYPE != li.linkclass) {
+ H5_FAILED();
+ puts(" Unexpected link class - should have been a UD hard link");
+ goto error;
+ }
+
+ /* Fill the query buffer */
+ if(H5Gget_linkval(fid, UD_CB_LINK_NAME, NAME_BUF_SIZE, query_buf) < 0) TEST_ERROR;
+ if(strcmp(query_buf, "query succeeded") != 0) TEST_ERROR;
+
+ /* Move the link */
+ if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR;
+
+ /* Re-open group to ensure that move worked */
+ if((gid = H5Gopen(fid, NEW_UD_CB_LINK_NAME)) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Remove UD link */
+ if(H5Gunlink(fid, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR;
+
+
+ /* Test that the callbacks don't work if the link class is not registered */
+
+ /* Create a new link. Just for fun, give it a non-default character
+ * encoding (to test that LAPLs work) */
+ if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
+#ifdef H5_GROUP_REVISION
+ if(H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) TEST_ERROR
+#endif /* H5_GROUP_REVISION */
+ if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, lcpl, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Pclose(lcpl)<0) TEST_ERROR
+
+ /* Check its character encoding */
+#ifdef H5_GROUP_REVISION
+ if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.cset != H5T_CSET_UTF8) TEST_ERROR;
+#endif /* H5_GROUP_REVISION */
+
+ /* Unregister the link class so the library forgets what its callbacks do */
+ if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR;
+
+ /* Now test that each of the callbacks fails */
+ H5E_BEGIN_TRY {
+ if(H5Lcreate_ud(fid, NEW_UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ if((gid = H5Gopen(gid, UD_CB_LINK_NAME)) >= 0) TEST_ERROR;
+ if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* The query callback should NOT fail, but should be unable to give a linklen */
+ if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 0) TEST_ERROR;
+ if(li.linkclass != UD_CB_TYPE) TEST_ERROR;
+ if(H5Gget_objinfo(fid, UD_CB_LINK_NAME, FALSE, &sb) <0) TEST_ERROR;
+ if(sb.type != H5G_UDLINK) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose (lcpl);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_callbacks() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: lapl_udata
+ *
+ * Purpose: Check that information can be passed to UD links using the
+ * Link Access Property List.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+UD_plist_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t udata_size, hid_t lapl_id)
+{
+ char target[NAME_BUF_SIZE];
+ hid_t ret_value;
+
+ if(udata_size != 0) TEST_ERROR;
+
+ /* Get the name of the target from the property list. */
+ if(H5Pget(lapl_id, DEST_PROP_NAME, target) < 0) TEST_ERROR;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0)
+ TEST_ERROR;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+const H5L_link_class_t UD_plist_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_PLIST_TYPE, /* Link type id number */
+ "UD_plist_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_plist_traverse, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+lapl_udata(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t plist_id = (-1); /* Property List ID */
+ char group_a_name[NAME_BUF_SIZE];
+ char group_b_name[NAME_BUF_SIZE];
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("user data passed through lapl");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Register UD link types from previous tests to check that having
+ * multiple types registered at once presents no problems. */
+ if(H5Lregister(UD_cb_class) < 0) TEST_ERROR;
+
+ /* Register the link class. We'll actually be using for this test. */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+
+ /* Another link class from a previous test */
+ if(H5Lregister(UD_hard_class) < 0) TEST_ERROR;
+
+ /* Unregister the first link type registered to make sure this doesn't
+ * break anything. */
+ if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR;
+
+ /* Create two groups for the UD link to point to */
+ if((gid = H5Gcreate(fid, "group_a", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if((gid = H5Gcreate(fid, "group_b", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. These UD links have no udata. */
+ if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Create a non-default lapl with a new property pointing to group a*/
+ if((plist_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ strcpy(group_a_name, "group_a");
+ if(H5Pinsert(plist_id, DEST_PROP_NAME, NAME_BUF_SIZE, group_a_name, NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR;
+
+ /* Try opening group through UD link */
+ if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR;
+ if((gid2 = H5Gcreate(gid, "subgroup_a", 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Verify that we can open the new group without using the ud link */
+ if((gid2 = H5Gopen(fid, "/group_a/subgroup_a")) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Now use the same ud link to access group_b */
+ strcpy(group_b_name, "group_b");
+ if(H5Pset(plist_id, DEST_PROP_NAME, group_b_name)<0) TEST_ERROR;
+
+ /* Create a subgroup */
+ if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR;
+ if((gid2 = H5Gcreate(gid, "subgroup_b", 0)) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Verify that we can open the new group without using the ud link */
+ if((gid2 = H5Gopen(fid, "/group_b/subgroup_b")) < 0) TEST_ERROR;
+ if(H5Gclose(gid2) < 0) TEST_ERROR;
+
+ /* Close property list */
+ if(H5Pclose(plist_id) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose (plist_id);
+ H5Gclose (gid);
+ H5Gclose (gid2);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end lapl_udata() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: ud_link_errors
+ *
+ * Purpose: Create error conditions in callbacks and ensure that the
+ * errors propagate correctly.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t UD_cbsucc_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id)
+{
+ /* Check to make sure that this "soft link" has a target */
+ if(udata_size < 1 || !udata)
+ return -1;
+
+ return 0;
+}
+static hid_t UD_cbsucc_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ const char *target = (char *) udata;
+ hid_t ret_value;
+
+ if(!target) goto error;
+
+ if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) goto error;
+
+ return ret_value;
+
+error:
+ return -1;
+}
+/* Failure callback for when the link is moved or renamed */
+herr_t UD_cbfail_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ /* This traversal function will always fail. */
+ return -1;
+}
+/* SuccessCallback for when the link is moved or renamed */
+herr_t UD_cbsucc_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
+{
+ /* This traversal function will always succeed. */
+ return 0;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cbsucc_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ /* This callback will always succeed */
+ return 0;
+}
+/* Callback for when the link is deleted. Also called during move */
+herr_t UD_cbfail_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size)
+{
+ /* This traversal function will always fail. */
+ /* Note: un-deletable links are in general a very bad idea! */
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbfail_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will always fail. */
+ return -1;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbfail_on_write_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will return a buffer size,
+ * but will fail when a buffer is passed in ("writing to the buffer"
+ * fails
+ */
+
+ if(buf != NULL)
+ return -1;
+
+ return 0;
+}
+/* Callback for when the link is queried */
+ssize_t UD_cbsucc_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size)
+{
+ /* This traversal function will return a buffer size,
+ * but will fail when a buffer is passed in ("writing to the buffer"
+ * fails
+ */
+
+ if(buf != NULL && buf_size >= 8)
+ strcpy(buf, "succeed");
+
+ return 8;
+}
+
+/* This class is full of failing callbacks */
+const H5L_link_class_t UD_cbfail_class1[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link1", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbfail_move, /* Move/rename callback */
+ UD_cbfail_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbfail_delete, /* Deletion callback */
+ UD_cbfail_query /* Query callback */
+}};
+
+/* This class is has two failing callbacks, move and query */
+const H5L_link_class_t UD_cbfail_class2[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link2", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbfail_move, /* Move/rename callback */
+ UD_cbsucc_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbsucc_delete, /* Deletion callback */
+ UD_cbfail_on_write_query /* Query callback */
+}};
+
+/* All of these callbacks will succeed */
+const H5L_link_class_t UD_cbfail_class3[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_CBFAIL_TYPE, /* Link type id number */
+ "UD_cbfail_link3", /* Link class name for debugging */
+ UD_cbsucc_create, /* Creation callback */
+ UD_cbsucc_move, /* Move/rename callback */
+ UD_cbsucc_move, /* Copy callback */
+ UD_cbsucc_traverse, /* The actual traversal function */
+ UD_cbsucc_delete, /* Deletion callback */
+ UD_cbsucc_query /* Query callback */
+}};
+
+/* Link classes that are invalid for various reasons */
+const H5L_link_class_t UD_error1_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_ERROR_TYPE, /* Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ NULL, /* This class has no traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error2_class[1] = {{
+ UD_BAD_VERS, /* Invalid H5L_link_class_t version */
+ UD_ERROR_TYPE, /* Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error3_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_BAD_TYPE1, /* Invalid Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+const H5L_link_class_t UD_error4_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ UD_BAD_TYPE2, /* Invalid Link type id number */
+ "UD_error_link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move/rename callback */
+ NULL, /* Copy callback */
+ UD_cbsucc_traverse, /* Traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+static int
+ud_link_errors(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group IDs */
+ char group_name[NAME_BUF_SIZE];
+ char filename[NAME_BUF_SIZE];
+ char query_buf[NAME_BUF_SIZE];
+ H5L_linkinfo_t li; /* Link information */
+
+ TESTING("user-defined link error conditions");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Try to register some invalid link classes */
+ H5E_BEGIN_TRY {
+ if(H5Lregister(UD_error1_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error2_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error3_class) >= 0) TEST_ERROR;
+ if(H5Lregister(UD_error4_class) >= 0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register the UD plist class. */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+ /* Now register the first class we'll be using.
+ * It has the same ID as the plist class, and should replace it. */
+ if(H5Lregister(UD_cbfail_class1) < 0) TEST_ERROR;
+
+ /* Create a group for the UD link to point to */
+ if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Create a user-defined link to the group. */
+ strcpy(group_name, "/group");
+ if(H5Lcreate_ud(fid, "/ud_link", UD_CBFAIL_TYPE, &group_name, strlen(group_name) + 1, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Open the group through the ud link */
+ if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Now test that each of the callbacks will cause a failure if it returns -1 */
+ H5E_BEGIN_TRY {
+ /* The create callback will fail if we pass in no udata */
+ if(H5Lcreate_ud(fid, "fail", UD_CBFAIL_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ /* The move and copy callbacks will fail */
+ if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR;
+ if(H5Lcopy(fid, "ud_link", fid, "copy_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR;
+ /* The traversal callback will fail if we remove its target */
+ if(H5Gunlink(fid, "group") < 0) TEST_ERROR;
+ if((gid = H5Gopen(gid, "ud_link")) >= 0) TEST_ERROR;
+ /* The deletion callback will always fail */
+ if(H5Gunlink(fid, "ud_link") >= 0) TEST_ERROR;
+ /* The query callback will fail */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Now use a class with different callback functions */
+ if(H5Lregister(UD_cbfail_class2) < 0) TEST_ERROR;
+
+ /* Moving should still fail, but copying will succeed */
+ H5E_BEGIN_TRY {
+ if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR
+ } H5E_END_TRY
+ if(H5Lcopy(fid, "ud_link", fid, "copy_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* The query callback will succeed when we only want to get the size of the buffer... */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 0) TEST_ERROR;
+ /* ...but fail when we try to write data to the buffer itself*/
+ H5E_BEGIN_TRY {
+ if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) >=0) TEST_ERROR;
+ } H5E_END_TRY
+
+ /* Register a new class */
+ if(H5Lregister(UD_cbfail_class3) < 0) TEST_ERROR;
+
+ /* Now querying should succeed */
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR;
+ if(li.u.link_size != 8) TEST_ERROR;
+ if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) <0) TEST_ERROR;
+ if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR;
+
+ /* Moving and copying should both succeed */
+ if(H5Gmove(fid, "copy_succ", "move_succ") < 0) TEST_ERROR
+ if(H5Lcopy(fid, "ud_link", fid, "copy_succ2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Delete link (this callback should work now) */
+ if(H5Gunlink(fid, "ud_link") <0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: lapl_nlinks
+ *
+ * Purpose: Check that the maximum number of soft links can be adjusted
+ * by the user using the Link Access Property List.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+lapl_nlinks(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1), gid2 = (-1); /* Group IDs */
+ hid_t plist = (-1); /* lapl ID */
+ hid_t tid = (-1), sid = (-1), did = (-1); /* Other IDs */
+ hid_t gapl = (-1), dapl = (-1), tapl = (-1); /* Other property lists */
+ char objname[NAME_BUF_SIZE]; /* Object name */
+ ssize_t name_len; /* Length of object name */
+ char filename[NAME_BUF_SIZE];
+ size_t nlinks; /* nlinks for H5Pset_nlinks */
+ hsize_t dims[2];
+
+ TESTING("adjusting nlinks with LAPL");
+
+ /* Make certain test is valid */
+ /* XXX: should probably make a "generic" test that creates the proper
+ * # of links based on this value - QAK
+ */
+ HDassert(H5G_NLINKS == 16);
+
+ /* Create file */
+ h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Create group with short name in file (used as target for links) */
+ if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR;
+
+ /* Create chain of soft links to existing object (limited) */
+ if(H5Glink2(fid, "final", H5G_LINK_SOFT, fid, "soft1") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft1", H5G_LINK_SOFT, fid, "soft2") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft2", H5G_LINK_SOFT, fid, "soft3") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft3", H5G_LINK_SOFT, fid, "soft4") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft4", H5G_LINK_SOFT, fid, "soft5") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft5", H5G_LINK_SOFT, fid, "soft6") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft6", H5G_LINK_SOFT, fid, "soft7") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft7", H5G_LINK_SOFT, fid, "soft8") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft8", H5G_LINK_SOFT, fid, "soft9") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft9", H5G_LINK_SOFT, fid, "soft10") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft10", H5G_LINK_SOFT, fid, "soft11") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft11", H5G_LINK_SOFT, fid, "soft12") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft12", H5G_LINK_SOFT, fid, "soft13") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft13", H5G_LINK_SOFT, fid, "soft14") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft14", H5G_LINK_SOFT, fid, "soft15") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft15", H5G_LINK_SOFT, fid, "soft16") < 0) TEST_ERROR;
+ if(H5Glink2(fid, "soft16", H5G_LINK_SOFT, fid, "soft17") < 0) TEST_ERROR;
+
+ /* Close objects */
+ if(H5Gclose(gid)<0) TEST_ERROR;
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ /* Open file */
+ if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
+
+ /* Create LAPL with higher-than-usual nlinks value */
+ /* Create a non-default lapl with udata set to point to the first group */
+ if((plist = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR;
+ nlinks = 20;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Ensure that nlinks was set successfully */
+ nlinks = 0;
+ if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR
+ if(nlinks != 20) TEST_ERROR
+
+ /* Open object through what is normally too many soft links using
+ * new property list */
+ if((gid = H5Oopen(fid, "soft17", plist)) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/soft17")) TEST_ERROR
+
+ /* Create group using soft link */
+ if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR
+
+ /* Close groups */
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Set nlinks to a smaller number */
+ nlinks = 4;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Ensure that nlinks was set successfully */
+ nlinks = 0;
+ if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR;
+ if(nlinks != 4) TEST_ERROR;
+
+ /* Try opening through what is now too many soft links */
+ H5E_BEGIN_TRY {
+ gid = H5Oopen(fid, "soft5", plist);
+ } H5E_END_TRY;
+ if (gid >= 0) {
+ H5_FAILED();
+ puts(" Should have failed for sequence of too many nested links.");
+ goto error;
+ }
+
+ /* Open object through lesser soft link */
+ if((gid = H5Oopen(fid, "soft4", plist)) < 0) TEST_ERROR;
+
+ /* Check name */
+ if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
+ if(HDstrcmp(objname, "/soft4")) TEST_ERROR
+
+
+ /* Test other functions that should use a LAPL */
+ nlinks = 20;
+ if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR;
+
+ /* Try copying and moving when both src and dst cotain many soft links
+ * using a non-default LAPL
+ */
+ if(H5Lcopy(fid, "soft17", fid, "soft17/newer_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR
+ if(H5Lmove(fid, "soft17/newer_soft", fid, "soft17/newest_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Llink */
+ if(H5Llink(fid, "soft17/link_to_group", gid, H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Lcreate_hard and H5Lcreate_soft */
+ if(H5Lcreate_hard(fid, "soft17", fid, "soft17/link2_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR
+ if(H5Lcreate_soft("/soft4", fid, "soft17/soft_link", H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* H5Lunlink */
+ if(H5Lunlink(fid, "soft17/soft_link", plist) < 0) TEST_ERROR
+
+ /* H5Lget_linkval and H5Lget_linkinfo */
+ if(H5Lget_linkval(fid, "soft17", 0, NULL, plist) < 0) TEST_ERROR
+ if(H5Lget_linkinfo(fid, "soft17", NULL, plist) < 0) TEST_ERROR
+
+ /* H5Lcreate_external and H5Lcreate_ud */
+ if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) <0) TEST_ERROR
+ if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR
+ if(H5Lcreate_ud(fid, "soft17/udlink", UD_HARD_TYPE, NULL, 0, H5P_DEFAULT, plist) < 0) TEST_ERROR
+
+ /* Close plist */
+ if(H5Pclose(plist) < 0) TEST_ERROR;
+
+
+ /* Create a datatype and dataset as targets inside the group */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if(H5Tcommit(gid, "datatype", tid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ dims[0] = 2;
+ dims[1] = 2;
+ if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
+ if((did = H5Dcreate(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR;
+
+ /* Close group */
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+
+ /* Try to open the objects using too many symlinks with default *APLs */
+ H5E_BEGIN_TRY {
+ if((gid = H5Gopen_expand(fid, "soft17", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ if((tid = H5Topen_expand(fid, "soft17/datatype", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ if((did = H5Dopen_expand(fid, "soft17/dataset", H5P_DEFAULT)) >=0) {
+ H5_FAILED();
+ puts(" Should have failed for too many nested links.");
+ TEST_ERROR;
+ }
+ } H5E_END_TRY
+
+ /* Create property lists with nlinks set */
+ if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR
+ if((tapl = H5Pcreate(H5P_DATATYPE_ACCESS)) < 0) TEST_ERROR
+ if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR
+
+ nlinks = 20;
+ if(H5Pset_nlinks(gapl, nlinks) < 0) TEST_ERROR
+ if(H5Pset_nlinks(tapl, nlinks) < 0) TEST_ERROR
+ if(H5Pset_nlinks(dapl, nlinks) < 0) TEST_ERROR
+
+ /* We should now be able to use these property lists to open each kind
+ * of object.
+ */
+ if((gid = H5Gopen_expand(fid, "soft17", gapl)) <0) TEST_ERROR
+ if((tid = H5Topen_expand(fid, "soft17/datatype", tapl)) <0) TEST_ERROR
+ if((did = H5Dopen_expand(fid, "soft17/dataset", dapl)) <0) TEST_ERROR
+
+ /* Close objects */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* Close plists */
+ if(H5Pclose(gapl) < 0) TEST_ERROR;
+ if(H5Pclose(tapl) < 0) TEST_ERROR;
+ if(H5Pclose(dapl) < 0) TEST_ERROR;
+
+ /* Close file */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Pclose(gapl);
+ H5Pclose(dapl);
+ H5Pclose(tapl);
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Tclose(tid);
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Pclose(plist);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end lapl_nlinks() */
+
+/*-------------------------------------------------------------------------
+ * Function: objinfo_linkclass
+ *
+ * Purpose: Check that the link class is returned correctly when queried.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: James Laird
+ * Tuesday, June 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+linkinfo(hid_t fapl)
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+ hid_t tid = (-1); /* Type ID */
+ hid_t sid = (-1), did = -(1); /* Dataspace and dataset IDs */
+ H5L_linkinfo_t li; /* Link information */
+ char filename[NAME_BUF_SIZE];
+
+ TESTING("linkclass field in H5Gget_objinfo");
+
+ /* Set up filename and create file*/
+ h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+
+ if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
+
+ /* Register a couple of user-defined link classes with the library */
+ if(H5Lregister(UD_plist_class) < 0) TEST_ERROR;
+
+ /* Create an object of each type */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR;
+ if(H5Tcommit(fid, "datatype", tid) < 0) TEST_ERROR;
+ if((gid = H5Gcreate(fid, "group", 0)) < 0) TEST_ERROR;
+ if(H5Glink(fid, H5G_LINK_SOFT, "group", "softlink") < 0) TEST_ERROR;
+
+ if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR;
+ if((did = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR;
+
+ if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lcreate_external("file_name", "obj_path", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Close all objects */
+ if(H5Tclose(tid) < 0) TEST_ERROR;
+ if(H5Gclose(gid) < 0) TEST_ERROR;
+ if(H5Dclose(did) < 0) TEST_ERROR;
+
+ /* Make sure that linkclass is correct when objects are queried */
+ if(H5Lget_linkinfo(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_HARD) TEST_ERROR;
+
+ if(H5Lget_linkinfo(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5L_LINK_EXTERNAL) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != H5G_LINK_SOFT) TEST_ERROR;
+ if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(li.linkclass != UD_PLIST_TYPE) TEST_ERROR;
+
+ /* Ensure that passing a NULL pointer doesn't cause an error */
+ if(H5Lget_linkinfo(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ if(H5Fclose(fid) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+ error:
+ H5E_BEGIN_TRY {
+ H5Tclose (tid);
+ H5Dclose (did);
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end ud_hard_links() */
+
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test links
@@ -1467,7 +4717,6 @@ main(void)
if (HDstrcmp(envval, "core") && HDstrcmp(envval, "split")) {
h5_reset();
fapl = h5_fileaccess();
-
/* The tests... */
nerrors += mklinks(fapl) < 0 ? 1 : 0;
nerrors += cklinks(fapl) < 0 ? 1 : 0;
@@ -1488,6 +4737,39 @@ main(void)
#endif
nerrors += test_compat(fapl);
+ nerrors += external_link_root(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_path(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_mult(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_self(fapl) < 0 ? 1 : 0;
+#endif
+ nerrors += external_link_pingpong(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_toomany(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_dangling(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_recursive(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_query(fapl) < 0 ? 1 : 0;
+ nerrors += external_link_unlink_compact(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_unlink_dense(fapl) < 0 ? 1 : 0;
+#endif /* H5_GROUP_REVISION */
+ nerrors += external_link_move(fapl) < 0 ? 1 : 0;
+#ifdef H5_GROUP_REVISION
+ nerrors += external_link_ride(fapl) < 0 ? 1 : 0;
+#endif /* H5_GROUP_REVISION */
+ nerrors += ext_link_endian(fapl) < 0 ? 1 : 0;
+
+ /* These tests assume that external links are a form of UD links,
+ * so assume that everything that passed for external links
+ * above has already been tested for UD links.
+ */
+ nerrors += ud_hard_links(fapl) < 0 ? 1 : 0;
+ nerrors += ud_link_reregister(fapl) < 0 ? 1 : 0;
+ nerrors += ud_callbacks(fapl) < 0 ? 1 : 0;
+ nerrors += ud_link_errors(fapl) < 0 ? 1 : 0;
+ nerrors += lapl_udata(fapl) < 0 ? 1 : 0;
+ nerrors += lapl_nlinks(fapl) < 0 ? 1 : 0;
+ nerrors += linkinfo(fapl) < 0 ? 1 : 0;
+
/* Results */
if (nerrors) {
printf("***** %d LINK TEST%s FAILED! *****\n",
@@ -1505,3 +4787,4 @@ main(void)
}
+
diff --git a/test/mount.c b/test/mount.c
index 8e5a903..cfd99dc 100644
--- a/test/mount.c
+++ b/test/mount.c
@@ -71,8 +71,8 @@ setup(hid_t fapl)
if (H5Gclose(H5Gcreate(file, "/mnt1/file1", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_unlink", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_move_a", (size_t)0))<0) goto error;
- if (H5Glink(file, H5G_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error;
- if (H5Glink(file, H5G_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error;
+ if (H5Glink(file, H5L_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error;
+ if (H5Glink(file, H5L_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error;
if (H5Fclose(file)<0) goto error;
/* file 2 */
@@ -486,9 +486,9 @@ test_move(hid_t fapl)
if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
/* First rename an object in the mounted file, then try it across files */
- if (H5Gmove(file1, "/mnt1/rename_a/x", "/mnt1/rename_b/y")<0) goto error;
+ if (H5Lmove(file1, "/mnt1/rename_a/x", H5L_SAME_LOC, "/mnt1/rename_b/y", H5P_DEFAULT, H5P_DEFAULT)<0) goto error;
H5E_BEGIN_TRY {
- status = H5Gmove(file1, "/mnt1/rename_b/y", "/y");
+ status = H5Lmove(file1, "/mnt1/rename_b/y", H5L_SAME_LOC, "/y", H5P_DEFAULT, H5P_DEFAULT);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -796,7 +796,7 @@ test_mvmpt(hid_t fapl)
if (H5Fmount(file1, "/mnt_move_a", file2, H5P_DEFAULT)<0) TEST_ERROR
/* Rename the mount point */
- if (H5Gmove(file1, "/mnt_move_a", "/mnt_move_b")<0) TEST_ERROR
+ if (H5Lmove(file1, "/mnt_move_a", H5L_SAME_LOC, "/mnt_move_b", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR
/* Access something under the new name */
if (H5Gget_objinfo(file1, "/mnt_move_b/file2", TRUE, NULL)<0) TEST_ERROR
@@ -854,7 +854,7 @@ test_interlink(hid_t fapl)
/* Try an interfile hard link directly */
H5E_BEGIN_TRY {
- status = H5Glink(file1, H5G_LINK_HARD, "/mnt1/file2", "/file2");
+ status = H5Glink(file1, H5L_LINK_HARD, "/mnt1/file2", "/file2");
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -864,7 +864,7 @@ test_interlink(hid_t fapl)
/* Try an interfile hard link by renaming something */
H5E_BEGIN_TRY {
- status = H5Gmove(file1, "/mnt1/file2", "/file2");
+ status = H5Lmove(file1, "/mnt1/file2", H5L_SAME_LOC, "/file2", H5P_DEFAULT, H5P_DEFAULT);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
@@ -1108,9 +1108,9 @@ test_mount_after_close(hid_t fapl)
TEST_ERROR
if((gidABM = H5Gcreate(gidAB , "M", (size_t)0)) < 0) /* Mount point */
TEST_ERROR
- if(H5Glink(gidAB, H5G_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */
+ if(H5Glink(gidAB, H5L_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */
TEST_ERROR
- if(H5Glink(gidAB, H5G_LINK_SOFT, "/A", "T") < 0) /* Soft link */
+ if(H5Glink(gidAB, H5L_LINK_SOFT, "/A", "T") < 0) /* Soft link */
TEST_ERROR
/* Close groups and file */
@@ -1144,7 +1144,7 @@ test_mount_after_close(hid_t fapl)
TEST_ERROR
if((did = H5Dcreate(gidXY, "D", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0)
TEST_ERROR
- if(H5Glink(gidX, H5G_LINK_SOFT, "./Y", "T") < 0) /* Soft link */
+ if(H5Glink(gidX, H5L_LINK_SOFT, "./Y", "T") < 0) /* Soft link */
TEST_ERROR
/* Write data to the dataset. */
@@ -1450,7 +1450,7 @@ test_mount_after_unmount(hid_t fapl)
/* Rename object in file #3 that is "disconnected" from name hiearchy */
/* (It is "disconnected" because it's parent file has been unmounted) */
- if(H5Gmove2(gidAMX,"M/Y",gidAMX,"M/Z") < 0)
+ if(H5Lmove(gidAMX,"M/Y",gidAMX,"M/Z", H5P_DEFAULT, H5P_DEFAULT) < 0)
TEST_ERROR
/* Close group in file #3 */
@@ -3686,7 +3686,7 @@ test_symlink(hid_t fapl)
TEST_ERROR
/* Create soft link to mounted object */
- if(H5Glink(fid1, H5G_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */
+ if(H5Glink(fid1, H5L_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */
TEST_ERROR
if(H5Fclose(fid1) < 0)
diff --git a/test/objcopy.c b/test/objcopy.c
index a96d5b0..7efef50 100755
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -25,6 +25,7 @@
const char *FILENAME[] = {
"objcopy_src",
"objcopy_dst",
+ "objcopy_ext",
NULL
};
@@ -63,6 +64,7 @@ const char *FILENAME[] = {
#define NAME_LINK_HARD "/g_links/hard_link_to_dataset_simple"
#define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple"
#define NAME_LINK_SOFT2 "/g_links2/soft_link_to_dataset_simple"
+#define NAME_LINK_EXTERN "/g_links/external_link_to_dataset_simple"
#define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere"
#define NAME_LINK_SOFT_DANGLE2 "/g_links2/soft_link_to_nowhere"
@@ -817,6 +819,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
H5G_obj_t objtype2; /* Type of object in group */
H5G_stat_t objstat; /* Object info */
H5G_stat_t objstat2; /* Object info */
+ H5L_linkinfo_t linfo; /* Link information */
+ H5L_linkinfo_t linfo2; /* Link information */
hid_t oid, oid2; /* IDs of objects within group */
/* Loop over contents of groups */
@@ -835,12 +839,16 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
if(H5Gget_objinfo(gid, objname, FALSE, &objstat) < 0) TEST_ERROR;
if(H5Gget_objinfo(gid2, objname2, FALSE, &objstat2) < 0) TEST_ERROR;
if(objstat.type != objstat2.type) TEST_ERROR;
- if(objstat.type != H5G_LINK) {
+ if(objstat.type != H5G_LINK && objstat.type != H5G_UDLINK) {
if(objstat.nlink != objstat2.nlink) TEST_ERROR;
if(objstat.ohdr.nmesgs != objstat2.ohdr.nmesgs) TEST_ERROR;
if(objstat.ohdr.nchunks != objstat2.ohdr.nchunks) TEST_ERROR;
} /* end if */
+ /* Get link info */
+ if(H5Lget_linkinfo(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkinfo(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR;
+
/* Check for object already having been compared */
if(addr_lookup(&objstat))
continue;
@@ -855,8 +863,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
char linkname2[NAME_BUF_SIZE]; /* Link value */
/* Check link values */
- if(H5Gget_linkval(gid, objname, NAME_BUF_SIZE, linkname) < 0) TEST_ERROR;
- if(H5Gget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkname, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2, H5P_DEFAULT) < 0) TEST_ERROR;
if(HDstrcmp(linkname, linkname2)) TEST_ERROR;
}
break;
@@ -900,6 +908,24 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth)
if(H5Tclose(oid2) < 0) TEST_ERROR;
break;
+ case H5G_UDLINK:
+ {
+ char linkval[NAME_BUF_SIZE]; /* Link value */
+ char linkval2[NAME_BUF_SIZE]; /* Link value */
+
+ /* Check that both links are the same type and the same size */
+ if(linfo.linkclass != linfo2.linkclass) TEST_ERROR;
+ if(linfo.u.link_size != linfo2.u.link_size) TEST_ERROR;
+
+ /* Get link udata */
+ if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkval, H5P_DEFAULT) < 0) TEST_ERROR;
+ if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkval2, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* Compare link udata */
+ if(HDmemcmp(linkval, linkval2, objstat.linklen)) TEST_ERROR;
+ }
+ break;
+
default:
HDassert(0 && "Unknown type of object");
break;
@@ -4102,7 +4128,7 @@ test_copy_group_loop(hid_t fapl)
if ( (gid_sub2 = H5Gcreate(gid, NAME_GROUP_SUB_SUB, (size_t)0)) < 0) TEST_ERROR;
/* Create link to top group */
- if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
+ if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
/* close sub sub group */
if( H5Gclose(gid_sub2) < 0) TEST_ERROR;
@@ -4223,13 +4249,13 @@ test_copy_group_wide_loop(hid_t fapl)
if ( (gid_sub2 = H5Gcreate(gid_sub, objname, (size_t)0)) < 0) TEST_ERROR;
/* Create link to top group */
- if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
+ if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR;
/* Create link to sub-group */
- if ( H5Glink2(gid_sub, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR;
+ if ( H5Glink2(gid_sub, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR;
/* Create link to self :-) */
- if ( H5Glink2(gid_sub2, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR;
+ if ( H5Glink2(gid_sub2, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR;
/* close sub sub group */
if( H5Gclose(gid_sub2) < 0) TEST_ERROR;
@@ -4364,13 +4390,16 @@ test_copy_group_links(hid_t fapl)
if (H5Dclose(did) < 0) TEST_ERROR;
/* make a hard link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR;
/* make a soft link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
/* make a soft link to nowhere */
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+
+ /* make a dangling external link */
+ if (H5Lcreate_external("filename", "obj_name", fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
/* close the group */
if ( H5Gclose(gid) < 0) TEST_ERROR;
@@ -4496,7 +4525,7 @@ test_copy_soft_link(hid_t fapl)
if (H5Dclose(did) < 0) TEST_ERROR;
/* make a soft link to the dataset */
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR;
/* close the group */
if ( H5Gclose(gid) < 0) TEST_ERROR;
@@ -4555,6 +4584,141 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_ext_link
+ *
+ * Purpose: Create an external link in SRC file and copy it to DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: James Laird
+ * Friday, June 16, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_ext_link(hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ hid_t gid = -1; /* Group ID */
+ hsize_t dim2d[2];
+ int buf[DIM_SIZE_1][DIM_SIZE_2];
+ int i, j;
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+ char ext_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Gcopy(): object through external link");
+
+ /* set initial data values */
+ for (i=0; i<DIM_SIZE_1; i++)
+ for (j=0; j<DIM_SIZE_2; j++)
+ buf[i][j] = 10000 + 100*i+j;
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+ h5_fixname(FILENAME[2], fapl, ext_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if ( (fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* create group at the SRC file */
+ if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
+
+ /* attach attributes to the group */
+ if ( test_copy_attach_attributes(gid, H5T_NATIVE_INT) < 0) TEST_ERROR;
+
+ /* Set dataspace dimensions */
+ dim2d[0]=DIM_SIZE_1;
+ dim2d[1]=DIM_SIZE_2;
+
+ /* create dataspace */
+ if ( (sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR;
+
+ /* add a dataset to the group */
+ if ( (did = H5Dcreate(fid_src, NAME_LINK_DATASET, H5T_NATIVE_INT, sid, H5P_DEFAULT) ) < 0) TEST_ERROR;
+ if ( H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR;
+
+ /* close dataspace */
+ if ( H5Sclose(sid) < 0) TEST_ERROR;
+ /* close the dataset */
+ if (H5Dclose(did) < 0) TEST_ERROR;
+ /* close the group */
+ if ( H5Gclose(gid) < 0) TEST_ERROR;
+
+
+ /* create file to hold external links to the src file */
+ if ( (fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* create group in the external file */
+ if ( (gid = H5Gcreate(fid_ext, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
+
+ /* Create an external link to the dataset */
+ if ( H5Lcreate_external(src_filename, NAME_LINK_DATASET, fid_ext, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* close the group and file */
+ if ( H5Gclose(gid) < 0) TEST_ERROR;
+ if (H5Fclose(fid_ext) < 0) TEST_ERROR;
+
+ /* open the "extern" file with read-only */
+ if ( (fid_ext = H5Fopen(ext_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR;
+
+ /* create destination file */
+ if ( (fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR;
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if ( H5Gclose(H5Gcreate(fid_dst, NAME_GROUP_UNCOPIED, (size_t)0)) < 0) TEST_ERROR;
+
+ /* copy the dataset from SRC to DST */
+ if ( H5Gcopy(fid_ext, NAME_LINK_EXTERN, fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
+
+ /* open the dataset through the external link */
+ if ( (did = H5Dopen(fid_ext, NAME_LINK_EXTERN)) < 0) TEST_ERROR;
+
+ /* open the destination dataset */
+ if ( (did2 = H5Dopen(fid_dst, NAME_DATASET_SIMPLE)) < 0) TEST_ERROR;
+
+ /* Check if the datasets are equal */
+ if ( compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR;
+
+ /* close the destination dataset */
+ if ( H5Dclose(did2) < 0) TEST_ERROR;
+
+ /* close the source dataset */
+ if ( H5Dclose(did) < 0) TEST_ERROR;
+
+ /* close the SRC file */
+ if ( H5Fclose(fid_src) < 0) TEST_ERROR;
+
+ /* close the EXT file */
+ if ( H5Fclose(fid_ext) < 0) TEST_ERROR;
+
+ /* close the DST file */
+ if ( H5Fclose(fid_dst) < 0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Sclose(sid);
+ H5Dclose(did2);
+ H5Dclose(did);
+ H5Gclose(gid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_ext_link */
+
+
+/*-------------------------------------------------------------------------
* Function: test_copy_exist
*
* Purpose: Create a simple dataset in SRC file and copy it onto an
@@ -6197,14 +6361,14 @@ test_copy_option(hid_t fapl, unsigned flag, hbool_t crt_intermediate_grp, const
if ((flag & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0) {
/* Create group to copy */
if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR;
if ( H5Gclose(gid) < 0) TEST_ERROR;
/* Create group to compare with */
if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK2, (size_t)0)) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR;
- if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR;
+ if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR;
if ( H5Gclose(gid) < 0) TEST_ERROR;
}
@@ -6396,6 +6560,7 @@ main(void)
nerrors += test_copy_group_wide_loop(fapl);
nerrors += test_copy_group_links(fapl);
nerrors += test_copy_soft_link(fapl);
+ nerrors += test_copy_ext_link(fapl);
nerrors += test_copy_exist(fapl);
nerrors += test_copy_path(fapl);
nerrors += test_copy_same_file_named_datatype(fapl);
diff --git a/test/stab.c b/test/stab.c
index 2562423..b684f9e 100644
--- a/test/stab.c
+++ b/test/stab.c
@@ -330,7 +330,7 @@ lifecycle(hid_t fapl)
/* Create group for testing lifecycle */
if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* Query group creation property settings */
if(H5Pget_local_heap_size_hint(gcpl, &lheap_size_hint) < 0) TEST_ERROR;
@@ -789,7 +789,7 @@ no_compact(hid_t fapl)
/* Create group for testing lifecycle */
if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR
+ if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* Close GCPL */
if(H5Pclose(gcpl) < 0) TEST_ERROR;
@@ -920,7 +920,7 @@ gcpl_on_root(hid_t fapl)
/* Create a group and intermediate groups, to check if root group settings are inherited */
if((gid2 = H5Gcreate_expand(gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
- if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid, lcpl)) < 0) TEST_ERROR
+ if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid2, lcpl, H5P_DEFAULT)) < 0) TEST_ERROR
/* Close LCPL */
if(H5Pclose(lcpl) < 0) TEST_ERROR;
diff --git a/test/testhdf5.c b/test/testhdf5.c
index 925b8f8..eadc2bd 100644
--- a/test/testhdf5.c
+++ b/test/testhdf5.c
@@ -50,6 +50,7 @@ main(int argc, char *argv[])
AddTest("skiplist", test_skiplist, NULL, "Skip Lists", NULL);
AddTest("refstr", test_refstr, NULL, "Reference Counted Strings", NULL);
AddTest("file", test_file, cleanup_file, "Low-Level File I/O", NULL);
+ AddTest("objects", test_h5o, cleanup_file, "Generic Object Functions", NULL);
AddTest("h5s", test_h5s, cleanup_h5s, "Dataspaces", NULL);
AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL);
AddTest("select", test_select, cleanup_select, "Selections", NULL);
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 2274b78..b4f1342 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -127,6 +127,7 @@ void test_tst(void);
void test_heap(void);
void test_refstr(void);
void test_file(void);
+void test_h5o(void);
void test_h5t(void);
void test_h5s(void);
void test_h5d(void);
@@ -148,6 +149,7 @@ void test_unicode(void);
/* Prototypes for the cleanup routines */
void cleanup_metadata(void);
void cleanup_file(void);
+void cleanup_h5o(void);
void cleanup_h5s(void);
void cleanup_attr(void);
void cleanup_select(void);
diff --git a/test/th5o.c b/test/th5o.c
new file mode 100644
index 0000000..fde15c7
--- /dev/null
+++ b/test/th5o.c
@@ -0,0 +1,601 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/***********************************************************
+*
+* Test program: th5o
+*
+* Test public H5O functions for accessing
+*
+*************************************************************/
+
+#include "testhdf5.h"
+
+/*#include "H5private.h"
+#include "H5Bprivate.h"
+#include "H5Sprivate.h"
+#include "H5Pprivate.h"
+*/
+
+#define TEST_FILENAME "th5o_file"
+
+#define RANK 2
+#define DIM0 5
+#define DIM1 10
+
+/****************************************************************
+**
+** test_h5o_open(): Test H5Oopen function.
+**
+****************************************************************/
+static void
+test_h5o_open(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ hsize_t dims[RANK];
+ H5I_type_t id_type; /* Type of IDs returned from H5Oopen */
+ hsize_t num_objs=-1; /* Number of objects in the group */
+ H5T_class_t type_class; /* Class of the datatype */
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Now make sure that H5Oopen can open all three types of objects */
+ grp = H5Oopen(fid, "group", H5P_DEFAULT);
+ CHECK(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
+ CHECK(dtype, FAIL, "H5Oopen");
+ /* Check that we can use the group as a valid location */
+ dset = H5Oopen(grp, "/dataset", H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Oopen");
+
+ /* Make sure that each is the right kind of ID */
+ id_type = H5Iget_type(grp);
+ VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
+ id_type = H5Iget_type(dtype);
+ VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
+ id_type = H5Iget_type(dset);
+ VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
+
+ /* Do something more complex with each of the IDs to make sure they "work" */
+ ret = H5Gget_num_objs(grp, &num_objs);
+ CHECK(ret, FAIL, "H5Gget_num_objs");
+ VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */
+
+ type_class = H5Tget_class(dtype);
+ VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
+
+ dspace = H5Dget_space(dset);
+ CHECK(dspace, FAIL, "H5Dget_space");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Trying to open objects with bogus names should fail gracefully */
+ H5E_BEGIN_TRY {
+ grp = H5Oopen(fid, "bogus_group", H5P_DEFAULT);
+ VERIFY(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/bogus_datatype", H5P_DEFAULT);
+ VERIFY(dtype, FAIL, "H5Oopen");
+ dset = H5Oopen(fid, "/bogus_dataset", H5P_DEFAULT);
+ VERIFY(dset, FAIL, "H5Oopen");
+ } H5E_END_TRY
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Trying to open an object with a bogus file ID should fail */
+ H5E_BEGIN_TRY {
+ dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
+ VERIFY(dset, FAIL, "H5Oopen");
+ } H5E_END_TRY
+} /* test_h5o_open() */
+
+
+
+/****************************************************************
+**
+** test_h5o_close(): Test H5Oclose function.
+**
+****************************************************************/
+static void
+test_h5o_close(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ hsize_t dims[RANK];
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group and close it with H5Oclose */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ VERIFY(H5Iget_type(grp), H5I_GROUP, "H5Iget_type");
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Attempting to close the data space with H5Oclose should fail */
+ H5E_BEGIN_TRY {
+ ret = H5Oclose(dspace);
+ VERIFY(ret, FAIL, "H5Oclose");
+ } H5E_END_TRY
+ /* Close the dataspace for real */
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Make sure that H5Oclose can close objects opened with H5Oopen */
+ grp = H5Oopen(fid, "group", H5P_DEFAULT);
+ CHECK(grp, FAIL, "H5Oopen");
+ dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
+ CHECK(dtype, FAIL, "H5Oopen");
+ dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Oopen");
+
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Make sure H5Oclose can close objects opened with H5*open */
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "group/datatype");
+ CHECK(dtype, FAIL, "H5Topen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Dopen");
+
+ ret = H5Oclose(grp);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dtype);
+ CHECK(ret, FAIL, "H5Oclose");
+ ret = H5Oclose(dset);
+ CHECK(ret, FAIL, "H5Oclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+}
+
+
+/****************************************************************
+**
+** test_h5o_open_by_addr(): Test H5Oopen_by_addr function.
+**
+****************************************************************/
+static void
+test_h5o_open_by_addr(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ H5L_linkinfo_t li; /* Buffer for H5Lget_linkinfo */
+ haddr_t grp_addr; /* Addresses for objects */
+ haddr_t dset_addr;
+ haddr_t dtype_addr;
+ hsize_t dims[RANK];
+ H5I_type_t id_type; /* Type of IDs returned from H5Oopen */
+ hsize_t num_objs=-1; /* Number of objects in the group */
+ H5T_class_t type_class; /* Class of the datatype */
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "group/datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Get address for each object */
+ ret = H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ grp_addr = li.u.address;
+ ret = H5Lget_linkinfo(fid, "group/datatype", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ dtype_addr = li.u.address;
+ ret = H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Lget_linkinfo");
+ dset_addr = li.u.address;
+
+ /* Now make sure that H5Oopen_by_addr can open all three types of objects */
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ CHECK(grp, FAIL, "H5Oopen_by_addr");
+ dtype = H5Oopen_by_addr(fid, dtype_addr);
+ CHECK(dtype, FAIL, "H5Oopen_by_addr");
+ /* Check that we can use the group ID as a valid location */
+ dset = H5Oopen_by_addr(grp, dset_addr);
+ CHECK(dset, FAIL, "H5Oopen_by_addr");
+
+ /* Make sure that each is the right kind of ID */
+ id_type = H5Iget_type(grp);
+ VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
+ id_type = H5Iget_type(dtype);
+ VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
+ id_type = H5Iget_type(dset);
+ VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
+
+ /* Do something more complex with each of the IDs to make sure they "work" */
+ ret = H5Gget_num_objs(grp, &num_objs);
+ CHECK(ret, FAIL, "H5Gget_num_objs");
+ VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */
+
+ type_class = H5Tget_class(dtype);
+ VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
+
+ dspace = H5Dget_space(dset);
+ CHECK(dspace, FAIL, "H5Dget_space");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Try giving some bogus values to H5O_open_by_addr. */
+ /* Try to open an object with a bad address */
+ grp_addr += 20;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ /* For instance, an objectno smaller than the end of the file's superblock should
+ * trigger an error */
+ grp_addr = 10;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ /* Likewise, an objectno larger than the size of the file should fail */
+ grp_addr = 0;
+ grp_addr = 1000000000;
+ H5E_BEGIN_TRY{
+ grp = H5Oopen_by_addr(fid, grp_addr);
+ }H5E_END_TRY
+ VERIFY(grp, FAIL, "H5Oopen_by_addr");
+
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Also, trying to open an object without a valid location should fail */
+ H5E_BEGIN_TRY{
+ dtype = H5Oopen_by_addr(fid, dtype_addr);
+ }H5E_END_TRY
+ VERIFY(dtype, FAIL, "H5Oopen_by_addr");
+} /* test_h5o_open_by_addr() */
+
+
+/****************************************************************
+**
+** test_h5o_refcount(): Test H5O refcounting functions.
+**
+****************************************************************/
+static void
+test_h5o_refcount(void)
+{
+ hid_t fid; /* HDF5 File ID */
+ hid_t grp, dset, dtype, dspace; /* Object identifiers */
+ H5G_stat_t sb; /* Statbuffer for H5Gget_objinfo */
+ hsize_t dims[RANK];
+ herr_t ret; /* Value returned from API calls */
+
+ /* Create a new HDF5 file */
+ fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Create a group, dataset, and committed datatype within the file */
+ /* Create the group */
+ grp = H5Gcreate(fid, "group", 0);
+ CHECK(grp, FAIL, "H5Gcreate");
+
+ /* Commit the type inside the group */
+ dtype = H5Tcopy(H5T_NATIVE_INT);
+ CHECK(dtype, FAIL, "H5Tcopy");
+ ret = H5Tcommit(fid, "datatype", dtype);
+ CHECK(ret, FAIL, "H5Tcommit");
+
+ /* Create the data space for the dataset. */
+ dims[0] = DIM0;
+ dims[1] = DIM1;
+ dspace = H5Screate_simple(RANK, dims, NULL);
+ CHECK(dspace, FAIL, "H5Screate_simple");
+
+ /* Create the dataset. */
+ dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+ ret = H5Sclose(dspace);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Get ref counts for each object. They should all be 1, since each object has a hard link. */
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Increment each object's reference count. */
+ ret = H5Oincr_refcount(grp);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+
+ /* Get ref counts for each object. They should all be 2 now. */
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+
+ /* Decrement the reference counts and check that they decrease back to 1. */
+ ret = H5Odecr_refcount(grp);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Increment the reference counts and then close the file to make sure the increment is permanant */
+ ret = H5Oincr_refcount(grp);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ CHECK(ret, FAIL, "H5Oincr_refcount");
+
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open the file and check that the reference counts were really incremented */
+ fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "datatype");
+ CHECK(dtype, FAIL, "H5Gopen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Gopen");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo");
+
+ /* Decrement the reference counts and close the file */
+ ret = H5Odecr_refcount(grp);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ CHECK(ret, FAIL, "H5Odecr_refcount");
+
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open the file and check that the reference counts were really decremented */
+ fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ grp = H5Gopen(fid, "group");
+ CHECK(grp, FAIL, "H5Gopen");
+ dtype = H5Topen(fid, "datatype");
+ CHECK(dtype, FAIL, "H5Gopen");
+ dset = H5Dopen(fid, "dataset");
+ CHECK(dset, FAIL, "H5Gopen");
+
+ ret = H5Gget_objinfo(fid, "group", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+ ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb);
+ CHECK(ret, FAIL, "H5Gget_objinfo");
+ VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo");
+
+ /* Close the IDs */
+ ret = H5Gclose(grp);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Tclose(dtype);
+ CHECK(ret, FAIL, "H5Tclose");
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Make sure that bogus IDs return errors properly */
+ H5E_BEGIN_TRY {
+ ret = H5Oincr_refcount(grp);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dtype);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Oincr_refcount(dset);
+ VERIFY(ret, FAIL, "H5Oincr_refcount");
+ ret = H5Odecr_refcount(grp);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dtype);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ ret = H5Odecr_refcount(dset);
+ VERIFY(ret, FAIL, "H5Odecr_refcount");
+ } H5E_END_TRY
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* test_h5o_refcount() */
+
+
+/****************************************************************
+**
+** test_h5o(): Main H5O (generic object) testing routine.
+**
+****************************************************************/
+void
+test_h5o(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Objects\n"));
+
+ test_h5o_open(); /* Test generic open function */
+ test_h5o_open_by_addr(); /* Test opening objects by address */
+ test_h5o_close(); /* Test generic close function */
+ test_h5o_refcount(); /* Test incrementing and decrementing reference count */
+} /* test_h5o() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_h5o
+ *
+ * Purpose: Cleanup temporary test files
+ *
+ * Return: none
+ *
+ * Programmer: James Laird
+ * June 3, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_h5o(void)
+{
+ remove(TEST_FILENAME);
+}
diff --git a/test/titerate.c b/test/titerate.c
index 0c41ce6..4850db0 100644
--- a/test/titerate.c
+++ b/test/titerate.c
@@ -854,10 +854,10 @@ static void test_links(void)
CHECK(gid1, FAIL, "H5Gcreate");
/* create soft and hard links to the group "/g1". */
- ret = H5Glink (gid, H5G_LINK_SOFT, "something", "softlink");
+ ret = H5Glink (gid, H5L_LINK_SOFT, "something", "softlink");
CHECK(ret, FAIL, "H5Glink");
- ret = H5Glink (gid, H5G_LINK_HARD, "/g1", "hardlink");
+ ret = H5Glink (gid, H5L_LINK_HARD, "/g1", "hardlink");
CHECK(ret, FAIL, "H5Glink");
ret = H5Gget_num_objs(gid, &nobjs);
diff --git a/test/tmisc.c b/test/tmisc.c
index cc4d7b2..b89a9a6 100644
--- a/test/tmisc.c
+++ b/test/tmisc.c
@@ -2850,6 +2850,7 @@ test_misc18(void)
#else /* H5_HAVE_LARGE_HSIZET */
VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Create second dataset */
did2 = H5Dcreate(fid, MISC18_DSET2_NAME, H5T_STD_U32LE, sid, H5P_DEFAULT);
@@ -2866,6 +2867,7 @@ test_misc18(void)
#else /* H5_HAVE_LARGE_HSIZET */
VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Loop creating attributes on each dataset, flushing them to the file each time */
for(u=0; u<10; u++) {
@@ -2905,6 +2907,7 @@ test_misc18(void)
VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo");
VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Get object information for dataset #2 now */
ret = H5Gget_objinfo(fid,MISC18_DSET2_NAME,0,&statbuf);
@@ -2920,6 +2923,7 @@ test_misc18(void)
VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo");
VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo");
#endif /* H5_HAVE_LARGE_HSIZET */
+ VERIFY(statbuf.linklen, 0, "H5Gget_objinfo");
/* Close second dataset */
ret = H5Dclose(did2);
@@ -3844,7 +3848,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
/* Query that the name of the new group is correct */
@@ -3870,7 +3874,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3880,7 +3884,7 @@ test_misc23(void)
tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id);
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(group_id, "B03/grp/", tmp_id, create_id);
+ status = H5Llink(group_id, "B03/grp/", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3890,7 +3894,7 @@ test_misc23(void)
if ( (tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id)) < 0)
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3900,7 +3904,7 @@ test_misc23(void)
if ( (tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id)) < 0)
CHECK(tmp_id, FAIL, "H5Gcreate_expand");
- status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Gclose(tmp_id);
@@ -3924,50 +3928,50 @@ test_misc23(void)
CHECK(status, FAIL, "H5Pset_create_intermediate_group");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(group_id, "B08/dset", tmp_id, create_id);
+ status = H5Llink(group_id, "B08/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
CHECK(status, FAIL, "H5Dclose");
- tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT);
+ tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
CHECK(tmp_id, FAIL, "H5Dcreate");
- status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Dclose(tmp_id);
@@ -4002,7 +4006,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4015,7 +4019,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4028,7 +4032,7 @@ test_misc23(void)
status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id);
+ status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4041,7 +4045,7 @@ test_misc23(void)
status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id);
+ status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4054,7 +4058,7 @@ test_misc23(void)
status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id);
CHECK(status, FAIL, "H5Tcommit_expand");
- status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id);
+ status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id, H5P_DEFAULT);
CHECK(status, FAIL, "H5Llink");
status = H5Tclose(tmp_id);
@@ -4110,13 +4114,13 @@ test_misc24(void)
CHECK(ret, FAIL, "H5Tcommit");
/* Create soft links to the objects created */
- ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5G_LINK_SOFT, file_id, MISC24_GROUP_LINK);
+ ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5L_LINK_SOFT, file_id, MISC24_GROUP_LINK);
CHECK(ret, FAIL, "H5Glink2");
- ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5G_LINK_SOFT, file_id, MISC24_DATASET_LINK);
+ ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5L_LINK_SOFT, file_id, MISC24_DATASET_LINK);
CHECK(ret, FAIL, "H5Glink2");
- ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5G_LINK_SOFT, file_id, MISC24_DATATYPE_LINK);
+ ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5L_LINK_SOFT, file_id, MISC24_DATATYPE_LINK);
CHECK(ret, FAIL, "H5Glink2");
/* Close IDs for objects */
diff --git a/test/unlink.c b/test/unlink.c
index d86e4eb..1ad3790 100644
--- a/test/unlink.c
+++ b/test/unlink.c
@@ -19,8 +19,14 @@
* Purpose: Test H5Gunlink().
*/
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+/* Define this macro to indicate that the testing APIs should be available */
+#define H5G_TESTING
+
#include <time.h>
#include "h5test.h"
+#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"unlink",
@@ -33,6 +39,7 @@ const char *FILENAME[] = {
"resurrect_type",
"resurrect_group",
"unlink_chunked",
+ "full_group",
NULL
};
@@ -68,6 +75,9 @@ const char *FILENAME[] = {
#define SLASHES_SOFTLINK_NAME "Soft///"
#define SLASHES_SOFTLINK2_NAME "Soft2///"
#define SLASHES_ROOTLINK_NAME "Root///"
+#define FULL_GROUP_NUM_KEEP 2
+#define FULL_GROUP_NUM_DELETE_COMPACT 2
+#define FULL_GROUP_NUM_DELETE_DENSE 16
/*-------------------------------------------------------------------------
@@ -170,7 +180,7 @@ test_many(hid_t file)
TESTING("forward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
@@ -182,7 +192,7 @@ test_many(hid_t file)
TESTING("backward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=how_many-1; i>=0; --i) {
sprintf(name, "obj_%05d", i);
@@ -194,7 +204,7 @@ test_many(hid_t file)
TESTING("inward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=0; i<how_many; i++) {
if (i%2) {
@@ -210,7 +220,7 @@ test_many(hid_t file)
TESTING("outward unlink");
for (i=0; i<how_many; i++) {
sprintf(name, "obj_%05d", i);
- if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error;
+ if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error;
}
for (i=how_many-1; i>=0; --i) {
if (i%2) {
@@ -259,7 +269,7 @@ test_symlink(hid_t file)
/* Create a test group and symlink */
if ((work=H5Gcreate(file, "/test_symlink", 0))<0) TEST_ERROR;
- if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link")<0) TEST_ERROR;
+ if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link")<0) TEST_ERROR;
if (H5Gunlink(work, "link")<0) TEST_ERROR;
/* Cleanup */
@@ -310,7 +320,7 @@ test_rename(hid_t file)
/* Try renaming a symlink */
TESTING("symlink renaming");
- if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link_one")<0) goto error;
+ if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link_one")<0) goto error;
if (H5Gmove(work, "link_one", "link_two")<0) goto error;
PASSED();
@@ -368,9 +378,9 @@ test_new_move(void)
if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) goto error;
/* Create hard and soft links. */
- if(H5Glink2(grp_1, "group_move", H5G_LINK_HARD, H5G_SAME_LOC, "hard")<0)
+ if(H5Glink2(grp_1, "group_move", H5L_LINK_HARD, H5G_SAME_LOC, "hard")<0)
goto error;
- if(H5Glink2(grp_1, "/group1/group_move", H5G_LINK_SOFT, grp_2, "soft")<0)
+ if(H5Glink2(grp_1, "/group1/group_move", H5L_LINK_SOFT, grp_2, "soft")<0)
goto error;
/* Move a group within the file. Both of source and destination use
@@ -1357,22 +1367,22 @@ test_link_slashes(void)
if(H5Gclose(gid2)<0) TEST_ERROR;
/* Create a hard link to the nested group */
- if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
/* Create a soft link with a relative path to the nested group */
- if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR;
/* Create a soft link with the full path to the nested group */
- if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR;
/* Create a soft link to the root group */
- if(H5Glink2(gid, "////", H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(gid, "////", H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR;
/* Close the group */
if(H5Gclose(gid)<0) TEST_ERROR;
/* Create a hard link to the existing group */
- if(H5Glink2(fid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
+ if(H5Glink2(fid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR;
/* Close the file */
if(H5Fclose(fid)<0) TEST_ERROR;
@@ -1861,7 +1871,7 @@ test_resurrect_dataset(void)
if(H5Iget_name(d, NULL, 0) != 0) TEST_ERROR;
/* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(d, ".", H5G_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR;
+ if(H5Glink2(d, ".", H5L_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR;
/* Close things */
if(H5Dclose(d)<0) TEST_ERROR;
@@ -1934,7 +1944,7 @@ test_resurrect_datatype(void)
if(H5Iget_name(type, NULL, 0) != 0) TEST_ERROR;
/* Re-link the datatype to the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(type, ".", H5G_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR;
+ if(H5Glink2(type, ".", H5L_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR;
/* Close things */
if(H5Tclose(type)<0) TEST_ERROR;
@@ -2003,7 +2013,7 @@ test_resurrect_group(void)
if(H5Iget_name(group, NULL, 0) != 0) TEST_ERROR;
/* Re-link the group into the group hierarchy (shouldn't get deleted now) */
- if(H5Glink2(group, ".", H5G_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR;
+ if(H5Glink2(group, ".", H5L_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR;
/* Close things */
if(H5Gclose(group)<0) TEST_ERROR;
@@ -2121,6 +2131,269 @@ error:
return 1;
} /* end test_unlink_chunked_dataset() */
+#ifdef H5_GROUP_REVISION
+
+/*-------------------------------------------------------------------------
+ * Function: test_full_group_compact
+ *
+ * Purpose: Test deleting a compact group which still has valid objects in it
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_full_group_compact(void)
+{
+ hid_t fapl_id = -1;
+ hid_t file_id = -1;
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ H5G_stat_t sb; /* Stat buffer for object */
+ char objname[128]; /* Buffer for name of objects to create */
+ char objname2[128]; /* Buffer for name of objects to create */
+ char filename[1024]; /* Buffer for filename */
+ off_t keep_size; /* Size of the file with objects to keep */
+ off_t file_size; /* Size of each file created */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking non-empty compact group");
+
+ /* Create file */
+ fapl_id = h5_fileaccess();
+ h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename);
+
+ /* Create the file */
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR
+
+ /* Create group to link objects to */
+ if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create several objects to link to */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "keep %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Close group with objects to keep */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Get the size of the file with only the objects to keep */
+ if((keep_size = h5_get_file_size(filename)) == 0) TEST_ERROR
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Create group to delete */
+ if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error;
+
+ /* Create external link (doesn't matter if it dangles) */
+ if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create soft link (doesn't matter if it dangles) */
+ if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR
+
+ /* Create hard links to objects in group to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ sprintf(objname2, "keep %u\n", u);
+ if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Create several objects to delete */
+ for(u = 0; u < FULL_GROUP_NUM_DELETE_COMPACT; u++) {
+ sprintf(objname, "delete %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) != TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR;
+
+ /* Close group with objects to delete */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 2) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Delete the full group */
+ if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 1) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Get the size of the file */
+ if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR
+
+ /* Verify the file is correct size */
+ if(file_size != keep_size) TEST_ERROR
+
+ /* Close the file access property list */
+ if(H5Pclose(fapl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(file_id);
+ H5Pclose(fapl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_full_group_compact() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_full_group_dense
+ *
+ * Purpose: Test deleting a dense group which still has valid objects in it
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 18, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_full_group_dense(void)
+{
+ hid_t fapl_id = -1;
+ hid_t file_id = -1;
+ hid_t gid = -1, gid2 = -1; /* Group IDs */
+ H5G_stat_t sb; /* Stat buffer for object */
+ char objname[128]; /* Buffer for name of objects to create */
+ char objname2[128]; /* Buffer for name of objects to create */
+ char filename[1024]; /* Buffer for filename */
+ unsigned u; /* Local index variable */
+
+ TESTING("unlinking non-empty dense group");
+
+ /* Create file */
+ fapl_id = h5_fileaccess();
+ h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename);
+
+ /* Create the file */
+ if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR
+
+ /* Create group to link objects to */
+ if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR
+
+ /* Create several objects to link to */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "keep %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Close group with objects to keep */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Create group to delete */
+ if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error;
+
+ /* Create external link (doesn't matter if it dangles) */
+ if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* Create soft link (doesn't matter if it dangles) */
+ if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR
+
+ /* Create hard links to objects in group to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ sprintf(objname2, "keep %u\n", u);
+ if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Create several objects to delete */
+ for(u = 0; u < FULL_GROUP_NUM_DELETE_DENSE; u++) {
+ sprintf(objname, "delete %u\n", u);
+ if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR
+ if(H5Gclose(gid2) < 0) TEST_ERROR
+ } /* end for */
+
+ /* Check on group's status */
+ if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR;
+ if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR;
+ if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR;
+
+ /* Close group with objects to delete */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 2) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+
+ /* Re-open the file */
+ if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR
+
+ /* Delete the full group */
+ if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR
+
+ /* Check reference count on objects to keep */
+ for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) {
+ sprintf(objname, "/keep/keep %u\n", u);
+ if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR
+ if(sb.nlink != 1) TEST_ERROR
+ } /* end for */
+
+ /* Close the file */
+ if(H5Fclose(file_id) < 0) TEST_ERROR
+
+ /* Close the file access property list */
+ if(H5Pclose(fapl_id) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid2);
+ H5Gclose(gid);
+ H5Fclose(file_id);
+ H5Pclose(fapl_id);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_full_group_dense() */
+#endif /* H5_GROUP_REVISION */
+
/*-------------------------------------------------------------------------
* Function: main
@@ -2209,13 +2482,20 @@ main(void)
/* Test unlinking chunked datasets */
nerrors += test_unlink_chunked_dataset();
- /* Close */
- if (H5Pclose(fapl2)<0) TEST_ERROR;
- if (H5Fclose(file)<0) TEST_ERROR;
- if (nerrors) {
- printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S");
+#ifdef H5_GROUP_REVISION
+ /* Test unlinked groups which still have objects in them */
+ nerrors += test_full_group_compact();
+ nerrors += test_full_group_dense();
+#endif /* H5_GROUP_REVISION */
+
+ /* Close */
+ if (H5Pclose(fapl2)<0) TEST_ERROR;
+ if (H5Fclose(file)<0) TEST_ERROR;
+ if (nerrors) {
+ printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S");
exit(1);
}
+
puts("All unlink tests passed.");
h5_cleanup(FILENAME, fapl);
}