hdf5/test/links.c
James Laird 0274a5f3a2 [svn-r12627] Skipped links and fheap tests when stdio file driver is used.
These errors should be investigated more thoroughly later.  The underlying
problem in links.c seems to be that files opened multiple times don't share
the same H5F_shared_t struct.  Perhaps identifying when this is the case
would be helpful?

Tested on mir.
2006-08-24 11:09:23 -05:00

5128 lines
174 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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: Robb Matzke <matzke@llnl.gov>
* Friday, April 10, 1998
*
* Purpose: Tests hard, soft (symbolic) & external links.
*/
#include "h5test.h"
#include "H5Lprivate.h"
/*
* This file needs to access private information from the H5G package.
* This file also needs to access the group testing code.
*/
#define H5G_PACKAGE
#define H5G_TESTING
#include "H5Gpkg.h" /* Groups */
const char *FILENAME[] = {
"links0",
"links1",
"links2",
"links3",
"links4a",
"links4b",
"links4c",
"links4d",
"links5",
NULL
};
#define LINK_BUF_SIZE 1024
#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
/*-------------------------------------------------------------------------
* Function: mklinks
*
* Purpose: Build a file with assorted links.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Friday, August 14, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
mklinks(hid_t fapl)
{
hid_t file, scalar, grp, d1;
hsize_t size[1] = {1};
char filename[NAME_BUF_SIZE];
TESTING("link creation");
/* Create a file */
h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
if ((scalar=H5Screate_simple (1, size, size))<0) TEST_ERROR;
/* Create a group */
if ((grp=H5Gcreate (file, "grp1", (size_t)0))<0) TEST_ERROR;
if (H5Gclose (grp)<0) TEST_ERROR;
/* Create a dataset */
if ((d1=H5Dcreate (file, "d1", H5T_NATIVE_INT, scalar, H5P_DEFAULT))<0) TEST_ERROR;
if (H5Dclose (d1)<0) TEST_ERROR;
/* Create a hard link */
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, H5P_DEFAULT)<0) TEST_ERROR;
/* Create a symbolic link to something that doesn't exist */
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, H5P_DEFAULT)<0) TEST_ERROR;
/* Close */
if (H5Sclose (scalar)<0) TEST_ERROR;
if (H5Fclose (file)<0) TEST_ERROR;
PASSED();
return 0;
error:
return -1;
}
/*-------------------------------------------------------------------------
* Function: new_links
*
* Purpose: Build a file with assorted links for different locations.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Raymond Lu
* Friday, April 19, 2002
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
new_links(hid_t fapl)
{
hid_t file_a, file_b=(-1);
hid_t grp1_a=(-1), grp1_b=(-1), grp2_a=(-1), grp2_b=(-1);
hid_t scalar=(-1);
hid_t dset1=(-1), dset2=(-1);
char filename[NAME_BUF_SIZE];
hsize_t size[1] = {1};
TESTING("H5Lcreate functions");
/* Create two files */
h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
h5_fixname(FILENAME[2], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
if ((scalar=H5Screate_simple (1, size, size))<0) TEST_ERROR;
/* Create two groups in each file */
if ((grp1_a=H5Gcreate (file_a, "grp1", (size_t)0))<0) TEST_ERROR;
if ((grp2_a=H5Gcreate (file_a, "grp2", (size_t)0))<0) TEST_ERROR;
if ((grp1_b=H5Gcreate (file_b, "grp1", (size_t)0))<0) TEST_ERROR;
if ((grp2_b=H5Gcreate (file_b, "grp2", (size_t)0))<0) TEST_ERROR;
/* Create datasets */
if((dset1=H5Dcreate(file_a, "dataset1", H5T_NATIVE_INT, scalar, H5P_DEFAULT))<0) TEST_ERROR;
if((dset2=H5Dcreate(grp1_a, "dataset2", H5T_NATIVE_INT, scalar, H5P_DEFAULT))<0) TEST_ERROR;
/* 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, H5P_DEFAULT)!=FAIL) TEST_ERROR;
} H5E_END_TRY;
H5E_BEGIN_TRY {
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, 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, 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, H5P_DEFAULT)<0) TEST_ERROR;
/* Close dataspace and files */
if (H5Sclose (scalar)<0) TEST_ERROR;
if (H5Dclose(dset1)<0) TEST_ERROR;
if (H5Dclose(dset2)<0) TEST_ERROR;
if (H5Gclose (grp1_a)<0) TEST_ERROR;
if (H5Gclose (grp2_a)<0) TEST_ERROR;
if (H5Gclose (grp1_b)<0) TEST_ERROR;
if (H5Gclose (grp2_b)<0) TEST_ERROR;
if (H5Fclose (file_a)<0) TEST_ERROR;
if (H5Fclose (file_b)<0) TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Sclose (scalar);
H5Dclose (dset1);
H5Dclose (dset2);
H5Gclose (grp1_a);
H5Gclose (grp2_a);
H5Gclose (grp1_b);
H5Gclose (grp2_b);
H5Fclose (file_a);
H5Fclose (file_b);
} H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* Function: cklinks
*
* Purpose: Open the file created in the first step and check that the
* links look correct.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Friday, August 14, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
cklinks(hid_t fapl)
{
hid_t file;
H5G_stat_t sb1, sb2;
char linkval[LINK_BUF_SIZE];
char filename[NAME_BUF_SIZE];
herr_t status;
TESTING("link queries");
/* Open the file */
h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR;
/* Hard link */
if (H5Gget_objinfo(file, "d1", TRUE, &sb1)<0) TEST_ERROR;
if (H5Gget_objinfo(file, "grp1/hard", TRUE, &sb2)<0) TEST_ERROR;
if (H5G_DATASET!=sb2.type) {
H5_FAILED();
printf(" %d: Unexpected object type should have been a dataset\n", __LINE__);
TEST_ERROR;
}
if (HDmemcmp(&sb1.objno, &sb2.objno, sizeof(sb1.objno))) {
H5_FAILED();
puts(" Hard link test failed. Link seems not to point to the ");
puts(" expected file location.");
TEST_ERROR;
}
/* Symbolic link */
if (H5Gget_objinfo(file, "grp1/soft", TRUE, &sb2)<0) TEST_ERROR;
if (H5G_DATASET!=sb2.type) {
H5_FAILED();
printf(" %d: Unexpected object type should have been a dataset\n", __LINE__);
TEST_ERROR;
}
if (HDmemcmp(&sb1.objno, &sb2.objno, sizeof(sb1.objno))) {
H5_FAILED();
puts(" Soft link test failed. Link seems not to point to the ");
puts(" expected file location.");
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");
TEST_ERROR;
}
/* Dangling link */
H5E_BEGIN_TRY {
status = H5Gget_objinfo(file, "grp1/dangle", TRUE, &sb2);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
puts(" H5Gget_objinfo() should have failed for a dangling link.");
TEST_ERROR;
}
if (H5Gget_objinfo(file, "grp1/dangle", FALSE, &sb2)<0) TEST_ERROR;
if (H5G_LINK!=sb2.type) {
H5_FAILED();
printf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__);
TEST_ERROR;
}
if (H5Gget_linkval(file, "grp1/dangle", sizeof linkval, linkval)<0) {
H5_FAILED();
printf(" %d: Can't retrieve link value\n", __LINE__);
TEST_ERROR;
}
if (HDstrcmp(linkval, "foobar")) {
H5_FAILED();
puts(" Dangling link test failed. Wrong link value");
TEST_ERROR;
}
/* Recursive link */
H5E_BEGIN_TRY {
status = H5Gget_objinfo(file, "grp1/recursive", TRUE, &sb2);
} H5E_END_TRY;
if (status>=0) {
H5_FAILED();
puts(" H5Gget_objinfo() should have failed for a recursive link.");
TEST_ERROR;
}
if (H5Gget_objinfo(file, "grp1/recursive", FALSE, &sb2)<0) TEST_ERROR;
if (H5G_LINK!=sb2.type) {
H5_FAILED();
printf(" %d: Unexpected object type should have been a symbolic link\n", __LINE__);
TEST_ERROR;
}
if (H5Gget_linkval(file, "grp1/recursive", sizeof linkval, linkval)<0) {
H5_FAILED();
printf(" %d: Can't retrieve link value\n", __LINE__);
TEST_ERROR;
}
if (HDstrcmp(linkval, "/grp1/recursive")) {
H5_FAILED();
puts(" Recursive link test failed. Wrong link value");
TEST_ERROR;
}
/* Cleanup */
if (H5Fclose(file)<0) TEST_ERROR;
PASSED();
return 0;
error:
return -1;
}
/*-------------------------------------------------------------------------
* Function: ck_new_links
*
* Purpose: Open the file created in the first step and check that the
* links look correct.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Raymond Lu
* Thursday, April 25, 2002
*
*-------------------------------------------------------------------------
*/
static int
ck_new_links(hid_t fapl)
{
hid_t file;
H5G_stat_t sb_dset, sb_hard1, sb_hard2;
char filename[NAME_BUF_SIZE];
TESTING("new link queries");
/* Open the file */
h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR;
/* Get hard link info */
if(H5Gget_objinfo(file, "/grp1/dataset2", TRUE, &sb_dset)<0)
TEST_ERROR;
if(H5Gget_objinfo(file, "/grp1/hard1", TRUE, &sb_hard1)<0)
TEST_ERROR;
if(H5Gget_objinfo(file, "/grp2/hard2", TRUE, &sb_hard2)<0)
TEST_ERROR;
/* Check hard links */
if(H5G_DATASET!=sb_hard1.type || H5G_DATASET!=sb_hard2.type) {
H5_FAILED();
printf(" %d: Unexpected object type should have been a dataset\n", __LINE__);
TEST_ERROR;
}
if(HDmemcmp(&sb_dset.objno, &sb_hard1.objno, sizeof(sb_dset.objno)) || HDmemcmp(&sb_dset.objno, &sb_hard2.objno, sizeof(sb_dset.objno))) {
H5_FAILED();
puts(" Hard link test failed. Link seems not to point to the ");
puts(" expected file location.");
TEST_ERROR;
}
/* Cleanup */
if(H5Fclose(file)<0) TEST_ERROR;
PASSED();
return 0;
error:
return -1;
}
/*-------------------------------------------------------------------------
* Function: long_links
*
* Purpose: Build a file with long names
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Quincey Koziol
* Saturday, April 16, 2005
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
long_links(hid_t fapl)
{
hid_t fid = (-1); /* File ID */
hid_t gid = (-1); /* Group ID */
hid_t gid2 = (-1); /* Datatype ID */
char *objname = NULL; /* Name of object [Long] */
size_t u; /* Local index variable */
char filename[NAME_BUF_SIZE];
TESTING("long names for objects & links");
/* Create files */
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) */
if((gid=H5Gcreate (fid, "grp1", (size_t)0))<0) TEST_ERROR;
/* Construct very long file name */
if((objname = HDmalloc((size_t)(MAX_NAME_LEN + 1))) == NULL) TEST_ERROR;
for(u = 0; u < MAX_NAME_LEN; u++)
objname[u] = 'a';
objname[MAX_NAME_LEN] = '\0';
/* Create hard link to existing object */
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, H5P_DEFAULT) < 0) TEST_ERROR;
/* Create group with long name in existing group */
if((gid2=H5Gcreate(gid, objname, (size_t)0))<0) TEST_ERROR;
/* Close objects */
if(H5Gclose(gid2)<0) TEST_ERROR;
if(H5Gclose(gid)<0) TEST_ERROR;
if(H5Fclose(fid)<0) TEST_ERROR;
/* Release memory */
HDfree(objname);
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose (gid2);
H5Gclose (gid);
H5Fclose (fid);
} H5E_END_TRY;
HDfree(objname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: toomany
*
* Purpose: Build a file with too many symbolic links
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Quincey Koziol
* Tuesday, August 9, 2005
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
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 filename[NAME_BUF_SIZE];
TESTING("too many 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(H5L_NLINKS_DEF == 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 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, 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, 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;
if(H5Fclose(fid)<0) TEST_ERROR;
/* Open file */
if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) TEST_ERROR;
/* Open object through last hard link */
if((gid = H5Gopen(fid, "hard21")) < 0) TEST_ERROR;
/* Check name */
if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/hard21")) TEST_ERROR
/* Create object in hard-linked group */
if((gid2 = H5Gcreate(gid, "new_hard", (size_t)0)) < 0) TEST_ERROR
/* Close group in hard-linked group */
if(H5Gclose(gid2) < 0) TEST_ERROR
/* Close hard-linked object */
if(H5Gclose(gid) < 0) TEST_ERROR;
/* Open object through too deep soft link */
H5E_BEGIN_TRY {
gid = H5Gopen(fid, "soft17");
} H5E_END_TRY;
if (gid >= 0) {
H5_FAILED();
puts(" Should have failed for sequence of too many nested links.");
TEST_ERROR;
}
/* Open object through lesser soft link */
if((gid = H5Gopen(fid, "soft16")) < 0) TEST_ERROR;
/* Check name */
if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/soft16")) TEST_ERROR
/* Create object using soft links */
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
/* 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 toomany() */
#ifdef H5_GROUP_REVISION
/*-------------------------------------------------------------------------
* Function: test_h5l_create
*
* Purpose: Tests H5Lcreate
*
* Return: Success: 0
* Failure: number of errors
*
* Programmer: James Laird
* Monday, January 30, 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_h5l_create(hid_t fapl)
{
hid_t file_id=-1;
hid_t group_id=-1;
hid_t space_id=-1;
hid_t dset_id=-1;
hid_t type_id=-1;
hid_t lcpl_id=-1;
char filename[1024];
hsize_t dims[2];
int i, n, j;
int wdata[H5L_DIM1][H5L_DIM2];
int rdata[H5L_DIM1][H5L_DIM2];
TESTING("H5Llink");
/* Create file */
h5_fixname(FILENAME[3], fapl, filename, sizeof filename);
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;
if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR;
if(! H5Tcommitted(type_id)) TEST_ERROR;
/* Create the dataspace */
dims[0] = H5L_DIM1;
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, H5P_DEFAULT)) <0) TEST_ERROR;
/* Verify that we can write to and read from the dataset */
/* Initialize the dataset */
for (i = n = 0; i < H5L_DIM1; i++)
for (j = 0; j < H5L_DIM2; j++)
wdata[i][j] = n++;
/* Write the data to the dataset */
if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata)<0) TEST_ERROR;
/* Read the data back */
if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata)<0) TEST_ERROR;
/* Verify the data */
for (i = 0; i < H5L_DIM1; i++) {
for (j = 0; j < H5L_DIM2; j++) {
if (wdata[i][j] != rdata[i][j])
{
TEST_ERROR;
}
}}
/* Create a group with no name*/
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, 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, H5P_DEFAULT)<0) TEST_ERROR;
/* Close IDs for dataset and datatype */
if(H5Dclose(dset_id)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
/* Re-open datatype using new link */
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, H5P_DEFAULT)<0) TEST_ERROR;
if(H5Gclose(group_id)<0) TEST_ERROR;
/* Open dataset through root group and verify its data */
if((dset_id = H5Dopen(file_id, "/group/inter_group/dataset"))<0) TEST_ERROR;
/* Read data from dataset */
if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata)<0) TEST_ERROR;
for (i = 0; i < H5L_DIM1; i++) {
for (j = 0; j < H5L_DIM2; j++) {
if (wdata[i][j] != rdata[i][j])
{
TEST_ERROR;
}
}}
/* Close open IDs */
if(H5Dclose(dset_id)<0) TEST_ERROR;
if(H5Tclose(type_id)<0) TEST_ERROR;
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
if(H5Sclose(space_id)<0) TEST_ERROR;
if(H5Fclose(file_id)<0) TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose(group_id);
H5Dclose(dset_id);
H5Tclose(type_id);
H5Pclose(lcpl_id);
H5Sclose(space_id);
H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* end test_h5l_create() */
/*-------------------------------------------------------------------------
* Function: test_lcpl
*
* Purpose: Tests Link Creation Property Lists
*
* Return: Success: 0
* Failure: number of errors
*
* Programmer: James Laird
* Monday, January 30, 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_lcpl(hid_t fapl)
{
hid_t file_id=-1;
hid_t group_id=-1;
hid_t space_id=-1;
hid_t dset_id=-1;
hid_t type_id=-1;
hid_t lcpl_id=-1;
H5L_linkinfo_t linfo;
char filename[1024];
hsize_t dims[2];
TESTING("link creation property lists");
/* Actually, intermediate group creation is tested elsewhere (tmisc).
* Here we only need to test the character encoding property */
/* Create file */
h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<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, 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, 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, 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, H5P_DEFAULT) < 0) TEST_ERROR;
if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR;
/* Create a dataspace */
dims[0] = H5L_DIM1;
dims[1] = H5L_DIM2;
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, 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, 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 */
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR;
/* 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, 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, 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, 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, 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, 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, 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. */
if(H5Pclose(lcpl_id)<0) TEST_ERROR;
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, H5P_DEFAULT) < 0) TEST_ERROR;
/* Check that its character encoding is ASCII */
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, 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;
if(H5Sclose(space_id)<0) TEST_ERROR;
if(H5Fclose(file_id)<0) TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose(group_id);
H5Dclose(dset_id);
H5Tclose(type_id);
H5Pclose(lcpl_id);
H5Sclose(space_id);
H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* end test_lcpl() */
#endif /* H5_GROUP_REVISION */
/*-------------------------------------------------------------------------
* Function: test_move
*
* Purpose: Tests H5Lmove()
*
* Return: Success: 0
*
* Failure: number of errors
*
* Programmer: James Laird
* Friday, March 30, 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_move(hid_t fapl)
{
hid_t file_a, file_b=(-1);
hid_t grp_1=(-1), grp_2=(-1), grp_move=(-1), moved_grp=(-1);
char filename[1024];
TESTING("H5Lmove");
/* Create two new files */
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[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
/* Create groups in first file */
if((grp_1=H5Gcreate(file_a, "group1", 0))<0) TEST_ERROR;
if((grp_2=H5Gcreate(file_a, "group2", 0))<0) TEST_ERROR;
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, H5P_DEFAULT)<0)
TEST_ERROR;
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, 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, 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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
if((moved_grp = H5Gopen(grp_2, "group_new_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is no longer in the original location */
H5E_BEGIN_TRY {
if((moved_grp = H5Gopen(grp_1, "group_move"))>=0)
TEST_ERROR;
} 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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
if((moved_grp = H5Gopen(grp_2, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
if((moved_grp = H5Gopen(grp_1, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
if((moved_grp = H5Gopen(grp_2, "group_newest_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is in no previous locations */
H5E_BEGIN_TRY {
if((moved_grp = H5Gopen(grp_1, "group_newer_name"))>=0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_2, "group_newer_name"))>=0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_2, "group_new_name"))>=0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_1, "group_copy"))>=0)
TEST_ERROR;
} H5E_END_TRY;
H5Gclose(grp_1);
H5Gclose(grp_2);
H5Gclose(grp_move);
H5Fclose(file_a);
H5Fclose(file_b);
PASSED();
return 0;
error:
H5_FAILED();
H5E_BEGIN_TRY {
H5Gclose(grp_1);
H5Gclose(grp_2);
H5Gclose(grp_move);
H5Gclose(moved_grp);
H5Fclose(file_a);
H5Fclose(file_b);
} H5E_END_TRY;
return 1;
}
/*-------------------------------------------------------------------------
* Function: test_copy
*
* Purpose: Tests H5Lcopy()
*
* Return: Success: 0
*
* Failure: number of errors
*
* Programmer: James Laird
* Friday, March 30, 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_copy(hid_t fapl)
{
hid_t file_a, file_b=(-1);
hid_t grp_1=(-1), grp_2=(-1), grp_move=(-1), moved_grp=(-1);
char filename[1024];
TESTING("H5Lcopy");
/* Create two new files */
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[1], fapl, filename, sizeof filename);
if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
TEST_ERROR;
/* Create groups in first file */
if((grp_1=H5Gcreate(file_a, "group1", 0))<0) TEST_ERROR;
if((grp_2=H5Gcreate(file_a, "group2", 0))<0) TEST_ERROR;
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, H5P_DEFAULT)<0)
TEST_ERROR;
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, 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, 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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
if((moved_grp = H5Gopen(grp_2, "group_new_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is also in the original location */
if((moved_grp = H5Gopen(grp_1, "group_copy"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group. */
if((moved_grp = H5Gopen(grp_2, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is also in the original location */
if((moved_grp = H5Gopen(grp_2, "group_new_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group . */
if((moved_grp = H5Gopen(grp_1, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is still in the previous location */
if((moved_grp = H5Gopen(grp_2, "group_new_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
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, H5P_DEFAULT)<0)
TEST_ERROR;
/* Open the group just moved to the new location. */
if((moved_grp = H5Gopen(grp_2, "group_newest_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
/* Verify that the group is still in all previous original locations */
if((moved_grp = H5Gopen(grp_1, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_2, "group_newer_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_2, "group_new_name"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
if((moved_grp = H5Gopen(grp_1, "group_copy"))<0)
TEST_ERROR;
if( H5Gclose(moved_grp) < 0)
TEST_ERROR;
H5Gclose(grp_1);
H5Gclose(grp_2);
H5Gclose(grp_move);
H5Fclose(file_a);
H5Fclose(file_b);
PASSED();
return 0;
error:
H5_FAILED();
H5E_BEGIN_TRY {
H5Gclose(grp_1);
H5Gclose(grp_2);
H5Gclose(grp_move);
H5Gclose(moved_grp);
H5Fclose(file_a);
H5Fclose(file_b);
} H5E_END_TRY;
return 1;
}
#ifdef H5_GROUP_REVISION
/*-------------------------------------------------------------------------
* Function: test_move_preserves
*
* Purpose: Tests that moving and renaming links preserves their
* properties.
*
* Return: Success: 0
* Failure: number of errors
*
* Programmer: James Laird
* Monday, January 30, 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_move_preserves(hid_t fapl_id)
{
hid_t file_id=-1;
hid_t group_id=-1;
hid_t lcpl_id=-1;
hid_t lcpl2_id=-1;
H5G_stat_t statbuf;
H5L_linkinfo_t linfo;
time_t old_create_time;
time_t old_modification_time;
time_t curr_time;
char filename[1024];
TESTING("moving and copying links preserves their properties");
/* Create file */
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 a link creation property list with the UTF-8 character encoding */
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR;
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, 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, 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;
/* If this test happens too quickly, the creation times will all be the same. Make sure the time changes. */
curr_time=time(NULL);
while(time(NULL) <= curr_time );
/* Close the file and reopen it */
if(H5Fclose(file_id)<0) TEST_ERROR;
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, 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, 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, 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, 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, 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, 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, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR;
/* 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, 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, 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, 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, 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, H5P_DEFAULT) <0) TEST_ERROR;
if(old_create_time != linfo.ctime) TEST_ERROR;
/* Check that its character encoding is not UTF-8 */
if(linfo.cset == H5T_CSET_UTF8) TEST_ERROR;
/* Close open IDs */
if(H5Pclose(lcpl_id) < 0) TEST_ERROR;
if(H5Fclose(file_id)<0) TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Pclose(lcpl_id);
H5Pclose(lcpl2_id);
H5Gclose(group_id);
H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* end test_move_preserves() */
#endif /* H5_GROUP_REVISION */
/*-------------------------------------------------------------------------
* Function: test_compat
*
* Purpose: Tests deprecated functions for backward compatibility.
*
* Return: Success: 0
* Failure: number of errors
*
* Programmer: James Laird
* Wednesday, April 26 2006
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_compat(hid_t fapl)
{
hid_t file_id=-1;
hid_t group1_id=-1;
hid_t group2_id=-1;
H5G_stat_t sb_hard1, sb_hard2, sb_soft1;
char filename[1024];
char linkval[1024];
TESTING("backwards compatibility");
/* Create file */
h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR;
/* Create two groups in the file */
if((group1_id = H5Gcreate(file_id, "group1", 1)) < 0) TEST_ERROR;
if((group2_id = H5Gcreate(file_id, "group2", 1)) < 0) TEST_ERROR;
/* Create links using H5Glink and H5Glink2 */
if(H5Glink(file_id, H5G_LINK_HARD, "group2", "group1/link_to_group2") < 0) TEST_ERROR;
if(H5Glink2(file_id, "group1", H5G_LINK_HARD, group2_id, "link_to_group1") < 0) TEST_ERROR;
if(H5Glink2(file_id, "link_to_group1", H5G_LINK_SOFT, H5G_SAME_LOC, "group2/soft_link_to_group1") < 0) TEST_ERROR;
/* Test that H5Glink created hard links properly */
if(H5Gget_objinfo(file_id, "/group2", TRUE, &sb_hard1)<0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "/group1/link_to_group2", TRUE, &sb_hard2)<0) TEST_ERROR;
if (HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) {
H5_FAILED();
puts(" Hard link test failed. Link seems not to point to the ");
puts(" expected file location.");
TEST_ERROR;
}
/* Test for the other hard link created */
if(H5Gget_objinfo(file_id, "/group1", TRUE, &sb_hard1)<0) TEST_ERROR;
if(H5Gget_objinfo(file_id, "/group2/link_to_group1", TRUE, &sb_hard2)<0) TEST_ERROR;
if (HDmemcmp(&sb_hard1.objno, sb_hard2.objno, sizeof(sb_hard1.objno))) {
H5_FAILED();
puts(" Hard link test failed. Link seems not to point to the ");
puts(" expected file location.");
TEST_ERROR;
}
/* Test the soft link */
if(H5Gget_objinfo(file_id, "/group2/soft_link_to_group1", FALSE, &sb_soft1)<0) TEST_ERROR;
if(sb_soft1.type != H5G_LINK) TEST_ERROR;
if(sb_soft1.linklen != HDstrlen("link_to_group1") + 1) TEST_ERROR;
if(H5Gget_linkval(group2_id, "soft_link_to_group1", sb_soft1.linklen, linkval) < 0) TEST_ERROR;
if(HDstrcmp("link_to_group1", linkval)) TEST_ERROR;
/* Test H5Gmove and H5Gmove2 */
if(H5Gmove(file_id, "group1", "moved_group1") < 0) TEST_ERROR;
if(H5Gmove2(file_id, "group2", group1_id, "moved_group2") < 0) TEST_ERROR;
/* Ensure that both groups can be opened */
if(H5Gclose(group2_id)<0) TEST_ERROR;
if(H5Gclose(group1_id)<0) TEST_ERROR;
if((group1_id = H5Gopen(file_id, "moved_group1")) < 0) TEST_ERROR;
if((group2_id = H5Gopen(file_id, "moved_group1/moved_group2")) < 0) TEST_ERROR;
/* Close open IDs */
if(H5Gclose(group2_id)<0) TEST_ERROR;
if(H5Gclose(group1_id)<0) TEST_ERROR;
/* Test H5Gunlink */
if(H5Gunlink(file_id, "moved_group1/moved_group2") < 0) TEST_ERROR;
H5E_BEGIN_TRY {
if(H5Gopen(file_id, "moved_group1/moved_group2") >=0) TEST_ERROR;
} H5E_END_TRY;
if(H5Fclose(file_id)<0) TEST_ERROR;
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose(group2_id);
H5Gclose(group1_id);
H5Fclose(file_id);
} H5E_END_TRY;
return 1;
} /* end test_compat() */
/*-------------------------------------------------------------------------
* 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;
/* Create a new object using H5Gcreate through the external link
* directly
*/
if((gid = H5Gcreate(fid, "ext_link/newer_group", (size_t)0)) < 0) TEST_ERROR
/* Close file and group */
if(H5Gclose(gid) < 0) TEST_ERROR;
if(H5Fclose(fid)<0) TEST_ERROR;
/* Open first file again with read-only access and check on objects created */
if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
/* Open objects created through external link */
if((gid = H5Gopen(fid, "new_group")) < 0) TEST_ERROR;
if((gid2 = H5Gopen(fid, "newer_group")) < 0) TEST_ERROR;
/* Check names */
if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/new_group")) TEST_ERROR
if((name_len = H5Iget_name( gid2, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR
if(HDstrcmp(objname, "/newer_group")) TEST_ERROR
/* Close opened objects */
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Gclose(gid2) < 0) TEST_ERROR
/* Close first file */
if(H5Fclose(fid)<0) TEST_ERROR;
/* Verify that new objects can't be created through a read-only external
* link.
*/
if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
H5E_BEGIN_TRY {
gid = H5Gcreate(fid, "ext_link/readonly_group", (size_t)0);
} H5E_END_TRY
if(gid >= 0) TEST_ERROR
/* Close second file again */
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_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(H5L_NLINKS_DEF == 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: external_link_closing
*
* Purpose: Test that files are closed correctly when traversing
* external links.
*
* Return: Success: 0
* Failure: -1
*
* Programmer: James Laird
* Wednesday, August 16, 2006
*
*-------------------------------------------------------------------------
*/
static int
external_link_closing(hid_t fapl)
{
hid_t fid1 = (-1), fid2 = (-1), fid3 = (-1), fid4=(-1);
hid_t gid=(-1), tid=(-1), tid2=(-1), sid=(-1), did=(-1);
hid_t lcpl_id=(-1);
hsize_t dims[2];
char filename1[NAME_BUF_SIZE],
filename2[NAME_BUF_SIZE],
filename3[NAME_BUF_SIZE],
filename4[NAME_BUF_SIZE], /* Names of files to externally link across */
buf[NAME_BUF_SIZE]; /* misc. buffer */
H5L_linkinfo_t li;
H5G_stat_t sb;
hobj_ref_t obj_ref;
TESTING("that external files are closed during traversal");
/* In this test, external links will go from file1 to file2 and from
* file2 to file3.
* Test that all functions that can traverse external files close
* the files they open.
* Test that providing unusual paths containing external links can't
* make HDF5 forget to close a file it opened.
*/
/* 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 four files */
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
/* Create a dataspace and a datatype so we can create/commit a dataset/datatype in the files */
dims[0] = 2;
dims[1] = 2;
if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
if((tid2 = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
/* Create external links from each file to the next */
if(H5Lcreate_external(filename2, "/", fid1, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lcreate_external(filename3, "/", fid2, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lcreate_external(filename4, "/", fid3, "elink", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Close all files but the first */
if(H5Fclose(fid4) < 0) TEST_ERROR
if(H5Fclose(fid3) < 0) TEST_ERROR
if(H5Fclose(fid2) < 0) TEST_ERROR
/* Test creating each kind of object */
if((gid = H5Gcreate(fid1, "elink/elink/elink/group1", 0)) < 0) TEST_ERROR
if(H5Tcommit(fid1, "elink/elink/elink/type1", tid) < 0) TEST_ERROR
if((did = H5Dcreate(fid1, "elink/elink/elink/dataset1", tid2, sid, H5P_DEFAULT)) < 0) TEST_ERROR
/* Close objects */
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Tclose(tid) < 0) TEST_ERROR
if(H5Dclose(did) < 0) TEST_ERROR
/* Test that getting info works */
if(H5Lget_linkinfo(fid1, "elink/elink/elink/type1", &li, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lget_linkinfo(fid1, "elink/elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Gget_objinfo(fid1, "elink/elink/elink/type1", TRUE, &sb) < 0) TEST_ERROR
if(H5Gget_objinfo(fid1, "elink/elink/elink", TRUE, &sb) < 0) TEST_ERROR
if(H5Gget_objinfo(fid1, "elink/elink/elink", FALSE, &sb) < 0) TEST_ERROR
/* Test move */
if(H5Lmove(fid1, "elink/elink/elink/group1", fid1,
"elink/elink/elink/group1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Open file 4 so we can do some fancy things */
if((fid4 = H5Fopen(filename4, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
if(H5Lmove(fid1, "elink/elink/elink/type1", fid4,
"type1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lmove(fid4, "dataset1", fid1,
"elink/elink/elink/dataset1_moved", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Close file 4 again */
if(H5Fclose(fid4) < 0) TEST_ERROR
/* Test copy (as of this test, it uses the same code as move) */
if(H5Lcopy(fid1, "elink/elink/elink", fid1,
"elink/elink/elink_copied", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lcopy(fid1, "elink/elink/elink", fid1,
"elink/elink/elink/elink_copied2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Test H5Gset and get comment */
if(H5Gset_comment(fid1, "elink/elink/elink/group1_moved", "comment") < 0) TEST_ERROR
if(H5Gget_comment(fid1, "elink/elink/elink/group1_moved", sizeof(buf), buf) < 0) TEST_ERROR
/* Test H5*open */
if((gid = H5Gopen(fid1, "elink/elink/elink/group1_moved")) < 0) TEST_ERROR
if((tid = H5Topen(fid1, "elink/elink/elink/type1_moved")) < 0) TEST_ERROR
if((did = H5Dopen(fid1, "elink/elink/elink/dataset1_moved")) < 0) TEST_ERROR
/* Close objects */
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Tclose(tid) < 0) TEST_ERROR
if(H5Dclose(did) < 0) TEST_ERROR
/* Test H5*open_expand */
if((gid = H5Gopen_expand(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT)) < 0) TEST_ERROR
if((tid = H5Topen_expand(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT)) < 0) TEST_ERROR
if((did = H5Dopen_expand(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) TEST_ERROR
/* Close objects */
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Tclose(tid) < 0) TEST_ERROR
if(H5Dclose(did) < 0) TEST_ERROR
/* Test H5Oopen */
if((did = H5Oopen(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT)) < 0) TEST_ERROR
if(H5Dclose(did) < 0) TEST_ERROR
/* Test H5Fmount */
if((gid = H5Gcreate(fid1, "elink/elink/elink/mnt", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
H5E_BEGIN_TRY {
if(H5Fmount(fid1, "elink/elink/elink/mnt", fid1, H5P_DEFAULT) >= 0) TEST_ERROR
if(H5Funmount(fid1, "elink/elink/elink/mnt") >= 0) TEST_ERROR
} H5E_END_TRY
/* Test H5Rcreate */
if(H5Rcreate(&obj_ref, fid1, "elink/elink/elink/type1_moved", H5R_OBJECT, (-1)) < 0) TEST_ERROR
/* Test unlink */
if(H5Lunlink(fid1, "elink/elink/elink/group1_moved", H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lunlink(fid1, "elink/elink/elink/type1_moved", H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lunlink(fid1, "elink/elink/elink/dataset1_moved", H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lunlink(fid1, "elink/elink/elink_copied", H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lunlink(fid1, "elink/elink/elink/elink_copied2", H5P_DEFAULT) < 0) TEST_ERROR
/* We've tested that the various functions above don't leave files open.
* Now test that we can't confuse HDF5 by giving unusual paths with external links
*/
/* Create an external link that points to another external link */
if((fid2 = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
if(H5Lcreate_external(filename3, "/elink", fid2, "elink2",
H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Fclose(fid2) < 0) TEST_ERROR
/* Do an external link traversal that recursively calls another external link. */
if((gid = H5Gcreate(fid1, "elink/elink2/group2", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
/* Create two more groups so that the last three elements in the path are
* all within the same external file
*/
if((gid = H5Gcreate(fid1, "elink/elink2/group2/group3", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
if((gid = H5Gcreate(fid1, "elink/elink2/group2/group3/group4", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Gget_objinfo(fid1, "elink/elink2/group2/group3/group4", TRUE, &sb) < 0) TEST_ERROR
#ifdef H5_GROUP_REVISION
/* Add a few regular groups and a soft link in file2 using intermediate group creation */
if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR
if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR
if(H5Lcreate_soft("/elink2", fid1, "elink/file2group1/file2group2/slink",
lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR
/* Try to traverse this path. There are three soft traversals in a row;
* slink points to (file2)/elink2, which points to (file3)/elink, which
* points to file 4.
*/
if((gid = H5Gcreate(fid1, "elink/file2group1/file2group2/slink/group3", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Lget_linkinfo(fid1, "elink/file2group1/file2group2/slink/group3", &li, H5P_DEFAULT) < 0) TEST_ERROR
/* Some simpler tests */
if((gid = H5Gcreate(fid1, "elink/file2group3", 0)) < 0) TEST_ERROR
if(H5Gclose(gid) < 0) TEST_ERROR
if(H5Lget_linkinfo(fid1, "elink/file2group3", &li, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lget_linkinfo(fid1, "elink/elink", &li, H5P_DEFAULT) < 0) TEST_ERROR
#endif /* H5_GROUP_REVISION */
/* Close file1, the only file that should still be open */
if(H5Fclose(fid1) < 0) TEST_ERROR
/* Re-create each file. If they are hanging open, these creates will fail */
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid4 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
/* Cleanup */
if(H5Sclose(sid) < 0) TEST_ERROR
if(H5Tclose(tid2) < 0) TEST_ERROR
if(H5Fclose(fid4) < 0) TEST_ERROR
if(H5Fclose(fid3) < 0) TEST_ERROR
if(H5Fclose(fid2) < 0) TEST_ERROR
if(H5Fclose(fid1) < 0) TEST_ERROR
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose(gid);
H5Tclose(tid);
H5Dclose(did);
H5Sclose(sid);
H5Tclose(tid2);
H5Fclose(fid4);
H5Fclose(fid3);
H5Fclose(fid2);
H5Fclose(fid1);
} H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* 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
external_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(H5Pset_elink_prefix(lapl_id, pathbuf) < 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. */
static 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 */
static herr_t
UD_cb_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size)
{
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 */
static 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 */
static 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(hid_t 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
*
*-------------------------------------------------------------------------
*/
static herr_t
UD_cbsucc_create(const char UNUSED * link_name, hid_t UNUSED loc_group,
void * udata, size_t udata_size, hid_t UNUSED 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 UNUSED * link_name, hid_t cur_group,
void * udata, size_t UNUSED 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 */
static herr_t
UD_cbfail_move(const char UNUSED * new_name, hid_t UNUSED new_loc,
void UNUSED * udata, size_t UNUSED udata_size)
{
/* This traversal function will always fail. */
return -1;
}
/* SuccessCallback for when the link is moved or renamed */
static herr_t
UD_cbsucc_move(const char UNUSED * new_name, hid_t UNUSED new_loc,
void UNUSED * udata, size_t UNUSED udata_size)
{
/* This traversal function will always succeed. */
return 0;
}
/* Callback for when the link is deleted. Also called during move */
static herr_t
UD_cbsucc_delete(const char UNUSED * link_name, hid_t UNUSED loc_group,
void UNUSED * udata, size_t UNUSED udata_size)
{
/* This callback will always succeed */
return 0;
}
/* Callback for when the link is deleted. Also called during move */
static herr_t
UD_cbfail_delete(const char UNUSED * link_name, hid_t UNUSED loc_group,
void UNUSED * udata, size_t UNUSED 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 */
static ssize_t
UD_cbfail_query(const char UNUSED * link_name, void UNUSED * udata,
size_t UNUSED udata_size, void UNUSED *buf, size_t UNUSED buf_size)
{
/* This traversal function will always fail. */
return -1;
}
/* Callback for when the link is queried */
static ssize_t
UD_cbfail_on_write_query(const char UNUSED * link_name, void UNUSED * udata,
size_t UNUSED udata_size, void *buf, size_t UNUSED 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 */
static ssize_t
UD_cbsucc_query(const char UNUSED * link_name, void UNUSED * udata, size_t UNUSED 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: check_all_closed
*
* Purpose: External links and some UD links open files. To make sure
* that all such files got closed correctly, try to create
* each of them.
*
* If the files are still open, this will fail (indicating that
* some other test made a mistake).
*
* Return: Success: 0
* Failure: -1
*
* Programmer: James Laird
* Thursday, August 17, 2006
*
*-------------------------------------------------------------------------
*/
static int
check_all_closed(hid_t fapl)
{
hid_t fid=-1;
char filename[NAME_BUF_SIZE];
int x;
TESTING("that all files were closed correctly")
/* Some of the external or UD link tests may have failed to close
* an external file properly.
* To check this, try to create every file used in this test. If
* a file is already open, creating it will fail.
*/
for(x=0; FILENAME[x] != NULL; x++)
{
h5_fixname(FILENAME[x], fapl, filename, sizeof filename);
if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if(H5Fclose(fid) < 0) TEST_ERROR
}
PASSED();
return 0;
error:
printf("Error on file %d.\n", x);
H5E_BEGIN_TRY {
H5Fclose(fid);
} H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test links
*
* Return: Success: exit(0)
*
* Failure: exit(non-zero)
*
* Programmer: Robb Matzke
* Friday, August 14, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
int
main(void)
{
int nerrors = 0;
hid_t fapl;
const char *envval = NULL;
envval = HDgetenv("HDF5_DRIVER");
if (envval == NULL)
envval = "nomatch";
if (HDstrcmp(envval, "core") && HDstrcmp(envval, "split") && HDstrcmp(envval, "multi") && HDstrcmp(envval, "family") && HDstrcmp(envval, "stdio")) {
h5_reset();
fapl = h5_fileaccess();
/* The tests... */
nerrors += mklinks(fapl) < 0 ? 1 : 0;
nerrors += cklinks(fapl) < 0 ? 1 : 0;
nerrors += new_links(fapl) < 0 ? 1 : 0;
nerrors += ck_new_links(fapl) < 0 ? 1 : 0;
nerrors += long_links(fapl) < 0 ? 1 : 0;
nerrors += toomany(fapl) < 0 ? 1 : 0;
/* Test new H5L link creation routine */
#ifdef H5_GROUP_REVISION
nerrors += test_h5l_create(fapl);
nerrors += test_lcpl(fapl);
#endif
nerrors += test_move(fapl);
nerrors += test_copy(fapl);
#ifdef H5_GROUP_REVISION
nerrors += test_move_preserves(fapl);
#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 += external_link_closing(fapl) < 0 ? 1 : 0;
nerrors += external_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;
nerrors += check_all_closed(fapl) < 0 ? 1 : 0;
/* Results */
if (nerrors) {
printf("***** %d LINK TEST%s FAILED! *****\n",
nerrors, 1 == nerrors ? "" : "S");
exit(1);
}
printf("All link tests passed.\n");
h5_cleanup(FILENAME, fapl);
}
else
{
puts("All link tests skipped - Incompatible with current Virtual File Driver");
}
return 0;
}