diff options
author | James Laird <jlaird@hdfgroup.org> | 2006-08-02 23:41:53 (GMT) |
---|---|---|
committer | James Laird <jlaird@hdfgroup.org> | 2006-08-02 23:41:53 (GMT) |
commit | 3e755623cb24eb37c19fa645d74dc46948318253 (patch) | |
tree | 66e0a3807f37d50a8d6e5f3469864c604cd837c6 | |
parent | 71a4d0e9c48c4e02e5384cd3f6e38a2a530e9d22 (diff) | |
download | hdf5-3e755623cb24eb37c19fa645d74dc46948318253.zip hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.gz hdf5-3e755623cb24eb37c19fa645d74dc46948318253.tar.bz2 |
[svn-r12528] Added User-Defined links to the library.
Users can create external links using H5L_create_external(). These links
point to an object in another HDF5 file. Users can alter the behavior of
external links or create new kinds of links by registering callbacks
using the H5L interface.
Added tests, tools support, etc.
Also a number of other, minor changes have been made (some restructuring of
the H5L interface, for instance).
Additional documentation and examples are forthcoming.
109 files changed, 9339 insertions, 2068 deletions
@@ -530,6 +530,7 @@ ./src/H5Iprivate.h ./src/H5Ipublic.h ./src/H5L.c +./src/H5Lexternal.c ./src/H5Lpkg.h ./src/H5Lprivate.h ./src/H5Lpublic.h @@ -571,6 +572,7 @@ ./src/H5Pfapl.c ./src/H5Pfcpl.c ./src/H5Pgcpl.c +./src/H5Plapl.c ./src/H5Plcpl.c ./src/H5Pocpl.c ./src/H5Ppkg.h @@ -646,6 +648,8 @@ ./test/Makefile.am ./test/Makefile.in ./test/be_data.h5 +./test/be_extlink1.h5 +./test/be_extlink2.h5 ./test/big.c ./test/bittests.c ./test/btree2.c @@ -689,6 +693,7 @@ ./test/gen_old_group.c _DO_NOT_DISTRIBUTE_ ./test/gen_old_layout.c _DO_NOT_DISTRIBUTE_ ./test/gen_old_mtime.c _DO_NOT_DISTRIBUTE_ +./test/gen_udlinks.c _DO_NOT_DISTRIBUTE_ ./test/getname.c ./test/gheap.c ./test/group_old.h5 @@ -697,6 +702,8 @@ ./test/hyperslab.c ./test/istore.c ./test/le_data.h5 +./test/le_extlink1.h5 +./test/le_extlink2.h5 ./test/lheap.c ./test/links.c ./test/mergemsg.h5 @@ -724,6 +731,7 @@ ./test/testmeta.c ./test/tfile.c ./test/tgenprop.c +./test/th5o.c ./test/th5s.c ./test/th5s.h5 ./test/theap.c @@ -983,6 +991,8 @@ ./tools/testfiles/tempty.ls ./tools/testfiles/tenum.h5 ./tools/testfiles/tenum.ddl +./tools/testfiles/textlink.h5 +./tools/testfiles/textlink.h5.xml ./tools/testfiles/tfamily.ddl ./tools/testfiles/tfamily00000.h5 ./tools/testfiles/tfamily00001.h5 @@ -1057,6 +1067,11 @@ ./tools/testfiles/tvldtypes5.h5 ./tools/testfiles/tvlstr.h5 ./tools/testfiles/tvlstr.ddl +./tools/testfiles/tudlink.h5 +./tools/testfiles/tudlink.h5.xml +./tools/testfiles/tudlink-1.ddl +./tools/testfiles/tudlink-2.ddl +./tools/testfiles/tudlink-1.ls ./tools/testfiles/tattr2.h5 ./tools/testfiles/tall-2A.ddl ./tools/testfiles/tall-2B.ddl diff --git a/bin/reconfigure b/bin/reconfigure index b82f734..857efe9 100755 --- a/bin/reconfigure +++ b/bin/reconfigure @@ -120,4 +120,11 @@ echo echo " Running trace script:" bin/trace src/H5*.c || exit 1 +# Run make_error +# make_error automatically generates the H5E headers that create error message +# types for HDF5. +echo +echo " Running error generation script:" +bin/make_err src/H5err.txt || exit 1 + exit 0 @@ -51,6 +51,7 @@ $Source = ""; "H5G_obj_t" => "Go", "H5G_stat_t*" => "Gs", "H5L_link_t" => "Ll", + "unsigned long" => "Lu", "hsize_t" => "h", "hssize_t" => "Hs", "hid_t" => "i", @@ -87,6 +88,7 @@ $Source = ""; "H5E_auto_t" => "x", "H5E_walk_t" => "x", "H5G_iterate_t" => "x", + "H5L_link_class_t" => "x", "H5MM_allocate_t" => "x", "H5MM_free_t" => "x", "H5P_cls_create_func_t" => "x", @@ -22,6 +22,7 @@ #include "H5FDprivate.h" /* File drivers */ #include "H5FLprivate.h" /* Free lists */ #include "H5Ipkg.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5Rpublic.h" /* References */ @@ -135,6 +136,8 @@ H5_init_library(void) * initialized. The property interface must be initialized before the file * & dataset interfaces though, in order to provide them with the proper * property classes. + * The link interface needs to be initialized so that link property lists + * have their properties registered. */ if (H5E_init()<0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface") @@ -148,6 +151,8 @@ H5_init_library(void) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataset interface") if (H5AC_init()<0) HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize metadata caching interface") + if (H5L_init()<0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize link interface") /* Debugging? */ H5_debug_mask("-all"); @@ -1903,7 +1908,10 @@ H5_trace (const double *returning, const char *func, const char *type, ...) fprintf (out, "H5G_UNKNOWN"); break; case H5G_LINK: - fprintf (out, "H5L_LINK"); + fprintf (out, "H5G_LINK"); + break; + case H5G_UDLINK: + fprintf (out, "H5G_UDLINK"); break; case H5G_GROUP: fprintf (out, "H5G_GROUP"); @@ -1914,7 +1922,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...) case H5G_TYPE: fprintf (out, "H5G_TYPE"); break; - case H5G_RESERVED_4: case H5G_RESERVED_5: case H5G_RESERVED_6: case H5G_RESERVED_7: @@ -228,6 +228,7 @@ H5D_init_interface(void) H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */ size_t nprops; /* Number of properties */ + H5P_genclass_t *acc_pclass; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_init_interface) @@ -428,6 +429,20 @@ H5D_init_interface(void) if (H5D_get_dxpl_cache_real(H5P_DATASET_XFER_DEFAULT, &H5D_def_dxpl_cache) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve default DXPL info") + /* ========== Dataset Access Property Class Initialization ============*/ + assert(H5P_CLS_DATASET_ACCESS_g!=-1); + + /* Get the pointer to dataset creation class */ + if(NULL == (acc_pclass = H5I_object(H5P_CLS_DATASET_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + + /* Only register the default property list if it hasn't been created yet */ + if(H5P_LST_DATASET_ACCESS_g == (-1)) { + /* Register the default dataset access property list */ + if((H5P_LST_DATASET_ACCESS_g = H5P_create_id(acc_pclass))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } @@ -1213,11 +1228,11 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") if(H5G_loc(dset_id, &dset_loc) <0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to get location for dataset") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get location for dataset") /* Link the new dataset */ - if( H5L_link(&loc, name, &dset_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to dataset") + if( H5L_link(&loc, name, &dset_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to dataset") ret_value = dset_id; @@ -1277,7 +1292,7 @@ done: */ hid_t H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id, - hid_t dcpl_id) + hid_t dcpl_id, hid_t dapl_id) { H5G_loc_t loc; /* Object location to insert dataset into */ H5D_t *new_dset = NULL; /* New dataset's info */ @@ -1285,7 +1300,7 @@ H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5Dcreate_expand, FAIL) - H5TRACE4("i","iiii",loc_id,type_id,space_id,dcpl_id); + H5TRACE5("i","iiiii",loc_id,type_id,space_id,dcpl_id,dapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc) < 0) @@ -1300,6 +1315,13 @@ H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id, if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID") + /* Get correct property list */ + if(H5P_DEFAULT == dapl_id) + dapl_id = H5P_DATASET_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") + /* build and open the new dataset */ if(NULL == (new_dset = H5D_create(loc.oloc->file, type_id, space, dcpl_id, H5AC_dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") @@ -1363,7 +1385,7 @@ H5Dopen(hid_t loc_id, const char *name) H5G_loc_reset(&dset_loc); /* Find the dataset object */ - if(H5G_loc_find(&loc, name, &dset_loc, dxpl_id) < 0) + if(H5G_loc_find(&loc, name, &dset_loc, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") ent_found = TRUE; @@ -1398,6 +1420,91 @@ done: /*------------------------------------------------------------------------- + * Function: H5Dopen_expand + * + * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns + * its ID. The dataset should be close when the caller is no + * longer interested in it. + * + * Takes a dataset access property list + * + * Return: Success: A new dataset ID + * Failure: FAIL + * + * Programmer: James Laird + * Thursday, July 27, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dopen_expand(hid_t loc_id, const char *name, hid_t dapl_id) +{ + H5D_t *dset = NULL; + H5G_loc_t loc; /* Object location of group */ + H5G_loc_t dset_loc; /* Object location of dataset */ + H5G_name_t path; /* Dataset group hier. path */ + H5O_loc_t oloc; /* Dataset object location */ + hbool_t ent_found = FALSE; /* Entry at 'name' found */ + hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */ + hid_t ret_value; + + FUNC_ENTER_API(H5Dopen_expand, FAIL) + H5TRACE3("i","isi",loc_id,name,dapl_id); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Get correct property list */ + if(H5P_DEFAULT == dapl_id) + dapl_id = H5P_DATASET_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") + + /* Set up dataset location to fill in */ + dset_loc.oloc = &oloc; + dset_loc.path = &path; + H5G_loc_reset(&dset_loc); + + /* Find the dataset object */ + if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") + ent_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&oloc, dxpl_id) != H5G_DATASET) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") + + /* Open the dataset */ + if((dset = H5D_open(&dset_loc, dxpl_id)) == NULL) { + ent_found = FALSE; /* Reset this, since H5D_open 'owns' it and then free's it on failure */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") + } /* end if */ + + /* Register an atom for the dataset */ + if((ret_value = H5I_register(H5I_DATASET, dset)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom") + +done: + if(ret_value < 0) { + if(dset != NULL) { + if(H5D_close(dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + } /* end if */ + else { + if(ent_found) + H5G_name_free(&path); + } /* end else */ + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5Dclose * * Purpose: Closes access to a dataset (DATASET_ID) and releases diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 45b13d8..b44bc8b 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -91,6 +91,7 @@ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, H5_DLL hid_t H5Dcreate(hid_t file_id, const char *name, hid_t type_id, hid_t space_id, hid_t plist_id); H5_DLL hid_t H5Dopen(hid_t file_id, const char *name); +H5_DLL hid_t H5Dopen_expand(hid_t file_id, const char *name, hid_t dapl_id); H5_DLL herr_t H5Dclose(hid_t dset_id); H5_DLL hid_t H5Dget_space(hid_t dset_id); H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation); @@ -112,7 +113,7 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size); H5_DLL herr_t H5Ddebug(hid_t dset_id); H5_DLL hid_t H5Dcreate_expand(hid_t file_id, hid_t type_id, - hid_t space_id, hid_t plist_id); + hid_t space_id, hid_t plist_id, hid_t dapl_id); #ifdef __cplusplus diff --git a/src/H5Edefin.h b/src/H5Edefin.h index 229a67f..9b14486 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -20,77 +20,47 @@ #define _H5Edefin_H /* Major error IDs */ -hid_t H5E_DATASET_g = FAIL; /* Dataset */ -hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */ +hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */ +hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */ +hid_t H5E_CACHE_g = FAIL; /* Object cache */ +hid_t H5E_SLIST_g = FAIL; /* Skip Lists */ hid_t H5E_STORAGE_g = FAIL; /* Data storage */ -hid_t H5E_FILE_g = FAIL; /* File accessability */ -hid_t H5E_SYM_g = FAIL; /* Symbol table */ -hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */ -hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */ -hid_t H5E_BTREE_g = FAIL; /* B-Tree node */ -hid_t H5E_REFERENCE_g = FAIL; /* References */ -hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */ +hid_t H5E_ATOM_g = FAIL; /* Object atom */ hid_t H5E_RESOURCE_g = FAIL; /* Resource unavailable */ -hid_t H5E_PLIST_g = FAIL; /* Property lists */ -hid_t H5E_DATATYPE_g = FAIL; /* Datatype */ -hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */ -hid_t H5E_HEAP_g = FAIL; /* Heap */ +hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */ hid_t H5E_OHDR_g = FAIL; /* Object header */ -hid_t H5E_ATOM_g = FAIL; /* Object atom */ +hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */ +hid_t H5E_ERROR_g = FAIL; /* Error API */ +hid_t H5E_BTREE_g = FAIL; /* B-Tree node */ hid_t H5E_ATTR_g = FAIL; /* Attribute */ -hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */ +hid_t H5E_PLIST_g = FAIL; /* Property lists */ +hid_t H5E_SYM_g = FAIL; /* Symbol table */ +hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */ +hid_t H5E_HEAP_g = FAIL; /* Heap */ +hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */ +hid_t H5E_FILE_g = FAIL; /* File accessability */ +hid_t H5E_LINK_g = FAIL; /* Links */ +hid_t H5E_DATATYPE_g = FAIL; /* Datatype */ +hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */ hid_t H5E_IO_g = FAIL; /* Low-level I/O */ -hid_t H5E_SLIST_g = FAIL; /* Skip Lists */ +hid_t H5E_DATASET_g = FAIL; /* Dataset */ +hid_t H5E_REFERENCE_g = FAIL; /* References */ hid_t H5E_EFL_g = FAIL; /* External file list */ -hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */ -hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */ -hid_t H5E_ERROR_g = FAIL; /* Error API */ +hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */ +hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */ hid_t H5E_PLINE_g = FAIL; /* Data filters */ -hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */ -hid_t H5E_CACHE_g = FAIL; /* Object cache */ /* Minor error IDs */ -/* Generic low-level file I/O errors */ -hid_t H5E_SEEKERROR_g = FAIL; /* Seek failed */ -hid_t H5E_READERROR_g = FAIL; /* Read failed */ -hid_t H5E_WRITEERROR_g = FAIL; /* Write failed */ -hid_t H5E_CLOSEERROR_g = FAIL; /* Close failed */ -hid_t H5E_OVERFLOW_g = FAIL; /* Address overflowed */ -hid_t H5E_FCNTL_g = FAIL; /* File control (fcntl) failed */ - -/* Resource errors */ -hid_t H5E_NOSPACE_g = FAIL; /* No space available for allocation */ -hid_t H5E_CANTALLOC_g = FAIL; /* Can't allocate space */ -hid_t H5E_CANTCOPY_g = FAIL; /* Unable to copy object */ -hid_t H5E_CANTFREE_g = FAIL; /* Unable to free object */ -hid_t H5E_ALREADYEXISTS_g = FAIL; /* Object already exists */ -hid_t H5E_CANTLOCK_g = FAIL; /* Unable to lock object */ -hid_t H5E_CANTUNLOCK_g = FAIL; /* Unable to unlock object */ -hid_t H5E_CANTGC_g = FAIL; /* Unable to garbage collect */ -hid_t H5E_CANTGETSIZE_g = FAIL; /* Unable to compute size */ - -/* Heap errors */ -hid_t H5E_CANTRESTORE_g = FAIL; /* Can't restore condition */ -hid_t H5E_CANTCOMPUTE_g = FAIL; /* Can't compute value */ -hid_t H5E_CANTEXTEND_g = FAIL; /* Can't extend heap's space */ -hid_t H5E_CANTATTACH_g = FAIL; /* Can't attach object */ -hid_t H5E_CANTUPDATE_g = FAIL; /* Can't update object */ - -/* Function entry/exit interface errors */ -hid_t H5E_CANTINIT_g = FAIL; /* Unable to initialize object */ -hid_t H5E_ALREADYINIT_g = FAIL; /* Object already initialized */ -hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */ - -/* Property list errors */ -hid_t H5E_CANTGET_g = FAIL; /* Can't get value */ -hid_t H5E_CANTSET_g = FAIL; /* Can't set value */ -hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */ +/* System level errors */ +hid_t H5E_SYSERRSTR_g = FAIL; /* System error message */ -/* Free space errors */ -hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */ -hid_t H5E_CANTREVIVE_g = FAIL; /* Can't revive object */ -hid_t H5E_CANTSHRINK_g = FAIL; /* Can't shrink container */ +/* I/O pipeline errors */ +hid_t H5E_NOFILTER_g = FAIL; /* Requested filter is not available */ +hid_t H5E_CALLBACK_g = FAIL; /* Callback failed */ +hid_t H5E_CANAPPLY_g = FAIL; /* Error from filter 'can apply' callback */ +hid_t H5E_SETLOCAL_g = FAIL; /* Error from filter 'set local' callback */ +hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled */ /* Object header related errors */ hid_t H5E_LINKCOUNT_g = FAIL; /* Bad object header link count */ @@ -101,26 +71,37 @@ hid_t H5E_CANTDELETE_g = FAIL; /* Can't delete message */ hid_t H5E_BADITER_g = FAIL; /* Iteration failed */ hid_t H5E_CANTPACK_g = FAIL; /* Can't pack messages */ -/* System level errors */ -hid_t H5E_SYSERRSTR_g = FAIL; /* System error message */ - -/* I/O pipeline errors */ -hid_t H5E_NOFILTER_g = FAIL; /* Requested filter is not available */ -hid_t H5E_CALLBACK_g = FAIL; /* Callback failed */ -hid_t H5E_CANAPPLY_g = FAIL; /* Error from filter 'can apply' callback */ -hid_t H5E_SETLOCAL_g = FAIL; /* Error from filter 'set local' callback */ -hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled */ +/* Resource errors */ +hid_t H5E_NOSPACE_g = FAIL; /* No space available for allocation */ +hid_t H5E_CANTALLOC_g = FAIL; /* Can't allocate space */ +hid_t H5E_CANTCOPY_g = FAIL; /* Unable to copy object */ +hid_t H5E_CANTFREE_g = FAIL; /* Unable to free object */ +hid_t H5E_ALREADYEXISTS_g = FAIL; /* Object already exists */ +hid_t H5E_CANTLOCK_g = FAIL; /* Unable to lock object */ +hid_t H5E_CANTUNLOCK_g = FAIL; /* Unable to unlock object */ +hid_t H5E_CANTGC_g = FAIL; /* Unable to garbage collect */ +hid_t H5E_CANTGETSIZE_g = FAIL; /* Unable to compute size */ -/* Group related errors */ -hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */ -hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */ -hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */ -hid_t H5E_LINK_g = FAIL; /* Link failure */ -hid_t H5E_SLINK_g = FAIL; /* Symbolic link error */ -hid_t H5E_PATH_g = FAIL; /* Problem with path to object */ +/* Generic low-level file I/O errors */ +hid_t H5E_SEEKERROR_g = FAIL; /* Seek failed */ +hid_t H5E_READERROR_g = FAIL; /* Read failed */ +hid_t H5E_WRITEERROR_g = FAIL; /* Write failed */ +hid_t H5E_CLOSEERROR_g = FAIL; /* Close failed */ +hid_t H5E_OVERFLOW_g = FAIL; /* Address overflowed */ +hid_t H5E_FCNTL_g = FAIL; /* File control (fcntl) failed */ -/* No error */ -hid_t H5E_NONE_MINOR_g = FAIL; /* No error */ +/* B-tree related errors */ +hid_t H5E_NOTFOUND_g = FAIL; /* Object not found */ +hid_t H5E_EXISTS_g = FAIL; /* Object already exists */ +hid_t H5E_CANTENCODE_g = FAIL; /* Unable to encode value */ +hid_t H5E_CANTDECODE_g = FAIL; /* Unable to decode value */ +hid_t H5E_CANTSPLIT_g = FAIL; /* Unable to split node */ +hid_t H5E_CANTREDISTRIBUTE_g = FAIL; /* Unable to redistribute records */ +hid_t H5E_CANTSWAP_g = FAIL; /* Unable to swap records */ +hid_t H5E_CANTINSERT_g = FAIL; /* Unable to insert object */ +hid_t H5E_CANTLIST_g = FAIL; /* Unable to list node */ +hid_t H5E_CANTMODIFY_g = FAIL; /* Unable to modify record */ +hid_t H5E_CANTREMOVE_g = FAIL; /* Unable to remove object */ /* File accessability errors */ hid_t H5E_FILEEXISTS_g = FAIL; /* File already exists */ @@ -133,6 +114,16 @@ hid_t H5E_BADFILE_g = FAIL; /* Bad file ID accessed */ hid_t H5E_TRUNCATED_g = FAIL; /* File has been truncated */ hid_t H5E_MOUNT_g = FAIL; /* File mount error */ +/* No error */ +hid_t H5E_NONE_MINOR_g = FAIL; /* No error */ + +/* Heap errors */ +hid_t H5E_CANTRESTORE_g = FAIL; /* Can't restore condition */ +hid_t H5E_CANTCOMPUTE_g = FAIL; /* Can't compute value */ +hid_t H5E_CANTEXTEND_g = FAIL; /* Can't extend heap's space */ +hid_t H5E_CANTATTACH_g = FAIL; /* Can't attach object */ +hid_t H5E_CANTUPDATE_g = FAIL; /* Can't update object */ + /* Object atom related errors */ hid_t H5E_BADATOM_g = FAIL; /* Unable to find atom information (already closed?) */ hid_t H5E_BADGROUP_g = FAIL; /* Unable to find ID group information */ @@ -141,6 +132,44 @@ hid_t H5E_CANTINC_g = FAIL; /* Unable to increment reference count * hid_t H5E_CANTDEC_g = FAIL; /* Unable to decrement reference count */ hid_t H5E_NOIDS_g = FAIL; /* Out of IDs for group */ +/* Group related errors */ +hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */ +hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */ +hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */ +hid_t H5E_PATH_g = FAIL; /* Problem with path to object */ + +/* Property list errors */ +hid_t H5E_CANTGET_g = FAIL; /* Can't get value */ +hid_t H5E_CANTSET_g = FAIL; /* Can't set value */ +hid_t H5E_DUPCLASS_g = FAIL; /* Duplicate class name in parent class */ + +/* Function entry/exit interface errors */ +hid_t H5E_CANTINIT_g = FAIL; /* Unable to initialize object */ +hid_t H5E_ALREADYINIT_g = FAIL; /* Object already initialized */ +hid_t H5E_CANTRELEASE_g = FAIL; /* Unable to release object */ + +/* Datatype conversion errors */ +hid_t H5E_CANTCONVERT_g = FAIL; /* Can't convert datatypes */ +hid_t H5E_BADSIZE_g = FAIL; /* Bad size for object */ + +/* Link related errors */ +hid_t H5E_TRAVERSE_g = FAIL; /* Link traversal failure */ +hid_t H5E_NLINKS_g = FAIL; /* Too many soft links in path */ +hid_t H5E_NOTREGISTERED_g = FAIL; /* Link class not registered */ +hid_t H5E_CANTMOVE_g = FAIL; /* Move callback returned error */ + +/* Parallel MPI errors */ +hid_t H5E_MPI_g = FAIL; /* Some MPI function failed */ +hid_t H5E_MPIERRSTR_g = FAIL; /* MPI Error String */ +hid_t H5E_CANTRECV_g = FAIL; /* Can't receive data */ + +/* Argument errors */ +hid_t H5E_UNINITIALIZED_g = FAIL; /* Information is uinitialized */ +hid_t H5E_UNSUPPORTED_g = FAIL; /* Feature is unsupported */ +hid_t H5E_BADTYPE_g = FAIL; /* Inappropriate type */ +hid_t H5E_BADRANGE_g = FAIL; /* Out of range */ +hid_t H5E_BADVALUE_g = FAIL; /* Bad value */ + /* Cache related errors */ hid_t H5E_CANTFLUSH_g = FAIL; /* Unable to flush data from cache */ hid_t H5E_CANTSERIALIZE_g = FAIL; /* Unable to serialize data from cache */ @@ -159,10 +188,10 @@ hid_t H5E_CANTDIRTY_g = FAIL; /* Unable to mark metadata as dirty */ hid_t H5E_CANTEXPUNGE_g = FAIL; /* Unable to expunge a metadata cache entry */ hid_t H5E_CANTRESIZE_g = FAIL; /* Unable to resize a metadata cache entry */ -/* Parallel MPI errors */ -hid_t H5E_MPI_g = FAIL; /* Some MPI function failed */ -hid_t H5E_MPIERRSTR_g = FAIL; /* MPI Error String */ -hid_t H5E_CANTRECV_g = FAIL; /* Can't receive data */ +/* Free space errors */ +hid_t H5E_CANTMERGE_g = FAIL; /* Can't merge objects */ +hid_t H5E_CANTREVIVE_g = FAIL; /* Can't revive object */ +hid_t H5E_CANTSHRINK_g = FAIL; /* Can't shrink container */ /* Dataspace errors */ hid_t H5E_CANTCLIP_g = FAIL; /* Can't clip hyperslab region */ @@ -172,28 +201,4 @@ hid_t H5E_CANTNEXT_g = FAIL; /* Can't move to next iterator location hid_t H5E_BADSELECT_g = FAIL; /* Invalid selection */ hid_t H5E_CANTCOMPARE_g = FAIL; /* Can't compare objects */ -/* B-tree related errors */ -hid_t H5E_NOTFOUND_g = FAIL; /* Object not found */ -hid_t H5E_EXISTS_g = FAIL; /* Object already exists */ -hid_t H5E_CANTENCODE_g = FAIL; /* Unable to encode value */ -hid_t H5E_CANTDECODE_g = FAIL; /* Unable to decode value */ -hid_t H5E_CANTSPLIT_g = FAIL; /* Unable to split node */ -hid_t H5E_CANTREDISTRIBUTE_g = FAIL; /* Unable to redistribute records */ -hid_t H5E_CANTSWAP_g = FAIL; /* Unable to swap records */ -hid_t H5E_CANTINSERT_g = FAIL; /* Unable to insert object */ -hid_t H5E_CANTLIST_g = FAIL; /* Unable to list node */ -hid_t H5E_CANTMODIFY_g = FAIL; /* Unable to modify record */ -hid_t H5E_CANTREMOVE_g = FAIL; /* Unable to remove object */ - -/* Argument errors */ -hid_t H5E_UNINITIALIZED_g = FAIL; /* Information is uinitialized */ -hid_t H5E_UNSUPPORTED_g = FAIL; /* Feature is unsupported */ -hid_t H5E_BADTYPE_g = FAIL; /* Inappropriate type */ -hid_t H5E_BADRANGE_g = FAIL; /* Out of range */ -hid_t H5E_BADVALUE_g = FAIL; /* Bad value */ - -/* Datatype conversion errors */ -hid_t H5E_CANTCONVERT_g = FAIL; /* Can't convert datatypes */ -hid_t H5E_BADSIZE_g = FAIL; /* Bad size for object */ - #endif /* H5Edefin_H */ diff --git a/src/H5Einit.h b/src/H5Einit.h index a5a3f18..c62282e 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -23,182 +23,226 @@ /* Major error codes */ /*********************/ -assert(H5E_DATASET_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL) +assert(H5E_NONE_MAJOR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FUNC_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL) +assert(H5E_RS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CACHE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_SLIST_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_STORAGE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FILE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL) +assert(H5E_ATOM_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_SYM_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL) +assert(H5E_RESOURCE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_VFL_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL) +assert(H5E_FSPACE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_INTERNAL_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL) +assert(H5E_OHDR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BTREE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "B-Tree node"))==NULL) +assert(H5E_FUNC_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_REFERENCE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "References"))==NULL) +assert(H5E_ERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_DATASPACE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataspace"))==NULL) +assert(H5E_BTREE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "B-Tree node"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_BTREE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_RESOURCE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL) +assert(H5E_ATTR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_PLIST_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_DATATYPE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL) +assert(H5E_SYM_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Symbol table"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_SYM_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_RS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL) +assert(H5E_ARGS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_HEAP_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_OHDR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL) +assert(H5E_INTERNAL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_OHDR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_INTERNAL_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ATOM_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL) +assert(H5E_FILE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_FILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ATTR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL) +assert(H5E_LINK_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Links"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_NONE_MAJOR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL) +assert(H5E_DATATYPE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_TST_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_IO_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_SLIST_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL) +assert(H5E_DATASET_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_REFERENCE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "References"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_REFERENCE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_EFL_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_TST_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ARGS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL) +assert(H5E_VFL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ARGS_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL) +assert(H5E_DATASPACE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataspace"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_DATASPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_PLINE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data filters"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_PLINE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FSPACE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CACHE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CACHE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /*********************/ /* Minor error codes */ /*********************/ -/* Generic low-level file I/O errors */ -assert(H5E_SEEKERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Seek failed"))==NULL) +/* System level errors */ +assert(H5E_SYSERRSTR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "System error message"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_READERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Read failed"))==NULL) + +/* I/O pipeline errors */ +assert(H5E_NOFILTER_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Requested filter is not available"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_WRITEERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Write failed"))==NULL) +assert(H5E_CALLBACK_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Callback failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CLOSEERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Close failed"))==NULL) +assert(H5E_CANAPPLY_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'can apply' callback"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_OVERFLOW_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Address overflowed"))==NULL) +assert(H5E_SETLOCAL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FCNTL_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "File control (fcntl) failed"))==NULL) +assert(H5E_NOENCODER_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") + +/* Object header related errors */ +assert(H5E_LINKCOUNT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad object header link count"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_VERSION_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Wrong version number"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_ALIGNMENT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Alignment error"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_BADMESG_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unrecognized message"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTDELETE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't delete message"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_BADITER_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTPACK_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Resource errors */ @@ -248,153 +292,206 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to compute size"))==NULL) if((H5E_CANTGETSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* Heap errors */ -assert(H5E_CANTRESTORE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't restore condition"))==NULL) +/* Generic low-level file I/O errors */ +assert(H5E_SEEKERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Seek failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_SEEKERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTCOMPUTE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compute value"))==NULL) +assert(H5E_READERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Read failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_READERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTEXTEND_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't extend heap's space"))==NULL) +assert(H5E_WRITEERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Write failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_WRITEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTATTACH_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't attach object"))==NULL) +assert(H5E_CLOSEERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Close failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CLOSEERROR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTUPDATE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't update object"))==NULL) +assert(H5E_OVERFLOW_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Address overflowed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_OVERFLOW_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_FCNTL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "File control (fcntl) failed"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_FCNTL_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* Function entry/exit interface errors */ -assert(H5E_CANTINIT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to initialize object"))==NULL) +/* B-tree related errors */ +assert(H5E_NOTFOUND_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Object not found"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ALREADYINIT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already initialized"))==NULL) +assert(H5E_EXISTS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTRELEASE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to release object"))==NULL) +assert(H5E_CANTENCODE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to encode value"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") - -/* Property list errors */ -assert(H5E_CANTGET_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't get value"))==NULL) +assert(H5E_CANTDECODE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decode value"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTSET_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't set value"))==NULL) +assert(H5E_CANTSPLIT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to split node"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_DUPCLASS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class"))==NULL) +assert(H5E_CANTREDISTRIBUTE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to redistribute records"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") - -/* Free space errors */ -assert(H5E_CANTMERGE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't merge objects"))==NULL) +assert(H5E_CANTSWAP_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to swap records"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTREVIVE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't revive object"))==NULL) +assert(H5E_CANTINSERT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTSHRINK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't shrink container"))==NULL) +assert(H5E_CANTLIST_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to list node"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTMODIFY_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to modify record"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTREMOVE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to remove object"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* Object header related errors */ -assert(H5E_LINKCOUNT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad object header link count"))==NULL) +/* File accessability errors */ +assert(H5E_FILEEXISTS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_LINKCOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_VERSION_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Wrong version number"))==NULL) +assert(H5E_FILEOPEN_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "File already open"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_VERSION_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ALIGNMENT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Alignment error"))==NULL) +assert(H5E_CANTCREATE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create file"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ALIGNMENT_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADMESG_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unrecognized message"))==NULL) +assert(H5E_CANTOPENFILE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to open file"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADMESG_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTDELETE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't delete message"))==NULL) +assert(H5E_CANTCLOSEFILE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to close file"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTDELETE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADITER_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL) +assert(H5E_NOTHDF5_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Not an HDF5 file"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTPACK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL) +assert(H5E_BADFILE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad file ID accessed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_TRUNCATED_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "File has been truncated"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_MOUNT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "File mount error"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* System level errors */ -assert(H5E_SYSERRSTR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "System error message"))==NULL) +/* No error */ +assert(H5E_NONE_MINOR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SYSERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* I/O pipeline errors */ -assert(H5E_NOFILTER_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Requested filter is not available"))==NULL) +/* Heap errors */ +assert(H5E_CANTRESTORE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't restore condition"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NOFILTER_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTRESTORE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CALLBACK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Callback failed"))==NULL) +assert(H5E_CANTCOMPUTE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compute value"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CALLBACK_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTCOMPUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANAPPLY_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'can apply' callback"))==NULL) +assert(H5E_CANTEXTEND_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't extend heap's space"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANAPPLY_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTEXTEND_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_SETLOCAL_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Error from filter 'set local' callback"))==NULL) +assert(H5E_CANTATTACH_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't attach object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SETLOCAL_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTATTACH_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_NOENCODER_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Filter present but encoding disabled"))==NULL) +assert(H5E_CANTUPDATE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't update object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NOENCODER_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTUPDATE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") + +/* Object atom related errors */ +assert(H5E_BADATOM_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find atom information (already closed?)"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_BADGROUP_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find ID group information"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTREGISTER_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to register new atom"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTINC_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to increment reference count"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTDEC_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decrement reference count"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_NOIDS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of IDs for group"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Group related errors */ @@ -413,106 +510,122 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Name component is too long"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_COMPLEN_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_LINK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Link failure"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_SLINK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Symbolic link error"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_SLINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_PATH_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MINOR, "Problem with path to object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_PATH_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* No error */ -assert(H5E_NONE_MINOR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "No error"))==NULL) +/* Property list errors */ +assert(H5E_CANTGET_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't get value"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NONE_MINOR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTGET_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_CANTSET_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't set value"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_CANTSET_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_DUPCLASS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Duplicate class name in parent class"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_DUPCLASS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* File accessability errors */ -assert(H5E_FILEEXISTS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "File already exists"))==NULL) +/* Function entry/exit interface errors */ +assert(H5E_CANTINIT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to initialize object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FILEEXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FILEOPEN_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "File already open"))==NULL) +assert(H5E_ALREADYINIT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already initialized"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FILEOPEN_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_ALREADYINIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTCREATE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to create file"))==NULL) +assert(H5E_CANTRELEASE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to release object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTCREATE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTRELEASE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTOPENFILE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to open file"))==NULL) + +/* Datatype conversion errors */ +assert(H5E_CANTCONVERT_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't convert datatypes"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTOPENFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTCLOSEFILE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to close file"))==NULL) +assert(H5E_BADSIZE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad size for object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTCLOSEFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_NOTHDF5_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Not an HDF5 file"))==NULL) + +/* Link related errors */ +assert(H5E_TRAVERSE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Link traversal failure"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NOTHDF5_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_TRAVERSE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADFILE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad file ID accessed"))==NULL) +assert(H5E_NLINKS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Too many soft links in path"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADFILE_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NLINKS_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_TRUNCATED_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "File has been truncated"))==NULL) +assert(H5E_NOTREGISTERED_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Link class not registered"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_TRUNCATED_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_NOTREGISTERED_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_MOUNT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "File mount error"))==NULL) +assert(H5E_CANTMOVE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Move callback returned error"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_MOUNT_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* Object atom related errors */ -assert(H5E_BADATOM_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find atom information (already closed?)"))==NULL) +/* Parallel MPI errors */ +assert(H5E_MPI_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Some MPI function failed"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADATOM_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADGROUP_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to find ID group information"))==NULL) +assert(H5E_MPIERRSTR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "MPI Error String"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADGROUP_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTREGISTER_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to register new atom"))==NULL) +assert(H5E_CANTRECV_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't receive data"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTREGISTER_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTINC_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to increment reference count"))==NULL) + +/* Argument errors */ +assert(H5E_UNINITIALIZED_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Information is uinitialized"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTINC_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTDEC_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decrement reference count"))==NULL) +assert(H5E_UNSUPPORTED_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Feature is unsupported"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTDEC_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_NOIDS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of IDs for group"))==NULL) +assert(H5E_BADTYPE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Inappropriate type"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NOIDS_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_BADRANGE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of range"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_BADVALUE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad value"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Cache related errors */ @@ -597,21 +710,21 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to resize a metadata cache entr if((H5E_CANTRESIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* Parallel MPI errors */ -assert(H5E_MPI_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Some MPI function failed"))==NULL) +/* Free space errors */ +assert(H5E_CANTMERGE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't merge objects"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_MPI_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTMERGE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_MPIERRSTR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "MPI Error String"))==NULL) +assert(H5E_CANTREVIVE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't revive object"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_MPIERRSTR_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTREVIVE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTRECV_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't receive data"))==NULL) +assert(H5E_CANTSHRINK_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't shrink container"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTRECV_g = H5I_register(H5I_ERROR_MSG, msg))<0) +if((H5E_CANTSHRINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") /* Dataspace errors */ @@ -646,100 +759,4 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't compare objects"))==NULL) if((H5E_CANTCOMPARE_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -/* B-tree related errors */ -assert(H5E_NOTFOUND_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Object not found"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_NOTFOUND_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_EXISTS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Object already exists"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_EXISTS_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTENCODE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to encode value"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTENCODE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTDECODE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to decode value"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTDECODE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTSPLIT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to split node"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTSPLIT_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTREDISTRIBUTE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to redistribute records"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTREDISTRIBUTE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTSWAP_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to swap records"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTSWAP_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTINSERT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to insert object"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTINSERT_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTLIST_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to list node"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTLIST_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTMODIFY_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to modify record"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTMODIFY_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_CANTREMOVE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Unable to remove object"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTREMOVE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") - -/* Argument errors */ -assert(H5E_UNINITIALIZED_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Information is uinitialized"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_UNINITIALIZED_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_UNSUPPORTED_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Feature is unsupported"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_UNSUPPORTED_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADTYPE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Inappropriate type"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADTYPE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADRANGE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Out of range"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADRANGE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADVALUE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad value"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADVALUE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") - -/* Datatype conversion errors */ -assert(H5E_CANTCONVERT_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't convert datatypes"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_CANTCONVERT_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_BADSIZE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Bad size for object"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_BADSIZE_g = H5I_register(H5I_ERROR_MSG, msg))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") - #endif /* H5Einit_H */ diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index 70334fa..7c53b8f 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -23,80 +23,100 @@ /* Major error codes */ /*********************/ -#define H5E_DATASET (H5OPEN H5E_DATASET_g) -#define H5E_FUNC (H5OPEN H5E_FUNC_g) +#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g) +#define H5E_RS (H5OPEN H5E_RS_g) +#define H5E_CACHE (H5OPEN H5E_CACHE_g) +#define H5E_SLIST (H5OPEN H5E_SLIST_g) #define H5E_STORAGE (H5OPEN H5E_STORAGE_g) -#define H5E_FILE (H5OPEN H5E_FILE_g) -#define H5E_SYM (H5OPEN H5E_SYM_g) -#define H5E_VFL (H5OPEN H5E_VFL_g) -#define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g) -#define H5E_BTREE (H5OPEN H5E_BTREE_g) -#define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g) -#define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g) +#define H5E_ATOM (H5OPEN H5E_ATOM_g) #define H5E_RESOURCE (H5OPEN H5E_RESOURCE_g) -#define H5E_PLIST (H5OPEN H5E_PLIST_g) -#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g) -#define H5E_RS (H5OPEN H5E_RS_g) -#define H5E_HEAP (H5OPEN H5E_HEAP_g) +#define H5E_FSPACE (H5OPEN H5E_FSPACE_g) #define H5E_OHDR (H5OPEN H5E_OHDR_g) -#define H5E_ATOM (H5OPEN H5E_ATOM_g) +#define H5E_FUNC (H5OPEN H5E_FUNC_g) +#define H5E_ERROR (H5OPEN H5E_ERROR_g) +#define H5E_BTREE (H5OPEN H5E_BTREE_g) #define H5E_ATTR (H5OPEN H5E_ATTR_g) -#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g) +#define H5E_PLIST (H5OPEN H5E_PLIST_g) +#define H5E_SYM (H5OPEN H5E_SYM_g) +#define H5E_ARGS (H5OPEN H5E_ARGS_g) +#define H5E_HEAP (H5OPEN H5E_HEAP_g) +#define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g) +#define H5E_FILE (H5OPEN H5E_FILE_g) +#define H5E_LINK (H5OPEN H5E_LINK_g) +#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g) +#define H5E_TST (H5OPEN H5E_TST_g) #define H5E_IO (H5OPEN H5E_IO_g) -#define H5E_SLIST (H5OPEN H5E_SLIST_g) +#define H5E_DATASET (H5OPEN H5E_DATASET_g) +#define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g) #define H5E_EFL (H5OPEN H5E_EFL_g) -#define H5E_TST (H5OPEN H5E_TST_g) -#define H5E_ARGS (H5OPEN H5E_ARGS_g) -#define H5E_ERROR (H5OPEN H5E_ERROR_g) +#define H5E_VFL (H5OPEN H5E_VFL_g) +#define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g) #define H5E_PLINE (H5OPEN H5E_PLINE_g) -#define H5E_FSPACE (H5OPEN H5E_FSPACE_g) -#define H5E_CACHE (H5OPEN H5E_CACHE_g) -H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */ -H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */ +H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */ +H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */ +H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */ +H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */ H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */ -H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */ -H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */ -H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */ -H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */ -H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */ -H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */ -H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */ +H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */ H5_DLLVAR hid_t H5E_RESOURCE_g; /* Resource unavailable */ -H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */ -H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */ -H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */ -H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */ +H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */ H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */ -H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */ +H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */ +H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */ +H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */ H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */ -H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */ +H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */ +H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */ +H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */ +H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */ +H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */ +H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */ +H5_DLLVAR hid_t H5E_LINK_g; /* Links */ +H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */ +H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */ H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */ -H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */ +H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */ +H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */ H5_DLLVAR hid_t H5E_EFL_g; /* External file list */ -H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */ -H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */ -H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */ +H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */ +H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */ H5_DLLVAR hid_t H5E_PLINE_g; /* Data filters */ -H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */ -H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */ /*********************/ /* Minor error codes */ /*********************/ -/* Generic low-level file I/O errors */ -#define H5E_SEEKERROR (H5OPEN H5E_SEEKERROR_g) -#define H5E_READERROR (H5OPEN H5E_READERROR_g) -#define H5E_WRITEERROR (H5OPEN H5E_WRITEERROR_g) -#define H5E_CLOSEERROR (H5OPEN H5E_CLOSEERROR_g) -#define H5E_OVERFLOW (H5OPEN H5E_OVERFLOW_g) -#define H5E_FCNTL (H5OPEN H5E_FCNTL_g) -H5_DLLVAR hid_t H5E_SEEKERROR_g; /* Seek failed */ -H5_DLLVAR hid_t H5E_READERROR_g; /* Read failed */ -H5_DLLVAR hid_t H5E_WRITEERROR_g; /* Write failed */ -H5_DLLVAR hid_t H5E_CLOSEERROR_g; /* Close failed */ -H5_DLLVAR hid_t H5E_OVERFLOW_g; /* Address overflowed */ -H5_DLLVAR hid_t H5E_FCNTL_g; /* File control (fcntl) failed */ +/* System level errors */ +#define H5E_SYSERRSTR (H5OPEN H5E_SYSERRSTR_g) +H5_DLLVAR hid_t H5E_SYSERRSTR_g; /* System error message */ + +/* I/O pipeline errors */ +#define H5E_NOFILTER (H5OPEN H5E_NOFILTER_g) +#define H5E_CALLBACK (H5OPEN H5E_CALLBACK_g) +#define H5E_CANAPPLY (H5OPEN H5E_CANAPPLY_g) +#define H5E_SETLOCAL (H5OPEN H5E_SETLOCAL_g) +#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g) +H5_DLLVAR hid_t H5E_NOFILTER_g; /* Requested filter is not available */ +H5_DLLVAR hid_t H5E_CALLBACK_g; /* Callback failed */ +H5_DLLVAR hid_t H5E_CANAPPLY_g; /* Error from filter 'can apply' callback */ +H5_DLLVAR hid_t H5E_SETLOCAL_g; /* Error from filter 'set local' callback */ +H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */ + +/* Object header related errors */ +#define H5E_LINKCOUNT (H5OPEN H5E_LINKCOUNT_g) +#define H5E_VERSION (H5OPEN H5E_VERSION_g) +#define H5E_ALIGNMENT (H5OPEN H5E_ALIGNMENT_g) +#define H5E_BADMESG (H5OPEN H5E_BADMESG_g) +#define H5E_CANTDELETE (H5OPEN H5E_CANTDELETE_g) +#define H5E_BADITER (H5OPEN H5E_BADITER_g) +#define H5E_CANTPACK (H5OPEN H5E_CANTPACK_g) +H5_DLLVAR hid_t H5E_LINKCOUNT_g; /* Bad object header link count */ +H5_DLLVAR hid_t H5E_VERSION_g; /* Wrong version number */ +H5_DLLVAR hid_t H5E_ALIGNMENT_g; /* Alignment error */ +H5_DLLVAR hid_t H5E_BADMESG_g; /* Unrecognized message */ +H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */ +H5_DLLVAR hid_t H5E_BADITER_g; /* Iteration failed */ +H5_DLLVAR hid_t H5E_CANTPACK_g; /* Can't pack messages */ /* Resource errors */ #define H5E_NOSPACE (H5OPEN H5E_NOSPACE_g) @@ -118,91 +138,43 @@ H5_DLLVAR hid_t H5E_CANTUNLOCK_g; /* Unable to unlock object */ H5_DLLVAR hid_t H5E_CANTGC_g; /* Unable to garbage collect */ H5_DLLVAR hid_t H5E_CANTGETSIZE_g; /* Unable to compute size */ -/* Heap errors */ -#define H5E_CANTRESTORE (H5OPEN H5E_CANTRESTORE_g) -#define H5E_CANTCOMPUTE (H5OPEN H5E_CANTCOMPUTE_g) -#define H5E_CANTEXTEND (H5OPEN H5E_CANTEXTEND_g) -#define H5E_CANTATTACH (H5OPEN H5E_CANTATTACH_g) -#define H5E_CANTUPDATE (H5OPEN H5E_CANTUPDATE_g) -H5_DLLVAR hid_t H5E_CANTRESTORE_g; /* Can't restore condition */ -H5_DLLVAR hid_t H5E_CANTCOMPUTE_g; /* Can't compute value */ -H5_DLLVAR hid_t H5E_CANTEXTEND_g; /* Can't extend heap's space */ -H5_DLLVAR hid_t H5E_CANTATTACH_g; /* Can't attach object */ -H5_DLLVAR hid_t H5E_CANTUPDATE_g; /* Can't update object */ - -/* Function entry/exit interface errors */ -#define H5E_CANTINIT (H5OPEN H5E_CANTINIT_g) -#define H5E_ALREADYINIT (H5OPEN H5E_ALREADYINIT_g) -#define H5E_CANTRELEASE (H5OPEN H5E_CANTRELEASE_g) -H5_DLLVAR hid_t H5E_CANTINIT_g; /* Unable to initialize object */ -H5_DLLVAR hid_t H5E_ALREADYINIT_g; /* Object already initialized */ -H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */ - -/* Property list errors */ -#define H5E_CANTGET (H5OPEN H5E_CANTGET_g) -#define H5E_CANTSET (H5OPEN H5E_CANTSET_g) -#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g) -H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */ -H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */ -H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */ - -/* Free space errors */ -#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g) -#define H5E_CANTREVIVE (H5OPEN H5E_CANTREVIVE_g) -#define H5E_CANTSHRINK (H5OPEN H5E_CANTSHRINK_g) -H5_DLLVAR hid_t H5E_CANTMERGE_g; /* Can't merge objects */ -H5_DLLVAR hid_t H5E_CANTREVIVE_g; /* Can't revive object */ -H5_DLLVAR hid_t H5E_CANTSHRINK_g; /* Can't shrink container */ - -/* Object header related errors */ -#define H5E_LINKCOUNT (H5OPEN H5E_LINKCOUNT_g) -#define H5E_VERSION (H5OPEN H5E_VERSION_g) -#define H5E_ALIGNMENT (H5OPEN H5E_ALIGNMENT_g) -#define H5E_BADMESG (H5OPEN H5E_BADMESG_g) -#define H5E_CANTDELETE (H5OPEN H5E_CANTDELETE_g) -#define H5E_BADITER (H5OPEN H5E_BADITER_g) -#define H5E_CANTPACK (H5OPEN H5E_CANTPACK_g) -H5_DLLVAR hid_t H5E_LINKCOUNT_g; /* Bad object header link count */ -H5_DLLVAR hid_t H5E_VERSION_g; /* Wrong version number */ -H5_DLLVAR hid_t H5E_ALIGNMENT_g; /* Alignment error */ -H5_DLLVAR hid_t H5E_BADMESG_g; /* Unrecognized message */ -H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */ -H5_DLLVAR hid_t H5E_BADITER_g; /* Iteration failed */ -H5_DLLVAR hid_t H5E_CANTPACK_g; /* Can't pack messages */ - -/* System level errors */ -#define H5E_SYSERRSTR (H5OPEN H5E_SYSERRSTR_g) -H5_DLLVAR hid_t H5E_SYSERRSTR_g; /* System error message */ - -/* I/O pipeline errors */ -#define H5E_NOFILTER (H5OPEN H5E_NOFILTER_g) -#define H5E_CALLBACK (H5OPEN H5E_CALLBACK_g) -#define H5E_CANAPPLY (H5OPEN H5E_CANAPPLY_g) -#define H5E_SETLOCAL (H5OPEN H5E_SETLOCAL_g) -#define H5E_NOENCODER (H5OPEN H5E_NOENCODER_g) -H5_DLLVAR hid_t H5E_NOFILTER_g; /* Requested filter is not available */ -H5_DLLVAR hid_t H5E_CALLBACK_g; /* Callback failed */ -H5_DLLVAR hid_t H5E_CANAPPLY_g; /* Error from filter 'can apply' callback */ -H5_DLLVAR hid_t H5E_SETLOCAL_g; /* Error from filter 'set local' callback */ -H5_DLLVAR hid_t H5E_NOENCODER_g; /* Filter present but encoding disabled */ - -/* Group related errors */ -#define H5E_CANTOPENOBJ (H5OPEN H5E_CANTOPENOBJ_g) -#define H5E_CANTCLOSEOBJ (H5OPEN H5E_CANTCLOSEOBJ_g) -#define H5E_COMPLEN (H5OPEN H5E_COMPLEN_g) -#define H5E_LINK (H5OPEN H5E_LINK_g) -#define H5E_SLINK (H5OPEN H5E_SLINK_g) -#define H5E_PATH (H5OPEN H5E_PATH_g) -H5_DLLVAR hid_t H5E_CANTOPENOBJ_g; /* Can't open object */ -H5_DLLVAR hid_t H5E_CANTCLOSEOBJ_g; /* Can't close object */ -H5_DLLVAR hid_t H5E_COMPLEN_g; /* Name component is too long */ -H5_DLLVAR hid_t H5E_LINK_g; /* Link failure */ -H5_DLLVAR hid_t H5E_SLINK_g; /* Symbolic link error */ -H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */ +/* Generic low-level file I/O errors */ +#define H5E_SEEKERROR (H5OPEN H5E_SEEKERROR_g) +#define H5E_READERROR (H5OPEN H5E_READERROR_g) +#define H5E_WRITEERROR (H5OPEN H5E_WRITEERROR_g) +#define H5E_CLOSEERROR (H5OPEN H5E_CLOSEERROR_g) +#define H5E_OVERFLOW (H5OPEN H5E_OVERFLOW_g) +#define H5E_FCNTL (H5OPEN H5E_FCNTL_g) +H5_DLLVAR hid_t H5E_SEEKERROR_g; /* Seek failed */ +H5_DLLVAR hid_t H5E_READERROR_g; /* Read failed */ +H5_DLLVAR hid_t H5E_WRITEERROR_g; /* Write failed */ +H5_DLLVAR hid_t H5E_CLOSEERROR_g; /* Close failed */ +H5_DLLVAR hid_t H5E_OVERFLOW_g; /* Address overflowed */ +H5_DLLVAR hid_t H5E_FCNTL_g; /* File control (fcntl) failed */ -/* No error */ -#define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g) -H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */ +/* B-tree related errors */ +#define H5E_NOTFOUND (H5OPEN H5E_NOTFOUND_g) +#define H5E_EXISTS (H5OPEN H5E_EXISTS_g) +#define H5E_CANTENCODE (H5OPEN H5E_CANTENCODE_g) +#define H5E_CANTDECODE (H5OPEN H5E_CANTDECODE_g) +#define H5E_CANTSPLIT (H5OPEN H5E_CANTSPLIT_g) +#define H5E_CANTREDISTRIBUTE (H5OPEN H5E_CANTREDISTRIBUTE_g) +#define H5E_CANTSWAP (H5OPEN H5E_CANTSWAP_g) +#define H5E_CANTINSERT (H5OPEN H5E_CANTINSERT_g) +#define H5E_CANTLIST (H5OPEN H5E_CANTLIST_g) +#define H5E_CANTMODIFY (H5OPEN H5E_CANTMODIFY_g) +#define H5E_CANTREMOVE (H5OPEN H5E_CANTREMOVE_g) +H5_DLLVAR hid_t H5E_NOTFOUND_g; /* Object not found */ +H5_DLLVAR hid_t H5E_EXISTS_g; /* Object already exists */ +H5_DLLVAR hid_t H5E_CANTENCODE_g; /* Unable to encode value */ +H5_DLLVAR hid_t H5E_CANTDECODE_g; /* Unable to decode value */ +H5_DLLVAR hid_t H5E_CANTSPLIT_g; /* Unable to split node */ +H5_DLLVAR hid_t H5E_CANTREDISTRIBUTE_g; /* Unable to redistribute records */ +H5_DLLVAR hid_t H5E_CANTSWAP_g; /* Unable to swap records */ +H5_DLLVAR hid_t H5E_CANTINSERT_g; /* Unable to insert object */ +H5_DLLVAR hid_t H5E_CANTLIST_g; /* Unable to list node */ +H5_DLLVAR hid_t H5E_CANTMODIFY_g; /* Unable to modify record */ +H5_DLLVAR hid_t H5E_CANTREMOVE_g; /* Unable to remove object */ /* File accessability errors */ #define H5E_FILEEXISTS (H5OPEN H5E_FILEEXISTS_g) @@ -224,6 +196,22 @@ H5_DLLVAR hid_t H5E_BADFILE_g; /* Bad file ID accessed */ H5_DLLVAR hid_t H5E_TRUNCATED_g; /* File has been truncated */ H5_DLLVAR hid_t H5E_MOUNT_g; /* File mount error */ +/* No error */ +#define H5E_NONE_MINOR (H5OPEN H5E_NONE_MINOR_g) +H5_DLLVAR hid_t H5E_NONE_MINOR_g; /* No error */ + +/* Heap errors */ +#define H5E_CANTRESTORE (H5OPEN H5E_CANTRESTORE_g) +#define H5E_CANTCOMPUTE (H5OPEN H5E_CANTCOMPUTE_g) +#define H5E_CANTEXTEND (H5OPEN H5E_CANTEXTEND_g) +#define H5E_CANTATTACH (H5OPEN H5E_CANTATTACH_g) +#define H5E_CANTUPDATE (H5OPEN H5E_CANTUPDATE_g) +H5_DLLVAR hid_t H5E_CANTRESTORE_g; /* Can't restore condition */ +H5_DLLVAR hid_t H5E_CANTCOMPUTE_g; /* Can't compute value */ +H5_DLLVAR hid_t H5E_CANTEXTEND_g; /* Can't extend heap's space */ +H5_DLLVAR hid_t H5E_CANTATTACH_g; /* Can't attach object */ +H5_DLLVAR hid_t H5E_CANTUPDATE_g; /* Can't update object */ + /* Object atom related errors */ #define H5E_BADATOM (H5OPEN H5E_BADATOM_g) #define H5E_BADGROUP (H5OPEN H5E_BADGROUP_g) @@ -238,6 +226,68 @@ H5_DLLVAR hid_t H5E_CANTINC_g; /* Unable to increment reference count */ H5_DLLVAR hid_t H5E_CANTDEC_g; /* Unable to decrement reference count */ H5_DLLVAR hid_t H5E_NOIDS_g; /* Out of IDs for group */ +/* Group related errors */ +#define H5E_CANTOPENOBJ (H5OPEN H5E_CANTOPENOBJ_g) +#define H5E_CANTCLOSEOBJ (H5OPEN H5E_CANTCLOSEOBJ_g) +#define H5E_COMPLEN (H5OPEN H5E_COMPLEN_g) +#define H5E_PATH (H5OPEN H5E_PATH_g) +H5_DLLVAR hid_t H5E_CANTOPENOBJ_g; /* Can't open object */ +H5_DLLVAR hid_t H5E_CANTCLOSEOBJ_g; /* Can't close object */ +H5_DLLVAR hid_t H5E_COMPLEN_g; /* Name component is too long */ +H5_DLLVAR hid_t H5E_PATH_g; /* Problem with path to object */ + +/* Property list errors */ +#define H5E_CANTGET (H5OPEN H5E_CANTGET_g) +#define H5E_CANTSET (H5OPEN H5E_CANTSET_g) +#define H5E_DUPCLASS (H5OPEN H5E_DUPCLASS_g) +H5_DLLVAR hid_t H5E_CANTGET_g; /* Can't get value */ +H5_DLLVAR hid_t H5E_CANTSET_g; /* Can't set value */ +H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */ + +/* Function entry/exit interface errors */ +#define H5E_CANTINIT (H5OPEN H5E_CANTINIT_g) +#define H5E_ALREADYINIT (H5OPEN H5E_ALREADYINIT_g) +#define H5E_CANTRELEASE (H5OPEN H5E_CANTRELEASE_g) +H5_DLLVAR hid_t H5E_CANTINIT_g; /* Unable to initialize object */ +H5_DLLVAR hid_t H5E_ALREADYINIT_g; /* Object already initialized */ +H5_DLLVAR hid_t H5E_CANTRELEASE_g; /* Unable to release object */ + +/* Datatype conversion errors */ +#define H5E_CANTCONVERT (H5OPEN H5E_CANTCONVERT_g) +#define H5E_BADSIZE (H5OPEN H5E_BADSIZE_g) +H5_DLLVAR hid_t H5E_CANTCONVERT_g; /* Can't convert datatypes */ +H5_DLLVAR hid_t H5E_BADSIZE_g; /* Bad size for object */ + +/* Link related errors */ +#define H5E_TRAVERSE (H5OPEN H5E_TRAVERSE_g) +#define H5E_NLINKS (H5OPEN H5E_NLINKS_g) +#define H5E_NOTREGISTERED (H5OPEN H5E_NOTREGISTERED_g) +#define H5E_CANTMOVE (H5OPEN H5E_CANTMOVE_g) +H5_DLLVAR hid_t H5E_TRAVERSE_g; /* Link traversal failure */ +H5_DLLVAR hid_t H5E_NLINKS_g; /* Too many soft links in path */ +H5_DLLVAR hid_t H5E_NOTREGISTERED_g; /* Link class not registered */ +H5_DLLVAR hid_t H5E_CANTMOVE_g; /* Move callback returned error */ + +/* Parallel MPI errors */ +#define H5E_MPI (H5OPEN H5E_MPI_g) +#define H5E_MPIERRSTR (H5OPEN H5E_MPIERRSTR_g) +#define H5E_CANTRECV (H5OPEN H5E_CANTRECV_g) +H5_DLLVAR hid_t H5E_MPI_g; /* Some MPI function failed */ +H5_DLLVAR hid_t H5E_MPIERRSTR_g; /* MPI Error String */ +H5_DLLVAR hid_t H5E_CANTRECV_g; /* Can't receive data */ + +/* Argument errors */ +#define H5E_UNINITIALIZED (H5OPEN H5E_UNINITIALIZED_g) +#define H5E_UNSUPPORTED (H5OPEN H5E_UNSUPPORTED_g) +#define H5E_BADTYPE (H5OPEN H5E_BADTYPE_g) +#define H5E_BADRANGE (H5OPEN H5E_BADRANGE_g) +#define H5E_BADVALUE (H5OPEN H5E_BADVALUE_g) +H5_DLLVAR hid_t H5E_UNINITIALIZED_g; /* Information is uinitialized */ +H5_DLLVAR hid_t H5E_UNSUPPORTED_g; /* Feature is unsupported */ +H5_DLLVAR hid_t H5E_BADTYPE_g; /* Inappropriate type */ +H5_DLLVAR hid_t H5E_BADRANGE_g; /* Out of range */ +H5_DLLVAR hid_t H5E_BADVALUE_g; /* Bad value */ + /* Cache related errors */ #define H5E_CANTFLUSH (H5OPEN H5E_CANTFLUSH_g) #define H5E_CANTSERIALIZE (H5OPEN H5E_CANTSERIALIZE_g) @@ -272,13 +322,13 @@ H5_DLLVAR hid_t H5E_CANTDIRTY_g; /* Unable to mark metadata as dirty */ H5_DLLVAR hid_t H5E_CANTEXPUNGE_g; /* Unable to expunge a metadata cache entry */ H5_DLLVAR hid_t H5E_CANTRESIZE_g; /* Unable to resize a metadata cache entry */ -/* Parallel MPI errors */ -#define H5E_MPI (H5OPEN H5E_MPI_g) -#define H5E_MPIERRSTR (H5OPEN H5E_MPIERRSTR_g) -#define H5E_CANTRECV (H5OPEN H5E_CANTRECV_g) -H5_DLLVAR hid_t H5E_MPI_g; /* Some MPI function failed */ -H5_DLLVAR hid_t H5E_MPIERRSTR_g; /* MPI Error String */ -H5_DLLVAR hid_t H5E_CANTRECV_g; /* Can't receive data */ +/* Free space errors */ +#define H5E_CANTMERGE (H5OPEN H5E_CANTMERGE_g) +#define H5E_CANTREVIVE (H5OPEN H5E_CANTREVIVE_g) +#define H5E_CANTSHRINK (H5OPEN H5E_CANTSHRINK_g) +H5_DLLVAR hid_t H5E_CANTMERGE_g; /* Can't merge objects */ +H5_DLLVAR hid_t H5E_CANTREVIVE_g; /* Can't revive object */ +H5_DLLVAR hid_t H5E_CANTSHRINK_g; /* Can't shrink container */ /* Dataspace errors */ #define H5E_CANTCLIP (H5OPEN H5E_CANTCLIP_g) @@ -294,46 +344,4 @@ H5_DLLVAR hid_t H5E_CANTNEXT_g; /* Can't move to next iterator location */ H5_DLLVAR hid_t H5E_BADSELECT_g; /* Invalid selection */ H5_DLLVAR hid_t H5E_CANTCOMPARE_g; /* Can't compare objects */ -/* B-tree related errors */ -#define H5E_NOTFOUND (H5OPEN H5E_NOTFOUND_g) -#define H5E_EXISTS (H5OPEN H5E_EXISTS_g) -#define H5E_CANTENCODE (H5OPEN H5E_CANTENCODE_g) -#define H5E_CANTDECODE (H5OPEN H5E_CANTDECODE_g) -#define H5E_CANTSPLIT (H5OPEN H5E_CANTSPLIT_g) -#define H5E_CANTREDISTRIBUTE (H5OPEN H5E_CANTREDISTRIBUTE_g) -#define H5E_CANTSWAP (H5OPEN H5E_CANTSWAP_g) -#define H5E_CANTINSERT (H5OPEN H5E_CANTINSERT_g) -#define H5E_CANTLIST (H5OPEN H5E_CANTLIST_g) -#define H5E_CANTMODIFY (H5OPEN H5E_CANTMODIFY_g) -#define H5E_CANTREMOVE (H5OPEN H5E_CANTREMOVE_g) -H5_DLLVAR hid_t H5E_NOTFOUND_g; /* Object not found */ -H5_DLLVAR hid_t H5E_EXISTS_g; /* Object already exists */ -H5_DLLVAR hid_t H5E_CANTENCODE_g; /* Unable to encode value */ -H5_DLLVAR hid_t H5E_CANTDECODE_g; /* Unable to decode value */ -H5_DLLVAR hid_t H5E_CANTSPLIT_g; /* Unable to split node */ -H5_DLLVAR hid_t H5E_CANTREDISTRIBUTE_g; /* Unable to redistribute records */ -H5_DLLVAR hid_t H5E_CANTSWAP_g; /* Unable to swap records */ -H5_DLLVAR hid_t H5E_CANTINSERT_g; /* Unable to insert object */ -H5_DLLVAR hid_t H5E_CANTLIST_g; /* Unable to list node */ -H5_DLLVAR hid_t H5E_CANTMODIFY_g; /* Unable to modify record */ -H5_DLLVAR hid_t H5E_CANTREMOVE_g; /* Unable to remove object */ - -/* Argument errors */ -#define H5E_UNINITIALIZED (H5OPEN H5E_UNINITIALIZED_g) -#define H5E_UNSUPPORTED (H5OPEN H5E_UNSUPPORTED_g) -#define H5E_BADTYPE (H5OPEN H5E_BADTYPE_g) -#define H5E_BADRANGE (H5OPEN H5E_BADRANGE_g) -#define H5E_BADVALUE (H5OPEN H5E_BADVALUE_g) -H5_DLLVAR hid_t H5E_UNINITIALIZED_g; /* Information is uinitialized */ -H5_DLLVAR hid_t H5E_UNSUPPORTED_g; /* Feature is unsupported */ -H5_DLLVAR hid_t H5E_BADTYPE_g; /* Inappropriate type */ -H5_DLLVAR hid_t H5E_BADRANGE_g; /* Out of range */ -H5_DLLVAR hid_t H5E_BADVALUE_g; /* Bad value */ - -/* Datatype conversion errors */ -#define H5E_CANTCONVERT (H5OPEN H5E_CANTCONVERT_g) -#define H5E_BADSIZE (H5OPEN H5E_BADSIZE_g) -H5_DLLVAR hid_t H5E_CANTCONVERT_g; /* Can't convert datatypes */ -H5_DLLVAR hid_t H5E_BADSIZE_g; /* Bad size for object */ - #endif /* H5Epubgen_H */ diff --git a/src/H5Eterm.h b/src/H5Eterm.h index c0d6f56..90c1cdf 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -21,78 +21,48 @@ /* Reset major error IDs */ -H5E_DATASET_g= -H5E_FUNC_g= +H5E_NONE_MAJOR_g= +H5E_RS_g= +H5E_CACHE_g= +H5E_SLIST_g= H5E_STORAGE_g= -H5E_FILE_g= -H5E_SYM_g= -H5E_VFL_g= -H5E_INTERNAL_g= -H5E_BTREE_g= -H5E_REFERENCE_g= -H5E_DATASPACE_g= +H5E_ATOM_g= H5E_RESOURCE_g= -H5E_PLIST_g= -H5E_DATATYPE_g= -H5E_RS_g= -H5E_HEAP_g= +H5E_FSPACE_g= H5E_OHDR_g= -H5E_ATOM_g= +H5E_FUNC_g= +H5E_ERROR_g= +H5E_BTREE_g= H5E_ATTR_g= -H5E_NONE_MAJOR_g= +H5E_PLIST_g= +H5E_SYM_g= +H5E_ARGS_g= +H5E_HEAP_g= +H5E_INTERNAL_g= +H5E_FILE_g= +H5E_LINK_g= +H5E_DATATYPE_g= +H5E_TST_g= H5E_IO_g= -H5E_SLIST_g= +H5E_DATASET_g= +H5E_REFERENCE_g= H5E_EFL_g= -H5E_TST_g= -H5E_ARGS_g= -H5E_ERROR_g= -H5E_PLINE_g= -H5E_FSPACE_g= -H5E_CACHE_g= (-1); +H5E_VFL_g= +H5E_DATASPACE_g= +H5E_PLINE_g= (-1); /* Reset minor error IDs */ -/* Generic low-level file I/O errors */ -H5E_SEEKERROR_g= -H5E_READERROR_g= -H5E_WRITEERROR_g= -H5E_CLOSEERROR_g= -H5E_OVERFLOW_g= -H5E_FCNTL_g= - -/* Resource errors */ -H5E_NOSPACE_g= -H5E_CANTALLOC_g= -H5E_CANTCOPY_g= -H5E_CANTFREE_g= -H5E_ALREADYEXISTS_g= -H5E_CANTLOCK_g= -H5E_CANTUNLOCK_g= -H5E_CANTGC_g= -H5E_CANTGETSIZE_g= - -/* Heap errors */ -H5E_CANTRESTORE_g= -H5E_CANTCOMPUTE_g= -H5E_CANTEXTEND_g= -H5E_CANTATTACH_g= -H5E_CANTUPDATE_g= - -/* Function entry/exit interface errors */ -H5E_CANTINIT_g= -H5E_ALREADYINIT_g= -H5E_CANTRELEASE_g= - -/* Property list errors */ -H5E_CANTGET_g= -H5E_CANTSET_g= -H5E_DUPCLASS_g= +/* System level errors */ +H5E_SYSERRSTR_g= -/* Free space errors */ -H5E_CANTMERGE_g= -H5E_CANTREVIVE_g= -H5E_CANTSHRINK_g= +/* I/O pipeline errors */ +H5E_NOFILTER_g= +H5E_CALLBACK_g= +H5E_CANAPPLY_g= +H5E_SETLOCAL_g= +H5E_NOENCODER_g= /* Object header related errors */ H5E_LINKCOUNT_g= @@ -103,26 +73,37 @@ H5E_CANTDELETE_g= H5E_BADITER_g= H5E_CANTPACK_g= -/* System level errors */ -H5E_SYSERRSTR_g= - -/* I/O pipeline errors */ -H5E_NOFILTER_g= -H5E_CALLBACK_g= -H5E_CANAPPLY_g= -H5E_SETLOCAL_g= -H5E_NOENCODER_g= +/* Resource errors */ +H5E_NOSPACE_g= +H5E_CANTALLOC_g= +H5E_CANTCOPY_g= +H5E_CANTFREE_g= +H5E_ALREADYEXISTS_g= +H5E_CANTLOCK_g= +H5E_CANTUNLOCK_g= +H5E_CANTGC_g= +H5E_CANTGETSIZE_g= -/* Group related errors */ -H5E_CANTOPENOBJ_g= -H5E_CANTCLOSEOBJ_g= -H5E_COMPLEN_g= -H5E_LINK_g= -H5E_SLINK_g= -H5E_PATH_g= +/* Generic low-level file I/O errors */ +H5E_SEEKERROR_g= +H5E_READERROR_g= +H5E_WRITEERROR_g= +H5E_CLOSEERROR_g= +H5E_OVERFLOW_g= +H5E_FCNTL_g= -/* No error */ -H5E_NONE_MINOR_g= +/* B-tree related errors */ +H5E_NOTFOUND_g= +H5E_EXISTS_g= +H5E_CANTENCODE_g= +H5E_CANTDECODE_g= +H5E_CANTSPLIT_g= +H5E_CANTREDISTRIBUTE_g= +H5E_CANTSWAP_g= +H5E_CANTINSERT_g= +H5E_CANTLIST_g= +H5E_CANTMODIFY_g= +H5E_CANTREMOVE_g= /* File accessability errors */ H5E_FILEEXISTS_g= @@ -135,6 +116,16 @@ H5E_BADFILE_g= H5E_TRUNCATED_g= H5E_MOUNT_g= +/* No error */ +H5E_NONE_MINOR_g= + +/* Heap errors */ +H5E_CANTRESTORE_g= +H5E_CANTCOMPUTE_g= +H5E_CANTEXTEND_g= +H5E_CANTATTACH_g= +H5E_CANTUPDATE_g= + /* Object atom related errors */ H5E_BADATOM_g= H5E_BADGROUP_g= @@ -143,6 +134,44 @@ H5E_CANTINC_g= H5E_CANTDEC_g= H5E_NOIDS_g= +/* Group related errors */ +H5E_CANTOPENOBJ_g= +H5E_CANTCLOSEOBJ_g= +H5E_COMPLEN_g= +H5E_PATH_g= + +/* Property list errors */ +H5E_CANTGET_g= +H5E_CANTSET_g= +H5E_DUPCLASS_g= + +/* Function entry/exit interface errors */ +H5E_CANTINIT_g= +H5E_ALREADYINIT_g= +H5E_CANTRELEASE_g= + +/* Datatype conversion errors */ +H5E_CANTCONVERT_g= +H5E_BADSIZE_g= + +/* Link related errors */ +H5E_TRAVERSE_g= +H5E_NLINKS_g= +H5E_NOTREGISTERED_g= +H5E_CANTMOVE_g= + +/* Parallel MPI errors */ +H5E_MPI_g= +H5E_MPIERRSTR_g= +H5E_CANTRECV_g= + +/* Argument errors */ +H5E_UNINITIALIZED_g= +H5E_UNSUPPORTED_g= +H5E_BADTYPE_g= +H5E_BADRANGE_g= +H5E_BADVALUE_g= + /* Cache related errors */ H5E_CANTFLUSH_g= H5E_CANTSERIALIZE_g= @@ -161,10 +190,10 @@ H5E_CANTDIRTY_g= H5E_CANTEXPUNGE_g= H5E_CANTRESIZE_g= -/* Parallel MPI errors */ -H5E_MPI_g= -H5E_MPIERRSTR_g= -H5E_CANTRECV_g= +/* Free space errors */ +H5E_CANTMERGE_g= +H5E_CANTREVIVE_g= +H5E_CANTSHRINK_g= /* Dataspace errors */ H5E_CANTCLIP_g= @@ -172,30 +201,6 @@ H5E_CANTCOUNT_g= H5E_CANTSELECT_g= H5E_CANTNEXT_g= H5E_BADSELECT_g= -H5E_CANTCOMPARE_g= - -/* B-tree related errors */ -H5E_NOTFOUND_g= -H5E_EXISTS_g= -H5E_CANTENCODE_g= -H5E_CANTDECODE_g= -H5E_CANTSPLIT_g= -H5E_CANTREDISTRIBUTE_g= -H5E_CANTSWAP_g= -H5E_CANTINSERT_g= -H5E_CANTLIST_g= -H5E_CANTMODIFY_g= -H5E_CANTREMOVE_g= - -/* Argument errors */ -H5E_UNINITIALIZED_g= -H5E_UNSUPPORTED_g= -H5E_BADTYPE_g= -H5E_BADRANGE_g= -H5E_BADVALUE_g= - -/* Datatype conversion errors */ -H5E_CANTCONVERT_g= -H5E_BADSIZE_g= (-1); +H5E_CANTCOMPARE_g= (-1); #endif /* H5Eterm_H */ diff --git a/src/H5Fmount.c b/src/H5Fmount.c index 17014dd..75af431 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -146,7 +146,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, */ if(child->mtab.parent) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "file is already mounted") - if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0) + if(H5G_loc_find(loc, name, &mp_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point not found") @@ -285,7 +285,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) * If we get the root group and the file has a parent in the mount tree, * then we must have found the mount point. */ - if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0) + if(H5G_loc_find(loc, name, &mp_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") mp_loc_setup = TRUE; child = mp_loc.oloc->file; @@ -107,6 +107,7 @@ typedef struct { typedef struct { H5G_stat_t *statbuf; /* Stat buffer about object */ hbool_t follow_link; /* Whether we are following a link or not */ + H5F_t *loc_file; /* Pointer to the file the location is in */ hid_t dxpl_id; /* Dataset transfer property list */ } H5G_trav_ud4_t; @@ -116,6 +117,14 @@ typedef struct { hid_t dxpl_id; /* Dataset transfer property list */ } H5G_trav_ud7_t; +/* User data for path traversal routine for getting external link name */ +typedef struct { + hbool_t want_file_name; /* Whether to retrieve file name (or object name) */ + size_t size; /* Size of user buffer */ + char *lname; /* User name buffer */ + size_t name_len; /* Full length of name found */ +} H5G_trav_ud8_t; + /* Package variables */ /* Local variables */ @@ -128,13 +137,15 @@ H5FL_DEFINE(H5G_shared_t); static H5G_t *H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t gapl_id); static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id); static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id); static int H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id); static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); @@ -224,17 +235,17 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint) /* Create the group */ if(NULL == (grp = H5G_create(file, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") if(H5G_loc(grp_id, &grp_loc) <0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to get location for new group") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get location for new group") /* Link the group */ - if( H5L_link(&loc, name, &grp_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to group") + if( H5L_link(&loc, name, &grp_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to group") ret_value = grp_id; @@ -314,14 +325,12 @@ H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list") -#ifdef LATER /* Check the group access property list */ if(H5P_DEFAULT == gapl_id) gapl_id = H5P_GROUP_ACCESS_DEFAULT; else if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") -#endif /* LATER */ if(NULL == (grp = H5G_create(loc.oloc->file, H5AC_dxpl_id, gcpl_id, gapl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") @@ -382,7 +391,7 @@ H5Gopen(hid_t loc_id, const char *name) H5G_loc_reset(&grp_loc); /* Find the group object */ - if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5AC_dxpl_id) < 0) + if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") ent_found = TRUE; @@ -413,6 +422,86 @@ done: /*------------------------------------------------------------------------- + * Function: H5Gopen_expand + * + * Purpose: Opens an existing group for modification. When finished, + * call H5Gclose() to close it and release resources. + * + * This function allows the user the pass in a Group Access + * Property List, which H5Gopen() does not. + * + * Return: Success: Object ID of the group. + * Failure: FAIL + * + * Programmer: James Laird + * Thursday, July 27, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id) +{ + H5G_t *grp = NULL; + H5G_loc_t loc; + H5G_loc_t grp_loc; /* Location used to open group */ + H5G_name_t grp_path; /* Opened object group hier. path */ + H5O_loc_t grp_oloc; /* Opened object object location */ + hbool_t ent_found = FALSE; /* Entry at 'name' found */ + hid_t ret_value=FAIL; /* Return value */ + + FUNC_ENTER_API(H5Gopen_expand, FAIL); + H5TRACE3("i","isi",loc_id,name,gapl_id); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Check the group access property list */ + if(H5P_DEFAULT == gapl_id) + gapl_id = H5P_GROUP_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") + + /* Set up opened group location to fill in */ + grp_loc.oloc = &grp_oloc; + grp_loc.path = &grp_path; + H5G_loc_reset(&grp_loc); + + /* Find the group object using the gapl passed in */ + if(H5G_loc_find(&loc, name, &grp_loc/*out*/, gapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + ent_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&grp_oloc, H5AC_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group") + + /* Open the group */ + if((grp = H5G_open(&grp_loc, H5AC_dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + + /* Register an atom for the group */ + if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + +done: + if(ret_value < 0) { + if(grp != NULL) + H5G_close(grp); + else { + if(ent_found) + H5G_name_free(&grp_path); + } /* end else */ + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5Gclose * * Purpose: Closes the specified group. The group ID will no longer be @@ -442,7 +531,7 @@ H5Gclose(hid_t group_id) * reaches zero. */ if (H5I_dec_ref(group_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group"); + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group"); done: FUNC_LEAVE_API(ret_value); @@ -920,7 +1009,7 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5G_loc_reset(&src_loc); /* Find the source object to copy */ - if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5AC_dxpl_id) < 0) + if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") ent_found = TRUE; @@ -985,7 +1074,7 @@ done: static herr_t H5G_init_interface(void) { - H5P_genclass_t *crt_pclass, *cpy_pclass; + H5P_genclass_t *crt_pclass, *acc_pclass, *cpy_pclass; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface); @@ -1009,16 +1098,30 @@ H5G_init_interface(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") } /* end if */ + /* ========== Group Access Property Class Initialization ============*/ + assert(H5P_CLS_GROUP_ACCESS_g!=-1); + + /* Get the pointer to group creation class */ + if(NULL == (acc_pclass = H5I_object(H5P_CLS_GROUP_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + + /* Only register the default property list if it hasn't been created yet */ + if(H5P_LST_GROUP_ACCESS_g == (-1)) { + /* Register the default group creation property list */ + if((H5P_LST_GROUP_ACCESS_g = H5P_create_id(acc_pclass))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") + } /* end if */ + /* ========== Object Copy Property Class Initialization ============*/ assert(H5P_CLS_OBJECT_COPY_g!=-1); - /* Get the pointer to group copy class */ + /* Get the pointer to group access class */ if(NULL == (cpy_pclass = H5I_object(H5P_CLS_OBJECT_COPY_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") /* Only register the default property list if it hasn't been created yet */ if(H5P_LST_OBJECT_COPY_g == (-1)) { - /* Register the default group copy property list */ + /* Register the default group access property list */ if((H5P_LST_OBJECT_COPY_g = H5P_create_id(cpy_pclass))<0) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") } /* end if */ @@ -1241,7 +1344,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) loc->oloc/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") if(1 != H5O_link(loc->oloc, 1, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)") + HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") } else { /* * Open the root object as a group. @@ -1736,7 +1839,7 @@ H5G_fileof(H5G_t *grp) */ static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1759,17 +1862,11 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_ if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno[0]) < 0) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno") - /* Get info for soft link */ - /* (If we don't follow the link, we can retrieve info about the soft link itself) */ - if(!udata->follow_link && lnk && lnk->type == H5L_LINK_SOFT) { - /* Set object type */ - statbuf->type = H5G_LINK; + /* Info for soft and UD links is gotten by H5L_get_linkinfo. If we have + * a hard link, follow it and get info on the object */ + if(udata->follow_link || !lnk || + (lnk->type == H5L_LINK_HARD)) { - /* Get length of link value */ - statbuf->linklen = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ - } /* end if */ - /* Get info for hard link */ - else { /* Get object type */ statbuf->type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id); if(statbuf->type == H5G_UNKNOWN) @@ -1796,16 +1893,13 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_ /* Get object header information */ if(H5O_get_info(obj_loc->oloc, &(statbuf->ohdr), udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information") - } /* end else */ + } /* end if */ } /* end if */ done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_get_objinfo_cb() */ @@ -1842,13 +1936,46 @@ H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, /* Set up user data for retrieving information */ udata.statbuf = statbuf; udata.follow_link = follow_link; + udata.loc_file = loc->oloc->file; udata.dxpl_id = dxpl_id; /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK), - H5G_get_objinfo_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK|H5G_TARGET_UDLINK), + H5G_get_objinfo_cb, &udata, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + /* Assign object type and link length for soft links and UD links */ + /* The default linklen (for non-links) is 0. */ + if(statbuf) + statbuf->linklen = 0; + + /* If we're pointing at a soft or UD link, get the real link length and type */ + if(statbuf && follow_link == 0) + { + H5L_linkinfo_t linfo; /* Link information buffer */ + herr_t ret; + + /* Get information about link to the object. If this fails, e.g. + * because the object is ".", just treat the object as a hard link. */ + H5E_BEGIN_TRY { + ret = H5L_get_linkinfo(loc, name, &linfo, H5P_DEFAULT, dxpl_id); + } H5E_END_TRY + + if(ret >=0 && linfo.linkclass != H5L_LINK_HARD) + { + statbuf->linklen = linfo.u.link_size; + if(linfo.linkclass == H5L_LINK_SOFT) + { + statbuf->type = H5G_LINK; + } + else /* UD link. H5L_get_linkinfo checked for invalid link classes */ + { + HDassert(linfo.linkclass >= H5L_LINK_UD_MIN && linfo.linkclass <= H5L_LINK_MAX); + statbuf->type = H5G_UDLINK; + } + } + } + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_get_objinfo() */ @@ -1876,7 +2003,7 @@ H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment) /* Get the symbol table entry for the object */ - if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0) + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Remove the previous comment message if any */ @@ -1922,7 +2049,7 @@ H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment) /* Get the symbol table entry for the object */ - if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0) + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the message */ @@ -1958,7 +2085,7 @@ done: */ static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1973,6 +2100,8 @@ H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H /* Get file pointer for location */ udata->file = grp_loc->oloc->file; + *own_obj_loc = FALSE; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_insertion_file_cb() */ @@ -2016,7 +2145,7 @@ H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id) * Look up the name to get the containing group and to make sure the name * doesn't already exist. */ - if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists") /* Set return value */ @@ -2168,6 +2297,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, H5G_loc_t new_loc; /* Group location of object copied */ hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */ unsigned cpy_option = 0; /* Copy options */ + hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_copy, FAIL); @@ -2197,7 +2327,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Insert the new object in the destination file's group */ - if(H5L_link(dst_loc, dst_name, &new_loc, dxpl_id, lcpl_id) < 0) + if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") entry_inserted = TRUE; @@ -2209,3 +2339,4 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_copy() */ + diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 4f2b837..31304b4 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -52,12 +52,12 @@ H5Glink(hid_t cur_loc_id, H5L_link_t type, const char *cur_name, const char *new if(type == H5L_LINK_HARD) { - if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name, H5P_DEFAULT)) < 0) + if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") } else if(type == H5L_LINK_SOFT) { - if((ret_value = H5Lcreate_soft(cur_name, cur_loc_id, new_name, H5P_DEFAULT)) < 0) + if((ret_value = H5Lcreate_soft(cur_name, cur_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") } else @@ -86,7 +86,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5L_link_t type, H5TRACE5("e","isLlis",cur_loc_id,cur_name,type,new_loc_id,new_name); if(type == H5L_LINK_HARD) { - if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0) + if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, new_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") } else if(type == H5L_LINK_SOFT) { @@ -95,7 +95,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5L_link_t type, if(new_loc_id == H5L_SAME_LOC) new_loc_id = cur_loc_id; - if((ret_value = H5Lcreate_soft(cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0) + if((ret_value = H5Lcreate_soft(cur_name, new_loc_id, new_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") } else @@ -121,7 +121,7 @@ H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name) FUNC_ENTER_API(H5Gmove, FAIL) H5TRACE3("e","iss",src_loc_id,src_name,dst_name); - if((ret_value=H5Lmove(src_loc_id, src_name, H5L_SAME_LOC, dst_name, H5P_DEFAULT)) < 0) + if((ret_value=H5Lmove(src_loc_id, src_name, H5L_SAME_LOC, dst_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link") done: @@ -143,8 +143,8 @@ herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, FUNC_ENTER_API(H5Gmove2, FAIL) - if((ret_value=H5Lmove(src_loc_id, src_name, dst_loc_id, dst_name, H5P_DEFAULT)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link") + if((ret_value=H5Lmove(src_loc_id, src_name, dst_loc_id, dst_name, H5P_DEFAULT, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't move link") done: FUNC_LEAVE_API(ret_value) @@ -166,7 +166,7 @@ H5Gunlink(hid_t loc_id, const char *name) FUNC_ENTER_API(H5Gunlink, FAIL) H5TRACE2("e","is",loc_id,name); - if((ret_value=H5Lunlink(loc_id, name)) < 0) + if((ret_value=H5Lunlink(loc_id, name, H5P_DEFAULT)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "Couldn't delete link") done: @@ -189,8 +189,8 @@ herr_t H5Gget_linkval(hid_t loc_id, const char *name, FUNC_ENTER_API(H5Gget_linkval, FAIL) - if((ret_value=H5Lget_linkval(loc_id, name, size, buf)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "Couldn't get link info") + if((ret_value=H5Lget_linkval(loc_id, name, size, buf, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "couldn't get link info") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Gent.c b/src/H5Gent.c index a8311f0..f242bad 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -183,8 +183,14 @@ H5G_ent_decode(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent) UINT32DECODE (*pp, ent->cache.slink.lval_offset); break; + case H5G_CACHED_ULINK: + UINT32DECODE (*pp, ent->cache.ulink.udata_size); + UINT32DECODE (*pp, ent->cache.ulink.udata_offset); + UINT32DECODE (*pp, ent->cache.ulink.link_type); + break; default: - HDabort(); + /* Error or unknown type. Bail out. */ + return -1; } *pp = p_ret + H5G_SIZEOF_ENTRY(f); @@ -296,8 +302,15 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent) UINT32ENCODE (*pp, ent->cache.slink.lval_offset); break; + case H5G_CACHED_ULINK: + UINT32ENCODE (*pp, ent->cache.ulink.udata_size); + UINT32ENCODE (*pp, ent->cache.ulink.udata_offset); + UINT32ENCODE (*pp, ent->cache.ulink.link_type); + break; + default: - HDabort(); + /* Unknown cached type. Bail out. */ + return -1; } } else { H5F_ENCODE_LENGTH(f, *pp, 0); @@ -457,7 +470,24 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t break; default: - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + if(lnk->type < H5L_LINK_UD_MIN) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + + { + size_t udata_offset = (size_t) (-1); /* Offset to data buffer */ + + if(lnk->u.ud.size > 0) + { + if((size_t)(-1) == (udata_offset = H5HL_insert(f, dxpl_id, + heap_addr, lnk->u.ud.size, lnk->u.ud.udata))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write user data to local heap") + } + + ent->type = H5G_CACHED_ULINK; + ent->cache.ulink.udata_size = lnk->u.ud.size; + ent->cache.ulink.udata_offset = udata_offset; + ent->cache.ulink.link_type = lnk->type; + } } /* end switch */ /* Set the file for the entry */ @@ -544,6 +574,64 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given, name not displayed!"); break; + case H5G_CACHED_ULINK: + if(ent->cache.ulink.link_type == H5L_LINK_EXTERNAL) + { + HDfprintf (stream, "External Link\n"); + HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, + "Cached information:"); + if(ent->cache.ulink.udata_size > 0) + { + HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, + "User data offset:", + (unsigned long)(ent->cache.ulink.udata_offset)); + } + HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, + "User data size:", + (unsigned long)(ent->cache.ulink.udata_size)); + if (heap>0 && H5F_addr_defined(heap)) { + const H5HL_t *heap_ptr; + char * filename; + char * pathname; + + heap_ptr = H5HL_protect(ent->file, dxpl_id, heap); + lval = H5HL_offset_into(ent->file, heap_ptr, ent->cache.ulink.udata_offset); + if(H5Lunpack_elink_val(lval, &filename, &pathname) < 0) return FAIL; + + HDfprintf (stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth, + "External link file name:", + lval); + HDfprintf (stream, "%*s%-*s %s\n", nested_indent, "", nested_fwidth, + "External link object name:", + pathname); + H5HL_unprotect(ent->file, dxpl_id, heap_ptr, heap, H5AC__NO_FLAGS_SET); + } else { + HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given!"); + } + } + else + { + HDfprintf (stream, "User-defined Link\n"); + HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, + "Cached information:"); + HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, + "Link class:", + (unsigned long)(ent->cache.ulink.link_type)); + if(ent->cache.ulink.udata_size > 0) + { + HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, + "User data offset:", + (unsigned long)(ent->cache.ulink.udata_offset)); + } + HDfprintf (stream, "%*s%-*s %lu\n", nested_indent, "", nested_fwidth, + "User data size:", + (unsigned long)(ent->cache.ulink.udata_size)); + if (heap<=0 || !H5F_addr_defined(heap)) { + HDfprintf(stream, "%*s%-*s\n", nested_indent, "", nested_fwidth, "Warning: Invalid heap address given!"); + } + } + break; + default: HDfprintf(stream, "*** Unknown symbol type %d\n", ent->type); break; diff --git a/src/H5Glink.c b/src/H5Glink.c index bf23058..1139e7c 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -294,7 +294,8 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, HDassert(name); /* Create link message from object entry */ - HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK); + HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK + || ent->type == H5G_CACHED_ULINK); /* XXX: Set character set & creation time for real? */ lnk->cset = H5F_CRT_DEFAULT_CSET; lnk->ctime = 0; @@ -302,7 +303,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, HDassert(lnk->name); switch(ent->type) { case H5G_NOTHING_CACHED: - lnk->type = H5G_LINK_HARD; + lnk->type = H5L_LINK_HARD; lnk->u.hard.addr = ent->header; break; @@ -310,7 +311,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, { const char *s; /* Pointer to link value in heap */ - lnk->type = H5G_LINK_SOFT; + lnk->type = H5L_LINK_SOFT; s = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset); HDassert(s); @@ -321,6 +322,25 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, } break; + case H5G_CACHED_ULINK: + { + const char *s; /* Pointer to link name in heap */ + + /* Copy link type and udata size from entry info */ + lnk->type = ent->cache.ulink.link_type; + lnk->u.ud.size = ent->cache.ulink.udata_size; + + /* Get pointer to udata in heap */ + s = H5HL_offset_into(ent->file, heap, ent->cache.ulink.udata_offset); + HDassert(s); + + /* Read udata from heap */ + if(NULL== (lnk->u.ud.udata = H5MM_malloc(lnk->u.ud.size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for user link data") + HDmemcpy(lnk->u.ud.udata, s, lnk->u.ud.size); + } + break; + default: HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") } /* end switch */ @@ -454,9 +474,11 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound") /* Determine type of object */ - if(ltable.lnks[idx].type == H5G_LINK_SOFT) + if(ltable.lnks[idx].type == H5L_LINK_SOFT) ret_value = H5G_LINK; - else { + else if(ltable.lnks[idx].type >= H5L_LINK_UD_MIN) + ret_value = H5G_UDLINK; + else if(ltable.lnks[idx].type == H5L_LINK_HARD){ H5O_loc_t tmp_oloc; /* Temporary object location */ /* Build temporary object location */ @@ -466,7 +488,9 @@ H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) /* Get the type of the object */ if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type") - } /* end else */ + } else{ + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unknown link type") + }/* end else */ done: /* Release link table */ @@ -501,7 +525,7 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) H5G_link_ud2_t *udata = (H5G_link_ud2_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5O_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_remove_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_link_remove_cb) /* check arguments */ HDassert(lnk); @@ -509,20 +533,32 @@ H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) /* If we've found the right link, get the object type */ if(HDstrcmp(lnk->name, udata->name) == 0) { - if(lnk->type == H5G_LINK_SOFT) - *(udata->obj_type) = H5G_LINK; - else { - H5O_loc_t tmp_oloc; /* Temporary object location */ + switch(lnk->type) + { + case H5L_LINK_HARD: + { + H5O_loc_t tmp_oloc; /* Temporary object location */ + + /* Build temporary object location */ + tmp_oloc.file = udata->file; + tmp_oloc.addr = lnk->u.hard.addr; + + /* Get the type of the object */ + /* Note: no way to check for error :-( */ + *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id); + } + break; - /* Build temporary object location */ - tmp_oloc.file = udata->file; - tmp_oloc.addr = lnk->u.hard.addr; + case H5L_LINK_SOFT: + *(udata->obj_type) = H5G_LINK; + break; - /* Get the type of the object */ - /* Note: no way to check for error :-( */ - *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id); - } /* end else */ + default: /* User-defined link */ + if(lnk->type < H5L_LINK_UD_MIN) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type"); + *(udata->obj_type) = H5G_UDLINK; + } /* Stop the iteration, we found the correct link */ HGOTO_DONE(H5O_ITER_STOP) } /* end if */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 4e22357..c022169 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -46,7 +46,8 @@ typedef struct { /* PRIVATE PROTOTYPES */ static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, + hbool_t *own_obj_loc/*out*/); /*------------------------------------------------------------------------- @@ -283,7 +284,7 @@ done: */ static herr_t H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5G_loc_ud1_t *udata = (H5G_loc_ud1_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -299,6 +300,7 @@ H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const * of the group location for the object, or freeing it. - QAK) */ H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW); + *own_obj_loc = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) @@ -319,7 +321,7 @@ done: */ herr_t H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/, - hid_t dxpl_id) + hid_t lapl_id, hid_t dxpl_id) { H5G_loc_ud1_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -335,7 +337,7 @@ H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/, udata.loc = obj_loc; /* Traverse group hierarchy to locate object */ - if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: diff --git a/src/H5Gname.c b/src/H5Gname.c index d3e1d12..fb2df97 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -936,6 +936,13 @@ H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc, search_datatype = 1; break; + case H5G_UDLINK: + /* User-defined links automatically wipe out names (because it + * would be too much work to track them), so there's no point + * in searching them. + */ + break; + default: HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not valid object type") } /* end switch */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index dabb01c..c640a65 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -283,16 +283,23 @@ H5G_node_debug_key (FILE *stream, H5F_t *f, hid_t dxpl_id, int indent, int fwidt HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Heap offset:", (unsigned)key->offset); - HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:"); + if(udata->heap_addr != 0) + { + HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Name:"); - if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); + if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name"); - s = H5HL_offset_into(f, heap, key->offset); - HDfprintf (stream, "%s\n", s); + s = H5HL_offset_into(f, heap, key->offset); + HDfprintf (stream, "%s\n", s); - if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + if (H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name"); + } + else + { + HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Cannot get name; heap address not specified\n"); + } done: FUNC_LEAVE_NOAPI(ret_value); @@ -1242,7 +1249,10 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, if(cmp) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found") - if(H5G_CACHED_SLINK == sn->entry[idx].type) { + switch(sn->entry[idx].type) + { + case H5G_CACHED_SLINK: + { /* Set the type of the link removed */ *(udata->obj_type) = H5G_LINK; @@ -1266,7 +1276,42 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.slink.lval_offset, len); H5E_clear_stack(NULL); /* no big deal */ - } else { + } + break; + + case H5G_CACHED_ULINK: + { + size_t ud_data_size = 0; /* User link data size */ + hbool_t ud_data_found; /* Indicate that the link user data was found */ + + /* Set the type of the link removed */ + *(udata->obj_type) = H5G_UDLINK; + + /* Remove the link user data from the heap */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name") + + s = H5HL_offset_into(f, heap, sn->entry[idx].cache.ulink.udata_offset); + if(s) + { + ud_data_found = 1; + ud_data_size = sn->entry[idx].cache.ulink.udata_size; + } + else + ud_data_found = 0; + if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name") + heap = NULL; s = NULL; + + if(ud_data_found) + H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.ulink.udata_offset, ud_data_size); + + H5E_clear_stack(NULL); /* no big deal */ + } + break; + + default: + { H5O_loc_t tmp_oloc; /* Temporary object location */ /* Build temporary object location */ @@ -1283,7 +1328,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, if(H5O_link(&tmp_oloc, -1, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to decrement object link count") } /* end if */ - } /* end else */ + } + } /* end switch */ /* Remove the name from the local heap */ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr))) @@ -1372,7 +1418,8 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, /* Reduce the link count for all entries in this node */ for(idx = 0; idx < sn->nsyms; idx++) { - if(H5G_CACHED_SLINK != sn->entry[idx].type) { + if(!(H5G_CACHED_SLINK == sn->entry[idx].type || + H5G_CACHED_ULINK == sn->entry[idx].type)) { /* Decrement the reference count, if requested */ if(udata->adj_link) { HDassert(H5F_addr_defined(sn->entry[idx].header)); @@ -1670,17 +1717,24 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, loc_idx = udata->idx - udata->num_objs; /* Check for a soft link */ - if(sn->entry[loc_idx].type == H5G_CACHED_SLINK) + switch(sn->entry[loc_idx].type) + { + case H5G_CACHED_SLINK: udata->type = H5G_LINK; - /* Must be a hard link */ - else { + break; + case H5G_CACHED_ULINK: + udata->type = H5G_UDLINK; + break; + + default: /* Build temporary object location */ tmp_oloc.file = f; HDassert(H5F_addr_defined(sn->entry[loc_idx].header)); tmp_oloc.addr = sn->entry[loc_idx].header; udata->type = H5O_obj_type(&tmp_oloc, dxpl_id); - } /* end else */ + break; + } ret_value = H5B_ITER_STOP; } else { udata->num_objs += sn->nsyms; @@ -1997,6 +2051,14 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, lnk.type = H5L_LINK_SOFT; lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset); } /* else if */ + else if(H5G_CACHED_ULINK == src_ent->type) { + /* user-defined link */ + + /* Construct link information for eventual insertion */ + lnk.type = src_ent->cache.ulink.link_type; + lnk.u.ud.size = src_ent->cache.ulink.udata_size; + lnk.u.ud.udata = H5HL_offset_into(f, heap, src_ent->cache.ulink.udata_offset); + } /* else if */ else HDassert(0 && "Unknown entry type"); diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 7b18469..9b61a26 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -35,6 +35,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property Lists */ /* Private typedefs */ @@ -424,7 +425,7 @@ H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, /* Increment reference count for object */ if(H5O_link(&obj_oloc, 1, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count") + HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "unable to increment hard link count") } /* end if */ done: @@ -779,6 +780,10 @@ H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxp H5MM_xfree(lnk_table[u].name); if(lnk_table[u].type == H5L_LINK_SOFT) H5MM_xfree(lnk_table[u].u.soft.name); + else if(lnk_table[u].type >= H5L_LINK_UD_MIN) { + if(lnk_table[u].u.ud.size > 0) + H5MM_xfree(lnk_table[u].u.ud.udata); + } /* end if */ } /* end for */ /* Release memory for link table */ @@ -897,7 +902,7 @@ done: */ static herr_t H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5G_obj_ud2_t *udata = (H5G_obj_ud2_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -918,7 +923,7 @@ H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const *udata->lnk = *lnk; HDassert(lnk->name); udata->lnk->name = H5MM_xstrdup(lnk->name); - if(lnk->type == H5G_LINK_SOFT) + if(lnk->type == H5L_LINK_SOFT) udata->lnk->u.soft.name = H5MM_xstrdup(lnk->u.soft.name); #endif /* H5_GROUP_REVISION */ } /* end if */ @@ -933,12 +938,9 @@ H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const } /* end if */ done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_find_cb() */ @@ -959,10 +961,10 @@ done: */ herr_t H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags, - H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id) + H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t lapl_id, hid_t dxpl_id) { - H5G_obj_ud2_t udata; /* User data for traversal callback */ - herr_t ret_value = SUCCEED; /* Return value */ + H5G_obj_ud2_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_obj_find, FAIL) @@ -970,13 +972,14 @@ H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags, HDassert(loc && loc->oloc->file); HDassert(name && *name); HDassert(obj_oloc); + HDassert(H5P_CLS_LINK_ACCESS_g != -1); /* Set up user data for locating object */ udata.lnk = lnk; udata.oloc = obj_oloc; /* Traverse group hierarchy to locate object */ - if(H5G_traverse(loc, name, traverse_flags, H5G_obj_find_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, name, traverse_flags, H5G_obj_find_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index b0d51d2..77eec67 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -36,7 +36,9 @@ #include "H5SLprivate.h" /* Skip lists */ #define H5G_SIZE_HINT 256 /* default root grp size hint */ -#define H5G_NLINKS 16 /*max symlinks to follow per lookup */ + +/* H5G_NLINKS is deprecated */ +#define H5G_NLINKS H5L_NLINKS_DEF /* * Various types of object header information can be cached in a symbol @@ -49,8 +51,9 @@ typedef enum H5G_type_t { H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */ H5G_CACHED_STAB = 1, /*symbol table, `stab' */ H5G_CACHED_SLINK = 2, /*symbolic link */ + H5G_CACHED_ULINK = 3, /*user-defined link */ - H5G_NCACHED = 3 /*THIS MUST BE LAST */ + H5G_NCACHED = 4 /*THIS MUST BE LAST */ } H5G_type_t; /* @@ -69,6 +72,12 @@ typedef union H5G_cache_t { struct { size_t lval_offset; /*link value offset */ } slink; + + struct { + size_t udata_size; /*size of user data buffer */ + size_t udata_offset; /*link's user data buffer */ + H5L_link_t link_type; /*link type ID */ + } ulink; } H5G_cache_t; /* @@ -232,25 +241,17 @@ typedef struct H5G_bt_it_ud5_t { } H5G_bt_it_ud5_t; /* Typedef for path traversal operations */ +/* grp_loc is the location of the group in which the targeted object is located. + * name is the last component of the object's name + * lnk is the link between the group and the object + * obj_loc is the target of the traversal (or NULL if the object doesn't exist) + * operator_data is whatever udata was supplied when H5G_traverse was called + * own_obj_loc should be set to TRUE if this callback takes ownership of obj_loc, + * and FALSE if obj_loc needs to be deleted. + */ typedef herr_t (*H5G_traverse_t)(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk/*in*/, H5G_loc_t *obj_loc/*out*/, void *operator_data/*in,out*/); - -/* "value" information for a link (as opposed to "name" of link) */ -typedef struct { - haddr_t addr; /* Address of object linked to */ -} H5G_linkvalue_hard_t; - -typedef struct { - char *name; /* Link value */ -} H5G_linkvalue_soft_t; - -typedef struct { - H5L_link_t type; /* Type of link */ - union { - H5G_linkvalue_hard_t hard; /* Information for hard link */ - H5G_linkvalue_soft_t soft; /* Information for soft link */ - } u; -} H5G_linkvalue_t; + const H5O_link_t *lnk/*in*/, H5G_loc_t *obj_loc/*out*/, void *operator_data/*in,out*/, + hbool_t *own_obj_loc/*out*/); /* * During name lookups (see H5G_traverse()) we sometimes want information about @@ -260,7 +261,8 @@ typedef struct { #define H5G_TARGET_NORMAL 0x0000 #define H5G_TARGET_SLINK 0x0001 #define H5G_TARGET_MOUNT 0x0002 -#define H5G_CRT_INTMD_GROUP 0x0004 +#define H5G_TARGET_UDLINK 0x0004 +#define H5G_CRT_INTMD_GROUP 0x0008 /* * This is the class identifier to give to the B-tree functions. @@ -278,7 +280,8 @@ H5_DLL H5G_t *H5G_rootof(H5F_t *f); H5_DLL const char * H5G_component(const char *name, size_t *size_p); H5_DLL herr_t H5G_traverse_term_interface(void); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, - unsigned target, H5G_traverse_t op, void *op_data, hid_t dxpl_id); + unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id, + hid_t dxpl_id); /* * Functions that understand symbol tables but not names. The @@ -377,7 +380,8 @@ H5_DLL H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5G_obj_find(H5G_loc_t *loc, const char *name, - unsigned traverse_flags, H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id); + unsigned traverse_flags, H5O_link_t *lnk, H5O_loc_t *obj_oloc, + hid_t lapl_id, hid_t dxpl_id); /* * These functions operate on group hierarchy names. diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index c1d3320..d4278a4 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -161,7 +161,7 @@ H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size); */ H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); H5_DLL herr_t H5G_loc_find(H5G_loc_t *loc, const char *name, - H5G_loc_t *obj_loc/*out*/, hid_t dxpl_id); + H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index a1583c9..52420e1 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -52,7 +52,7 @@ typedef enum H5G_obj_t { H5G_DATASET, /* Object is a dataset */ H5G_TYPE, /* Object is a named data type */ H5G_LINK, /* Object is a symbolic link */ - H5G_RESERVED_4, /* Reserved for future use */ + H5G_UDLINK, /* Object is a user-defined link */ H5G_RESERVED_5, /* Reserved for future use */ H5G_RESERVED_6, /* Reserved for future use */ H5G_RESERVED_7 /* Reserved for future use */ @@ -63,30 +63,6 @@ typedef enum H5G_obj_t { #define H5G_NUSERTYPES (H5G_NTYPES-H5G_NLIBTYPES) #define H5G_USERTYPE(X) (8+(X)) /* User defined types */ -#ifdef QAK -/* Information about an object */ -typedef struct H5G_obj_stat_t { - haddr_t objno; /* Object number */ - unsigned nlink; /* Number of hard links to object*/ - time_t mtime; /* Modification time */ - H5O_stat_t ohdr; /* Object header information */ -} H5G_obj_stat_t; - -typedef struct H5G_slink_stat_t { - size_t linklen; /* Symbolic link value length */ -} H5G_slink_stat_t; - -typedef struct H5G_stat_t { - unsigned long fileno; /* File number */ - H5T_cset_t cset; /* Character set of link name */ - time_t ctime; /* Creation time */ - H5G_obj_t type; /* Object type */ - union { - H5G_obj_stat_t obj; /* Information about objects */ - H5G_slink_stat_t slink; /* Information about symbolic links */ - } u; -} H5G_stat_t; -#else /* QAK */ /* Information about an object */ typedef struct H5G_stat_t { unsigned long fileno[2]; /*file number */ @@ -97,7 +73,6 @@ typedef struct H5G_stat_t { size_t linklen; /*symbolic link value length */ H5O_stat_t ohdr; /* Object header information */ } H5G_stat_t; -#endif /* QAK */ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, void *op_data); @@ -112,6 +87,7 @@ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, H5_DLL hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint); H5_DLL hid_t H5Gopen(hid_t loc_id, const char *name); +H5_DLL hid_t H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id); H5_DLL herr_t H5Gclose(hid_t group_id); H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5G_iterate_t op, void *op_data); @@ -154,8 +130,10 @@ H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, #define H5G_link_t H5L_link_t #define H5G_SAME_LOC H5L_SAME_LOC + #ifdef __cplusplus } #endif #endif + diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 651ddf3..926aa0e 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -608,8 +608,11 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) udata->lnk->ctime = 0; udata->lnk->name = H5MM_xstrdup(udata->name); - /* Object is a symbolic link */ - if(H5G_CACHED_SLINK == ent->type) { + /* Object is a symbolic or user-defined link */ + switch(ent->type) + { + case H5G_CACHED_SLINK: + { const char *s; /* Pointer to link value */ const H5HL_t *heap; /* Pointer to local heap for group */ @@ -628,14 +631,47 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) /* Set link type */ udata->lnk->type = H5L_LINK_SOFT; - } /* end if */ - else { + } + break; + + case H5G_CACHED_ULINK: + { + void * s; /* Pointer to heap value */ + const H5HL_t *heap; /* Pointer to local heap for group */ + size_t data_size; /* Size of user link data */ + + /* Lock the local heap */ + if(NULL == (heap = H5HL_protect(udata->file, udata->dxpl_id, udata->heap_addr))) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + + data_size =ent->cache.ulink.udata_size; + + if(data_size > 0) + { + s = H5HL_offset_into(udata->file, heap, ent->cache.ulink.udata_offset); + + /* Allocate space for the user data and copy it from the heap */ + udata->lnk->u.ud.udata = H5MM_malloc(data_size); + HDmemcpy(udata->lnk->u.ud.udata, s, data_size); + } /* end if */ + + /* Release the local heap */ + if(H5HL_unprotect(udata->file, udata->dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") + + /* Set link size and type */ + udata->lnk->u.ud.size = data_size; + udata->lnk->type = ent->cache.ulink.link_type; + } + break; + + default: /* Set address of object */ udata->lnk->u.hard.addr = ent->header; /* Set link type */ udata->lnk->type = H5L_LINK_HARD; - } /* end else */ + } /* end switch */ } /* end if */ done: @@ -697,3 +733,4 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup() */ + diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index c94cd86..03db4d3 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -28,10 +28,12 @@ /* Packages needed by this file... */ #include "H5private.h" /* Generic Functions */ +#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ +#include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppublic.h" /* Property Lists */ @@ -51,13 +53,21 @@ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* PRIVATE PROTOTYPES */ static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); +static herr_t H5G_traverse_ud(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, + H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id, + hid_t dxpl_id); +static herr_t H5G_traverse_elink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, + H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id, + hid_t dxpl_id); static herr_t H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id, + hid_t dxpl_id); static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/); static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name, unsigned target, int *nlinks, H5G_traverse_t op, void *op_data, - hid_t dxpl_id); + hid_t lapl_id, hid_t dxpl_id); /*------------------------------------------------------------------------- @@ -103,7 +113,7 @@ H5G_traverse_term_interface(void) */ static herr_t H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -118,18 +128,149 @@ H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_traverse_link_cb() */ /*------------------------------------------------------------------------- + * Function: H5G_traverse_link_ud + * + * Purpose: Callback for user-defined link traversal. Sets up a + * location ID and passes it to the user traversal callback. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, September 13, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t H5G_traverse_ud(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, + H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id, + hid_t dxpl_id) +{ + const H5L_link_class_t *link_class; /* User-defined link class */ + hid_t cb_return = -1; /* The ID the user-defined callback returned */ + H5O_loc_t *new_oloc=NULL; + H5F_t *temp_file=NULL; + H5F_t *new_file=NULL; + H5G_t *grp; + H5P_genplist_t *lapl_default; + H5P_genplist_t *lapl; /* LAPL with nlinks set */ + hid_t cur_grp; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_ud) + + /* Sanity check */ + HDassert(grp_loc); + HDassert(lnk); + HDassert(lnk->type >= H5L_LINK_UD_MIN); + HDassert(obj_loc); + HDassert(nlinks); + + /* Reset the object's path information, because we can't detect any changes + * in the "path" the user-defined callback takes */ + H5G_name_free(obj_loc->path); + + /* Get the link class for this type of link. */ + if(NULL == (link_class = H5L_find_class(lnk->type))) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get UD link class") + + /* Set up location for user-defined callback */ + if((grp = H5G_open(grp_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + if((cur_grp = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + + /* Record number of soft links left to traverse in the property list. + * If no property list exists yet, create one. */ + if(lapl_id == H5P_DEFAULT) + { + HDassert(H5P_LINK_ACCESS_DEFAULT != -1); + if(NULL == (lapl_default = H5I_object(H5P_LINK_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get default property list") + + if((lapl_id = H5P_copy_plist(lapl_default)) <0) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to copy property list") + } + + if(NULL == (lapl = H5I_object(lapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID") + if(H5P_set(lapl, H5L_NLINKS_NAME, nlinks) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info") + + /* User-defined callback function */ + if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + + /* Get the oloc from the ID the user callback returned */ + switch(H5I_get_type(cb_return)) + { + case H5I_GROUP: + if((new_oloc = H5G_oloc(H5I_object(cb_return))) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from group ID") + break; + case H5I_DATASET: + if((new_oloc = H5D_oloc(H5I_object(cb_return))) ==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from dataset ID") + break; + case H5I_DATATYPE: + if((new_oloc = H5T_oloc(H5I_object(cb_return))) ==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from datatype ID") + break; + case H5I_FILE: + if((temp_file = H5I_object(cb_return)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "couldn't get file from ID") + if((new_oloc = H5G_oloc(temp_file->shared->root_grp)) ==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get root group location from file ID") + break; + default: + HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL, "not a valid location or object ID") + } + + if(H5O_loc_copy(obj_loc->oloc, new_oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") + + /* The user has given us an open object, but we only want its location. However, + * if the object is in another file and we close it, the file will close as well and + * clear its information from the location we've just copied. + * Thus, we play with the number of open objects in the file to close the object without + * closing the file. -JML 5/06*/ + obj_loc->oloc->file->nopen_objs++; + H5Idec_ref(cb_return); + HDassert(obj_loc->oloc->file->nopen_objs > 0); + obj_loc->oloc->file->nopen_objs--; + +done: + /* Close location given to callback. + * This has the side effect of calling H5F_try_close on grp_loc's file. + * If we have a series of external links (file1 to file2 to file3 to + * file4), this closes file2 and file3 when we're done traversing + * through them (unless they have other IDs holding them open). + */ + if(cur_grp > 0) + { + if(H5I_object_verify(cur_grp, H5I_GROUP)) + if(H5I_dec_ref(cur_grp) < 0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location") + } + + if(ret_value < 0 && cb_return >= 0) + { + if(H5I_dec_ref(cb_return) < 0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") + } + + FUNC_LEAVE_NOAPI(ret_value) + +} + +/*------------------------------------------------------------------------- * Function: H5G_traverse_slink * * Purpose: Traverses symbolic link. The link head appears in the group @@ -149,7 +290,8 @@ done: */ static herr_t H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t lapl_id, + hid_t dxpl_id) { H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */ H5G_name_t tmp_obj_path; /* Temporary copy of object's path */ @@ -192,7 +334,7 @@ H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, udata.obj_loc = obj_loc; /* Traverse the link */ - if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, dxpl_id) < 0) + if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") done: @@ -296,7 +438,7 @@ done: */ static herr_t H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, - int *nlinks, H5G_traverse_t op, void *op_data, hid_t dxpl_id) + int *nlinks, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id) { H5G_loc_t loc; /* Location of start object */ H5O_loc_t grp_oloc; /* Object loc. for current group */ @@ -305,10 +447,13 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5O_loc_t obj_oloc; /* Object found */ H5G_name_t obj_path; /* Path for object found */ H5G_loc_t obj_loc; /* Location of object */ + H5O_link_t *cb_lnk=NULL; /* Pointer to link info for callback */ + H5G_loc_t *cb_loc=NULL; /* Pointer to object location for callback */ size_t nchars; /* component name length */ H5O_link_t lnk; /* Link information for object */ hbool_t link_valid = FALSE; /* Flag to indicate that the link information is valid */ hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */ + hbool_t own_cb_loc=FALSE; /* Flag to indicate that callback took ownership of cb_loc */ hbool_t group_copy = FALSE; /* Flag to indicate that the group entry is copied */ hbool_t last_comp = FALSE; /* Flag to indicate that a component is the last component in the name */ herr_t ret_value = SUCCEED; /* Return value */ @@ -403,7 +548,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5O_reset(H5O_LINK_ID, &lnk); #else /* H5_GROUP_REVISION */ /* Free information for link (but don't free link pointer) */ - if(lnk.type == H5G_LINK_SOFT) + if(lnk.type == H5L_LINK_SOFT) lnk.u.soft.name = H5MM_xfree(lnk.u.soft.name); lnk.name = H5MM_xfree(lnk.name); #endif /* H5_GROUP_REVISION */ @@ -417,6 +562,9 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* If the lookup was OK, try traversing soft links and mount points, if allowed */ if(lookup_status >= 0) { /* Indicate that the link info is valid */ + HDassert(lnk.type >= H5L_LINK_HARD); + if(lnk.type >H5L_LINK_BUILTIN_MAX && lnk.type < H5L_LINK_UD_MIN) + HGOTO_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, "unknown link type") link_valid = TRUE; /* Build object's group hier. location */ @@ -437,9 +585,21 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, if(H5L_LINK_SOFT == lnk.type && (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "too many links") - if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_SLINK, FAIL, "symbolic link traversal failed") + HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") + if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed") + } /* end if */ + + /* + * If we found an external link then we should follow it. But if this + * is the last component of the name and the H5G_TARGET_ELINK bit of + * TARGET is set then we don't follow it. + */ + if( lnk.type >= H5L_LINK_UD_MIN && ((0 == (target & H5G_TARGET_UDLINK)) || !last_comp) ) { + if((*nlinks)-- <= 0) + HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") + if(H5G_traverse_ud(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed") } /* end if */ /* @@ -449,9 +609,9 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, * * (If this link is a hard link, try to perform mount point traversal) * - * (Note that the soft link traversal above can change the status of - * the object (into a hard link), so don't use an 'else' statement - * here. -QAK) + * (Note that the soft and external link traversal above can change + * the status of the object (into a hard link), so don't use an 'else' + * statement here. -QAK) */ if(H5F_addr_defined(obj_loc.oloc->addr) && (0 == (target & H5G_TARGET_MOUNT) || !last_comp)) { @@ -462,25 +622,23 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Check for last component in name provided */ if(last_comp) { - H5O_link_t *tmp_lnk; /* Pointer to link info for callback */ - H5G_loc_t *tmp_loc; /* Pointer to object location for callback */ - /* Set callback parameters appropriately, based on link being found */ if(lookup_status < 0) { - tmp_lnk = NULL; - tmp_loc = NULL; + cb_lnk = NULL; + cb_loc = NULL; } /* end if */ else { - tmp_lnk = &lnk; - tmp_loc = &obj_loc; + cb_lnk = &lnk; + cb_loc = &obj_loc; } /* end else */ /* Operator routine will take care of object location, succeed or fail */ obj_loc_valid = FALSE; /* Call 'operator' routine */ - if((op)(&grp_loc, H5G_comp_g, tmp_lnk, tmp_loc, op_data) < 0) + if((op)(&grp_loc, H5G_comp_g, cb_lnk, cb_loc, op_data, &own_cb_loc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CALLBACK, FAIL, "traversal operator failed") + HGOTO_DONE(SUCCEED) } /* end if */ @@ -533,27 +691,54 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* If we've fallen through to here, the name must be something like just '.' * and we should issue the callback on that. -QAK */ - /* Reset "group copied" flag */ - /* (callback will take ownership of group location, succeed or fail) */ + cb_loc = &grp_loc; + + /* Reset "group copied" flag (cb_loc will be freed automatically unless the + * callback takes ownership of it) */ HDassert(group_copy); group_copy = FALSE; + /* Call 'operator' routine */ - if((op)(&grp_loc, ".", NULL, &grp_loc, op_data) < 0) + if((op)(&grp_loc, ".", NULL, cb_loc, op_data, &own_cb_loc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "traversal operator failed") + HGOTO_DONE(SUCCEED) done: + /* If the operator routine didn't take ownership of the location we + * passed it (or if there was an error), free it. If it's in a new + * file, also try to close its file. */ + if(!own_cb_loc && cb_loc) + { + if(cb_loc->oloc->file != grp_loc.oloc->file) + { + if(H5F_try_close(cb_loc->oloc->file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close external file opened during traversal") + } + H5G_loc_free(cb_loc); + } + /* If the object location is still valid (usually in an error situation), reset it */ if(obj_loc_valid) + { + if(ret_value < 0) + { + H5F_try_close(obj_loc.oloc->file); + } H5G_loc_free(&obj_loc); + } + if(ret_value < 0 && grp_loc.oloc->file) + { + H5F_try_close(grp_loc.oloc->file); + } /* If there's valid information in the link, reset it */ if(link_valid) { #ifdef H5_GROUP_REVISION H5O_reset(H5O_LINK_ID, &lnk); #else /* H5_GROUP_REVISION */ /* Free information for link (but don't free link pointer) */ - if(lnk.type == H5G_LINK_SOFT) + if(lnk.type == H5L_LINK_SOFT) lnk.u.soft.name = H5MM_xfree(lnk.u.soft.name); lnk.name = H5MM_xfree(lnk.name); #endif /* H5_GROUP_REVISION */ @@ -584,10 +769,11 @@ done: */ herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op, - void *op_data, hid_t dxpl_id) + void *op_data, hid_t lapl_id, hid_t dxpl_id) { - int nlinks = H5G_NLINKS; /* Link countdown value */ - herr_t ret_value = SUCCEED; /* Return value */ + int nlinks; /* Link countdown value */ + H5P_genplist_t *lapl; /* Property list with value for nlinks */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_traverse, FAIL) @@ -598,9 +784,23 @@ H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traver HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no starting location") if(!op) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no operation provided") + HDassert(lapl_id >= 0); + + /* Set nlinks value from property list, if it exists */ + if(lapl_id == H5P_DEFAULT) + { + nlinks = H5L_NLINKS_DEF; + } + else + { + if(NULL == (lapl = H5I_object(lapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + if(H5P_get(lapl, H5L_NLINKS_NAME, &nlinks) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links") + } /* Go perform "real" traversal */ - if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, dxpl_id) < 0) + if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "path traversal failed") done: @@ -14,7 +14,7 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5G_PACKAGE /*suppress error about including H5Gpkg */ -#define H5L_PACKAGE /*suppress error about including H5Gpkg */ +#define H5L_PACKAGE /*suppress error about including H5Lpkg */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5L_init_interface @@ -37,35 +37,37 @@ /* User data for path traversal routine for getting link metadata */ typedef struct { H5L_linkinfo_t *linfo; /* Buffer to return to user */ - hid_t dxpl_id; /* dxpl to use in callback */ + hid_t dxpl_id; /* dxpl to use in callback */ } H5L_trav_ud1_t; /* User data for path traversal callback to creating a link */ typedef struct { - H5F_t *file; /* Pointer to the file */ - hid_t dxpl_id; /* Dataset transfer property list */ - H5G_name_t *path; /* Path to object being linked */ - H5O_link_t *lnk; /* Pointer to link information to insert */ + H5F_t *file; /* Pointer to the file */ + hid_t dxpl_id; /* Dataset transfer property list */ + hid_t lcpl_id; /* Link creation property list */ + H5G_name_t *path; /* Path to object being linked */ + H5O_link_t *lnk; /* Pointer to link information to insert */ } H5L_trav_ud3_t; /* User data for path traversal routine for moving and renaming a link */ typedef struct { - const char *dst_name; /* Destination name for moving object */ - H5T_cset_t cset; /* Char set for new name */ - H5G_loc_t *dst_loc; /* Destination location for moving object */ - hbool_t copy; /* TRUE if this is a copy operation */ - hid_t dxpl_id; /* dxpl to use in callback */ + const char *dst_name; /* Destination name for moving object */ + H5T_cset_t cset; /* Char set for new name */ + H5G_loc_t *dst_loc; /* Destination location for moving object */ + hbool_t copy; /* TRUE if this is a copy operation */ + hid_t lapl_id; /* lapl to use in callback */ + hid_t dxpl_id; /* dxpl to use in callback */ } H5L_trav_ud4_t; /* User data for path traversal routine for getting soft link value */ typedef struct { - size_t size; /* Size of user buffer */ - char *buf; /* User buffer */ + size_t size; /* Size of user buffer */ + char *buf; /* User buffer */ } H5L_trav_ud5_t; /* User data for path traversal routine for removing link (i.e. unlink) */ typedef struct { - hid_t dxpl_id; /* Dataset transfer property list */ + hid_t dxpl_id; /* Dataset transfer property list */ } H5L_trav_ud6_t; /* User data for path traversal routine for retrieving link creation property list */ @@ -75,9 +77,10 @@ typedef struct { /* User data for path traversal routine for moving and renaming an object */ typedef struct { - H5F_t *file; /* Pointer to the file */ - H5O_link_t *lnk; /* Pointer to link information to insert */ - hid_t dxpl_id; /* Dataset transfer property list */ + H5F_t *file; /* Pointer to the file */ + H5O_link_t *lnk; /* Pointer to link information to insert */ + hbool_t copy; /* TRUE if this is a copy operation */ + hid_t dxpl_id; /* Dataset transfer property list */ } H5L_trav_ud10_t; /* Package variables */ @@ -86,32 +89,196 @@ typedef struct { /* Private prototypes */ static herr_t H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5L_create_real(H5G_loc_t *link_loc, const char *link_name, - H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id, - hid_t lcpl_id); + H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, hid_t lcpl_id, + hid_t lapl_id, hid_t dxpl_id); static herr_t H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, - H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id); -static herr_t H5L_create_soft(const char *target_path, H5G_loc_t *loc, - const char *name, hid_t dxpl_id, hid_t lcpl_id); + H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id, + hid_t lapl_id, hid_t dxpl_id); +static herr_t H5L_create_soft(const char *target_path, H5G_loc_t *cur_loc, + const char *cur_name, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id); static herr_t H5L_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, - char *buf/*out*/, hid_t dxpl_id); + char *buf/*out*/, hid_t lapl_id, hid_t dxpl_id); static herr_t H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); +static herr_t H5L_unlink(H5G_loc_t *loc, const char *name, hid_t lapl_id, + hid_t dxpl_id); static herr_t H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hbool_t copy_flag, - hid_t lcpl_id, hid_t dxpl_id); + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id); static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, - const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5L_get_linkinfo(H5G_loc_t *loc, const char *name, - H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id); + const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); static herr_t H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, - const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/); + const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, + hbool_t *own_obj_loc/*out*/); +static int H5L_find_class_idx(H5L_link_t id); + + +/* Information about user-defined links */ +static size_t H5L_table_alloc_g = 0; +static size_t H5L_table_used_g = 0; +static H5L_link_class_t *H5L_table_g = NULL; + + + +#define H5L_MIN_TABLE_SIZE 32 /* Minimum size of the user-defined link type table if it is allocated */ + + + +/*------------------------------------------------------------------------- + * Function: H5L_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: James Laird + * Thursday, July 13, 2006 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_init(void) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_init, FAIL); + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5Lregister + * + * Purpose: Registers a class of user-defined links, or changes the + * behavior of an existing class. + * + * The link class passed in will override any existing link + * class for the specified link class ID. It must at least + * include a H5L_link_class_t version (which should be + * H5L_LINK_CLASS_T_VERS), a link class ID, and a traversal + * function. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lregister(const H5L_link_class_t *cls) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lregister, FAIL) + H5TRACE1("e","*x",cls); + + /* Check args */ + if (cls==NULL) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class") + + /* Check H5L_link_class_t version number; this is where a function to convert + * from an outdated version should be called. + */ + if(cls->version != H5L_LINK_CLASS_T_VERS) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5L_link_class_t version number"); + + if (cls->id<H5L_LINK_UD_MIN || cls->id>H5L_LINK_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link identification number") + if (cls->trav_func==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no traversal function specified") + + /* Do it */ + if (H5L_register (cls)<0) + HGOTO_ERROR (H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register link type") + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5L_find_class_idx + * + * Purpose: Given a link class ID, return the offset in the global array + * that holds all the registered link classes. + * + * Return: Success: Non-negative index of entry in global + * link class table. + * Failure: Negative + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +static int +H5L_find_class_idx(H5L_link_t id) +{ + size_t i; /* Local index variable */ + int ret_value=FAIL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_find_class_idx) + + for (i=0; i<H5L_table_used_g; i++) + if (H5L_table_g[i].id == id) + HGOTO_DONE((int)i) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_find_class_idx */ + + +/*------------------------------------------------------------------------- + * Function: H5L_find_class + * + * Purpose: Given a link class ID return a pointer to a global struct that + * defines the link class. + * + * Return: Success: Ptr to entry in global link class table. + * Failure: NULL + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +const H5L_link_class_t * +H5L_find_class(H5L_link_t id) +{ + int idx; /* Filter index in global table */ + H5L_link_class_t *ret_value=NULL; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_find_class, NULL) + + /* Get the index in the global table */ + if((idx=H5L_find_class_idx(id))<0) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, NULL, "unable to find link class") + + /* Set return value */ + ret_value=H5L_table_g+idx; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_find_class */ /*------------------------------------------------------------------------- @@ -130,6 +297,7 @@ static herr_t H5L_init_interface(void) { H5P_genclass_t *crt_pclass; + H5P_genclass_t *acc_pclass; size_t nprops; /* Number of properties */ unsigned intmd_group = H5L_CRT_INTERMEDIATE_GROUP_DEF; herr_t ret_value = SUCCEED; /* Return value */ @@ -163,12 +331,57 @@ H5L_init_interface(void) HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list") } /* end if */ + /* ========== Link Access Property Class Initialization ============*/ + assert(H5P_CLS_LINK_ACCESS_g!=-1); + + /* Get the pointer to link access class */ + if(NULL == (acc_pclass = H5I_object(H5P_CLS_LINK_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + + /* Only register the default property list if it hasn't been created yet */ + if(H5P_LST_LINK_ACCESS_g == (-1)) { + /* Register the default link access property list */ + if((H5P_LST_LINK_ACCESS_g = H5P_create_id(acc_pclass))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default LAPL") + } /* end if */ + + + /* Initialize user-defined link classes */ + if(H5L_register_external() <0) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register external link class") + done: FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- + * Function: H5L_term_interface + * + * Purpose: Terminate any resources allocated in H5L_init_interface. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, January 24, 2006 + * + *------------------------------------------------------------------------- + */ +int +H5L_term_interface(void) +{ + int n=0; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_term_interface) + + /* Free the table of link types */ + H5L_table_g = H5MM_xfree(H5L_table_g); + H5L_table_used_g = H5L_table_alloc_g = 0; + + FUNC_LEAVE_NOAPI(n) +} + +/*------------------------------------------------------------------------- * Function: H5Lmove * * Purpose: Renames an object within an HDF5 file and moves it to a new @@ -187,14 +400,15 @@ done: */ herr_t H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name, hid_t lcpl_id) + const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { H5G_loc_t src_loc, *src_loc_p; H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lmove, FAIL) - H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id); + H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id, + lapl_id); /* Check arguments */ if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) @@ -220,8 +434,8 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, - FALSE, lcpl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link") + FALSE, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") done: FUNC_LEAVE_API(ret_value) @@ -244,14 +458,15 @@ done: */ herr_t H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name, hid_t lcpl_id) + const char *dst_name, hid_t lcpl_id, hid_t lapl_id) { H5G_loc_t src_loc, *src_loc_p; H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lcopy, FAIL) - H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id); + H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id, + lapl_id); /* Check arguments */ if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) @@ -276,8 +491,9 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") - if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link") + if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id, + lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") done: FUNC_LEAVE_API(ret_value) @@ -306,14 +522,15 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id) +H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id, + hid_t lapl_id) { H5G_loc_t new_loc; H5G_loc_t obj_loc; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Llink, FAIL) - H5TRACE4("e","isii",new_loc_id,new_name,obj_id,lcpl_id); + H5TRACE5("e","isiii",new_loc_id,new_name,obj_id,lcpl_id,lapl_id); /* Check arguments */ if(new_loc_id == H5L_SAME_LOC) @@ -328,8 +545,8 @@ H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id) if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") - if(H5L_link(&new_loc, new_name, &obj_loc, H5AC_dxpl_id, lcpl_id ) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + if(H5L_link(&new_loc, new_name, &obj_loc, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -356,20 +573,20 @@ done: */ herr_t H5Lcreate_soft(const char *target_path, - hid_t loc_id, const char *name, hid_t lcpl_id) + hid_t cur_loc, const char *cur_name, hid_t lcpl_id, hid_t lapl_id) { H5G_loc_t new_loc, *new_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lcreate_soft, FAIL) - H5TRACE4("e","sisi",target_path,loc_id,name,lcpl_id); + H5TRACE5("e","sisii",target_path,cur_loc,cur_name,lcpl_id,lapl_id); /* Check arguments */ - if(H5G_loc(loc_id, &new_loc) < 0) + if(H5G_loc(cur_loc, &new_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!target_path || !*target_path) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no target specified") - if(!name || !*name) + if(!cur_name || !*cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) @@ -377,8 +594,9 @@ H5Lcreate_soft(const char *target_path, new_loc_p = &new_loc; - if(H5L_create_soft(target_path, new_loc_p, name, H5AC_dxpl_id, lcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + if(H5L_create_soft(target_path, new_loc_p, cur_name, + lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -403,14 +621,15 @@ done: */ herr_t H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, - hid_t new_loc_id, const char *new_name, hid_t lcpl_id) + hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { H5G_loc_t cur_loc, *cur_loc_p; H5G_loc_t new_loc, *new_loc_p; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lcreate_hard, FAIL) - H5TRACE5("e","isisi",cur_loc_id,cur_name,new_loc_id,new_name,lcpl_id); + H5TRACE6("e","isisii",cur_loc_id,cur_name,new_loc_id,new_name,lcpl_id, + lapl_id); /* Check arguments */ if(cur_loc_id != H5L_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0) @@ -437,14 +656,66 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, else if(cur_loc_p->oloc->file != new_loc_p->oloc->file) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") - if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, H5AC_dxpl_id, lcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, + lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) } /* end H5Lcreate_hard() */ + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_ud + * + * Purpose: Creates a user-defined link of type LINK_TYPE named LINK_NAME + * with user-specified data UDATA. + * + * The format of the information pointed to by UDATA is + * defined by the user. UDATA_SIZE holds the size of this buffer. + * + * LINK_NAME is interpreted relative to LINK_LOC_ID. + * + * The property list specified by LCPL_ID holds properties used + * to create the link. + * + * The link class of the new link must already be registered + * with the library. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, December 13, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_link_t link_type, void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id) +{ + H5G_loc_t link_loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lcreate_ud, FAIL) + H5TRACE7("e","isLlxzii",link_loc_id,link_name,link_type,udata,udata_size, + lcpl_id,lapl_id); + + /* Check arguments */ + if(H5G_loc(link_loc_id, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!link_name || !*link_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") + + /* Create external link */ + if(H5L_create_ud(&link_loc, link_name, udata, udata_size, link_type, + H5G_TARGET_NORMAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Lcreate_ud */ + + /*------------------------------------------------------------------------- * Function: H5Lunlink * @@ -463,13 +734,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lunlink(hid_t loc_id, const char *name) +H5Lunlink(hid_t loc_id, const char *name, hid_t lapl_id) { H5G_loc_t loc; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lunlink, FAIL) - H5TRACE2("e","is",loc_id,name); + H5TRACE3("e","isi",loc_id,name,lapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc) < 0) @@ -478,8 +749,8 @@ H5Lunlink(hid_t loc_id, const char *name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") /* Unlink */ - if(H5L_unlink(&loc, name, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object") + if(H5L_unlink(&loc, name, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to unlink object") done: FUNC_LEAVE_API(ret_value) @@ -506,13 +777,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) +H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/, + hid_t lapl_id) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Lget_linkval, FAIL) - H5TRACE4("e","iszx",loc_id,name,size,buf); + H5TRACE5("e","iszxi",loc_id,name,size,buf,lapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc)) @@ -521,7 +793,7 @@ H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Get the link value */ - if(H5L_linkval(&loc, name, size, buf, H5AC_ind_dxpl_id) < 0) + if(H5L_linkval(&loc, name, size, buf, lapl_id, H5AC_ind_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") done: @@ -544,12 +816,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/) +H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/, + hid_t lapl_id) { H5G_loc_t loc; herr_t ret_value = SUCCEED; FUNC_ENTER_API(H5Lget_linkinfo, FAIL) - H5TRACE3("e","isx",loc_id,name,linkbuf); + H5TRACE4("e","isxi",loc_id,name,linkbuf,lapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc)) @@ -558,7 +831,7 @@ H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Get the creation time */ - if(H5L_get_linkinfo(&loc, name, linkbuf, H5AC_ind_dxpl_id) < 0) + if(H5L_get_linkinfo(&loc, name, linkbuf, lapl_id, H5AC_ind_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") done: @@ -566,6 +839,79 @@ done: } +/*------------------------------------------------------------------------- + * Function: H5Lunregister + * + * Purpose: Unregisters a class of user-defined links, preventing them + * from being traversed, queried, moved, etc. + * + * A link class can be re-registered using H5Lregister(). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lunregister(H5L_link_t id) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lunregister, FAIL) + H5TRACE1("e","Ll",id); + + /* Check args */ + if (id<0 || id>H5L_LINK_MAX) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type") + + /* Do it */ + if (H5L_unregister (id)<0) + HGOTO_ERROR (H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to unregister link type") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lunregister() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lis_registered + * + * Purpose: Tests whether a user-defined link class has been registered + * or not. + * + * Return: Positive if the link class has been registered + * Zero if it is unregistered + * Negative on error (if the class is not a valid UD class ID) + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +htri_t H5Lis_registered(H5L_link_t id) +{ + size_t i; /* Local index variable */ + htri_t ret_value=FALSE; /* Return value */ + + FUNC_ENTER_API(H5Lis_registered, FAIL) + + /* Check args */ + if(id<0 || id>H5L_LINK_MAX) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type id number") + + /* Is the link class already registered? */ + for(i=0; i<H5L_table_used_g; i++) + if(H5L_table_g[i].id==id) { + ret_value=TRUE; + break; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} +/* end H5Lis_registered */ /* *------------------------------------------------------------------------- @@ -576,6 +922,107 @@ done: */ /*------------------------------------------------------------------------- + * Function: H5L_register + * + * Purpose: Registers a class of user-defined links, or changes the + * behavior of an existing class. + * + * See H5Lregister for full documentation. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_register (const H5L_link_class_t *cls) +{ + size_t i; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_register, FAIL) + + assert (cls); + assert (cls->id>=0 && cls->id<=H5L_LINK_MAX); + + /* Is the link type already registered? */ + for (i=0; i<H5L_table_used_g; i++) + if (H5L_table_g[i].id==cls->id) + break; + + /* Filter not already registered */ + if (i>=H5L_table_used_g) { + if (H5L_table_used_g>=H5L_table_alloc_g) { + size_t n = MAX(H5L_MIN_TABLE_SIZE, 2*H5L_table_alloc_g); + H5L_link_class_t *table = H5MM_realloc(H5L_table_g, + n*sizeof(H5L_link_class_t)); + if (!table) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend link type table") + H5L_table_g = table; + H5L_table_alloc_g = n; + } /* end if */ + + /* Initialize */ + i = H5L_table_used_g++; + HDmemcpy(H5L_table_g+i, cls, sizeof(H5L_link_class_t)); + } /* end if */ + /* Filter already registered */ + else { + /* Replace old contents */ + HDmemcpy(H5L_table_g+i, cls, sizeof(H5L_link_class_t)); + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_register */ + + +/*------------------------------------------------------------------------- + * Function: H5L_unregister + * + * Purpose: Unregisters a class of user-defined links. + * + * See H5Lunregister for full documentation. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_unregister (H5L_link_t id) +{ + size_t i; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_unregister,FAIL) + + assert (id>=0 && id<=H5L_LINK_MAX); + + /* Is the filter already registered? */ + for (i=0; i<H5L_table_used_g; i++) + if (H5L_table_g[i].id==id) + break; + + /* Fail if filter not found */ + if (i>=H5L_table_used_g) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered") + + /* Remove filter from table */ + /* Don't worry about shrinking table size (for now) */ + HDmemmove(&H5L_table_g[i],&H5L_table_g[i+1],sizeof(H5L_link_class_t)*((H5L_table_used_g-1)-i)); + H5L_table_used_g--; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_unregister() */ + + +/*------------------------------------------------------------------------- * Function: H5L_link * * Purpose: Creates a link from OBJ_ID to CUR_NAME. See H5Llink() for @@ -590,7 +1037,7 @@ done: */ herr_t H5L_link(H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, - hid_t dxpl_id, hid_t lcpl_id) + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id) { H5F_t *file = NULL; /* File link will be in */ H5O_link_t lnk; /* Link to insert */ @@ -614,8 +1061,8 @@ H5L_link(H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, lnk.u.hard.addr = obj_loc->oloc->addr; /* Create the link */ - if( H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, dxpl_id, lcpl_id) <0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + if( H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, lcpl_id, lapl_id, dxpl_id) <0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object") done: FUNC_LEAVE_NOAPI(ret_value) @@ -636,9 +1083,13 @@ done: */ static herr_t H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5L_trav_ud3_t *udata = (H5L_trav_ud3_t *)_udata; /* User data passed in */ + H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */ + hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ + H5G_loc_t temp_loc; /* For UD callback */ + hbool_t temp_loc_init = FALSE; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_link_cb) @@ -652,7 +1103,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED if(udata->lnk->type == H5L_LINK_HARD) { /* Check that both objects are in same file */ if(grp_loc->oloc->file->shared != udata->file->shared) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed") + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "interfile hard links are not allowed") } /* end if */ /* Set the link's name correctly */ @@ -661,7 +1112,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED /* Insert link into group */ if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link for object") /* Set object's path if it has been passed in and is not set */ if(udata->path != NULL && udata->path->user_path_r == NULL) @@ -670,15 +1121,59 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name") } + /* If link is a user-defined link, trigger its creation callback if it has one*/ + if(udata->lnk->type >= H5L_LINK_UD_MIN) + { + const H5L_link_class_t *link_class; /* User-defined link class */ + H5O_loc_t temp_oloc; + H5G_name_t temp_path; + + /* Get the link class for this type of link. */ + if(NULL == (link_class = H5L_find_class(udata->lnk->type))) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get class of UD link") + + if(link_class->create_func != NULL) + { + /* Create a temporary location (or else H5G_open will do a shallow + * copy and wipe out grp_loc) + */ + H5G_name_reset(&temp_path); + if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") + + temp_loc.oloc = &temp_oloc; + temp_loc.path = &temp_path; + temp_loc_init = TRUE; + + /* Set up location for user-defined callback */ + if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register ID for group") + + if((link_class->create_func)(name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size, H5P_DEFAULT) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link creation callback failed") + } + } + done: - if(ret_value < 0) { - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - } /* end if */ + /* Close the location given to the user callback if it was created */ + if(grp_id >= 0) + { + if(H5I_dec_ref(grp_id) <0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") + } + else if(grp != NULL) + { + if(H5G_close(grp) <0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback") + } + else if(temp_loc_init) + H5G_loc_free(&temp_loc); + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_link_cb() */ @@ -706,7 +1201,7 @@ done: */ static herr_t H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path, - H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id, hid_t lcpl_id) + H5F_t *obj_file, H5O_link_t *lnk, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id) { char *norm_link_name = NULL; /* Pointer to normalized link name */ unsigned target_flags = H5G_TARGET_NORMAL; /* Flags to pass to group traversal function */ @@ -718,9 +1213,10 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path FUNC_ENTER_NOAPI_NOINIT(H5L_create_real) /* Check args */ + HDassert(lnk); HDassert(link_loc); HDassert(link_name && *link_name); - HDassert(lnk); + HDassert(lnk->type >= H5L_LINK_HARD && lnk->type <= H5L_LINK_MAX); /* Get normalized link name */ if((norm_link_name = H5G_normalize(link_name)) == NULL) @@ -746,6 +1242,9 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") } /* end if */ + /* Pass the lcpl to the link creation callback */ + udata.lcpl_id = lcpl_id; + /* Fill in common data for the link struct */ lnk->cset = char_encoding; #ifdef H5_HAVE_GETTIMEOFDAY @@ -776,7 +1275,7 @@ H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path udata.path = obj_path; /* Traverse the destination path & create new link */ - if(H5G_traverse(link_loc, link_name, target_flags, H5L_link_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(link_loc, link_name, target_flags, H5L_link_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") done: @@ -802,7 +1301,8 @@ done: */ static herr_t H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, - H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id) + H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id, hid_t lapl_id, + hid_t dxpl_id) { char *norm_cur_name = NULL; /* Pointer to normalized current name */ H5F_t *link_file = NULL; /* Pointer to file to link to */ @@ -826,7 +1326,7 @@ H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, lnk.type = H5L_LINK_HARD; /* Get object location for object pointed to */ - if(H5G_obj_find(cur_loc, norm_cur_name, H5G_TARGET_NORMAL, NULL, &obj_oloc, dxpl_id) < 0) + if(H5G_obj_find(cur_loc, norm_cur_name, H5G_TARGET_NORMAL, NULL, &obj_oloc, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") /* Construct link information for eventual insertion */ @@ -837,8 +1337,9 @@ H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, /* Create actual link to the object. Pass in NULL for the path, since this * function shouldn't change an object's user path. */ - if(H5L_create_real(link_loc, link_name, NULL, link_file, &lnk, dxpl_id, lcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + if(H5L_create_real(link_loc, link_name, NULL, link_file, &lnk, lcpl_id, + lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object") done: /* Free the normalized path name */ @@ -863,7 +1364,7 @@ done: */ static herr_t H5L_create_soft( const char *target_path, H5G_loc_t *link_loc, - const char *link_name, hid_t dxpl_id, hid_t lcpl_id) + const char *link_name, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id) { char *norm_target = NULL; /* Pointer to normalized current name */ H5O_link_t lnk; /* Link to insert */ @@ -885,8 +1386,9 @@ H5L_create_soft( const char *target_path, H5G_loc_t *link_loc, lnk.u.soft.name = norm_target; /* Create actual link to the object */ - if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, dxpl_id, lcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, lcpl_id, + lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object") done: /* Free the normalized target name */ @@ -898,9 +1400,65 @@ done: /*------------------------------------------------------------------------- + * Function: H5L_create_ud + * + * Purpose: Creates a user-defined link. See H5Lcreate_ud for + * full documentation. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Friday, May 19, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_create_ud(H5G_loc_t *link_loc, const char *link_name, void * ud_data, + size_t ud_data_size, H5L_link_t type, unsigned traverse_flags, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id) +{ + H5O_link_t lnk; /* Link to insert */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_create_ud) + + /* Check args */ + HDassert(type >= H5L_LINK_UD_MIN && type <= H5L_LINK_MAX); + HDassert(link_loc); + HDassert(link_name && *link_name); + HDassert(ud_data_size >= 0); + HDassert(ud_data_size == 0 || ud_data); + + /* Make sure that this link class is registered */ + if(H5L_find_class_idx(type) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "link class has not been registered with library") + + /* Fill in UD link-specific information in the link struct*/ + if(ud_data_size > 0) + { + lnk.u.ud.udata = H5MM_malloc((size_t) ud_data_size); + HDmemcpy(lnk.u.ud.udata, ud_data, (size_t) ud_data_size); + } + else + lnk.u.ud.udata = NULL; + + lnk.u.ud.size = ud_data_size; + lnk.type = type; + + /* Create actual link to the object */ + if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, lcpl_id, + lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to register new name for object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_create_ud() */ + + +/*------------------------------------------------------------------------- * Function: H5L_linkval_cb * - * Purpose: Callback for retrieving soft link value for an object. + * Purpose: Callback for retrieving link value or udata. * * Return: Non-negative on success/Negative on failure * @@ -911,10 +1469,11 @@ done: */ static herr_t H5L_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) + H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5L_trav_ud5_t *udata = (H5L_trav_ud5_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5L_link_class_t *link_class; /* User-defined link class */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_linkval_cb) @@ -922,23 +1481,35 @@ H5L_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H if(lnk == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - if(H5L_LINK_SOFT != lnk->type) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link") - - /* Copy to output buffer */ - if(udata->size > 0 && udata->buf) { - HDstrncpy(udata->buf, lnk->u.soft.name, udata->size); - if(HDstrlen(lnk->u.soft.name) >= udata->size) - udata->buf[udata->size - 1] = '\0'; - } /* end if */ + if(H5L_LINK_SOFT == lnk->type) + { + /* Copy to output buffer */ + if(udata->size > 0 && udata->buf) { + HDstrncpy(udata->buf, lnk->u.soft.name, udata->size); + if(HDstrlen(lnk->u.soft.name) >= udata->size) + udata->buf[udata->size - 1] = '\0'; + } /* end if */ + } + else if(lnk->type >= H5L_LINK_UD_MIN) + { + /* Get the link class for this type of link. It's okay if the class isn't registered, though--we + * just can't give any more information about it */ + link_class = H5L_find_class(lnk->type); + + if(link_class != NULL && link_class->query_func != NULL) { + if((link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, udata->buf, udata->size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query callback returned failure") + } + else if(udata->buf && udata->size > 0) + udata->buf[0] = '\0'; + } + else + HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "object is not a symbolic or user-defined link") done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_linkval_cb() */ @@ -947,7 +1518,8 @@ done: /*------------------------------------------------------------------------- * Function: H5L_linkval * - * Purpose: Returns the value of a symbolic link. + * Purpose: Returns the value of a symbolic link or the udata for a + * user-defined link. * * Return: Success: Non-negative, with at most SIZE bytes of the * link value copied into the BUF buffer. If the @@ -963,7 +1535,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id) +H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t lapl_id, hid_t dxpl_id) { H5L_trav_ud5_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -975,8 +1547,8 @@ H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid udata.buf = buf; /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_linkval_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L_linkval_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") done: FUNC_LEAVE_NOAPI(ret_value) @@ -998,10 +1570,14 @@ done: */ static herr_t H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { + H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */ + hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ H5L_trav_ud6_t *udata = (H5L_trav_ud6_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t temp_loc; /* For UD callback */ + hbool_t temp_loc_init = FALSE; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5L_unlink_cb) @@ -1011,19 +1587,57 @@ H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSE /* Check for removing '.' */ if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't delete self") + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "can't delete self") + + /* If there is a user-defined callback, call it before deleting the link */ + if(lnk->type >= H5L_LINK_UD_MIN) + { + const H5L_link_class_t *link_class; /* User-defined link class */ + H5O_loc_t temp_oloc; + H5G_name_t temp_path; + + /* Get the link class for this type of link. */ + if(NULL == (link_class = H5L_find_class(lnk->type))) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class not registered") + + if(link_class->del_func != NULL) + { + H5G_name_reset(&temp_path); + + if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") + + temp_loc.oloc = &temp_oloc; + temp_loc.path = &temp_path; + temp_loc_init = TRUE; + + /* Set up location for user-defined callback */ + if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") + if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + + if((link_class->del_func)(name, grp_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link deletion callback returned failure") + } + } /* Remove the link from the group */ if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from group") done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Close the location given to the user callback if it was created */ + if(grp_id >= 0) + H5I_dec_ref(grp_id); + else if(grp != NULL) + H5G_close(grp); + else if(temp_loc_init) + H5G_loc_free(&temp_loc); + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_unlink_cb() */ @@ -1042,7 +1656,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id) +H5L_unlink(H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) { H5L_trav_ud6_t udata; /* User data for callback */ char *norm_name = NULL; /* Pointer to normalized name */ @@ -1061,7 +1675,7 @@ H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id) /* Set up user data for unlink operation */ udata.dxpl_id = dxpl_id; - if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_unlink_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_unlink_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") done: @@ -1089,10 +1703,14 @@ done: */ static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5L_trav_ud10_t *udata = (H5L_trav_ud10_t *)_udata; /* User data passed in */ H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ + H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */ + hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ + H5G_loc_t temp_loc; /* For UD callback */ + hbool_t temp_loc_init = FALSE; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_move_dest_cb) @@ -1105,25 +1723,78 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *l if(udata->lnk->type == H5L_LINK_HARD) { /* Check that both objects are in same file */ if(grp_loc->oloc->file->shared != udata->file->shared) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "moving a link across files is not allowed") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "moving a link across files is not allowed") } /* end if */ /* Give the object its new name */ /* Casting away const okay -JML */ udata->lnk->name = H5MM_xfree(udata->lnk->name); - udata->lnk->name=name; + udata->lnk->name= (char *)name; /* Insert the link into the group */ if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object") + /* If the link was a user-defined link, call its move callback if it has one */ + if(udata->lnk->type >= H5L_LINK_UD_MIN) + { + const H5L_link_class_t *link_class; /* User-defined link class */ + H5O_loc_t temp_oloc; + H5G_name_t temp_path; + + /* Get the link class for this type of link. */ + if(NULL == (link_class = H5L_find_class(udata->lnk->type))) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered") + + if((!udata->copy && link_class->move_func != NULL) || (udata->copy && link_class->move_func)) + { + /* Create a temporary location (or else H5G_open will do a shallow + * copy and wipe out grp_loc) + */ + H5G_name_reset(&temp_path); + if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") + + temp_loc.oloc = &temp_oloc; + temp_loc.path = &temp_path; + temp_loc_init = TRUE; + + /* Set up location for user-defined callback */ + if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group ID") + + if(udata->copy) + { + if((link_class->copy_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD copy callback returned error") + } + else + { + if((link_class->move_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD move callback returned error") + } + } + } done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Close the location given to the user callback if it was created */ + if(grp_id >= 0) + { + if(H5I_dec_ref(grp_id) <0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") + } + else if(grp != NULL) + { + if(H5G_close(grp) <0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback") + } + else if(temp_loc_init) + H5G_loc_free(&temp_loc); + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; if(dst_name_r) H5RS_decr(dst_name_r); @@ -1147,7 +1818,7 @@ done: */ static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5L_trav_ud4_t *udata = (H5L_trav_ud4_t *)_udata; /* User data passed in */ H5L_trav_ud10_t udata_out; /* User data for H5L_move_dest_cb traversal */ @@ -1178,21 +1849,24 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, break; default: - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + if(lnk->type < H5L_LINK_UD_MIN) + HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unrecognized link type") + type = H5G_UDLINK; } /* end switch */ /* Set up user data for move_dest_cb */ if((udata_out.lnk = H5O_link_copy(lnk, NULL, 0)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy link to be moved"); + HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link to be moved"); udata_out.lnk->cset = udata->cset; udata_out.file = grp_loc->oloc->file; + udata_out.copy = udata->copy; udata_out.dxpl_id = udata->dxpl_id; /* Remember the link's original name (in case it's changed by H5G_name_replace) */ orig_name = H5MM_xstrdup(name); /* Insert the link into its new location */ - if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->dxpl_id) < 0) + if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") /* If this is a move and not a copy operation, change the object's name and remove the old link */ @@ -1214,12 +1888,9 @@ done: if(orig_name) H5MM_xfree(orig_name); - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_move_cb() */ @@ -1247,12 +1918,15 @@ done: */ static herr_t H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, - const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t dxpl_id) + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, + hid_t lapl_id, hid_t dxpl_id) { - unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK; /* Flags to pass to group traversal function */ + unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK|H5G_TARGET_UDLINK; H5T_cset_t char_encoding = H5F_CRT_DEFAULT_CSET; /* Character encoding for link */ H5P_genplist_t* lc_plist; /* Link creation property list */ + H5P_genplist_t* la_plist; /* Link access property list */ H5L_trav_ud4_t udata; /* User data for traversal */ + hid_t lapl_copy; /* Copy of lapl for this function */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_move) @@ -1284,15 +1958,29 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") } /* end if */ + /* Copy the link access property list because traversing UD links will + * decrease the NLINKS property. HDF5 should have NLINKS traversals to + * get to the source and NLINKS more to get to the destination. */ + if(lapl_id == H5P_DEFAULT) { + lapl_copy = lapl_id; + } + else { + if (NULL==(la_plist=H5I_object(lapl_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a valid access PL") + if((lapl_copy=H5P_copy_plist(la_plist)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy access properties") + } + /* Set up user data */ udata.dst_loc = dst_loc; udata.dst_name= dst_name; udata.cset = char_encoding; udata.copy = copy_flag; + udata.lapl_id = lapl_copy; udata.dxpl_id = dxpl_id; /* Do the move */ - if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT|H5G_TARGET_SLINK, H5L_move_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(src_loc, src_name, target_flags, H5L_move_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link") done: @@ -1301,110 +1989,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5L_get_lcpl_cb - * - * Purpose: Callback for getting a link's creation property list. This - * routine gets properties from the link and sets them on the - * copy of the default property list passed in. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: James Laird - * Friday, January 27, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5L_get_lcpl_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) -{ - H5L_trav_ud8_t *udata = (H5L_trav_ud8_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5L_get_lcpl_cb) - - /* Check if the name in this group resolved to a valid link */ - if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - - /* Set appropriate character encoding */ - if(H5P_set(udata->lcpl, H5P_CHAR_ENCODING_NAME, &(lnk->cset)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set property value for character encoding") - -done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_lcpl_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5L_get_create_plist - * - * Purpose: Returns a copy of the link's creation property list given - * given a link's location and name. - * - * Return: Success: ID of the property list - * - * Failure: Negative - * - * Programmer: James Laird - * Friday, January 27, 2006 - * - *------------------------------------------------------------------------- - */ -hid_t H5L_get_create_plist(H5G_loc_t *loc, const char* name) -{ - H5P_genplist_t *plist; /* Default property list */ - H5P_genplist_t *plist_copy; /* Copy of list to be modified */ - hid_t lcpl_id=-1; - H5L_trav_ud8_t udata; /* User data for traversal */ - char *norm_name = NULL; /* Pointer to normalized name */ - hid_t ret_value; - - FUNC_ENTER_NOAPI(H5L_get_create_plist, FAIL) - - /* Check arguments */ - HDassert(loc); - HDassert(name && *name); - - /* Get normalized copy of the name */ - if((norm_name = H5G_normalize(name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - - /* Get copy of default lcpl */ - if (NULL==(plist=H5I_object(H5P_LST_LINK_CREATE_g))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default LCPL") - if((lcpl_id=H5P_copy_plist(plist)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") - if (NULL==(plist_copy=H5I_object(lcpl_id))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get copy of LCPL") - - /* Set up user data */ - udata.lcpl = plist_copy; - - if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_get_lcpl_cb, &udata, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") - - ret_value = lcpl_id; - -done: - /* Free the normalized path name */ - if(norm_name) - H5MM_xfree(norm_name); - /* If we've created a new lcpl, close it */ - if(ret_value <0 && lcpl_id >= 0) - H5P_close(H5I_object(lcpl_id)); - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_create_plist */ - - -/*------------------------------------------------------------------------- * Function: H5L_get_linfo_cb * * Purpose: Callback for retrieving a link's metadata @@ -1418,10 +2002,12 @@ done: */ static herr_t H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) + H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/) { H5L_trav_ud1_t *udata = (H5L_trav_ud1_t *)_udata; /* User data passed in */ H5L_linkinfo_t *linfo = udata->linfo; + const H5L_link_class_t *link_class; /* User-defined link class */ + ssize_t cb_ret; /* Return value from UD callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_get_linfo_cb) @@ -1431,31 +2017,49 @@ H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Get information from the link */ - linfo->cset = lnk->cset; - linfo->ctime = lnk->ctime; - linfo->linkclass = lnk->type; - - switch(lnk->type) + if(linfo) { - case H5L_LINK_HARD: - linfo->u.objno = lnk->u.hard.addr; - break; - - case H5L_LINK_SOFT: - linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ - break; - - default: - HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "unknown link type"); - } + linfo->cset = lnk->cset; + linfo->ctime = lnk->ctime; + linfo->linkclass = lnk->type; + + switch(lnk->type) + { + case H5L_LINK_HARD: + linfo->u.address = lnk->u.hard.addr; + break; + + case H5L_LINK_SOFT: + linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ + break; + + default: + if(lnk->type < H5L_LINK_UD_MIN || lnk->type > H5L_LINK_MAX) + HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "unknown link class") + + /* User-defined link; call its query function to get the link udata size. */ + /* Get the link class for this type of link. It's okay if the class + * isn't registered, though--we just can't give any more information + * about it + */ + link_class = H5L_find_class(lnk->type); + + if(link_class != NULL && link_class->query_func != NULL) { + if((cb_ret = (link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, NULL, 0)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query buffer size callback returned failure") + + linfo->u.link_size = cb_ret; + } + else { + linfo->u.link_size = 0; + } + } /* end switch */ + } /* end if */ done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_obj_loc = FALSE; FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_get_linfo_cb() */ @@ -1473,8 +2077,8 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5L_get_linkinfo(H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id) +herr_t +H5L_get_linkinfo(const H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id) { H5L_trav_ud1_t udata; herr_t ret_value = SUCCEED; /* Return value */ @@ -1485,7 +2089,7 @@ H5L_get_linkinfo(H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out* udata.dxpl_id = dxpl_id; /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_get_linfo_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_linfo_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") done: @@ -1494,7 +2098,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5L get_default_lcpl + * Function: H5L_get_default_lcpl * * Purpose: Accessor for the default Link Creation Property List * diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c new file mode 100644 index 0000000..5609658 --- /dev/null +++ b/src/H5Lexternal.c @@ -0,0 +1,314 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5L_PACKAGE /*suppress error about including H5Lpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5L_init_extern_interface + +#include "H5private.h" /* Generic Functions */ +#include "H5Lpkg.h" /* Links */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Opublic.h" /* File objects */ +#include "H5Ppublic.h" /* Property lists */ +#include "H5Gpkg.h" /* Groups */ + +/*------------------------------------------------------------------------- + * Function: H5L_extern_traverse + * + * Purpose: Default traversal function for external links. This can + * be overridden using H5Lregister(). + * + * Given a filename and path packed into the link udata, + * attempts to open an object within an external file. + * If the H5L_ELINK_PREFIX_PROP property is set in the + * link access property list, appends that prefix to the + * filename being opened. + * + * Return: ID of the opened object on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +static hid_t H5L_extern_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id) +{ + hid_t fid; + char *file_name; + char *obj_name; + size_t fname_len; + htri_t result; + hbool_t fname_alloc = FALSE; + hid_t ret_value = -1; + + file_name = (char *) udata; + fname_len = strlen(file_name); + obj_name = ((char *) udata) + fname_len + 1; + + /* See if the external link prefix property is set */ + if((result = H5Pexist(lapl_id, H5L_ELINK_PREFIX_PROP)) < 0) + goto error; + + /* If so, prepend it to the filename */ + if(result > 0) + { + size_t buf_size; + + if(H5Pget_size(lapl_id, H5L_ELINK_PREFIX_PROP, &buf_size) < 0) + goto error; + + /* Allocate a buffer to hold the filename plus prefix */ + file_name = malloc(buf_size + fname_len + 1); + fname_alloc = TRUE; + + if(H5Pget(lapl_id, H5L_ELINK_PREFIX_PROP, file_name) < 0) + goto error; + + /* Add the external link's filename to the prefix supplied */ + strcat(file_name, udata); + } + + if((fid = H5Fopen(file_name, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) + goto error; + ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */ + if(H5Fclose(fid) < 0) + goto error; + + /* Free file_name if it's been allocated */ + if(fname_alloc) + free(file_name); + + return ret_value; + +error: + /* Free file_name if it's been allocated */ + if(fname_alloc) + free(file_name); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5L_extern_query + * + * Purpose: Default query function for external links. This can + * be overridden using H5Lregister(). + * + * Returns the size of the link's user data. If a buffer of + * is provided, copies at most buf_size bytes of the udata + * into it. + * + * Return: Size of buffer on success/Negative on failure + * + * Programmer: James Laird + * Monday, July 10, 2006 + * + *------------------------------------------------------------------------- + */ +static ssize_t H5L_extern_query(const char * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size) +{ + size_t ret_value; + + /* If the buffer is NULL, skip writng anything in it and just return + * the size needed */ + if(buf) + { + if(udata_size < buf_size) + buf_size = udata_size; + + /* Copy the udata verbatim up to udata_size*/ + memcpy(buf, udata, udata_size); + } + + ret_value = udata_size; + return ret_value; +} + +/* Default External Link link class */ +const H5L_link_class_t H5L_EXTERN_LINK_CLASS[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + H5L_LINK_EXTERNAL, /* Link type id number */ + "external_link", /* Link name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move callback */ + NULL, /* Copy callback */ + H5L_extern_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + H5L_extern_query /* Query callback */ +}}; + + +/*-------------------------------------------------------------------------- +NAME + H5L_init_extern_interface -- Initialize interface-specific information +USAGE + herr_t H5L_init_extern_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5T_init_iterface currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5L_init_extern_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_init_extern_interface) + + FUNC_LEAVE_NOAPI(H5L_init()) +} /* H5L_init_extern_interface() */ + + + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_external + * + * Purpose: Creates an external link from LINK_NAME to OBJ_NAME. + * + * External links are links to objects in other HDF5 files. They + * are allowed to "dangle" like soft links internal to a file. + * FILE_NAME is the name of the file that OBJ_NAME is is contained + * within. If OBJ_NAME is given as a relative path name, the + * path will be relative to the root group of FILE_NAME. + * LINK_NAME is interpreted relative to LINK_LOC_ID, which is + * either a file ID or a group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, May 18, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_external(const char *file_name, const char *obj_name, + hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) +{ + H5G_loc_t link_loc; + char *temp_name = NULL; + size_t buf_size; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lcreate_external, FAIL) + H5TRACE6("e","ssisii",file_name,obj_name,link_loc_id,link_name,lcpl_id, + lapl_id); + + /* Check arguments */ + if(!file_name || !*file_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified") + if(!obj_name || !*obj_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified") + if(H5G_loc(link_loc_id, &link_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!link_name || !*link_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") + + /* Combine the filename and link name into a single buffer to give to the UD link */ + buf_size = HDstrlen(file_name) + HDstrlen(obj_name) + 2; + if(NULL == (temp_name = H5MM_malloc(buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer") + HDstrcpy(temp_name, file_name); + HDstrcpy(temp_name + (HDstrlen(file_name) + 1), obj_name); + + /* Create an external link */ + if(H5L_create_ud(&link_loc, link_name, temp_name, buf_size, H5L_LINK_EXTERNAL, H5G_TARGET_NORMAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + +done: + if(temp_name != NULL) + H5MM_free(temp_name); + FUNC_LEAVE_API(ret_value); +} /* end H5Lcreate_external() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_register_external + * + * Purpose: Registers default "External Link" link class. + * Use during library initialization or to restore the default + * after users change it. + * + * Return: Non-negative on success/ negative on failure + * + * Programmer: James Laird + * Monday, July 17, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_register_external() +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_register_external, FAIL) + + if(H5L_register(H5L_EXTERN_LINK_CLASS) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register external link class") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Lunpack_elink_path + * + * Purpose: Given a buffer holding the "link value" from an external link, + * gets pointers to the filename and object path within the + * link value buffer. + * + * External link linkvalues are two NULL-terminated strings + * one after the other. + * + * FILENAME and OBJ_PATH will be set to pointers within + * ext_linkval unless they are NULL. + * + * Using this function on strings that aren't external link + * udata buffers can result in segmentation faults. + * + * Return: Non-negative on success/ Negative on failure + * + * Programmer: James Laird + * Monday, July 17, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lunpack_elink_val(char *ext_linkval, char **filename, char **obj_path) +{ + size_t len; /* Length of the filename in the linkval*/ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lunpack_elink_val, FAIL) + H5TRACE3("e","s*s*s",ext_linkval,filename,obj_path); + + if(ext_linkval == NULL ) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an external link linkval buffer") + + if(filename != NULL) + *filename = ext_linkval; + + if(obj_path != NULL) + { + len = HDstrlen(ext_linkval); + *obj_path = ext_linkval + len + 1; /* Add one for NULL terminator */ + } + +done: + FUNC_LEAVE_API(ret_value) +} diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h index 04a74f4..8a02791 100644 --- a/src/H5Lpkg.h +++ b/src/H5Lpkg.h @@ -30,6 +30,13 @@ /* Get package's private header */ #include "H5Lprivate.h" +/******************************/ +/* Package Private Prototypes */ +/******************************/ + +H5_DLL herr_t H5L_create_ud(H5G_loc_t *link_loc, const char *link_name, + void * ud_data, size_t ud_data_size, H5L_link_t type, + unsigned traverse_flags, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id); #endif /* _H5Lpkg_H */ diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index 78743da..d5cc7d8 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -31,13 +31,27 @@ #define H5L_CRT_INTERMEDIATE_GROUP_SIZE sizeof(unsigned) #define H5L_CRT_INTERMEDIATE_GROUP_DEF 0 +/* Definitions for accessing links */ +#define H5L_NLINKS_NAME "max soft links" +#define H5L_NLINKS_SIZE sizeof(size_t) +#define H5L_NLINKS_DEF 16 /*max symlinks to follow per lookup */ /* Functions that understand link messages */ /* forward reference for later use */ struct H5HL_t; /* defined in H5HLprivate.h */ H5_DLL herr_t H5L_link(H5G_loc_t *new_loc, const char *new_name, - H5G_loc_t *obj_loc, hid_t dxpl, hid_t lcpl_id); + H5G_loc_t *obj_loc, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id); H5_DLL hid_t H5L_get_default_lcpl(void); +H5_DLL herr_t H5L_get_linkinfo(const H5G_loc_t *loc, const char *name, + H5L_linkinfo_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5L_init(void); +H5_DLL herr_t H5L_register_external(void); + +/* User-defined link functions */ +H5_DLL herr_t H5L_register (const H5L_link_class_t *cls); +H5_DLL herr_t H5L_unregister (H5L_link_t id); +H5_DLL const H5L_link_class_t *H5L_find_class(H5L_link_t id); + #endif /* _H5Lprivate_H */ diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index a922908..29dc840 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -34,42 +34,110 @@ extern "C" { #endif -/* Types of links */ -typedef enum H5L_link_t { - H5L_LINK_ERROR = -1, - H5L_LINK_HARD = 0, - H5L_LINK_SOFT = 1 -} H5L_link_t; +/* Link classes. + * Values less than 64 are reserved for the HDF5 library's internal use. + * Values 64 to 255 are for "user-defined" link types; these types are + * defined by HDF5 but their behavior can be overridden by users. + * Users who want to create new classes of links should contact the HDF5 + * development team at hdfhelp@ncsa.uiuc.edu . + * These values can never change because they appear in HDF5 files. + */ +typedef int H5L_link_t; +#define H5L_LINK_ERROR (-1) +#define H5L_LINK_HARD 0 +#define H5L_LINK_SOFT 1 +#define H5L_LINK_BUILTIN_MAX H5L_LINK_SOFT /* Maximum value link value for "built-in" link types */ +#define H5L_LINK_UD_MIN 64 /*link ids at or above this value are "user-defined" link types. */ +#define H5L_LINK_EXTERNAL 64 +#define H5L_LINK_MAX 255 /*maximum link id */ /* Metadata buffer for user query function */ typedef struct H5L_linkinfo_t { - H5T_cset_t cset; /* Character set of link name */ - time_t ctime; /* Creation time */ - H5L_link_t linkclass; /* Type of link */ + H5T_cset_t cset; /* Character set of link name */ + time_t ctime; /* Creation time */ + H5L_link_t linkclass; /* Type of link */ union { - haddr_t objno; /* Data stored in a hard link */ - size_t link_size; /* Size of a soft link */ + haddr_t address; /* Address hard link points to */ + size_t link_size; /* Size of a soft link or UD link */ } u; } H5L_linkinfo_t; #define H5L_SAME_LOC 0 +/* The H5L_link_class_t struct can be used to override the behavior of a + * "user-defined" link class. Users should populate the struct with callback + * functions defined below. + */ +/* Current version of the H5L_link_class_t struct */ +#define H5L_LINK_CLASS_T_VERS (0) + +/* Callback prototypes for user-defined links */ +/* Link creation callback */ +typedef herr_t (*H5L_create_func_t)(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id); + +/* Callback for when the link is moved */ +typedef herr_t (*H5L_move_func_t)(const char * new_name, hid_t new_loc, void * udata, size_t udata_size); + +/* Callback for when the link is moved */ +typedef herr_t (*H5L_copy_func_t)(const char * new_name, hid_t new_loc, void * udata, size_t udata_size); + +/* The actual link function, called during traversal */ +typedef herr_t (*H5L_func_t)(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id); + +/* Callback for when the link is deleted */ +typedef herr_t (*H5L_delete_func_t)(const char * link_name, hid_t loc_group, void * udata, size_t udata_size); + +/* Callback for querying the link */ +/* Returns the size of the buffer needed */ +typedef ssize_t (*H5L_query_func_t)(const char * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size); + +/* User-defined link types */ +typedef struct H5L_link_class_t { + int version; /* Version number of this struct */ + H5L_link_t id; /* Link type ID */ + const char *comment; /* Comment for debugging */ + H5L_create_func_t create_func; /* Callback during link creation */ + H5L_move_func_t move_func; /* Callback after moving link */ + H5L_copy_func_t copy_func; /* Callback after copying link */ + H5L_func_t trav_func; /* The main traversal function */ + H5L_delete_func_t del_func; /* Callback for link deletion */ + H5L_query_func_t query_func; /* Callback for queries */ +} H5L_link_class_t; + +#define H5L_ELINK_PREFIX_PROP "elink_prefix" + + +/* Public prototypes */ H5_DLL herr_t H5Llink(hid_t cur_loc_id, const char *cur_name, - hid_t obj_id, hid_t lcpl_id); + hid_t obj_id, hid_t lcpl_id, hid_t lapl_id); H5_DLL herr_t H5Lmove(hid_t src_loc, const char *src_name, hid_t dst_loc, - const char *dst_name, hid_t lcpl_id); + const char *dst_name, hid_t lcpl_id, hid_t lapl_id); H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc, - const char *dst_name, hid_t lcpl_id); + const char *dst_name, hid_t lcpl_id, hid_t lapl_id); H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name, - hid_t dst_loc, const char *dst_name, hid_t lcpl_id); -H5_DLL herr_t H5Lcreate_soft(const char *target_path, hid_t loc, - const char *name, hid_t lcpl_id); -H5_DLL herr_t H5Lunlink(hid_t loc_id, const char *name); + hid_t dst_loc, const char *dst_name, hid_t lcpl_id, + hid_t lapl_id); +H5_DLL herr_t H5Lcreate_soft(const char *target_path, hid_t cur_loc, + const char *cur_name, hid_t lcpl_id, hid_t lapl_id); +H5_DLL herr_t H5Lunlink(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL herr_t H5Lget_linkval(hid_t loc_id, const char *name, size_t size, - char *buf/*out*/); + char *buf/*out*/, hid_t lapl_id); H5_DLL herr_t H5Lget_linkinfo(hid_t loc_id, const char *name, - H5L_linkinfo_t *linkbuf /*out*/); + H5L_linkinfo_t *linkbuf /*out*/, hid_t lapl_id); + +/* UD link functions */ +H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, + H5L_link_t link_type, void * udata, size_t udata_size, hid_t lcpl_id, + hid_t lapl_id); +H5_DLL herr_t H5Lregister(const H5L_link_class_t *cls); +H5_DLL herr_t H5Lunregister(H5L_link_t id); +H5_DLL htri_t H5Lis_registered(H5L_link_t id); +/* External link functions */ +H5_DLL herr_t H5Lunpack_elink_val(char * ext_linkval/*in*/, + char ** filename/*out*/, char** obj_path /*out*/); +H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, + hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); #ifdef __cplusplus } @@ -33,6 +33,7 @@ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free lists */ #include "H5MFprivate.h" /* File memory management */ +#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ @@ -175,6 +176,8 @@ H5FL_EXTERN(H5O_cont_t); H5FL_DEFINE_STATIC(H5O_addr_map_t); /* PRIVATE PROTOTYPES */ +static hid_t H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id); +static H5O_loc_t * H5O_get_oloc(hid_t id); static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/, haddr_t header); static herr_t H5O_reset_real(const H5O_msg_class_t *type, void *native); @@ -229,6 +232,401 @@ static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data); /*------------------------------------------------------------------------- + * Function: H5Oopen + * + * Purpose: Opens an object within an HDF5 file. + * + * This function opens an object in the same way that H5Gopen, + * H5Topen, and H5Dopen do. However, H5Oopen doesn't require + * the type of object to be known beforehand. This can be + * useful in user-defined links, for instance, when only a + * path is known. + * + * The opened object should be closed again with H5Oclose + * or H5Gclose, H5Tclose, or H5Dclose. + * Return: Success: An open object identifier + * Failure: Negative + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) +{ + H5G_loc_t loc; + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + hbool_t ent_found = FALSE; /* Entry at 'name' found */ + hid_t ret_value = FAIL; + + FUNC_ENTER_API(H5Oopen, FAIL) + H5TRACE3("i","isi",loc_id,name,lapl_id); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(&loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + ent_found = TRUE; + + if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + +done: + if(ret_value < 0) { + if(ent_found) + H5G_name_free(&obj_path); + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} + + + +/*------------------------------------------------------------------------- + * Function: H5Oopen_by_addr + * + * Purpose: Warning! This function is EXTREMELY DANGEROUS! + * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA, + * and other VERY BAD THINGS! + * + * This function opens an object using its address within the + * HDF5 file, similar to an HDF5 hard link. The open object + * is identical to an object opened with H5Oopen() and should + * be closed with H5Oclose() or a type-specific closing + * function (such as H5Gclose() ). + * + * This function is very dangerous if called on an invalid + * address. For this reason, H5Oincr_refcount() should be + * used to prevent HDF5 from deleting any object that is + * referenced by address (e.g. by a user-defined link). + * H5Odecr_refcount() should be used when the object is + * no longer being referenced by address (e.g. when the UD link + * is deleted). + * + * The address of the HDF5 file on disk has no effect on + * H5Oopen_by_addr(), nor does the use of any unusual file + * drivers. The "address" is really the offset within the + * HDF5 file, and HDF5's file drivers will transparently + * map this to an address on disk for the filesystem. + * + * Return: Success: An open object identifier + * Failure: Negative + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Oopen_by_addr(hid_t loc_id, haddr_t addr) +{ + H5G_loc_t loc; + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + hbool_t ent_found = FALSE; /* Entry at 'name' found */ + hid_t ret_value = FAIL; + + FUNC_ENTER_API(H5Oopen_by_addr, FAIL) + H5TRACE2("i","ia",loc_id,addr); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied") + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + obj_loc.oloc->addr = addr; + obj_loc.oloc->file = loc.oloc->file; + H5G_name_reset(obj_loc.path); + + if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + +done: + if(ret_value < 0) { + if(ent_found) + H5G_name_free(&obj_path); + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Oclose + * + * Purpose: Close an open file object. + * + * This is the companion to H5Oopen. It is used to close any + * open object in an HDF5 file (but not IDs are that not file + * objects, such as property lists and dataspaces). It has + * the same effect as calling H5Gclose, H5Dclose, or H5Tclose. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oclose(hid_t object_id) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(H5Oclose, FAIL) + H5TRACE1("e","i",object_id); + + /* Get the type of the object and open it in the correct way */ + switch(H5I_get_type(object_id)) + { + case(H5I_GROUP): + case(H5I_DATATYPE): + case(H5I_DATASET): + if( H5I_object(object_id) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object"); + if (H5I_dec_ref(object_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object"); + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)"); + break; + } + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Oincr_refcount + * + * Purpose: Warning! This function is EXTREMELY DANGEROUS! + * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA, + * and other VERY BAD THINGS! + * + * This function increments the "hard link" reference count + * for an object. It should be used a user-defined link + * that references an object by address is deleted. When the + * link is deleted, H5Odecr_refcount should be used. + * + * Return: Success: The object's new refcount + * Failure: Negative + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +int +H5Oincr_refcount(hid_t object_id) +{ + H5O_loc_t *oloc; + int ret_value; + FUNC_ENTER_API(H5Oincr_refcount, FAIL) + H5TRACE1("Is","i",object_id); + + /* Get the object's oloc so we can adjust its link count */ + if((oloc = H5O_get_oloc(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + ret_value = H5O_link(oloc, 1, H5AC_dxpl_id); + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Odecr_refcount + * + * Purpose: Warning! This function is EXTREMELY DANGEROUS! + * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA, + * and other VERY BAD THINGS! + * + * This function decrements the "hard link" reference count + * for an object. It should be used when user-defined links + * that reference an object by address are deleted, and only + * after H5Oincr_refcount has already been used. + * + * Return: Success: The object's new refcount + * Failure: Negative + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +int H5Odecr_refcount(hid_t object_id) +{ + H5O_loc_t *oloc; + int ret_value; + + FUNC_ENTER_API(H5Odecr_refcount, FAIL) + + /* Get the object's oloc so we can adjust its link count */ + if((oloc = H5O_get_oloc(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + ret_value = H5O_link(oloc, -1, H5AC_dxpl_id); + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5O_open_by_loc + * + * Purpose: Opens an object and returns an ID given its group loction. + * + * This functions simply invokes H5G_open, H5T_open, or + * H5D_open depending on the object type. + * + * Return: Success: Open object identifier + * Failure: Negative + * + * Programmer: James Laird + * July 25 2006 + * + *------------------------------------------------------------------------- + */ +static hid_t +H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + H5G_t *grp = NULL; + H5D_t *dset = NULL; + H5T_t *type = NULL; + hid_t ret_value; + + FUNC_ENTER_NOAPI(H5O_open_by_loc, FAIL) + + HDassert(obj_loc); + + /* Get the type of the object and open it in the correct way */ + switch(H5O_obj_type(obj_loc->oloc, dxpl_id)) + { + case(H5G_GROUP): + /* Open the group */ + if((grp = H5G_open(obj_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + /* Register an atom for the group */ + if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + break; + + case(H5G_DATASET): + /* Open the group */ + if((dset = H5D_open(obj_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + /* Register an atom for the group */ + if((ret_value = H5I_register(H5I_DATASET, dset)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataset") + break; + + case(H5G_TYPE): + /* Open the group */ + if((type = H5T_open(obj_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open datatype") + /* Register an atom for the group */ + if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "invalid object type") + } + +done: + if(ret_value < 0) { + if(grp != NULL) + H5G_close(grp); + else if(dset != NULL) + H5D_close(dset); + else if(type != NULL) + H5T_close(type); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5O_get_oloc + * + * Purpose: Gets the oloc for an object given its ID. + * + * Return: Success: Pointer to H5O_loc_t + * Failure: NULL + * + * Programmer: James Laird + * July 25 2006 + * + *------------------------------------------------------------------------- + */ +static H5O_loc_t * +H5O_get_oloc(hid_t object_id) +{ + H5G_t *grp = NULL; + H5D_t *dset = NULL; + H5T_t *type = NULL; + H5O_loc_t *ret_value; + + FUNC_ENTER_NOAPI(H5O_get_oloc, NULL) + + switch(H5I_get_type(object_id)) + { + case(H5I_GROUP): + if((grp = H5I_object(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get group from ID") + if((ret_value = H5G_oloc(grp)) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from group ID") + break; + + case(H5I_DATASET): + if((dset = H5I_object(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get dataset from ID") + if((ret_value = H5D_oloc(dset)) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from dataset ID") + break; + + case(H5I_DATATYPE): + if((type = H5I_object(object_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get type from ID") + if((ret_value = H5T_oloc(type)) == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from datatype ID") + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, NULL, "invalid object type") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5O_create * * Purpose: Creates a new object header. Allocates space for it and @@ -1604,7 +2002,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t /* Increment any links in message */ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count"); + HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared object link count"); done: FUNC_LEAVE_NOAPI(ret_value); diff --git a/src/H5Oattr.c b/src/H5Oattr.c index f0c15e7..84bb09d 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -589,7 +589,7 @@ H5O_attr_delete(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_l /* Decrement the reference count on the shared datatype, if requested */ if(adj_link) if(H5T_link(attr->dt, -1, dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count") + HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") } /* end if */ done: @@ -628,7 +628,7 @@ H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg) if(H5T_committed(attr->dt)) { /* Increment the reference count on the shared datatype */ if(H5T_link(attr->dt,1,dxpl_id)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared datatype link count"); + HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count"); } /* end if */ done: diff --git a/src/H5Olink.c b/src/H5Olink.c index 00a2b92..53fa99e 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -124,7 +124,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p) /* Get the type of the link */ lnk->type = *p++; - if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_SOFT) + if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_MAX) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type") /* Get the link creation time from the file */ @@ -165,9 +165,21 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p) p += len; break; + /* User-defined linkes */ default: - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type") - break; + if(lnk->type < H5L_LINK_UD_MIN || lnk->type > H5L_LINK_MAX) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type") + + /* A UD link. Get the user-supplied data */ + UINT16DECODE(p, len) + lnk->u.ud.size = len; + if(len > 0) + { + if(NULL == (lnk->u.ud.udata = H5MM_malloc((size_t)len))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDmemcpy(lnk->u.ud.udata, p, len); + p += len; + } } /* end switch */ /* Set return value */ @@ -252,8 +264,18 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg) p += len; break; + /* User-defined links */ default: - HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT)); + HDassert(lnk->type >= H5L_LINK_UD_MIN && lnk->type <= H5L_LINK_MAX); + + /* Store the user-supplied data, however long it is */ + len = (uint16_t)lnk->u.ud.size; + UINT16ENCODE(p, len) + if(len > 0) + { + HDmemcpy(p, lnk->u.ud.udata, len); + p+=len; + } break; } /* end switch */ @@ -300,6 +322,14 @@ H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags) dest->name = H5MM_xstrdup(lnk->name); if(lnk->type == H5L_LINK_SOFT) dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name); + else if(lnk->type >= H5L_LINK_UD_MIN) { + if(lnk->u.ud.size != 0) + { + if(NULL == (dest->u.ud.udata = H5MM_malloc(lnk->u.ud.size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDmemcpy(dest->u.ud.udata, lnk->u.ud.udata, lnk->u.ud.size); + } + }/* end if */ /* Set return value */ ret_value=dest; @@ -354,8 +384,10 @@ H5O_link_size(const H5F_t *f, const void *_mesg) HDstrlen(lnk->u.soft.name); /* Link value */ break; - default: - HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT)); + default: /* Default is user-defined link type */ + HDassert(lnk->type >= H5L_LINK_UD_MIN); + ret_value += 2 + /* User-defined data size */ + lnk->u.ud.size; /* User-defined data */ break; } /* end switch */ @@ -387,6 +419,12 @@ H5O_link_reset(void *_mesg) /* Free information for link (but don't free link pointer) */ if(lnk->type == H5L_LINK_SOFT) lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name); + else if (lnk->type >= H5L_LINK_UD_MIN) { + if(lnk->u.ud.size > 0) + { + lnk->u.ud.udata = H5MM_xfree(lnk->u.ud.udata); + } + } /* end if */ lnk->name = H5MM_xfree(lnk->name); } /* end if */ @@ -561,6 +599,17 @@ H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_ break; default: + if(link_src->type >= H5L_LINK_UD_MIN) + { + /* Copy the user-defined link's user data */ + if(link_src->u.ud.size != 0) + { + if(NULL == (link_dst->u.ud.udata = H5MM_malloc(link_src->u.ud.size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDmemcpy(link_dst->u.ud.udata, link_src->u.ud.udata, link_src->u.ud.size); + } + } + else HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unrecognized link type") } /* end switch */ @@ -610,7 +659,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, HDassert(cpy_info->max_depth < 0 || cpy_info->curr_depth < cpy_info->max_depth); /* Expand soft link */ - if(H5G_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) { + if(H5L_LINK_SOFT == link_src->type && cpy_info->expand_soft_link) { H5G_stat_t statbuf; /* Information about object pointed to by soft link */ H5G_loc_t grp_loc; /* Group location for parent of soft link */ H5G_name_t grp_path; /* Path for parent of soft link */ @@ -635,10 +684,10 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, #else link_src->u.hard.addr = statbuf.objno[0]; #endif - link_src->type = H5G_LINK_HARD; + link_src->type = H5L_LINK_HARD; /* Convert destination link to hard link */ - link_dst->type = H5G_LINK_HARD; + link_dst->type = H5L_LINK_HARD; link_dst->u.soft.name = H5MM_xfree(link_dst->u.soft.name); } /* end if */ } /* if ((H5G_CACHED_SLINK == src_ent->type)... */ @@ -674,6 +723,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, break; case H5L_LINK_SOFT: + case H5L_LINK_EXTERNAL: HGOTO_DONE(SUCCEED) break; @@ -720,7 +770,9 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Link Type:", (lnk->type == H5L_LINK_HARD ? "Hard" : - (lnk->type == H5L_LINK_SOFT ? "Soft" : "Unknown"))); + (lnk->type == H5L_LINK_SOFT ? "Soft" : + (lnk->type == H5L_LINK_EXTERNAL ? "External" : + (lnk->type >= H5L_LINK_UD_MIN ? "User-defined" : "Unknown"))))); tm = HDlocaltime(&(lnk->ctime)); HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); @@ -744,6 +796,15 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * "Link Value:", lnk->u.soft.name); break; + case H5L_LINK_EXTERNAL: + { + char * objname = (char *) lnk->u.ud.udata + (HDstrlen(lnk->u.ud.udata) + 1); + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Link File Name:", lnk->u.ud.udata); + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Link Object Name:", objname); + } + default: break; } /* end switch */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 59c2081..07d2468 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -153,6 +153,11 @@ typedef struct H5O_link_soft_t { char *name; /* Destination name */ } H5O_link_soft_t; +typedef struct H5O_link_ud_t { + void *udata; /* Opaque data supplied by the user */ + size_t size; /* Size of udata */ +} H5O_link_ud_t; + typedef struct H5O_link_t { H5L_link_t type; /* Type of link */ time_t ctime; /* Time link was createed */ @@ -161,6 +166,7 @@ typedef struct H5O_link_t { union { H5O_link_hard_t hard; /* Information for hard links */ H5O_link_soft_t soft; /* Information for soft links */ + H5O_link_ud_t ud; /* Information for user-defined links */ } u; } H5O_link_t; diff --git a/src/H5Opublic.h b/src/H5Opublic.h index e71ff9c..9fe00cb 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -30,6 +30,7 @@ /* Public headers needed by this file */ #include "H5public.h" +#include "H5Ipublic.h" typedef struct H5O_stat_t { hsize_t size; /* Total size of object header in file */ @@ -42,6 +43,12 @@ typedef struct H5O_stat_t { extern "C" { #endif +H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); +H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); +H5_DLL herr_t H5Oclose(hid_t object_id); +H5_DLL herr_t H5Oincr_refcount(hid_t object_id); +H5_DLL herr_t H5Odecr_refcount(hid_t object_id); + #ifdef __cplusplus } #endif diff --git a/src/H5Oshared.c b/src/H5Oshared.c index 226f300..367e001 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -155,9 +155,9 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adj * object header. */ if(shared->oloc.file->shared != f->shared) - HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "interfile hard links are not allowed") if((ret_value = H5O_link(&(shared->oloc), adjust, dxpl_id)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count") + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count") done: FUNC_LEAVE_NOAPI(ret_value) @@ -370,7 +370,7 @@ H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) /* Decrement the reference count on the shared object, if requested */ if(adj_link) if(H5O_shared_link_adj(f, dxpl_id, shared, -1)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count") + HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count") done: FUNC_LEAVE_NOAPI(ret_value); @@ -406,7 +406,7 @@ H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg) /* Decrement the reference count on the shared object */ if(H5O_shared_link_adj(f,dxpl_id,shared,1)<0) - HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count"); + HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count"); done: FUNC_LEAVE_NOAPI(ret_value); @@ -30,6 +30,7 @@ #include "H5Fprivate.h" /* Files */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppkg.h" /* Property lists */ @@ -57,6 +58,7 @@ hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL; hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL; hid_t H5P_CLS_OBJECT_COPY_g = FAIL; hid_t H5P_CLS_LINK_CREATE_g = FAIL; +hid_t H5P_CLS_LINK_ACCESS_g = FAIL; hid_t H5P_CLS_STRING_CREATE_g = FAIL; /* @@ -77,6 +79,7 @@ hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL; hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL; hid_t H5P_LST_OBJECT_COPY_g = FAIL; hid_t H5P_LST_LINK_CREATE_g = FAIL; +hid_t H5P_LST_LINK_ACCESS_g = FAIL; /* Track the revision count of a class, to make comparisons faster */ static unsigned H5P_next_rev=0; @@ -233,6 +236,13 @@ H5P_init_interface(void) { H5P_genclass_t *root_class; /* Pointer to root property list class created */ H5P_genclass_t *pclass; /* Pointer to property list class to create */ + /* Link access property class variables. In sequence, they are, + * - Access property list class to modify + * - Default value for "user-supplied data" + * - Default value for "max number of soft links to traverse" + */ + H5P_genclass_t *lacc_class; /* Pointer to link access property list class created */ + int nlinks = H5L_NLINKS_DEF; /* Group creation property class variables. In sequence, they are, * - Creation property list class to modify * - Default value for "group info" @@ -314,6 +324,28 @@ H5P_init_interface(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") } /* end if */ + /* Create link property classes (which need to be inherited by later classes */ + /* Allocate the link access class */ + HDassert(H5P_CLS_LINK_ACCESS_g == (-1)); + if(NULL == (lacc_class = H5P_create_class(root_class, "link access", 1, NULL, NULL, NULL, NULL, NULL, NULL))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed") + + /* Register the link access class */ + if((H5P_CLS_LINK_ACCESS_g = H5I_register(H5I_GENPROP_CLS, lacc_class)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class") + + /* Get the number of properties in the class */ + if(H5P_get_nprops_pclass(lacc_class, &nprops, FALSE) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") + + /* Assume that if there are properties in the class, they are the default ones */ + if(nprops == 0) { + /* Register property for number of links traversed */ + if(H5P_register(lacc_class, H5L_NLINKS_NAME, H5L_NLINKS_SIZE, + &nlinks, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + } /* end if */ + /* Register the group creation and group access property classes */ /* (Register the group property classes before file property classes, so * file creation property class can inherit from group creation property @@ -344,7 +376,7 @@ H5P_init_interface(void) /* Allocate the group access class */ HDassert(H5P_CLS_GROUP_ACCESS_g == (-1)); - if(NULL == (pclass = H5P_create_class(root_class, "group access", 1, NULL, NULL, NULL, NULL, NULL, NULL))) + if(NULL == (pclass = H5P_create_class(lacc_class, "group access", 1, NULL, NULL, NULL, NULL, NULL, NULL))) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); /* Register the group access class */ @@ -384,7 +416,7 @@ H5P_init_interface(void) /* Allocate the dataset access class */ assert(H5P_CLS_DATASET_ACCESS_g==(-1)); - if (NULL==(pclass = H5P_create_class (root_class,"dataset access",1,NULL,NULL,NULL,NULL,NULL,NULL))) + if (NULL==(pclass = H5P_create_class (lacc_class,"dataset access",1,NULL,NULL,NULL,NULL,NULL,NULL))) HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); /* Register the dataset access class */ @@ -424,7 +456,7 @@ H5P_init_interface(void) /* Allocate the datatype access class */ assert(H5P_CLS_DATATYPE_ACCESS_g==(-1)); - if (NULL==(pclass = H5P_create_class (root_class,"datatype access",1,NULL /*H5T_acs_create*/,NULL,NULL /*H5T_acs_copy*/,NULL,NULL /*H5T_acs_close*/,NULL))) + if (NULL==(pclass = H5P_create_class (lacc_class,"datatype access",1,NULL /*H5T_acs_create*/,NULL,NULL /*H5T_acs_copy*/,NULL,NULL /*H5T_acs_close*/,NULL))) HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); /* Register the datatype access class */ @@ -536,6 +568,7 @@ H5P_term_interface(void) H5P_LST_ATTRIBUTE_CREATE_g = H5P_LST_OBJECT_COPY_g = H5P_LST_LINK_CREATE_g = + H5P_LST_LINK_ACCESS_g = H5P_LST_MOUNT_g = (-1); } /* end if */ } /* end if */ @@ -561,6 +594,7 @@ H5P_term_interface(void) H5P_CLS_ATTRIBUTE_CREATE_g = H5P_CLS_OBJECT_COPY_g = H5P_CLS_LINK_CREATE_g = + H5P_CLS_LINK_ACCESS_g = H5P_CLS_MOUNT_g = (-1); } /* end if */ } /* end if */ diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c index 6e883e5..b78bc2b 100644 --- a/src/H5Pgcpl.c +++ b/src/H5Pgcpl.c @@ -292,5 +292,7 @@ H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /*out*/, unsigned done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_est_link_info() */ + + #endif /* H5_GROUP_REVISION */ diff --git a/src/H5Plapl.c b/src/H5Plapl.c new file mode 100644 index 0000000..cfe6b50 --- /dev/null +++ b/src/H5Plapl.c @@ -0,0 +1,117 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5P_PACKAGE /*suppress error about including H5Ppkg */ + +/* Private header files */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ +#include "H5Ppkg.h" /* Property lists */ + +/* Local datatypes */ + +/* Static function prototypes */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_nlinks + * + * Purpose: Set the number of soft or UD link traversals allowed before + * the library assumes it has found a cycle and aborts the + * traversal. + * + * The limit on soft or UD link traversals is designed to + * terminate link traversal if one or more links form a cycle. + * However, users may have a file with a legitimate path + * formed of a large number of soft or user-defined links. + * This property can be used to allow traversal of as many + * links as desired. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Friday, July 14, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_nlinks(hid_t plist_id, size_t nlinks) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pset_nlinks, FAIL) + H5TRACE2("e","iz",plist_id,nlinks); + + if(nlinks <= 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of links must be positive"); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set number of links */ + if(H5P_set(plist, H5L_NLINKS_NAME, &nlinks) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_nlinks() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_nlinks + * + * Purpose: Get the number of soft or UD traversals allowed when using + * this property list. + * Purpose: Gets the number of soft or user-defined links that can be + * traversed before a failure occurs. + * + * Retrieves the current setting for the nlinks property on + * the given property list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Friday, July 14, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_nlinks(hid_t plist_id, size_t *nlinks) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pget_nlinks, FAIL) + H5TRACE2("e","i*z",plist_id,nlinks); + + if(!nlinks) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer passed in"); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the current number of links */ + if(H5P_get(plist, H5L_NLINKS_NAME, nlinks) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links") + +done: + FUNC_LEAVE_API(ret_value) +} + + diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index b8f5edb..589b30c 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -96,6 +96,7 @@ typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); #define H5P_ATTRIBUTE_CREATE (H5OPEN H5P_CLS_ATTRIBUTE_CREATE_g) #define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_g) #define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_g) +#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_g) H5_DLLVAR hid_t H5P_CLS_NO_CLASS_g; H5_DLLVAR hid_t H5P_CLS_OBJECT_CREATE_g; H5_DLLVAR hid_t H5P_CLS_FILE_CREATE_g; @@ -112,6 +113,7 @@ H5_DLLVAR hid_t H5P_CLS_STRING_CREATE_g; H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_CREATE_g; H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_g; H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g; +H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_g; /* * The library created default property lists @@ -135,6 +137,7 @@ H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g; #define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_g) #define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_g) #define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_g) +#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_g) H5_DLLVAR hid_t H5P_LST_NO_CLASS_g; H5_DLLVAR hid_t H5P_LST_FILE_CREATE_g; H5_DLLVAR hid_t H5P_LST_FILE_ACCESS_g; @@ -149,6 +152,7 @@ H5_DLLVAR hid_t H5P_LST_DATATYPE_ACCESS_g; H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_CREATE_g; H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_g; H5_DLLVAR hid_t H5P_LST_LINK_CREATE_g; +H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_g; /* Public functions */ H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, @@ -357,8 +361,12 @@ H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* H5_DLL herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding); H5_DLL herr_t H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/); + #endif /* H5_GROUP_REVISION */ +H5_DLL herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks); +H5_DLL herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks); + H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd); H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/); @@ -156,7 +156,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5 H5G_loc_reset(&obj_loc); /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc, dxpl_id) < 0) + if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") obj_found = TRUE; @@ -733,6 +733,7 @@ H5T_init_interface(void) herr_t status; unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */ H5P_genclass_t *crt_pclass; /* Property list class for datatype creation properties */ + H5P_genclass_t *acc_pclass; /* Property list class for datatype access properties */ herr_t ret_value=SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5T_init_interface); @@ -1325,6 +1326,20 @@ H5T_init_interface(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") } /* end if */ + /* ========== Datatype Access Property Class Initialization ============*/ + assert(H5P_CLS_DATATYPE_ACCESS_g!=-1); + + /* Get the pointer to dataset access class */ + if(NULL == (acc_pclass = H5I_object(H5P_CLS_DATATYPE_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + + /* Only register the default property list if it hasn't been created yet */ + if(H5P_LST_DATATYPE_ACCESS_g == (-1)) { + /* Register the default dataset access property list */ + if((H5P_LST_DATATYPE_ACCESS_g = H5P_create_id(acc_pclass))<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class") + } /* end if */ + done: /* General cleanup */ if (compound!=NULL) diff --git a/src/H5Tbit.c b/src/H5Tbit.c index d298d4c..6ae8836 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -265,7 +265,8 @@ H5T_bit_get_d (uint8_t *buf, size_t offset, size_t size) break; default: - HDabort (); + /* Unknown endianness. Bail out. */ + return -1; } /* Set return value */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index e842c78..cccee9e 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -108,13 +108,13 @@ H5Tcommit(hid_t loc_id, const char *name, hid_t type_id) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") if(H5G_loc(type_id, &type_loc) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get committed datatype's location") + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get committed datatype's location") /* Link the type into the group hierarchy */ - if( H5L_link(&loc, name, &type_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) + if( H5L_link(&loc, name, &type_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) { uncommit = TRUE; /* Linking failed, and we need to undo H5T_commit. */ - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to type") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to type") } done: @@ -182,14 +182,12 @@ H5Tcommit_expand(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) if(TRUE != H5P_isa_class(tcpl_id, H5P_DATATYPE_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype create property list") -#ifdef LATER /* Get correct property list */ if(H5P_DEFAULT == tapl_id) tapl_id = H5P_DATATYPE_ACCESS_DEFAULT; else if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list") -#endif /* LATER */ /* Commit the type */ if(H5T_commit(loc.oloc->file, type, H5AC_dxpl_id, tcpl_id, tapl_id) < 0) @@ -384,7 +382,7 @@ H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id) /* Adjust the link count on the named datatype */ if((ret_value = H5O_link(&(type->oloc), adjust, dxpl_id)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count") + HGOTO_ERROR(H5E_DATATYPE, H5E_LINKCOUNT, FAIL, "unable to adjust named datatype link count") done: FUNC_LEAVE_NOAPI(ret_value) @@ -435,7 +433,7 @@ H5Topen(hid_t loc_id, const char *name) * Find the named datatype object header and read the datatype message * from it. */ - if(H5G_loc_find(&loc, name, &type_loc/*out*/, dxpl_id) < 0) + if(H5G_loc_find(&loc, name, &type_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found") obj_found = TRUE; @@ -466,6 +464,87 @@ done: /*------------------------------------------------------------------------- + * Function: H5Topen_expand + * + * Purpose: Opens a named datatype using a Datatype Access Property + * List. + * + * Return: Success: Object ID of the named datatype. + * Failure: Negative + * + * Programmer: James Laird + * Thursday July 27, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Topen_expand(hid_t loc_id, const char *name, hid_t tapl_id) +{ + H5T_t *type = NULL; + H5G_loc_t loc; + H5G_name_t path; /* Datatype group hier. path */ + H5O_loc_t oloc; /* Datatype object location */ + H5G_loc_t type_loc; /* Group object for datatype */ + hbool_t obj_found = FALSE; /* Object at 'name' found */ + hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */ + hid_t ret_value = FAIL; + + FUNC_ENTER_API(H5Topen_expand, FAIL) + H5TRACE3("i","isi",loc_id,name,tapl_id); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Get correct property list */ + if(H5P_DEFAULT == tapl_id) + tapl_id = H5P_DATATYPE_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list") + + /* Set up datatype location to fill in */ + type_loc.oloc = &oloc; + type_loc.path = &path; + H5G_loc_reset(&type_loc); + + /* + * Find the named datatype object header and read the datatype message + * from it. + */ + if(H5G_loc_find(&loc, name, &type_loc/*out*/, tapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found") + obj_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&oloc, dxpl_id) != H5G_TYPE) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a named datatype") + + /* Open it */ + if((type = H5T_open(&type_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype") + + /* Register the type and return the ID */ + if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype") + +done: + if(ret_value < 0) { + if(type != NULL) + H5T_close(type); + else { + if(obj_found && H5F_addr_defined(type_loc.oloc->addr)) + H5G_name_free(type_loc.path); + } /* end else */ + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5T_open * * Purpose: Open a named datatype. diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 51da42a..44daec2 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -497,6 +497,7 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST64_g; /* Operations defined on all datatypes */ H5_DLL hid_t H5Topen(hid_t loc_id, const char *name); +H5_DLL hid_t H5Topen_expand(hid_t loc_id, const char *name, hid_t tapl_id); H5_DLL hid_t H5Tcreate(H5T_class_t type, size_t size); H5_DLL hid_t H5Tcopy(hid_t type_id); H5_DLL herr_t H5Tclose(hid_t type_id); diff --git a/src/H5err.txt b/src/H5err.txt index 25accb7..d7b4ac7 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -52,6 +52,7 @@ MAJOR, H5E_IO, Low-level I/O MAJOR, H5E_FUNC, Function entry/exit MAJOR, H5E_ATOM, Object atom MAJOR, H5E_CACHE, Object cache +MAJOR, H5E_LINK, Links MAJOR, H5E_BTREE, B-Tree node MAJOR, H5E_SYM, Symbol table MAJOR, H5E_HEAP, Heap @@ -81,6 +82,7 @@ SECTION, FILE, Generic low-level file I/O errors SECTION, FUNC, Function entry/exit interface errors SECTION, ATOM, Object atom related errors SECTION, CACHE, Cache related errors +SECTION, LINK, Link related errors SECTION, BTREE, B-tree related errors SECTION, OHDR, Object header related errors SECTION, GROUP, Group related errors @@ -190,8 +192,6 @@ MINOR, OHDR, H5E_CANTPACK, Can't pack messages MINOR, GROUP, H5E_CANTOPENOBJ, Can't open object MINOR, GROUP, H5E_CANTCLOSEOBJ, Can't close object MINOR, GROUP, H5E_COMPLEN, Name component is too long -MINOR, GROUP, H5E_LINK, Link failure -MINOR, GROUP, H5E_SLINK, Symbolic link error MINOR, GROUP, H5E_PATH, Problem with path to object # Datatype conversion errors @@ -211,6 +211,13 @@ MINOR, PLIST, H5E_CANTGET, Can't get value MINOR, PLIST, H5E_CANTSET, Can't set value MINOR, PLIST, H5E_DUPCLASS, Duplicate class name in parent class +# Link errors +MINOR, LINK, H5E_TRAVERSE, Link traversal failure +MINOR, LINK, H5E_NLINKS, Too many soft links in path +MINOR, LINK, H5E_NOTREGISTERED, Link class not registered +MINOR, LINK, H5E_CANTMOVE, Move callback returned error + + # Parallel MPI errors MINOR, MPI, H5E_MPI, Some MPI function failed MINOR, MPI, H5E_MPIERRSTR, MPI Error String diff --git a/src/H5private.h b/src/H5private.h index c216f92..9dd989d 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1439,6 +1439,7 @@ H5_DLL int H5F_term_interface(void); H5_DLL int H5FS_term_interface(void); H5_DLL int H5G_term_interface(void); H5_DLL int H5I_term_interface(void); +H5_DLL int H5L_term_interface(void); H5_DLL int H5P_term_interface(void); H5_DLL int H5R_term_interface(void); H5_DLL int H5S_term_interface(void); diff --git a/src/Makefile.am b/src/Makefile.am index 55edb50..4b7995d 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -55,12 +55,12 @@ libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ - H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ + H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c \ - H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ + H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ H5Sselect.c H5Stest.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 2cb791f..fe6bfd5 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -90,19 +90,20 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \ H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo \ H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \ - H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \ - H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo H5Gloc.lo H5Gname.lo \ - H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \ - H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ - H5HFdtable.lo H5HFhdr.lo H5HFiblock.lo H5HFint.lo H5HFiter.lo \ - H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HG.lo \ - H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo \ - H5MP.lo H5MPtest.lo H5L.lo H5O.lo H5Oattr.lo H5Obogus.lo \ - H5Ocache.lo H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ - H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omtime.lo \ - H5Oname.lo H5Onull.lo H5Opline.lo H5Osdspace.lo H5Oshared.lo \ - H5Ostab.lo H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo \ - H5Pfcpl.lo H5Pgcpl.lo H5Plcpl.lo H5Pocpl.lo H5Pstrcpl.lo \ + H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ + H5FSsection.lo H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo \ + H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo \ + H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo \ + H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFiblock.lo \ + H5HFint.lo H5HFiter.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo \ + H5HFtest.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo \ + H5I.lo H5MF.lo H5MM.lo H5MP.lo H5MPtest.lo H5L.lo \ + H5Lexternal.lo H5O.lo H5Oattr.lo H5Obogus.lo H5Ocache.lo \ + H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ + H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omtime.lo H5Oname.lo \ + H5Onull.lo H5Opline.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \ + H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \ + H5Pgcpl.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pstrcpl.lo \ H5Ptest.lo H5R.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Shyper.lo \ H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo \ H5SL.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \ @@ -402,12 +403,12 @@ libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ - H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ + H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c \ - H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ + H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ H5Sselect.c H5Stest.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ @@ -590,8 +591,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FS.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FScache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSdbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSsection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@ @@ -627,6 +628,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MM.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MP.Plo@am__quote@ @@ -657,6 +659,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pgcpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pstrcpl.Plo@am__quote@ diff --git a/test/Makefile.am b/test/Makefile.am index afadd52..4e7818b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -58,16 +58,14 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat testmeta # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. +BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \ + gen_new_group gen_new_mtime gen_new_super gen_noencoder \ + gen_nullspace space_overflow gen_cross gen_udlinks + if BUILD_ALL_CONDITIONAL - BUILD_ALL_PROGS=gen_deflate gen_filters gen_new_array gen_new_fill \ - gen_new_group gen_new_mtime gen_new_super gen_noencoder \ - gen_nullspace space_overflow gen_cross -else - BUILD_ALL_PROGS= + noinst_PROGRAMS=$(BUILD_ALL_PROGS) endif -noinst_PROGRAMS=$(BUILD_ALL_PROGS) - # The libh5test library provides common support code for the tests. noinst_LTLIBRARIES=libh5test.la libh5test_la_SOURCES=h5test.c testframe.c cache_common.c @@ -118,7 +116,7 @@ CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \ - th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \ + th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \ tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c include $(top_srcdir)/config/conclude.am diff --git a/test/Makefile.in b/test/Makefile.in index 5339b48..7934415 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -31,7 +31,7 @@ # -SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c +SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fheap.c fillval.c flush1.c flush2.c gen_cross.c gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -60,7 +60,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/config/conclude.am check_PROGRAMS = $(am__EXEEXT_1) error_test$(EXEEXT) \ err_compat$(EXEEXT) testmeta$(EXEEXT) -noinst_PROGRAMS = $(am__EXEEXT_2) +@BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2) subdir = test ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in @@ -85,17 +85,12 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \ getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \ dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \ fheap$(EXEEXT) btree2$(EXEEXT) -@BUILD_ALL_CONDITIONAL_TRUE@am__EXEEXT_2 = gen_deflate$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_filters$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_array$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_fill$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_mtime$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_super$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_noencoder$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ space_overflow$(EXEEXT) \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_cross$(EXEEXT) +am__EXEEXT_2 = gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \ + gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \ + gen_new_group$(EXEEXT) gen_new_mtime$(EXEEXT) \ + gen_new_super$(EXEEXT) gen_noencoder$(EXEEXT) \ + gen_nullspace$(EXEEXT) space_overflow$(EXEEXT) \ + gen_cross$(EXEEXT) gen_udlinks$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) big_SOURCES = big.c big_OBJECTS = big.$(OBJEXT) @@ -222,6 +217,10 @@ gen_nullspace_SOURCES = gen_nullspace.c gen_nullspace_OBJECTS = gen_nullspace.$(OBJEXT) gen_nullspace_LDADD = $(LDADD) gen_nullspace_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1) +gen_udlinks_SOURCES = gen_udlinks.c +gen_udlinks_OBJECTS = gen_udlinks.$(OBJEXT) +gen_udlinks_LDADD = $(LDADD) +gen_udlinks_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1) getname_SOURCES = getname.c getname_OBJECTS = getname.$(OBJEXT) getname_LDADD = $(LDADD) @@ -292,12 +291,12 @@ stream_test_LDADD = $(LDADD) stream_test_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1) am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) tarray.$(OBJEXT) \ tattr.$(OBJEXT) tconfig.$(OBJEXT) tfile.$(OBJEXT) \ - tgenprop.$(OBJEXT) th5s.$(OBJEXT) theap.$(OBJEXT) \ - tid.$(OBJEXT) titerate.$(OBJEXT) tmeta.$(OBJEXT) \ - tmisc.$(OBJEXT) ttime.$(OBJEXT) trefer.$(OBJEXT) \ - trefstr.$(OBJEXT) tselect.$(OBJEXT) tskiplist.$(OBJEXT) \ - ttst.$(OBJEXT) tunicode.$(OBJEXT) tvltypes.$(OBJEXT) \ - tvlstr.$(OBJEXT) + tgenprop.$(OBJEXT) th5o.$(OBJEXT) th5s.$(OBJEXT) \ + theap.$(OBJEXT) tid.$(OBJEXT) titerate.$(OBJEXT) \ + tmeta.$(OBJEXT) tmisc.$(OBJEXT) ttime.$(OBJEXT) \ + trefer.$(OBJEXT) trefstr.$(OBJEXT) tselect.$(OBJEXT) \ + tskiplist.$(OBJEXT) ttst.$(OBJEXT) tunicode.$(OBJEXT) \ + tvltypes.$(OBJEXT) tvlstr.$(OBJEXT) testhdf5_OBJECTS = $(am_testhdf5_OBJECTS) testhdf5_LDADD = $(LDADD) testhdf5_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1) @@ -336,22 +335,24 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \ error_test.c extend.c external.c fheap.c fillval.c flush1.c \ flush2.c gen_cross.c gen_deflate.c gen_filters.c \ gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ - gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \ - gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \ - ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \ - space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \ - testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c + gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ + getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \ + mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \ + set_extent.c space_overflow.c stab.c stream_test.c \ + $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ + vfd.c DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \ cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \ dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \ error_test.c extend.c external.c fheap.c fillval.c flush1.c \ flush2.c gen_cross.c gen_deflate.c gen_filters.c \ gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \ - gen_new_super.c gen_noencoder.c gen_nullspace.c getname.c \ - gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \ - ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \ - space_overflow.c stab.c stream_test.c $(testhdf5_SOURCES) \ - testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c + gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \ + getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \ + mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \ + set_extent.c space_overflow.c stab.c stream_test.c \ + $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c \ + vfd.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -629,7 +630,6 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \ getname vfd ntypes dangle dtransform reserved cross_read \ fheap btree2 -@BUILD_ALL_CONDITIONAL_FALSE@BUILD_ALL_PROGS = # These programs generate test files for the tests. They don't need to be # compiled every time we want to test the library. However, putting @@ -638,9 +638,9 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \ # --enable-build-all at configure time. # The gen_old_* files can only be compiled with older versions of the library # so do not appear in this list. -@BUILD_ALL_CONDITIONAL_TRUE@BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_new_group gen_new_mtime gen_new_super gen_noencoder \ -@BUILD_ALL_CONDITIONAL_TRUE@ gen_nullspace space_overflow gen_cross +BUILD_ALL_PROGS = gen_deflate gen_filters gen_new_array gen_new_fill \ + gen_new_group gen_new_mtime gen_new_super gen_noencoder \ + gen_nullspace space_overflow gen_cross gen_udlinks # The libh5test library provides common support code for the tests. @@ -658,7 +658,7 @@ VFD_LIST = sec2 stdio core split multi family # Sources for testhdf5 executable testhdf5_SOURCES = testhdf5.c tarray.c tattr.c tconfig.c tfile.c tgenprop.c \ - th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \ + th5o.c th5s.c theap.c tid.c titerate.c tmeta.c tmisc.c ttime.c trefer.c trefstr.c \ tselect.c tskiplist.c ttst.c tunicode.c tvltypes.c tvlstr.c @@ -829,6 +829,9 @@ gen_noencoder$(EXEEXT): $(gen_noencoder_OBJECTS) $(gen_noencoder_DEPENDENCIES) gen_nullspace$(EXEEXT): $(gen_nullspace_OBJECTS) $(gen_nullspace_DEPENDENCIES) @rm -f gen_nullspace$(EXEEXT) $(LINK) $(gen_nullspace_LDFLAGS) $(gen_nullspace_OBJECTS) $(gen_nullspace_LDADD) $(LIBS) +gen_udlinks$(EXEEXT): $(gen_udlinks_OBJECTS) $(gen_udlinks_DEPENDENCIES) + @rm -f gen_udlinks$(EXEEXT) + $(LINK) $(gen_udlinks_LDFLAGS) $(gen_udlinks_OBJECTS) $(gen_udlinks_LDADD) $(LIBS) getname$(EXEEXT): $(getname_OBJECTS) $(getname_DEPENDENCIES) @rm -f getname$(EXEEXT) $(LINK) $(getname_LDFLAGS) $(getname_OBJECTS) $(getname_LDADD) $(LIBS) @@ -934,6 +937,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_new_super.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_noencoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_nullspace.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_udlinks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getname.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gheap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5test.Plo@am__quote@ @@ -960,6 +964,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testmeta.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tgenprop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5o.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/theap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tid.Po@am__quote@ diff --git a/test/be_extlink1.h5 b/test/be_extlink1.h5 Binary files differnew file mode 100644 index 0000000..dedd0a5 --- /dev/null +++ b/test/be_extlink1.h5 diff --git a/test/be_extlink2.h5 b/test/be_extlink2.h5 Binary files differnew file mode 100644 index 0000000..d6f9921 --- /dev/null +++ b/test/be_extlink2.h5 diff --git a/test/gen_udlinks.c b/test/gen_udlinks.c new file mode 100644 index 0000000..1230ffe --- /dev/null +++ b/test/gen_udlinks.c @@ -0,0 +1,81 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: James Laird <jlaird@hdfgroup.org> + * Tuesday, June 6, 2006 + * + * This program creates HDF5 files with user-defined links. These files + * should be created on a little-endian and a big-endian machine. + * They will be named according to the platform and should + * be placed in the hdf5/test directory so that the links test can use them. + */ + +#include "hdf5.h" +#include <string.h> + +#define NAME_LE_1 "le_extlink1.h5" +#define NAME_LE_2 "le_extlink2.h5" +#define NAME_BE_1 "be_extlink1.h5" +#define NAME_BE_2 "be_extlink2.h5" +#define NAME_BUF_SIZE 25 + +int +main (void) +{ + hid_t fid1=-1; + hid_t fid2=-1; + hid_t gid=-1; + char filename1[NAME_BUF_SIZE]; + char filename2[NAME_BUF_SIZE]; + + /* Name the files differently depending on the endianness of this platform */ + + switch(H5Tget_order(H5T_NATIVE_INT)) + { + case H5T_ORDER_LE: + strcpy(filename1, NAME_LE_1); + strcpy(filename2, NAME_LE_2); + break; + case H5T_ORDER_BE: + strcpy(filename1, NAME_BE_1); + strcpy(filename2, NAME_BE_2); + break; + default: + goto error; + } + + /* Create the two files */ + if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; + if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto error; + + /* Create two groups in the second file */ + if((gid = H5Gcreate(fid2, "group", 0)) < 0) goto error; + if((H5Gclose(gid)) < 0) goto error; + if((gid = H5Gcreate(fid2, "group/subgroup", 0)) < 0) goto error; + if((H5Gclose(gid)) < 0) goto error; + + /* Create an external link in the first file pointing to the group in the second file */ + if(H5Lcreate_external(filename2, "group", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error; + + return 0; + +error: + H5E_BEGIN_TRY { + H5Fclose(fid1); + H5Fclose(fid2); + H5Gclose(gid); + } H5E_END_TRY + return 1; +} diff --git a/test/le_extlink1.h5 b/test/le_extlink1.h5 Binary files differnew file mode 100644 index 0000000..877ba37 --- /dev/null +++ b/test/le_extlink1.h5 diff --git a/test/le_extlink2.h5 b/test/le_extlink2.h5 Binary files differnew file mode 100644 index 0000000..d6f9921 --- /dev/null +++ b/test/le_extlink2.h5 diff --git a/test/links.c b/test/links.c index 0e4f680..92f4984 100644 --- a/test/links.c +++ b/test/links.c @@ -16,34 +16,23 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Friday, April 10, 1998 * - * Purpose: Tests hard and soft (symbolic) links. + * Purpose: Tests hard, soft (symbolic) & external links. */ -#define H5G_PACKAGE /*suppress error about including H5Gpkg */ - -/* Define this macro to indicate that the testing APIs should be available */ -#define H5G_TESTING +#include "H5Lprivate.h" #include "h5test.h" -#include "H5Gpkg.h" /* Groups */ const char *FILENAME[] = { "links0", "links1", "links2", "links3", - "links4", + "links4a", + "links4b", + "links4c", + "links4d", "links5", - "links6", - "links7", - "links8", - "links9", - "links10", - "links11", - "links12", - "links13", - "links14", - "links15", NULL }; @@ -51,6 +40,27 @@ const char *FILENAME[] = { #define NAME_BUF_SIZE 1024 #define MAX_NAME_LEN ((64*1024)+1024) +/* Link type IDs */ +#define UD_HARD_TYPE 201 +#define UD_CB_TYPE H5L_LINK_MAX +#define UD_PLIST_TYPE 128 +#define UD_CBFAIL_TYPE UD_PLIST_TYPE +#define UD_ERROR_TYPE 189 +#define UD_BAD_TYPE1 H5G_LINK_HARD +#define UD_BAD_TYPE2 (H5L_LINK_UD_MIN - 5) +#define UD_BAD_VERS (H5L_LINK_CLASS_T_VERS + 1) + +#define DEST_PROP_NAME "destination_group" +#define REREG_TARGET_NAME "rereg_target" + +#define UD_CB_LINK_NAME "ud_callback_link" +#define NEW_UD_CB_LINK_NAME "ud_callback_link2" +#define UD_CB_TARGET "ud_target" +#define UD_CB_TARGET_LEN 10 + +#define LE_FILENAME "le_extlink1.h5" +#define BE_FILENAME "be_extlink1.h5" + #define H5L_DIM1 100 #define H5L_DIM2 100 @@ -94,16 +104,16 @@ mklinks(hid_t fapl) if (H5Dclose (d1)<0) TEST_ERROR; /* Create a hard link */ - if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT)<0) TEST_ERROR; + if (H5Lcreate_hard (file, "d1", H5L_SAME_LOC, "grp1/hard", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Create a symbolic link */ - if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT)<0) TEST_ERROR; + if (H5Lcreate_soft ("/d1", file, "grp1/soft", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Create a symbolic link to something that doesn't exist */ - if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT)<0) TEST_ERROR; + if (H5Lcreate_soft ("foobar", file, "grp1/dangle", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Create a recursive symbolic link */ - if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT)<0) TEST_ERROR; + if (H5Lcreate_soft ("/grp1/recursive", file, "/grp1/recursive", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Close */ if (H5Sclose (scalar)<0) TEST_ERROR; @@ -167,22 +177,22 @@ new_links(hid_t fapl) /* Create links within a file. Both of source and destination use * H5L_SAME_LOC. Both hard and soft links should fail. */ H5E_BEGIN_TRY { - if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR; + if(H5Lcreate_hard(H5L_SAME_LOC, "dataset1", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR; } H5E_END_TRY; H5E_BEGIN_TRY { - if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT)!=FAIL) TEST_ERROR; + if(H5Lcreate_soft("dataset1", H5L_SAME_LOC, "soft", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR; } H5E_END_TRY; /* Create links across files with hard link. Should fail. */ H5E_BEGIN_TRY { - if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT)!=FAIL) TEST_ERROR; + if(H5Lcreate_hard(file_a, "dataset1", file_b, "hard", H5P_DEFAULT, H5P_DEFAULT)!=FAIL) TEST_ERROR; } H5E_END_TRY; /* Create hard link to test H5L_SAME_LOC */ - if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT)<0) TEST_ERROR; + if(H5Lcreate_hard(grp1_a, "dataset2", H5L_SAME_LOC, "hard1", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Create links to test hard links across different locations */ - if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT)<0) TEST_ERROR; + if(H5Lcreate_hard(grp1_a, "dataset2", grp2_a, "hard2", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Close dataspace and files */ if (H5Sclose (scalar)<0) TEST_ERROR; @@ -274,7 +284,7 @@ cklinks(hid_t fapl) puts(" expected file location."); TEST_ERROR; } - if (H5Gget_linkval(file, "grp1/soft", sizeof linkval, linkval)<0) TEST_ERROR; + if (H5Lget_linkval(file, "grp1/soft", sizeof linkval, linkval, H5P_DEFAULT)<0) TEST_ERROR; if (HDstrcmp(linkval, "/d1")) { H5_FAILED(); puts(" Soft link test failed. Wrong link value"); @@ -431,7 +441,7 @@ long_links(hid_t fapl) TESTING("long names for objects & links"); /* Create files */ - h5_fixname(FILENAME[13], fapl, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; /* Create group with short name in file (used as target for hard links) */ @@ -444,11 +454,11 @@ long_links(hid_t fapl) objname[MAX_NAME_LEN] = '\0'; /* Create hard link to existing object */ - if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* Create soft link to existing object */ objname[0] = 'b'; - if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* Create group with long name in existing group */ if((gid2=H5Gcreate(gid, objname, (size_t)0))<0) TEST_ERROR; @@ -495,8 +505,7 @@ static int toomany(hid_t fapl) { hid_t fid = (-1); /* File ID */ - hid_t gid = (-1); /* Group ID */ - hid_t gid2 = (-1); /* Datatype ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ char objname[NAME_BUF_SIZE]; /* Object name */ ssize_t name_len; /* Length of object name */ char filename[NAME_BUF_SIZE]; @@ -509,54 +518,54 @@ toomany(hid_t fapl) */ HDassert(H5G_NLINKS == 16); - /* Create files */ - h5_fixname(FILENAME[14], fapl, filename, sizeof filename); + /* Create file */ + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; /* Create group with short name in file (used as target for hard links) */ if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR; /* Create chain of hard links to existing object (no limit on #) */ - if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "final", fid, "hard1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard1", fid, "hard2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard2", fid, "hard3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard3", fid, "hard4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard4", fid, "hard5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard5", fid, "hard6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard6", fid, "hard7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard7", fid, "hard8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard8", fid, "hard9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard9", fid, "hard10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard10", fid, "hard11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard11", fid, "hard12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard12", fid, "hard13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard13", fid, "hard14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard14", fid, "hard15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard15", fid, "hard16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard16", fid, "hard17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard17", fid, "hard18", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard18", fid, "hard19", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard19", fid, "hard20", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(fid, "hard20", fid, "hard21", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* Create chain of soft links to existing object (limited) */ - if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("final", fid, "soft1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft1", fid, "soft2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft2", fid, "soft3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft3", fid, "soft4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft4", fid, "soft5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft5", fid, "soft6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft6", fid, "soft7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft7", fid, "soft8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft8", fid, "soft9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft9", fid, "soft10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft10", fid, "soft11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft11", fid, "soft12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft12", fid, "soft13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft13", fid, "soft14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft14", fid, "soft15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft15", fid, "soft16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_soft("soft16", fid, "soft17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* Close objects */ if(H5Gclose(gid)<0) TEST_ERROR; @@ -598,16 +607,14 @@ toomany(hid_t fapl) if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR if(HDstrcmp(objname, "/soft16")) TEST_ERROR - /* Create object in external file */ + /* Create object using soft links */ if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR - /* Close group in external file */ + /* Close groups */ if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR - /* Close external object */ - if(H5Gclose(gid) < 0) TEST_ERROR; - - /* Close first file */ + /* Close file */ if(H5Fclose(fid)<0) TEST_ERROR; PASSED(); @@ -642,7 +649,6 @@ toomany(hid_t fapl) static int test_h5l_create(hid_t fapl) { - hid_t fapl_id=-1; hid_t file_id=-1; hid_t group_id=-1; hid_t space_id=-1; @@ -654,13 +660,12 @@ test_h5l_create(hid_t fapl) int i, n, j; int wdata[H5L_DIM1][H5L_DIM2]; int rdata[H5L_DIM1][H5L_DIM2]; - TESTING("H5Lcreate"); + TESTING("H5Llink"); /* Create file */ - fapl_id = h5_fileaccess(); - h5_fixname(FILENAME[3], fapl_id, filename, sizeof filename); + h5_fixname(FILENAME[3], fapl, filename, sizeof filename); - if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR; + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; /* Create and commit a datatype with no name */ if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; @@ -672,7 +677,7 @@ test_h5l_create(hid_t fapl) dims[1] = H5L_DIM2; if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR; /* Create a dataset with no name using the committed datatype*/ - if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT)) <0) TEST_ERROR; + if ((dset_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR; /* Verify that we can write to and read from the dataset */ /* Initialize the dataset */ @@ -699,14 +704,14 @@ test_h5l_create(hid_t fapl) if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; /* Link nameless datatype into nameless group */ - if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT)<0) TEST_ERROR; + if(H5Llink(group_id, "datatype", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Create LCPL with intermediate group creation flag set */ if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR; if(H5Pset_create_intermediate_group(lcpl_id, TRUE) <0) TEST_ERROR; /* Link nameless dataset into nameless group with intermediate group */ - if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id)<0) TEST_ERROR; + if(H5Llink(group_id, "inter_group/dataset", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR; /* Close IDs for dataset and datatype */ if(H5Dclose(dset_id)<0) TEST_ERROR; @@ -716,7 +721,7 @@ test_h5l_create(hid_t fapl) if((type_id = H5Topen(group_id, "datatype"))<0) TEST_ERROR; /* Link nameless group to root group and close the group ID*/ - if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR; + if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; if(H5Gclose(group_id)<0) TEST_ERROR; /* Open dataset through root group and verify its data */ @@ -738,7 +743,6 @@ test_h5l_create(hid_t fapl) if(H5Pclose(lcpl_id)<0) TEST_ERROR; if(H5Sclose(space_id)<0) TEST_ERROR; if(H5Fclose(file_id)<0) TEST_ERROR; - if(H5Pclose(fapl_id)<0) TEST_ERROR; PASSED(); return 0; @@ -750,7 +754,6 @@ error: H5Pclose(lcpl_id); H5Sclose(space_id); H5Fclose(file_id); - H5Pclose(fapl_id); } H5E_END_TRY; return 1; } /* end test_h5l_create() */ @@ -791,27 +794,27 @@ test_lcpl(hid_t fapl) /* Create file */ fapl_id = h5_fileaccess(); - h5_fixname(FILENAME[12], fapl_id, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR; /* Create and link a group with the default LCPL */ if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; - if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT)<0) TEST_ERROR; + if(H5Llink(file_id, "/group", group_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; if(H5Gclose(group_id)<0) TEST_ERROR; /* Check that its character encoding is the default */ - if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR; /* Create and commit a datatype with the default LCPL */ if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT)<0) TEST_ERROR; + if(H5Llink(file_id, "/type", type_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; if(H5Tclose(type_id)<0) TEST_ERROR; /* Check that its character encoding is the default */ - if(H5Lget_linkinfo(file_id, "type", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "type", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR; /* Create a dataspace */ @@ -820,12 +823,12 @@ test_lcpl(hid_t fapl) if((space_id=H5Screate_simple(2 ,dims, NULL))<0) TEST_ERROR; /* Create a dataset using the default LCPL */ - if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR; - if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT)<0) TEST_ERROR; + if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR; + if(H5Llink(file_id, "/dataset", dset_id, H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; if(H5Dclose(dset_id)<0) TEST_ERROR; /* Check that its character encoding is the default */ - if(H5Lget_linkinfo(file_id, "dataset", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "dataset", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5F_CRT_DEFAULT_CSET) TEST_ERROR; /* Create a link creation property list with the UTF-8 character encoding */ @@ -834,30 +837,30 @@ test_lcpl(hid_t fapl) /* Create and link a group with the new LCPL */ if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; - if(H5Llink(file_id, "/group2", group_id, lcpl_id)<0) TEST_ERROR; + if(H5Llink(file_id, "/group2", group_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR; if(H5Gclose(group_id)<0) TEST_ERROR; /* Check that its character encoding is UTF-8 */ - if(H5Lget_linkinfo(file_id, "group2", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Create and commit a datatype with the new LCPL */ if((type_id =H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; if(H5Tcommit_expand(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; - if(H5Llink(file_id, "/type2", type_id, lcpl_id)<0) TEST_ERROR; + if(H5Llink(file_id, "/type2", type_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR; if(H5Tclose(type_id)<0) TEST_ERROR; /* Check that its character encoding is UTF-8 */ - if(H5Lget_linkinfo(file_id, "type2", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "type2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Create a dataset using the new LCPL */ - if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT)) <0) TEST_ERROR; - if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id)<0) TEST_ERROR; + if ((dset_id = H5Dcreate_expand(file_id, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR; + if(H5Llink(file_id, "/dataset2", dset_id, lcpl_id, H5P_DEFAULT)<0) TEST_ERROR; if(H5Dclose(dset_id)<0) TEST_ERROR; /* Check that its character encoding is UTF-8 */ - if(H5Lget_linkinfo(file_id, "dataset2", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Create a new link to the dataset with a different character encoding. */ @@ -865,15 +868,46 @@ test_lcpl(hid_t fapl) if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) <0) TEST_ERROR; if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR; - if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id) < 0) TEST_ERROR; + if(H5Lcreate_hard(file_id, "/dataset2", file_id, "/dataset2_link", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR; /* Check that its character encoding is ASCII */ - if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "/dataset2_link", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR; /* Check that the first link's encoding hasn't changed */ - if(H5Lget_linkinfo(file_id, "/dataset2", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "/dataset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; + + +/* JAMES: these tests don't work because the character set encoding is + * not stored in the symbol table. + * Quincey says this will be fixed someday. + */ +#ifdef NOTYET + /* Make sure that LCPLs work properly for other API calls: */ + /* H5Lcreate_soft */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR + if(H5Lcreate_soft("dataset2", file_id, "slink_to_dset2", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_linkinfo(file_id, "slink_to_dset2", &linfo, H5P_DEFAULT) < 0) TEST_ERROR + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR + + /* H5Lmove */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_ASCII) < 0) TEST_ERROR + if(H5Lmove(file_id, "slink_to_dset2", file_id, "moved_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_linkinfo(file_id, "moved_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; + if(linfo.cset != H5T_CSET_ASCII) TEST_ERROR; + + /* H5Lcopy */ + if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR; + if(H5Lcopy(file_id, "moved_slink", file_id, "copied_slink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_linkinfo(file_id, "copied_slink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; + if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; + + /* H5Lcreate_external */ + if(H5Lcreate_external("filename", "path", file_id, "extlink", lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lget_linkinfo(file_id, "extlink", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; +#endif /* NOTYET */ /* Close open IDs */ if(H5Pclose(lcpl_id)<0) TEST_ERROR; @@ -924,10 +958,10 @@ test_move(hid_t fapl) TESTING("H5Lmove"); /* Create two new files */ - h5_fixname(FILENAME[8], fapl, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; - h5_fixname(FILENAME[9], fapl, filename, sizeof filename); + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; @@ -937,26 +971,26 @@ test_move(hid_t fapl) if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) TEST_ERROR; /* Create hard and soft links. */ - if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0) + if(H5Lcreate_hard(grp_1, "group_move", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; - if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT)<0) + if(H5Lcreate_soft("/group1/group_move", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Move a group within the file. Both of source and destination use * H5L_SAME_LOC. Should fail. */ H5E_BEGIN_TRY { - if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT) + if(H5Lmove(H5L_SAME_LOC, "group_move", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) !=FAIL) TEST_ERROR; } H5E_END_TRY; /* Move a group across files. Should fail. */ H5E_BEGIN_TRY { - if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT) + if(H5Lmove(grp_1, "group_move", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) !=FAIL) TEST_ERROR; } H5E_END_TRY; /* Move a group across groups in the same file while renaming it. */ - if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT)<0) + if(H5Lmove(grp_1, "group_move", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group just moved to the new location. */ @@ -972,7 +1006,7 @@ test_move(hid_t fapl) } H5E_END_TRY; /* Use H5Lmove to rename a group without moving it. */ - if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0) + if(H5Lmove(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group. */ @@ -982,7 +1016,7 @@ test_move(hid_t fapl) TEST_ERROR; /* Use H5Lmove to move a group without renaming it. */ - if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0) + if(H5Lmove(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group . */ @@ -992,7 +1026,7 @@ test_move(hid_t fapl) TEST_ERROR; /* Move the group while giving long paths. */ - if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0) + if(H5Lmove(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group just moved to the new location. */ @@ -1063,10 +1097,10 @@ test_copy(hid_t fapl) TESTING("H5Lcopy"); /* Create two new files */ - h5_fixname(FILENAME[8], fapl, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if ((file_a=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; - h5_fixname(FILENAME[9], fapl, filename, sizeof filename); + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); if ((file_b=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; @@ -1076,26 +1110,26 @@ test_copy(hid_t fapl) if((grp_move=H5Gcreate(grp_1, "group_copy", 0))<0) TEST_ERROR; /* Create hard and soft links. */ - if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT)<0) + if(H5Lcreate_hard(grp_1, "group_copy", H5L_SAME_LOC, "hard", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; - if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT)<0) + if(H5Lcreate_soft("/group1/group_copy", grp_2, "soft", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Copy a group within the file. Both of source and destination use * H5L_SAME_LOC. Should fail. */ H5E_BEGIN_TRY { - if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT) + if(H5Lcopy(H5L_SAME_LOC, "group_copy", H5L_SAME_LOC, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) !=FAIL) TEST_ERROR; } H5E_END_TRY; /* Copy a group across files. Should fail. */ H5E_BEGIN_TRY { - if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT) + if(H5Lcopy(grp_1, "group_copy", file_b, "group_new_name", H5P_DEFAULT, H5P_DEFAULT) !=FAIL) TEST_ERROR; } H5E_END_TRY; /* Move a group across groups in the same file while renaming it. */ - if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT)<0) + if(H5Lcopy(grp_1, "group_copy", grp_2, "group_new_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group just moved to the new location. */ @@ -1111,7 +1145,7 @@ test_copy(hid_t fapl) TEST_ERROR; /* Use H5Lcopy to create a group in the same location with a different name. */ - if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT)<0) + if(H5Lcopy(grp_2, "group_new_name", H5L_SAME_LOC, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group. */ @@ -1126,7 +1160,7 @@ test_copy(hid_t fapl) TEST_ERROR; /* Use H5Lcopy to copy to a different location with the same name. */ - if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT)<0) + if(H5Lcopy(grp_2, "group_newer_name", grp_1, "group_newer_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group . */ @@ -1141,7 +1175,7 @@ test_copy(hid_t fapl) TEST_ERROR; /* Copy the group while giving long paths. */ - if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT)<0) + if(H5Lcopy(file_a, "/group1/group_newer_name", grp_2, "/group2/group_newest_name", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR; /* Open the group just moved to the new location. */ @@ -1224,7 +1258,7 @@ test_move_preserves(hid_t fapl_id) TESTING("moving and copying links preserves their properties"); /* Create file */ - h5_fixname(FILENAME[11], fapl_id, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR; @@ -1233,11 +1267,11 @@ test_move_preserves(hid_t fapl_id) if(H5Pset_char_encoding(lcpl_id, H5T_CSET_UTF8) < 0) TEST_ERROR; /* Create a group with that lcpl */ if((group_id = H5Gcreate_expand(file_id, H5P_DEFAULT, H5P_DEFAULT)) <0) TEST_ERROR; - if(H5Llink(file_id, "group", group_id, lcpl_id) < 0) TEST_ERROR; + if(H5Llink(file_id, "group", group_id, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR; if(H5Gclose(group_id) < 0) TEST_ERROR; /* Get the group's link's creation time */ - if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR; old_create_time = linfo.ctime; old_modification_time = statbuf.mtime; @@ -1251,33 +1285,33 @@ test_move_preserves(hid_t fapl_id) if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) <0) TEST_ERROR; /* Get the group's link's creation time. The times should be unchanged */ - if(H5Lget_linkinfo(file_id, "group", &linfo) < 0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) < 0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; /* Create a new link to the group. It should have a different creation time but the same modification time */ - if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_hard(file_id, "group", file_id, "group2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group2", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group2", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group2", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time == linfo.ctime) TEST_ERROR; /* Copy the first link to a UTF-8 name. Its creation time and modification time should not change. */ - if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id) <0) TEST_ERROR; + if(H5Lcopy(file_id, "group", file_id, "group_copied", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group_copied", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group_copied", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group_copied", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; /* Check that its character encoding is UTF-8 */ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Move the link with the default property list. */ - if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT) <0) TEST_ERROR; + if(H5Lmove(file_id, "group_copied", file_id, "group_copied2", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group_copied2", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group_copied2", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group_copied2", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; /* Check that its character encoding is not UTF-8 */ @@ -1286,25 +1320,25 @@ test_move_preserves(hid_t fapl_id) /* Check that the original link is unchanged */ if(H5Gget_objinfo(file_id, "group", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Move the first link to a UTF-8 name. Its creation time and modification time should not change. */ - if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id) <0) TEST_ERROR; + if(H5Lmove(file_id, "group", file_id, "group_moved", lcpl_id, H5P_DEFAULT) <0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group_moved", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group_moved", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group_moved", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; /* Check that its character encoding is UTF-8 */ if(linfo.cset != H5T_CSET_UTF8) TEST_ERROR; /* Move the link again using the default property list. */ - if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT) <0) TEST_ERROR; + if(H5Lmove(file_id, "group_moved", file_id, "group_moved_again", H5P_DEFAULT, H5P_DEFAULT) <0) TEST_ERROR; if(H5Gget_objinfo(file_id, "group_moved_again", TRUE, &statbuf) <0) TEST_ERROR; if(old_modification_time != statbuf.mtime) TEST_ERROR; - if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo) <0) TEST_ERROR; + if(H5Lget_linkinfo(file_id, "group_moved_again", &linfo, H5P_DEFAULT) <0) TEST_ERROR; if(old_create_time != linfo.ctime) TEST_ERROR; /* Check that its character encoding is not UTF-8 */ @@ -1357,7 +1391,7 @@ test_compat(hid_t fapl) TESTING("backwards compatibility"); /* Create file */ - h5_fixname(FILENAME[15], fapl, filename, sizeof filename); + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; @@ -1439,6 +1473,3222 @@ error: /*------------------------------------------------------------------------- + * Function: external_link_root + * + * Purpose: Build a file with external link to root group in external file + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Wednesday, May 25, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_root(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + H5G_stat_t sb; /* Object information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE]; + char filename2[NAME_BUF_SIZE]; + char *file; /* File from external link */ + char *path; /* Path from external link */ + + TESTING("external link to root"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create file to point to */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Check that external links are registered with the library */ + if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR + + /* Create file with link to first file */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external link to object in first file */ + if(H5Lcreate_external(filename1, "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Check information for external link */ + if (H5Gget_objinfo(fid, "ext_link", FALSE, &sb)<0) goto error; + if (H5G_UDLINK!=sb.type) { + H5_FAILED(); + puts(" Unexpected object type - should have been an external link"); + goto error; + } + if(H5Lget_linkval(fid, "ext_link", sizeof(objname), objname, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Lunpack_elink_val(objname, &file, &path) < 0) TEST_ERROR + if(HDstrcmp(file, filename1)) + { + H5_FAILED(); + puts(" External link file name incorrect"); + goto error; + } + if(HDstrcmp(path, "/")) + { + H5_FAILED(); + puts(" External link path incorrect"); + goto error; + } + + /* Close and re-open file to ensure that data is written to disk */ + if(H5Fclose(fid) < 0) TEST_ERROR; + if((fid = H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR; + + + /* Open object through external link */ + if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object (lets first file close) */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close second file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file again and check on object created */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Open object created through external link */ + if((gid = H5Gopen(fid, "new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Fclose (gid2); + H5Fclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_root() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_path + * + * Purpose: Build a file with external link to object down a path in the + * external file + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, July 26, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_path(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE]; + char filename2[NAME_BUF_SIZE]; + + TESTING("external link to object on path"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create file to point to */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create object down a path */ + if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Create file with link to first file */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external link to object in first file */ + if(H5Lcreate_external(filename1, "/A/B/C", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Open object through external link */ + if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object (lets first file close) */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close second file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file again and check on object created */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Open object created through external link */ + if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_path() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_mult + * + * Purpose: Build a file with external link to object that crossed several + * external file links + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, July 26, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_mult(hid_t fapl) +{ + hid_t fid = (-1), fid2 = (-1); /* File IDs */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE], + filename3[NAME_BUF_SIZE], + filename4[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("external links across multiple files"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + h5_fixname(FILENAME[5], fapl, filename3, sizeof filename3); + h5_fixname(FILENAME[6], fapl, filename4, sizeof filename4); + + /* Create first file to point to */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create object down a path */ + if((gid = H5Gcreate(fid, "A", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "A/B", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "A/B/C", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create second file to point to */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external link down a path */ + if((gid = H5Gcreate(fid, "D", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "D/E", (size_t)0)) < 0) TEST_ERROR + + /* Create external link to object in first file */ + if(H5Lcreate_external(filename1, "/A/B/C", gid, "F", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create third file to point to */ + if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external link down a path */ + if((gid = H5Gcreate(fid, "G", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if((gid = H5Gcreate(fid, "G/H", (size_t)0)) < 0) TEST_ERROR + + /* Create external link to object in second file */ + if(H5Lcreate_external(filename2, "/D/E/F", gid, "I", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Create file with link to third file */ + if((fid=H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external link to object in first file */ + if(H5Lcreate_external(filename3, "/G/H/I", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Open object through external link */ + if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object (lets first file close) */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close second file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file again and check on object created */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Open object created through external link */ + if((gid = H5Gopen(fid, "/A/B/C/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/A/B/C/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR + + + /* Open an object through external links */ + if((fid = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) <0) TEST_ERROR + if((gid = H5Gopen(fid, "ext_link")) < 0) TEST_ERROR + + /* The intermediate files should not stay open. Replace one of them with a new file. */ + if((fid2=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + if(H5Fclose(fid2)<0) TEST_ERROR + + /* Open the other with write access and delete the external link in it */ + if((fid2=H5Fopen(filename3, H5F_ACC_RDWR, fapl))<0) TEST_ERROR + if(H5Lunlink(fid2, "G/H/I", H5P_DEFAULT) < 0) TEST_ERROR + + if(H5Fclose(fid2)<0) TEST_ERROR + + /* Cleanup */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid)<0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_mult() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_self + * + * Purpose: Build a file with external link to itself + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: James Laird + * Wednesday, July 12, 2006 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifdef H5_GROUP_REVISION +static int +external_link_self(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + hid_t lcpl_id = (-1); /* Link Creation Property List ID */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE]; + char filename2[NAME_BUF_SIZE]; + char filename3[NAME_BUF_SIZE]; + + TESTING("external link to self"); + + /* Set up filename */ + h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[2], fapl, filename2, sizeof filename1); + h5_fixname(FILENAME[3], fapl, filename3, sizeof filename1); + + /* Create file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create an lcpl with intermediate group creation set */ + if((lcpl_id=H5Pcreate(H5P_LINK_CREATE))<0) TEST_ERROR + if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) TEST_ERROR + + /* Create a series of groups within the file: /A/B and /X/Y/Z */ + if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Llink(fid, "A/B", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if((gid=H5Gcreate_expand(fid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Llink(fid, "X/Y", gid, lcpl_id, H5P_DEFAULT) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + if(H5Pclose (lcpl_id) <0) TEST_ERROR + + /* Create external link to own root group*/ + if(H5Lcreate_external(filename1, "/X", fid, "A/B/C", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Open object through external link */ + if((gid = H5Gopen(fid, "A/B/C/")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object through external link */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close created group */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close object opened through external link */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Check on object created */ + if((gid = H5Gopen(fid, "X/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/X/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Complicate things. Use this file as an intermediate file in a chain + * of external links that will go: file2 -> file1 -> file1 -> file3 + */ + + /* Create file2 with an external link to file1 */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR + + if(H5Lcreate_external(filename1, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file2 */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create file3 as a target */ + if((fid=H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR + if((gid=H5Gcreate(fid, "end", 0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open file1 and create an extlink pointing to file3 */ + if((fid=H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR + + if(H5Lcreate_external(filename3, "/", fid, "/X/Y/Z", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file1 */ + if(H5Fclose(fid) < 0) TEST_ERROR + + + /* Re-open file2 and traverse through file1 (with its recursive extlink) to file3 */ + if((fid=H5Fopen(filename2, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR + + if((gid=H5Gopen(fid, "ext_link/B/C/Y/Z/end")) < 0) TEST_ERROR + + /* Create object through external link */ + if((gid2 = H5Gcreate(gid, "newer_group", 0)) < 0) TEST_ERROR + + /* Cleanup */ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open up file3 and make sure the object was created successfully */ + if((fid=H5Fopen(filename3, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR + + if((gid=H5Gopen(fid, "end/newer_group")) < 0) TEST_ERROR + + /* Cleanup */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Fclose (gid2); + H5Fclose (gid); + H5Pclose (lcpl_id); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_self() */ +#endif /* H5_GROUP_REVISION */ + + +/*------------------------------------------------------------------------- + * Function: external_link_pingpong + * + * Purpose: Build a file with external link to object that goes back and + * force between two files a couple of times: + * + * file1:/link1 -> file2: /link2 + * file2:/link2 -> file1: /link3 + * file1:/link3 -> file2: /link4 + * file2:/link4 -> file1: /link5 + * file1:/link5 -> file2: /link6 + * file2:/link6 -> file1: /final + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, July 26, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_pingpong(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("external links back and forth"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external links for chain */ + if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Create final object */ + if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create second file */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external links for chain */ + if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/final", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file */ + if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR; + + /* Open object through external link */ + if((gid = H5Gopen(fid, "link1")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object (lets first file close) */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file again and check on object created */ + if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Open object created through external link */ + if((gid = H5Gopen(fid, "/final/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/final/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_pingpong() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_toomany + * + * Purpose: Build a file with too many external links to objects (i.e. + * more than H5G_NLINKS. Use a "back & forth" style of + * linking (like the "ping pong" test above) to minimize the + * number of files involved: + * + * file1:/link1 -> file2: /link2 + * file2:/link2 -> file1: /link3 + * file1:/link3 -> file2: /link4 + * file2:/link4 -> file1: /link5 + * file1:/link5 -> file2: /link6 + * file2:/link6 -> file1: /link7 + * file1:/link7 -> file2: /link8 + * file2:/link8 -> file1: /link9 + * file1:/link9 -> file2: /link10 + * file2:/link10 -> file1: /link11 + * file1:/link11 -> file2: /link12 + * file2:/link12 -> file1: /link13 + * file1:/link13 -> file2: /link14 + * file2:/link14 -> file1: /link15 + * file1:/link15 -> file2: /link16 + * file2:/link16 -> file1: /link17 + * file1:/link17 -> file2: /final + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, August 8, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_toomany(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("too many external links"); + + /* Make certain test is valid */ + /* XXX: should probably make a "generic" test that creates the proper + * # of links based on this value - QAK + */ + HDassert(H5G_NLINKS == 16); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external links for chain */ + if(H5Lcreate_external(filename2, "/link2", fid, "link1", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link4", fid, "link3", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link6", fid, "link5", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link8", fid, "link7", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link10", fid, "link9", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link12", fid, "link11", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link14", fid, "link13", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/link16", fid, "link15", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/final", fid, "link17", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create second file */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create external links for chain */ + if(H5Lcreate_external(filename1, "/link3", fid, "link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link5", fid, "link4", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link7", fid, "link6", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link9", fid, "link8", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link11", fid, "link10", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link13", fid, "link12", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link15", fid, "link14", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename1, "/link17", fid, "link16", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Create final object */ + if((gid = H5Gcreate(fid, "final", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file */ + if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR; + + /* Open object through external link */ + H5E_BEGIN_TRY { + gid = H5Gopen(fid, "link1"); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + puts(" Should have failed for sequence of too many nested links."); + goto error; + } + + /* Open object through external link */ + if((gid = H5Gopen(fid, "link3")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_toomany() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_dangling + * + * Purpose: Build a file with "dangling" external links: with both + * missing files and missing objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Quincey Koziol + * Tuesday, August 9, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_dangling(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group IDs */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("dangling external links"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create dangling external links */ + if(H5Lcreate_external("missing", "/missing", fid, "no_file", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external(filename2, "/missing", fid, "no_object", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create second file (for dangling object test) */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open first file */ + if((fid=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0) TEST_ERROR; + + /* Open object through dangling file external link */ + H5E_BEGIN_TRY { + gid = H5Gopen(fid, "no_file"); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + puts(" Should have failed for sequence of too many nested links."); + goto error; + } + + /* Open object through dangling object external link */ + H5E_BEGIN_TRY { + gid = H5Gopen(fid, "no_object"); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + puts(" Should have failed for sequence of too many nested links."); + goto error; + } + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_dangling() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_recursive + * + * Purpose: Build a file with "recursive" external link + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, August 15, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_recursive(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group IDs */ + char filename1[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("recursive external links"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + + /* Create first file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create recursive external links */ + if(H5Lcreate_external(filename1, "/recursive", fid, "recursive", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + /* Open file */ + if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR; + + /* Open object through dangling file external link */ + H5E_BEGIN_TRY { + gid = H5Gopen(fid, "recursive"); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + puts(" Should have failed for recursive external links."); + goto error; + } + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_recursive() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_query + * + * Purpose: Query file & object names for external links, as well as + * information from H5Gget_obj_info + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, August 15, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +external_link_query(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group IDs */ + char *file_name; /* Name of the file the external link points to */ + char *object_name; /* Name of the object the external link points to */ + H5G_stat_t sb; /* Object information */ + H5L_linkinfo_t li; /* Link information */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE], /* Names of files to externally link across */ + query_buf[NAME_BUF_SIZE]; /* Buffer to hold query result */ + + + TESTING("query aspects of external link"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR + + /* Create external link */ + if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Get size of buffer for external link */ + if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR + if (H5L_LINK_EXTERNAL != li.linkclass) { + H5_FAILED(); + puts(" Unexpected link class - should have been an external link"); + goto error; + } + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Create second file to point to */ + if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR + + + /* Open first file */ + if((fid=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0) TEST_ERROR + + /* Get size of buffer for external link */ + if(H5Lget_linkinfo(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR + if(li.u.link_size != (HDstrlen(filename2) + HDstrlen("/dst") + 2)) TEST_ERROR + if (H5L_LINK_EXTERNAL != li.linkclass) { + H5_FAILED(); + puts(" Unexpected link class - should have been an external link"); + goto error; + } + + /* Get information for external link. It should be two strings right after each other */ + if(H5Lget_linkval(fid, "src", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Extract the file and object names from the buffer */ + if(H5Lunpack_elink_val(query_buf, &file_name, &object_name) < 0) TEST_ERROR + + /* Compare the file and object names */ + if(strcmp(file_name, filename2)) TEST_ERROR; + if(strcmp(object_name, "/dst")) TEST_ERROR + + /* Query information about object that external link points to */ + if (H5Gget_objinfo(fid, "src", TRUE, &sb)<0) goto error; + if (H5G_GROUP != sb.type) { + H5_FAILED(); + puts(" Unexpected object type - should have been a group"); + goto error; + } + + /* Close first file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Make sure that passing in NULLs to H5Lunpack_elink_val works */ + if(H5Lunpack_elink_val(query_buf, NULL, NULL) < 0) TEST_ERROR + + /* Make sure that bogus cases trigger errors in H5Lunpack_elink_val */ + H5E_BEGIN_TRY { + if(H5Lunpack_elink_val(NULL, NULL, NULL) >= 0) TEST_ERROR + } H5E_END_TRY + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end external_link_query() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_unlink_compact + * + * Purpose: Remove an external link (from a compact group) + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Wednesday, January 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +external_link_unlink_compact(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("unlinking external link in compact group"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create external link */ + if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create second file to point to */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + +/* Unlink external link */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Unlink external link */ + if(H5Gunlink(fid, "src") < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group for external link */ + if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end external_link_unlink_compact() */ + + +/*------------------------------------------------------------------------- + * Function: external_link_unlink_dense + * + * Purpose: Remove an external link (from a dense group) + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Wednesday, January 18, 2006 + * + *------------------------------------------------------------------------- + */ +#ifdef H5_GROUP_REVISION +static int +external_link_unlink_dense(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gcpl = (-1); /* Group creation property list ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + unsigned nmsgs; /* Number of messages in group's header */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + unsigned u; /* Local index variable */ + + TESTING("unlinking external link in dense group"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Open root group */ + if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR + + /* Query the group creation properties */ + if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR + if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create external link */ + /* (This also covers the case of having an external link in a compact group that's converted to a dense group) */ + if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR; + if(nmsgs != 1) TEST_ERROR; + if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR; + + /* Create enough objects in the root group to change it into a "dense" group */ + for(u = 0; u < max_compact; u++) { + sprintf(objname, "filler %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR; + if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR; + + /* Close group creation property list */ + if(H5Pclose(gcpl) < 0) TEST_ERROR + + /* Close root group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create second file to point to */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + +/* Unlink external link */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Open root group */ + if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR + + /* Unlink external link */ + if(H5Gunlink(fid, "src") < 0) TEST_ERROR + + /* Remove enough objects in the root group to change it into a "compact" group */ + for(u = 0; u < ((max_compact - min_dense) + 1); u++) { + sprintf(objname, "filler %u\n", u); + if(H5Gunlink(gid, objname) < 0) TEST_ERROR + } /* end for */ + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR; + if(nmsgs != (min_dense - 1)) TEST_ERROR; + if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR; + + /* Close root group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group for external link (should be unaffected) */ + if((gid = H5Gopen(fid, "dst")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end external_link_unlink_dense() */ +#endif /* H5_GROUP_REVISION */ + + +/*------------------------------------------------------------------------- + * Function: external_link_move + * + * Purpose: Move/rename external link + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Monday, December 5, 2005 + * + *------------------------------------------------------------------------- + */ +static int +external_link_move(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + + TESTING("move external link"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create external link */ + if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create second file to point to */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + +/* Move external link to different name within same group */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Move external link within same group */ + if(H5Gmove(fid, "src", "src2") < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen(fid, "src2")) < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created through external link */ + if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + +/* Move external link to different group */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Create another group, to move the external link into */ + if((gid = H5Gcreate(fid, "group2", (size_t)0)) < 0) TEST_ERROR + + /* Move external link to different group */ + if(H5Gmove2(fid, "src2", gid, "src3") < 0) TEST_ERROR + + /* Close new group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created through external link */ + if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + +/* Move external link back to original group */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen(fid, "/group2/src3")) < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Move external link back to original location */ + if(H5Gmove(fid, "/group2/src3", "/src") < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group3", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created through external link */ + if((gid = H5Gopen(fid, "dst/new_group3")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end external_link_move() */ + + +#ifdef H5_GROUP_REVISION +/*------------------------------------------------------------------------- + * Function: external_link_ride + * + * Purpose: Let an external link "come along for the ride" when a group is + * converted between compact & dense forms. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * Wednesday, January 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +external_link_ride(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gcpl = (-1); /* Group creation property list ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename1[NAME_BUF_SIZE], + filename2[NAME_BUF_SIZE]; /* Names of files to externally link across */ + unsigned nmsgs; /* Number of messages in group's header */ + unsigned max_compact; /* Maximum # of links to store in group compactly */ + unsigned min_dense; /* Minimum # of links to store in group "densely" */ + unsigned u; /* Local index variable */ + + TESTING("external link along for the ride"); + + /* Set up filenames */ + h5_fixname(FILENAME[3], fapl, filename1, sizeof filename1); + h5_fixname(FILENAME[4], fapl, filename2, sizeof filename2); + + /* Create first file, with external link to object in second file */ + if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Open root group */ + if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) != TRUE) TEST_ERROR + + /* Query the group creation properties */ + if((gcpl = H5Gget_create_plist(gid)) < 0) TEST_ERROR + if(H5Pget_link_phase_change(gcpl, &max_compact, &min_dense) < 0) TEST_ERROR + + /* Create enough objects in the root group to change it into a "dense" group */ + for(u = 0; u < (max_compact + 1); u++) { + sprintf(objname, "filler %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR; + if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR; + + /* Create external link */ + /* (This also covers the case of adding an external link to a dense group) */ + if(H5Lcreate_external(filename2, "/dst", gid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR; + if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR; + + /* Close group creation property list */ + if(H5Pclose(gcpl) < 0) TEST_ERROR + + /* Close root group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Create second file to point to */ + if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR + + /* Create object to link to */ + if((gid = H5Gcreate(fid, "dst", (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + +/* Remove enough objects to convert group containing external link back into compact form */ + + /* Open first file */ + if((fid = H5Fopen(filename1, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Open root group */ + if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR + + /* Remove enough objects in the root group to change it into a "compact" group */ + for(u = 0; u < ((max_compact - min_dense) + 3); u++) { + sprintf(objname, "filler %u\n", u); + if(H5Gunlink(gid, objname) < 0) TEST_ERROR + } /* end for */ + + /* Check on root group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, &nmsgs) != TRUE) TEST_ERROR; + if(nmsgs != (min_dense - 1)) TEST_ERROR; + if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR; + + /* Close root group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Open object through external link */ + if((gid = H5Gopen(fid, "src")) < 0) TEST_ERROR + + /* Check name */ + if((name_len = H5Iget_name(gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in external file */ + if((gid2 = H5Gcreate(gid, "new_group2", (size_t)0)) < 0) TEST_ERROR + + /* Close group in external file */ + if(H5Gclose(gid2) < 0) TEST_ERROR + + /* Close external object */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close first file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + /* Open second file */ + if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR + + /* Open group created through external link */ + if((gid = H5Gopen(fid, "dst/new_group")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Open group created through external link */ + if((gid = H5Gopen(fid, "dst/new_group2")) < 0) TEST_ERROR + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close file */ + if(H5Fclose(fid) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(gcpl); + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end external_link_ride() */ +#endif /* H5_GROUP_REVISION */ + + +/*------------------------------------------------------------------------- + * Function: ext_link_endian + * + * Purpose: Check that external links work properly when they are + * moved from big-endian to little-endian systems and + * vice versa. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +static int +ext_link_endian(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + hid_t lapl_id = (-1); /* Prop List ID */ + char * srcdir = getenv("srcdir"); /* The source directory */ + char pathbuf[NAME_BUF_SIZE]; /* Path to the files */ + char namebuf[NAME_BUF_SIZE]; + + TESTING("endianness of external links"); + + /* + * Create the name of the file to open (in case we are using the --srcdir + * option and the file is in a different directory from this test). + */ + if (srcdir && ((HDstrlen(srcdir) + 2) < sizeof(pathbuf)) ) + { + HDstrcpy(pathbuf, srcdir); + HDstrcat(pathbuf, "/"); + } + else + HDstrcpy(pathbuf, ""); + + /* Create a link access property list with the path to the srcdir */ + if((lapl_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR; + if(H5Pinsert(lapl_id, H5L_ELINK_PREFIX_PROP, strlen(pathbuf) + 1, pathbuf, + NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR; + + if(HDstrlen(pathbuf) + HDstrlen(LE_FILENAME) >= sizeof(namebuf)) TEST_ERROR; + + HDstrcpy(namebuf, pathbuf); + HDstrcat(namebuf, LE_FILENAME); + + /* Test LE file; try to open a group through the external link */ + if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; + if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR; + + /* Open a group in the external file using that group ID */ + if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR; + + /* Close the IDs */ + if(H5Gclose(gid2) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + if(H5Fclose(fid) < 0) TEST_ERROR; + + if(HDstrlen(pathbuf) + HDstrlen(BE_FILENAME) >= sizeof(namebuf)) TEST_ERROR; + + HDstrcpy(namebuf, pathbuf); + HDstrcat(namebuf, BE_FILENAME); + + /* Test BE file; try to open a group through the external link */ + if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; + if((gid = H5Oopen(fid, "ext_link", lapl_id)) < 0) TEST_ERROR; + + /* Open a group in the external file using that group ID */ + if((gid2 = H5Gopen(gid, "subgroup")) < 0) TEST_ERROR; + + /* Close the IDs */ + if(H5Gclose(gid2) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + if(H5Fclose(fid) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} + +/*------------------------------------------------------------------------- + * Function: ud_hard_links + * + * Purpose: Check that the functionality of hard links can be duplicated + * with user-defined links. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +/* Callback functions for UD hard links. */ +/* UD_hard_create increments the object's reference count */ +static herr_t UD_hard_create(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t UNUSED lcpl_id) +{ + haddr_t addr; + hid_t target_obj = -1; + herr_t ret_value = 0; + + if(udata_size != sizeof(haddr_t)) + { + ret_value = -1; + goto done; + } + + addr = *((haddr_t *) udata); + + /* Open the object this link points to */ + target_obj= H5Oopen_by_addr(loc_group, addr); + if(target_obj < 0) + { + ret_value = -1; + goto done; + } + + /* Increment the reference count of the target object */ + if(H5Oincr_refcount(target_obj) < 0) + { + ret_value = -1; + goto done; + } + +done: + /* Close the target object if we opened it */ + if(target_obj >= 0) + { + switch(H5Iget_type(target_obj)) + { + case H5I_GROUP: + if(H5Gclose(target_obj) <0) + ret_value = -1; + break; + case H5I_DATASET: + if(H5Dclose(target_obj) <0) + ret_value = -1; + break; + case H5I_DATATYPE: + if(H5Tclose(target_obj) <0) + ret_value = -1; + break; + default: + return -1; + } + } + + return ret_value; +} + +/* UD_hard_delete decrements the object's reference count */ +static herr_t UD_hard_delete(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size) +{ + haddr_t addr; + hid_t target_obj = -1; + herr_t ret_value = 0; + + if(udata_size != sizeof(haddr_t)) + { + ret_value = -1; + goto done; + } + + addr = *((haddr_t *) udata); + + /* Open the object this link points to */ + target_obj= H5Oopen_by_addr(loc_group, addr); + if(target_obj < 0) + { + ret_value = -1; + goto done; + } + + /* Decrement the reference count of the target object */ + if(H5Odecr_refcount(target_obj) < 0) + { + ret_value = -1; + goto done; + } + +done: + /* Close the target object if we opened it */ + if(target_obj >= 0) + { + switch(H5Iget_type(target_obj)) + { + case H5I_GROUP: + if(H5Gclose(target_obj) <0) + ret_value = -1; + break; + case H5I_DATASET: + if(H5Dclose(target_obj) <0) + ret_value = -1; + break; + case H5I_DATATYPE: + if(H5Tclose(target_obj) <0) + ret_value = -1; + break; + default: + return -1; + } + } + + return ret_value; +} + +static hid_t UD_hard_traverse(const char UNUSED *link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t UNUSED lapl_id) +{ + haddr_t addr; + hid_t ret_value = -1; + + if(udata_size != sizeof(haddr_t)) + return -1; + + addr = *((haddr_t *) udata); + + ret_value = H5Oopen_by_addr(cur_group, addr); /* If this fails, our return value will be negative. */ + + return ret_value; +} + +const H5L_link_class_t UD_hard_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_HARD_TYPE, /* Link type id number */ + "UD_hard_link", /* Link class name for debugging */ + UD_hard_create, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_hard_traverse, /* The actual traversal function */ + UD_hard_delete, /* Deletion callback */ + NULL /* Query callback */ +}}; + +static int +ud_hard_links(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + H5L_linkinfo_t li; /* Link information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + h5_stat_size_t empty_size; /* Size of an empty file */ + char filename[NAME_BUF_SIZE]; + + TESTING("user-defined hard link"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Get the size of the empty file for reference */ + if(H5Fclose(fid) < 0) TEST_ERROR; + if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR; + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Check that external links are registered and UD hard links are not */ + if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR + + /* Register "user-defined hard links" with the library */ + if(H5Lregister(UD_hard_class) < 0) TEST_ERROR; + + /* Check that UD hard links are now registered */ + if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Create a group for the UD hard link to point to */ + if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR; + + /* Get address for the group to give to the hard link */ + if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR; + + if(H5Gclose(gid) < 0) TEST_ERROR; + + + /* Create a user-defined "hard link" to the group using the address we got + * from H5Lget_linkinfo */ + if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address), sizeof(haddr_t), H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close and re-open file to ensure that data is written to disk */ + if(H5Fclose(fid) < 0) TEST_ERROR; + if((fid = H5Fopen(filename, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) TEST_ERROR; + + /* Open group through UD link */ + if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in group */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close groups*/ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Re-open group without using ud link to check that it was created properly */ + if((gid = H5Gopen(fid, "group/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/group/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Check that H5Gget_objinfo works on the hard link */ + if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR + /* UD hard links have no query function, thus return a "link length" of 0 */ + if(li.u.link_size != 0) TEST_ERROR + if (UD_HARD_TYPE != li.linkclass) { + H5_FAILED(); + puts(" Unexpected link class - should have been a UD hard link"); + goto error; + } + + /* Unlink the group pointed to by the UD link. It shouldn't be + * deleted because of the UD link. */ + if(H5Gunlink(fid, "/group") < 0) TEST_ERROR; + + /* Ensure we can open the group through the UD link */ + if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR; + + /* Unlink the group contained within it. */ + if(H5Gunlink(gid, "new_group") < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Now delete the UD link. This should cause the group to be + * deleted, too. */ + if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* The file should be empty again. */ + if(empty_size!=h5_get_file_size(filename)) TEST_ERROR; + + if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end ud_hard_links() */ + + +/*------------------------------------------------------------------------- + * Function: ext_link_endian + * + * Purpose: Check that user defined link types can be unregistered and + * reregistered properly. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ + /* A traversal function that ignores any udata and simply opens an object + * in the current group named REREG_TARGET_NAME + */ +static hid_t UD_rereg_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t UNUSED udata_size, hid_t lapl_id) +{ + hid_t ret_value; + + if((ret_value = H5Oopen(cur_group, REREG_TARGET_NAME, lapl_id)) < 0) TEST_ERROR; + + return ret_value; + +error: + return -1; +} + +/* This link class has the same ID number as the UD hard links but + * has a very different traversal function */ +const H5L_link_class_t UD_rereg_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_HARD_TYPE, /* Link type id number */ + "UD_reregistered_type", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_rereg_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + +static int +ud_link_reregister(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + H5L_linkinfo_t li; /* Link information */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename[NAME_BUF_SIZE]; + h5_stat_size_t empty_size; /* Size of an empty file */ + + TESTING("registering a new class for existing UD links"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Get the size of the empty file for reference */ + if(H5Fclose(fid) < 0) TEST_ERROR; + if((empty_size=h5_get_file_size(filename))==0) TEST_ERROR; + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Check that UD hard links are not registered */ + if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR + + /* Register "user-defined hard links" with the library */ + if(H5Lregister(UD_hard_class) < 0) TEST_ERROR; + + /* Check that UD hard links are registered */ + if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Point a UD defined hard link to a group in the same way as the previous test */ + if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR; + if (H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT)<0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + if(H5Lcreate_ud(fid, "ud_link", UD_HARD_TYPE, &(li.u.address), + sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) < 0) + TEST_ERROR; + + /* Create a group named REREG_TARGET_NAME in the same group as the ud link */ + if((gid = H5Gcreate(fid, REREG_TARGET_NAME, 0)) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Now unregister UD hard links */ + if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR; + + /* Check that UD hard links are no longer registered */ + if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR + + /* Verify that we can't traverse the ud link anymore */ + H5E_BEGIN_TRY { + if((gid = H5Gopen(fid, "ud_link")) >= 0) TEST_ERROR; + } H5E_END_TRY + + /* Verify that we can't create any new links of this type */ + H5E_BEGIN_TRY { + if(H5Lcreate_ud(fid, "ud_link2", UD_HARD_TYPE, &(li.u.address), + sizeof(li.u.address), H5P_DEFAULT, H5P_DEFAULT) >= 0) + TEST_ERROR; + } H5E_END_TRY + + /* Register a new kind of link with the same ID number */ + if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR; + + /* Check that UD hard links are registered again */ + if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Open a group through the ud link (now a different class of link). + * It should be a different group + * than the UD hard link pointed to */ + if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(name_len != 0) TEST_ERROR + + /* Create object in group */ + if((gid2 = H5Gcreate(gid, "new_group", (size_t)0)) < 0) TEST_ERROR + + /* Close groups*/ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Re-open group without using ud link to check that it was created properly */ + if((gid = H5Gopen(fid, "rereg_target/new_group")) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/rereg_target/new_group")) TEST_ERROR + + /* Close opened object */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Unlink the group pointed to by the UD hard link. It shouldn't be + * deleted because the UD link incremented its reference count. */ + if(H5Gunlink(fid, "/group") < 0) TEST_ERROR; + + /* What a mess! Re-register user-defined links to clean up the + * reference counts. We shouldn't actually need to unregister the + * other link type */ + if(H5Lregister(UD_hard_class) < 0) TEST_ERROR; + if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR + + /* Ensure we can open the group through the UD link (now that UD hard + * links have been registered) */ + if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Delete the UD hard link. This should cause the group to be + * deleted, too. */ + if(H5Gunlink(fid, "ud_link")<0) TEST_ERROR; + + /* Unlink the other two groups so that we can make sure the file is empty */ + if(H5Gunlink(fid, "/rereg_target/new_group")<0) TEST_ERROR; + if(H5Gunlink(fid, REREG_TARGET_NAME)<0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + /* The file should be empty again. */ + if(empty_size!=h5_get_file_size(filename)) TEST_ERROR; + + if(H5Lunregister(UD_HARD_TYPE) < 0) TEST_ERROR + if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid2); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end ud_link_reregister() */ + + +/*------------------------------------------------------------------------- + * Function: ud_callbacks + * + * Purpose: Check that all callbacks are called and are given the correct + * information. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +/* Callback functions for UD "callback" links. */ +/* Creation callback. Called during move as well. */ +herr_t UD_cb_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id) +{ + if(!link_name) TEST_ERROR; + if(loc_group < 0) TEST_ERROR; + if(udata_size > 0 && !udata) TEST_ERROR; + if(lcpl_id < 0) TEST_ERROR; + + if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR; + if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR; + if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR; + + return 0; + +error: + return -1; +} +static hid_t UD_cb_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id) +{ + const char *target = (char *) udata; + hid_t ret_value; + + if(!link_name) TEST_ERROR; + if(cur_group < 0) TEST_ERROR; + if(udata_size > 0 && !udata) TEST_ERROR; + + if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR; + if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR; + if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR; + + if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) + TEST_ERROR; + + return ret_value; + +error: + return -1; +} +/* Callback for when the link is moved or renamed */ +herr_t UD_cb_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size) +{ + const char *target = (char *) udata; + + if(!new_name) TEST_ERROR; + if(new_loc < 0) TEST_ERROR; + if(udata_size > 0 && !udata) TEST_ERROR; + + if(strcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR; + if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR; + if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR; + + return 0; + +error: + return -1; +} +/* Callback for when the link is deleted. Also called during move */ +herr_t UD_cb_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size) +{ + if(!link_name) TEST_ERROR; + if(loc_group < 0) TEST_ERROR; + if(udata_size > 0 && !udata) TEST_ERROR; + + if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR; + if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR; + if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR; + + return 0; + +error: + return -1; +} +/* Callback for when the link is queried */ +ssize_t UD_cb_query(const char * link_name, void * udata, size_t udata_size, void* buf, size_t buf_size) +{ + if(!link_name) TEST_ERROR; + if(udata_size > 0 && !udata) TEST_ERROR; + + if(strcmp(link_name, UD_CB_LINK_NAME)) TEST_ERROR; + if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR; + if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR; + + if(buf) + { + if(buf_size < 16) TEST_ERROR; + strcpy(buf, "query succeeded"); + } + + /* There are 15 characters and a NULL in "query succeeded" */ + return 16; + +error: + return -1; +} + +const H5L_link_class_t UD_cb_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_CB_TYPE, /* Link type id number */ + NULL, /* NULL name (to make sure this doesn't break anything */ + UD_cb_create, /* Creation callback */ + UD_cb_move, /* Move/rename callback */ + UD_cb_move, /* Copy callback */ + UD_cb_traverse, /* The actual traversal function */ + UD_cb_delete, /* Deletion callback */ + UD_cb_query /* Query callback */ +}}; + +static int +ud_callbacks(fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group ID */ + hid_t lcpl = (-1); /* Link Creation PL */ + H5G_stat_t sb; /* Object information */ + H5L_linkinfo_t li; /* Link information */ + char ud_target_name[] = UD_CB_TARGET; /* Link target name */ + char filename[NAME_BUF_SIZE]; + char query_buf[NAME_BUF_SIZE]; + + TESTING("user-defined link callbacks"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Check that registered link classes are, and unregistered ones aren't */ + if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered(UD_HARD_TYPE) != 0) TEST_ERROR + if(H5Lis_registered(UD_CB_TYPE) != 0) TEST_ERROR + + /* Hit two birds with one stone: register UD hard links from previous + * test to check that having two UD links registered at once presents + * no problems. */ + if(H5Lregister(UD_hard_class) < 0) TEST_ERROR; + + /* Register user-defined link class. This is the one we'll actually + * be using. */ + if(H5Lregister(UD_cb_class) < 0) TEST_ERROR; + + /* Check that registered link classes are, and unregistered ones aren't */ + if(H5Lis_registered(H5L_LINK_EXTERNAL) != TRUE) TEST_ERROR + if(H5Lis_registered(UD_HARD_TYPE) != TRUE) TEST_ERROR + if(H5Lis_registered(UD_CB_TYPE) != TRUE) TEST_ERROR + + /* Create a group for the UD link to point to */ + if((gid = H5Gcreate(fid, UD_CB_TARGET, 0)) <0) TEST_ERROR; + + /* Create a user-defined link to the group. These UD links behave like soft links. */ + if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Try opening group through UD link */ + if((gid = H5Gopen(fid, UD_CB_LINK_NAME)) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Query the link to test its query callback */ + if (H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT)<0) TEST_ERROR; + if(li.u.link_size != 16) TEST_ERROR; + if (UD_CB_TYPE != li.linkclass) { + H5_FAILED(); + puts(" Unexpected link class - should have been a UD hard link"); + goto error; + } + + /* Fill the query buffer */ + if(H5Gget_linkval(fid, UD_CB_LINK_NAME, NAME_BUF_SIZE, query_buf) < 0) TEST_ERROR; + if(strcmp(query_buf, "query succeeded") != 0) TEST_ERROR; + + /* Move the link */ + if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR; + + /* Re-open group to ensure that move worked */ + if((gid = H5Gopen(fid, NEW_UD_CB_LINK_NAME)) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Remove UD link */ + if(H5Gunlink(fid, NEW_UD_CB_LINK_NAME) < 0) TEST_ERROR; + + + /* Test that the callbacks don't work if the link class is not registered */ + + /* Create a new link. Just for fun, give it a non-default character + * encoding (to test that LAPLs work) */ + if((lcpl = H5Pcreate(H5P_LINK_CREATE)) < 0) TEST_ERROR +#ifdef H5_GROUP_REVISION + if(H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) TEST_ERROR +#endif /* H5_GROUP_REVISION */ + if(H5Lcreate_ud(fid, UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, lcpl, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Pclose(lcpl)<0) TEST_ERROR + + /* Check its character encoding */ +#ifdef H5_GROUP_REVISION + if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.cset != H5T_CSET_UTF8) TEST_ERROR; +#endif /* H5_GROUP_REVISION */ + + /* Unregister the link class so the library forgets what its callbacks do */ + if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR; + + /* Now test that each of the callbacks fails */ + H5E_BEGIN_TRY { + if(H5Lcreate_ud(fid, NEW_UD_CB_LINK_NAME, UD_CB_TYPE, ud_target_name, UD_CB_TARGET_LEN, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR; + if(H5Gmove(fid, UD_CB_LINK_NAME, NEW_UD_CB_LINK_NAME) >= 0) TEST_ERROR; + if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR; + if((gid = H5Gopen(gid, UD_CB_LINK_NAME)) >= 0) TEST_ERROR; + if(H5Gunlink(fid, UD_CB_LINK_NAME) >= 0) TEST_ERROR; + } H5E_END_TRY + + /* The query callback should NOT fail, but should be unable to give a linklen */ + if(H5Lget_linkinfo(fid, UD_CB_LINK_NAME, &li, H5P_DEFAULT) <0) TEST_ERROR; + if(li.u.link_size != 0) TEST_ERROR; + if(li.linkclass != UD_CB_TYPE) TEST_ERROR; + if(H5Gget_objinfo(fid, UD_CB_LINK_NAME, FALSE, &sb) <0) TEST_ERROR; + if(sb.type != H5G_UDLINK) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Pclose (lcpl); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end ud_callbacks() */ + + +/*------------------------------------------------------------------------- + * Function: lapl_udata + * + * Purpose: Check that information can be passed to UD links using the + * Link Access Property List. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +static hid_t +UD_plist_traverse(const char UNUSED * link_name, hid_t cur_group, void UNUSED * udata, size_t udata_size, hid_t lapl_id) +{ + char target[NAME_BUF_SIZE]; + hid_t ret_value; + + if(udata_size != 0) TEST_ERROR; + + /* Get the name of the target from the property list. */ + if(H5Pget(lapl_id, DEST_PROP_NAME, target) < 0) TEST_ERROR; + + if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) + TEST_ERROR; + + return ret_value; + +error: + return -1; +} +const H5L_link_class_t UD_plist_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_PLIST_TYPE, /* Link type id number */ + "UD_plist_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_plist_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + +static int +lapl_udata(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + hid_t plist_id = (-1); /* Property List ID */ + char group_a_name[NAME_BUF_SIZE]; + char group_b_name[NAME_BUF_SIZE]; + char filename[NAME_BUF_SIZE]; + + TESTING("user data passed through lapl"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Register UD link types from previous tests to check that having + * multiple types registered at once presents no problems. */ + if(H5Lregister(UD_cb_class) < 0) TEST_ERROR; + + /* Register the link class. We'll actually be using for this test. */ + if(H5Lregister(UD_plist_class) < 0) TEST_ERROR; + + /* Another link class from a previous test */ + if(H5Lregister(UD_hard_class) < 0) TEST_ERROR; + + /* Unregister the first link type registered to make sure this doesn't + * break anything. */ + if(H5Lunregister(UD_CB_TYPE) < 0) TEST_ERROR; + + /* Create two groups for the UD link to point to */ + if((gid = H5Gcreate(fid, "group_a", 0)) <0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + if((gid = H5Gcreate(fid, "group_b", 0)) <0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Create a user-defined link to the group. These UD links have no udata. */ + if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Create a non-default lapl with a new property pointing to group a*/ + if((plist_id = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR; + strcpy(group_a_name, "group_a"); + if(H5Pinsert(plist_id, DEST_PROP_NAME, NAME_BUF_SIZE, group_a_name, NULL, NULL, NULL, NULL, NULL, NULL) < 0) TEST_ERROR; + + /* Try opening group through UD link */ + if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR; + if((gid2 = H5Gcreate(gid, "subgroup_a", 0)) < 0) TEST_ERROR; + if(H5Gclose(gid2) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Verify that we can open the new group without using the ud link */ + if((gid2 = H5Gopen(fid, "/group_a/subgroup_a")) < 0) TEST_ERROR; + if(H5Gclose(gid2) < 0) TEST_ERROR; + + /* Now use the same ud link to access group_b */ + strcpy(group_b_name, "group_b"); + if(H5Pset(plist_id, DEST_PROP_NAME, group_b_name)<0) TEST_ERROR; + + /* Create a subgroup */ + if((gid = H5Oopen(fid, "ud_link", plist_id)) < 0) TEST_ERROR; + if((gid2 = H5Gcreate(gid, "subgroup_b", 0)) < 0) TEST_ERROR; + if(H5Gclose(gid2) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Verify that we can open the new group without using the ud link */ + if((gid2 = H5Gopen(fid, "/group_b/subgroup_b")) < 0) TEST_ERROR; + if(H5Gclose(gid2) < 0) TEST_ERROR; + + /* Close property list */ + if(H5Pclose(plist_id) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Pclose (plist_id); + H5Gclose (gid); + H5Gclose (gid2); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end lapl_udata() */ + + +/*------------------------------------------------------------------------- + * Function: ud_link_errors + * + * Purpose: Create error conditions in callbacks and ensure that the + * errors propagate correctly. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t UD_cbsucc_create(const char * link_name, hid_t loc_group, void * udata, size_t udata_size, hid_t lcpl_id) +{ + /* Check to make sure that this "soft link" has a target */ + if(udata_size < 1 || !udata) + return -1; + + return 0; +} +static hid_t UD_cbsucc_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id) +{ + const char *target = (char *) udata; + hid_t ret_value; + + if(!target) goto error; + + if((ret_value = H5Oopen(cur_group, target, lapl_id)) < 0) goto error; + + return ret_value; + +error: + return -1; +} +/* Failure callback for when the link is moved or renamed */ +herr_t UD_cbfail_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size) +{ + /* This traversal function will always fail. */ + return -1; +} +/* SuccessCallback for when the link is moved or renamed */ +herr_t UD_cbsucc_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size) +{ + /* This traversal function will always succeed. */ + return 0; +} +/* Callback for when the link is deleted. Also called during move */ +herr_t UD_cbsucc_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size) +{ + /* This callback will always succeed */ + return 0; +} +/* Callback for when the link is deleted. Also called during move */ +herr_t UD_cbfail_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size) +{ + /* This traversal function will always fail. */ + /* Note: un-deletable links are in general a very bad idea! */ + return -1; +} +/* Callback for when the link is queried */ +ssize_t UD_cbfail_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size) +{ + /* This traversal function will always fail. */ + return -1; +} +/* Callback for when the link is queried */ +ssize_t UD_cbfail_on_write_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size) +{ + /* This traversal function will return a buffer size, + * but will fail when a buffer is passed in ("writing to the buffer" + * fails + */ + + if(buf != NULL) + return -1; + + return 0; +} +/* Callback for when the link is queried */ +ssize_t UD_cbsucc_query(const char * link_name, void * udata, size_t udata_size, void *buf, size_t buf_size) +{ + /* This traversal function will return a buffer size, + * but will fail when a buffer is passed in ("writing to the buffer" + * fails + */ + + if(buf != NULL && buf_size >= 8) + strcpy(buf, "succeed"); + + return 8; +} + +/* This class is full of failing callbacks */ +const H5L_link_class_t UD_cbfail_class1[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_CBFAIL_TYPE, /* Link type id number */ + "UD_cbfail_link1", /* Link class name for debugging */ + UD_cbsucc_create, /* Creation callback */ + UD_cbfail_move, /* Move/rename callback */ + UD_cbfail_move, /* Copy callback */ + UD_cbsucc_traverse, /* The actual traversal function */ + UD_cbfail_delete, /* Deletion callback */ + UD_cbfail_query /* Query callback */ +}}; + +/* This class is has two failing callbacks, move and query */ +const H5L_link_class_t UD_cbfail_class2[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_CBFAIL_TYPE, /* Link type id number */ + "UD_cbfail_link2", /* Link class name for debugging */ + UD_cbsucc_create, /* Creation callback */ + UD_cbfail_move, /* Move/rename callback */ + UD_cbsucc_move, /* Copy callback */ + UD_cbsucc_traverse, /* The actual traversal function */ + UD_cbsucc_delete, /* Deletion callback */ + UD_cbfail_on_write_query /* Query callback */ +}}; + +/* All of these callbacks will succeed */ +const H5L_link_class_t UD_cbfail_class3[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_CBFAIL_TYPE, /* Link type id number */ + "UD_cbfail_link3", /* Link class name for debugging */ + UD_cbsucc_create, /* Creation callback */ + UD_cbsucc_move, /* Move/rename callback */ + UD_cbsucc_move, /* Copy callback */ + UD_cbsucc_traverse, /* The actual traversal function */ + UD_cbsucc_delete, /* Deletion callback */ + UD_cbsucc_query /* Query callback */ +}}; + +/* Link classes that are invalid for various reasons */ +const H5L_link_class_t UD_error1_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_ERROR_TYPE, /* Link type id number */ + "UD_error_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + NULL, /* This class has no traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; +const H5L_link_class_t UD_error2_class[1] = {{ + UD_BAD_VERS, /* Invalid H5L_link_class_t version */ + UD_ERROR_TYPE, /* Link type id number */ + "UD_error_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_cbsucc_traverse, /* Traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; +const H5L_link_class_t UD_error3_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_BAD_TYPE1, /* Invalid Link type id number */ + "UD_error_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_cbsucc_traverse, /* Traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; +const H5L_link_class_t UD_error4_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + UD_BAD_TYPE2, /* Invalid Link type id number */ + "UD_error_link", /* Link class name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_cbsucc_traverse, /* Traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + +static int +ud_link_errors(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group IDs */ + char group_name[NAME_BUF_SIZE]; + char filename[NAME_BUF_SIZE]; + char query_buf[NAME_BUF_SIZE]; + H5L_linkinfo_t li; /* Link information */ + + TESTING("user-defined link error conditions"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Try to register some invalid link classes */ + H5E_BEGIN_TRY { + if(H5Lregister(UD_error1_class) >= 0) TEST_ERROR; + if(H5Lregister(UD_error2_class) >= 0) TEST_ERROR; + if(H5Lregister(UD_error3_class) >= 0) TEST_ERROR; + if(H5Lregister(UD_error4_class) >= 0) TEST_ERROR; + } H5E_END_TRY + + /* Register the UD plist class. */ + if(H5Lregister(UD_plist_class) < 0) TEST_ERROR; + /* Now register the first class we'll be using. + * It has the same ID as the plist class, and should replace it. */ + if(H5Lregister(UD_cbfail_class1) < 0) TEST_ERROR; + + /* Create a group for the UD link to point to */ + if((gid = H5Gcreate(fid, "group", 0)) <0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Create a user-defined link to the group. */ + strcpy(group_name, "/group"); + if(H5Lcreate_ud(fid, "/ud_link", UD_CBFAIL_TYPE, &group_name, strlen(group_name) + 1, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Open the group through the ud link */ + if((gid = H5Gopen(fid, "ud_link")) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Now test that each of the callbacks will cause a failure if it returns -1 */ + H5E_BEGIN_TRY { + /* The create callback will fail if we pass in no udata */ + if(H5Lcreate_ud(fid, "fail", UD_CBFAIL_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR; + /* The move and copy callbacks will fail */ + if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR; + if(H5Lcopy(fid, "ud_link", fid, "copy_fail", H5P_DEFAULT, H5P_DEFAULT) >= 0) TEST_ERROR; + /* The traversal callback will fail if we remove its target */ + if(H5Gunlink(fid, "group") < 0) TEST_ERROR; + if((gid = H5Gopen(gid, "ud_link")) >= 0) TEST_ERROR; + /* The deletion callback will always fail */ + if(H5Gunlink(fid, "ud_link") >= 0) TEST_ERROR; + /* The query callback will fail */ + if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) >=0) TEST_ERROR; + } H5E_END_TRY + + /* Now use a class with different callback functions */ + if(H5Lregister(UD_cbfail_class2) < 0) TEST_ERROR; + + /* Moving should still fail, but copying will succeed */ + H5E_BEGIN_TRY { + if(H5Gmove(fid, "ud_link", "move_fail") >= 0) TEST_ERROR + } H5E_END_TRY + if(H5Lcopy(fid, "ud_link", fid, "copy_succ", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* The query callback will succeed when we only want to get the size of the buffer... */ + if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR; + if(li.u.link_size != 0) TEST_ERROR; + /* ...but fail when we try to write data to the buffer itself*/ + H5E_BEGIN_TRY { + if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) >=0) TEST_ERROR; + } H5E_END_TRY + + /* Register a new class */ + if(H5Lregister(UD_cbfail_class3) < 0) TEST_ERROR; + + /* Now querying should succeed */ + if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) <0) TEST_ERROR; + if(li.u.link_size != 8) TEST_ERROR; + if(H5Lget_linkval(fid, "ud_link", NAME_BUF_SIZE, query_buf, H5P_DEFAULT) <0) TEST_ERROR; + if(HDstrcmp(query_buf, "succeed") != 0) TEST_ERROR; + + /* Moving and copying should both succeed */ + if(H5Gmove(fid, "copy_succ", "move_succ") < 0) TEST_ERROR + if(H5Lcopy(fid, "ud_link", fid, "copy_succ2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Delete link (this callback should work now) */ + if(H5Gunlink(fid, "ud_link") <0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} + + + +/*------------------------------------------------------------------------- + * Function: lapl_nlinks + * + * Purpose: Check that the maximum number of soft links can be adjusted + * by the user using the Link Access Property List. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +lapl_nlinks(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1), gid2 = (-1); /* Group IDs */ + hid_t plist = (-1); /* lapl ID */ + hid_t tid = (-1), sid = (-1), did = (-1); /* Other IDs */ + hid_t gapl = (-1), dapl = (-1), tapl = (-1); /* Other property lists */ + char objname[NAME_BUF_SIZE]; /* Object name */ + ssize_t name_len; /* Length of object name */ + char filename[NAME_BUF_SIZE]; + size_t nlinks; /* nlinks for H5Pset_nlinks */ + hsize_t dims[2]; + + TESTING("adjusting nlinks with LAPL"); + + /* Make certain test is valid */ + /* XXX: should probably make a "generic" test that creates the proper + * # of links based on this value - QAK + */ + HDassert(H5G_NLINKS == 16); + + /* Create file */ + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Create group with short name in file (used as target for links) */ + if((gid=H5Gcreate (fid, "final", (size_t)0))<0) TEST_ERROR; + + /* Create chain of soft links to existing object (limited) */ + if(H5Glink2(fid, "final", H5G_LINK_SOFT, fid, "soft1") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft1", H5G_LINK_SOFT, fid, "soft2") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft2", H5G_LINK_SOFT, fid, "soft3") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft3", H5G_LINK_SOFT, fid, "soft4") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft4", H5G_LINK_SOFT, fid, "soft5") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft5", H5G_LINK_SOFT, fid, "soft6") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft6", H5G_LINK_SOFT, fid, "soft7") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft7", H5G_LINK_SOFT, fid, "soft8") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft8", H5G_LINK_SOFT, fid, "soft9") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft9", H5G_LINK_SOFT, fid, "soft10") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft10", H5G_LINK_SOFT, fid, "soft11") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft11", H5G_LINK_SOFT, fid, "soft12") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft12", H5G_LINK_SOFT, fid, "soft13") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft13", H5G_LINK_SOFT, fid, "soft14") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft14", H5G_LINK_SOFT, fid, "soft15") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft15", H5G_LINK_SOFT, fid, "soft16") < 0) TEST_ERROR; + if(H5Glink2(fid, "soft16", H5G_LINK_SOFT, fid, "soft17") < 0) TEST_ERROR; + + /* Close objects */ + if(H5Gclose(gid)<0) TEST_ERROR; + if(H5Fclose(fid)<0) TEST_ERROR; + + /* Open file */ + if((fid=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) TEST_ERROR; + + /* Create LAPL with higher-than-usual nlinks value */ + /* Create a non-default lapl with udata set to point to the first group */ + if((plist = H5Pcreate(H5P_LINK_ACCESS)) < 0) TEST_ERROR; + nlinks = 20; + if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR; + + /* Ensure that nlinks was set successfully */ + nlinks = 0; + if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR + if(nlinks != 20) TEST_ERROR + + /* Open object through what is normally too many soft links using + * new property list */ + if((gid = H5Oopen(fid, "soft17", plist)) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/soft17")) TEST_ERROR + + /* Create group using soft link */ + if((gid2 = H5Gcreate(gid, "new_soft", (size_t)0)) < 0) TEST_ERROR + + /* Close groups */ + if(H5Gclose(gid2) < 0) TEST_ERROR + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Set nlinks to a smaller number */ + nlinks = 4; + if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR; + + /* Ensure that nlinks was set successfully */ + nlinks = 0; + if(H5Pget_nlinks(plist, &nlinks)<0) TEST_ERROR; + if(nlinks != 4) TEST_ERROR; + + /* Try opening through what is now too many soft links */ + H5E_BEGIN_TRY { + gid = H5Oopen(fid, "soft5", plist); + } H5E_END_TRY; + if (gid >= 0) { + H5_FAILED(); + puts(" Should have failed for sequence of too many nested links."); + goto error; + } + + /* Open object through lesser soft link */ + if((gid = H5Oopen(fid, "soft4", plist)) < 0) TEST_ERROR; + + /* Check name */ + if((name_len = H5Iget_name( gid, objname, (size_t)NAME_BUF_SIZE )) < 0) TEST_ERROR + if(HDstrcmp(objname, "/soft4")) TEST_ERROR + + + /* Test other functions that should use a LAPL */ + nlinks = 20; + if(H5Pset_nlinks(plist, nlinks)<0) TEST_ERROR; + + /* Try copying and moving when both src and dst cotain many soft links + * using a non-default LAPL + */ + if(H5Lcopy(fid, "soft17", fid, "soft17/newer_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR + if(H5Lmove(fid, "soft17/newer_soft", fid, "soft17/newest_soft", H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Llink */ + if(H5Llink(fid, "soft17/link_to_group", gid, H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Lcreate_hard and H5Lcreate_soft */ + if(H5Lcreate_hard(fid, "soft17", fid, "soft17/link2_to_group", H5P_DEFAULT, plist) < 0) TEST_ERROR + if(H5Lcreate_soft("/soft4", fid, "soft17/soft_link", H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* H5Lunlink */ + if(H5Lunlink(fid, "soft17/soft_link", plist) < 0) TEST_ERROR + + /* H5Lget_linkval and H5Lget_linkinfo */ + if(H5Lget_linkval(fid, "soft17", 0, NULL, plist) < 0) TEST_ERROR + if(H5Lget_linkinfo(fid, "soft17", NULL, plist) < 0) TEST_ERROR + + /* H5Lcreate_external and H5Lcreate_ud */ + if(H5Lcreate_external("filename", "path", fid, "soft17/extlink", H5P_DEFAULT, plist) <0) TEST_ERROR + if(H5Lregister(UD_rereg_class) < 0) TEST_ERROR + if(H5Lcreate_ud(fid, "soft17/udlink", UD_HARD_TYPE, NULL, 0, H5P_DEFAULT, plist) < 0) TEST_ERROR + + /* Close plist */ + if(H5Pclose(plist) < 0) TEST_ERROR; + + + /* Create a datatype and dataset as targets inside the group */ + if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR + if(H5Tcommit(gid, "datatype", tid) < 0) TEST_ERROR + if(H5Tclose(tid) < 0) TEST_ERROR + + dims[0] = 2; + dims[1] = 2; + if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR + if((did = H5Dcreate(gid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR; + + /* Close group */ + if(H5Gclose(gid) < 0) TEST_ERROR; + + /* Try to open the objects using too many symlinks with default *APLs */ + H5E_BEGIN_TRY { + if((gid = H5Gopen_expand(fid, "soft17", H5P_DEFAULT)) >=0) { + H5_FAILED(); + puts(" Should have failed for too many nested links."); + TEST_ERROR; + } + if((tid = H5Topen_expand(fid, "soft17/datatype", H5P_DEFAULT)) >=0) { + H5_FAILED(); + puts(" Should have failed for too many nested links."); + TEST_ERROR; + } + if((did = H5Dopen_expand(fid, "soft17/dataset", H5P_DEFAULT)) >=0) { + H5_FAILED(); + puts(" Should have failed for too many nested links."); + TEST_ERROR; + } + } H5E_END_TRY + + /* Create property lists with nlinks set */ + if((gapl = H5Pcreate(H5P_GROUP_ACCESS)) < 0) TEST_ERROR + if((tapl = H5Pcreate(H5P_DATATYPE_ACCESS)) < 0) TEST_ERROR + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) TEST_ERROR + + nlinks = 20; + if(H5Pset_nlinks(gapl, nlinks) < 0) TEST_ERROR + if(H5Pset_nlinks(tapl, nlinks) < 0) TEST_ERROR + if(H5Pset_nlinks(dapl, nlinks) < 0) TEST_ERROR + + /* We should now be able to use these property lists to open each kind + * of object. + */ + if((gid = H5Gopen_expand(fid, "soft17", gapl)) <0) TEST_ERROR + if((tid = H5Topen_expand(fid, "soft17/datatype", tapl)) <0) TEST_ERROR + if((did = H5Dopen_expand(fid, "soft17/dataset", dapl)) <0) TEST_ERROR + + /* Close objects */ + if(H5Gclose(gid) < 0) TEST_ERROR + if(H5Tclose(tid) < 0) TEST_ERROR + if(H5Dclose(did) < 0) TEST_ERROR + + /* Close plists */ + if(H5Pclose(gapl) < 0) TEST_ERROR; + if(H5Pclose(tapl) < 0) TEST_ERROR; + if(H5Pclose(dapl) < 0) TEST_ERROR; + + /* Close file */ + if(H5Fclose(fid)<0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Pclose(gapl); + H5Pclose(dapl); + H5Pclose(tapl); + H5Dclose(did); + H5Sclose(sid); + H5Tclose(tid); + H5Gclose(gid2); + H5Gclose(gid); + H5Pclose(plist); + H5Fclose(fid); + } H5E_END_TRY; + return -1; +} /* end lapl_nlinks() */ + +/*------------------------------------------------------------------------- + * Function: objinfo_linkclass + * + * Purpose: Check that the link class is returned correctly when queried. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + *------------------------------------------------------------------------- + */ +static int +linkinfo(hid_t fapl) +{ + hid_t fid = (-1); /* File ID */ + hid_t gid = (-1); /* Group ID */ + hid_t tid = (-1); /* Type ID */ + hid_t sid = (-1), did = -(1); /* Dataspace and dataset IDs */ + H5L_linkinfo_t li; /* Link information */ + char filename[NAME_BUF_SIZE]; + + TESTING("linkclass field in H5Gget_objinfo"); + + /* Set up filename and create file*/ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + if((fid=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) TEST_ERROR; + + /* Register a couple of user-defined link classes with the library */ + if(H5Lregister(UD_plist_class) < 0) TEST_ERROR; + + /* Create an object of each type */ + if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; + if(H5Tcommit(fid, "datatype", tid) < 0) TEST_ERROR; + if((gid = H5Gcreate(fid, "group", 0)) < 0) TEST_ERROR; + if(H5Glink(fid, H5G_LINK_SOFT, "group", "softlink") < 0) TEST_ERROR; + + if((sid = H5Screate(H5S_SCALAR)) < 0) TEST_ERROR; + if((did = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR; + + if(H5Lcreate_ud(fid, "ud_link", UD_PLIST_TYPE, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lcreate_external("file_name", "obj_path", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Close all objects */ + if(H5Tclose(tid) < 0) TEST_ERROR; + if(H5Gclose(gid) < 0) TEST_ERROR; + if(H5Dclose(did) < 0) TEST_ERROR; + + /* Make sure that linkclass is correct when objects are queried */ + if(H5Lget_linkinfo(fid, "datatype", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != H5L_LINK_HARD) TEST_ERROR; + if(H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != H5L_LINK_HARD) TEST_ERROR; + if(H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != H5L_LINK_HARD) TEST_ERROR; + + if(H5Lget_linkinfo(fid, "ext_link", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != H5L_LINK_EXTERNAL) TEST_ERROR; + if(H5Lget_linkinfo(fid, "softlink", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != H5G_LINK_SOFT) TEST_ERROR; + if(H5Lget_linkinfo(fid, "ud_link", &li, H5P_DEFAULT) < 0) TEST_ERROR; + if(li.linkclass != UD_PLIST_TYPE) TEST_ERROR; + + /* Ensure that passing a NULL pointer doesn't cause an error */ + if(H5Lget_linkinfo(fid, "group", NULL, H5P_DEFAULT) < 0) TEST_ERROR; + + if(H5Fclose(fid) < 0) TEST_ERROR; + + PASSED(); + return 0; + + error: + H5E_BEGIN_TRY { + H5Tclose (tid); + H5Dclose (did); + H5Gclose (gid); + H5Fclose (fid); + } H5E_END_TRY; + return -1; +} /* end ud_hard_links() */ + + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Test links @@ -1467,7 +4717,6 @@ main(void) if (HDstrcmp(envval, "core") && HDstrcmp(envval, "split")) { h5_reset(); fapl = h5_fileaccess(); - /* The tests... */ nerrors += mklinks(fapl) < 0 ? 1 : 0; nerrors += cklinks(fapl) < 0 ? 1 : 0; @@ -1488,6 +4737,39 @@ main(void) #endif nerrors += test_compat(fapl); + nerrors += external_link_root(fapl) < 0 ? 1 : 0; + nerrors += external_link_path(fapl) < 0 ? 1 : 0; + nerrors += external_link_mult(fapl) < 0 ? 1 : 0; +#ifdef H5_GROUP_REVISION + nerrors += external_link_self(fapl) < 0 ? 1 : 0; +#endif + nerrors += external_link_pingpong(fapl) < 0 ? 1 : 0; + nerrors += external_link_toomany(fapl) < 0 ? 1 : 0; + nerrors += external_link_dangling(fapl) < 0 ? 1 : 0; + nerrors += external_link_recursive(fapl) < 0 ? 1 : 0; + nerrors += external_link_query(fapl) < 0 ? 1 : 0; + nerrors += external_link_unlink_compact(fapl) < 0 ? 1 : 0; +#ifdef H5_GROUP_REVISION + nerrors += external_link_unlink_dense(fapl) < 0 ? 1 : 0; +#endif /* H5_GROUP_REVISION */ + nerrors += external_link_move(fapl) < 0 ? 1 : 0; +#ifdef H5_GROUP_REVISION + nerrors += external_link_ride(fapl) < 0 ? 1 : 0; +#endif /* H5_GROUP_REVISION */ + nerrors += ext_link_endian(fapl) < 0 ? 1 : 0; + + /* These tests assume that external links are a form of UD links, + * so assume that everything that passed for external links + * above has already been tested for UD links. + */ + nerrors += ud_hard_links(fapl) < 0 ? 1 : 0; + nerrors += ud_link_reregister(fapl) < 0 ? 1 : 0; + nerrors += ud_callbacks(fapl) < 0 ? 1 : 0; + nerrors += ud_link_errors(fapl) < 0 ? 1 : 0; + nerrors += lapl_udata(fapl) < 0 ? 1 : 0; + nerrors += lapl_nlinks(fapl) < 0 ? 1 : 0; + nerrors += linkinfo(fapl) < 0 ? 1 : 0; + /* Results */ if (nerrors) { printf("***** %d LINK TEST%s FAILED! *****\n", @@ -1505,3 +4787,4 @@ main(void) } + diff --git a/test/mount.c b/test/mount.c index 8e5a903..cfd99dc 100644 --- a/test/mount.c +++ b/test/mount.c @@ -71,8 +71,8 @@ setup(hid_t fapl) if (H5Gclose(H5Gcreate(file, "/mnt1/file1", (size_t)0))<0) goto error; if (H5Gclose(H5Gcreate(file, "/mnt_unlink", (size_t)0))<0) goto error; if (H5Gclose(H5Gcreate(file, "/mnt_move_a", (size_t)0))<0) goto error; - if (H5Glink(file, H5G_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error; - if (H5Glink(file, H5G_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error; + if (H5Glink(file, H5L_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error; + if (H5Glink(file, H5L_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error; if (H5Fclose(file)<0) goto error; /* file 2 */ @@ -486,9 +486,9 @@ test_move(hid_t fapl) if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error; /* First rename an object in the mounted file, then try it across files */ - if (H5Gmove(file1, "/mnt1/rename_a/x", "/mnt1/rename_b/y")<0) goto error; + if (H5Lmove(file1, "/mnt1/rename_a/x", H5L_SAME_LOC, "/mnt1/rename_b/y", H5P_DEFAULT, H5P_DEFAULT)<0) goto error; H5E_BEGIN_TRY { - status = H5Gmove(file1, "/mnt1/rename_b/y", "/y"); + status = H5Lmove(file1, "/mnt1/rename_b/y", H5L_SAME_LOC, "/y", H5P_DEFAULT, H5P_DEFAULT); } H5E_END_TRY; if (status>=0) { H5_FAILED(); @@ -796,7 +796,7 @@ test_mvmpt(hid_t fapl) if (H5Fmount(file1, "/mnt_move_a", file2, H5P_DEFAULT)<0) TEST_ERROR /* Rename the mount point */ - if (H5Gmove(file1, "/mnt_move_a", "/mnt_move_b")<0) TEST_ERROR + if (H5Lmove(file1, "/mnt_move_a", H5L_SAME_LOC, "/mnt_move_b", H5P_DEFAULT, H5P_DEFAULT)<0) TEST_ERROR /* Access something under the new name */ if (H5Gget_objinfo(file1, "/mnt_move_b/file2", TRUE, NULL)<0) TEST_ERROR @@ -854,7 +854,7 @@ test_interlink(hid_t fapl) /* Try an interfile hard link directly */ H5E_BEGIN_TRY { - status = H5Glink(file1, H5G_LINK_HARD, "/mnt1/file2", "/file2"); + status = H5Glink(file1, H5L_LINK_HARD, "/mnt1/file2", "/file2"); } H5E_END_TRY; if (status>=0) { H5_FAILED(); @@ -864,7 +864,7 @@ test_interlink(hid_t fapl) /* Try an interfile hard link by renaming something */ H5E_BEGIN_TRY { - status = H5Gmove(file1, "/mnt1/file2", "/file2"); + status = H5Lmove(file1, "/mnt1/file2", H5L_SAME_LOC, "/file2", H5P_DEFAULT, H5P_DEFAULT); } H5E_END_TRY; if (status>=0) { H5_FAILED(); @@ -1108,9 +1108,9 @@ test_mount_after_close(hid_t fapl) TEST_ERROR if((gidABM = H5Gcreate(gidAB , "M", (size_t)0)) < 0) /* Mount point */ TEST_ERROR - if(H5Glink(gidAB, H5G_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */ + if(H5Glink(gidAB, H5L_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */ TEST_ERROR - if(H5Glink(gidAB, H5G_LINK_SOFT, "/A", "T") < 0) /* Soft link */ + if(H5Glink(gidAB, H5L_LINK_SOFT, "/A", "T") < 0) /* Soft link */ TEST_ERROR /* Close groups and file */ @@ -1144,7 +1144,7 @@ test_mount_after_close(hid_t fapl) TEST_ERROR if((did = H5Dcreate(gidXY, "D", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Glink(gidX, H5G_LINK_SOFT, "./Y", "T") < 0) /* Soft link */ + if(H5Glink(gidX, H5L_LINK_SOFT, "./Y", "T") < 0) /* Soft link */ TEST_ERROR /* Write data to the dataset. */ @@ -1450,7 +1450,7 @@ test_mount_after_unmount(hid_t fapl) /* Rename object in file #3 that is "disconnected" from name hiearchy */ /* (It is "disconnected" because it's parent file has been unmounted) */ - if(H5Gmove2(gidAMX,"M/Y",gidAMX,"M/Z") < 0) + if(H5Lmove(gidAMX,"M/Y",gidAMX,"M/Z", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR /* Close group in file #3 */ @@ -3686,7 +3686,7 @@ test_symlink(hid_t fapl) TEST_ERROR /* Create soft link to mounted object */ - if(H5Glink(fid1, H5G_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */ + if(H5Glink(fid1, H5L_LINK_SOFT, "./A/D/H", "L") < 0) /* Soft link */ TEST_ERROR if(H5Fclose(fid1) < 0) diff --git a/test/objcopy.c b/test/objcopy.c index a96d5b0..7efef50 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -25,6 +25,7 @@ const char *FILENAME[] = { "objcopy_src", "objcopy_dst", + "objcopy_ext", NULL }; @@ -63,6 +64,7 @@ const char *FILENAME[] = { #define NAME_LINK_HARD "/g_links/hard_link_to_dataset_simple" #define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple" #define NAME_LINK_SOFT2 "/g_links2/soft_link_to_dataset_simple" +#define NAME_LINK_EXTERN "/g_links/external_link_to_dataset_simple" #define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere" #define NAME_LINK_SOFT_DANGLE2 "/g_links2/soft_link_to_nowhere" @@ -817,6 +819,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth) H5G_obj_t objtype2; /* Type of object in group */ H5G_stat_t objstat; /* Object info */ H5G_stat_t objstat2; /* Object info */ + H5L_linkinfo_t linfo; /* Link information */ + H5L_linkinfo_t linfo2; /* Link information */ hid_t oid, oid2; /* IDs of objects within group */ /* Loop over contents of groups */ @@ -835,12 +839,16 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth) if(H5Gget_objinfo(gid, objname, FALSE, &objstat) < 0) TEST_ERROR; if(H5Gget_objinfo(gid2, objname2, FALSE, &objstat2) < 0) TEST_ERROR; if(objstat.type != objstat2.type) TEST_ERROR; - if(objstat.type != H5G_LINK) { + if(objstat.type != H5G_LINK && objstat.type != H5G_UDLINK) { if(objstat.nlink != objstat2.nlink) TEST_ERROR; if(objstat.ohdr.nmesgs != objstat2.ohdr.nmesgs) TEST_ERROR; if(objstat.ohdr.nchunks != objstat2.ohdr.nchunks) TEST_ERROR; } /* end if */ + /* Get link info */ + if(H5Lget_linkinfo(gid, objname, &linfo, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lget_linkinfo(gid2, objname2, &linfo2, H5P_DEFAULT) < 0) TEST_ERROR; + /* Check for object already having been compared */ if(addr_lookup(&objstat)) continue; @@ -855,8 +863,8 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth) char linkname2[NAME_BUF_SIZE]; /* Link value */ /* Check link values */ - if(H5Gget_linkval(gid, objname, NAME_BUF_SIZE, linkname) < 0) TEST_ERROR; - if(H5Gget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2) < 0) TEST_ERROR; + if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkname, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkname2, H5P_DEFAULT) < 0) TEST_ERROR; if(HDstrcmp(linkname, linkname2)) TEST_ERROR; } break; @@ -900,6 +908,24 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth) if(H5Tclose(oid2) < 0) TEST_ERROR; break; + case H5G_UDLINK: + { + char linkval[NAME_BUF_SIZE]; /* Link value */ + char linkval2[NAME_BUF_SIZE]; /* Link value */ + + /* Check that both links are the same type and the same size */ + if(linfo.linkclass != linfo2.linkclass) TEST_ERROR; + if(linfo.u.link_size != linfo2.u.link_size) TEST_ERROR; + + /* Get link udata */ + if(H5Lget_linkval(gid, objname, NAME_BUF_SIZE, linkval, H5P_DEFAULT) < 0) TEST_ERROR; + if(H5Lget_linkval(gid2, objname2, NAME_BUF_SIZE, linkval2, H5P_DEFAULT) < 0) TEST_ERROR; + + /* Compare link udata */ + if(HDmemcmp(linkval, linkval2, objstat.linklen)) TEST_ERROR; + } + break; + default: HDassert(0 && "Unknown type of object"); break; @@ -4102,7 +4128,7 @@ test_copy_group_loop(hid_t fapl) if ( (gid_sub2 = H5Gcreate(gid, NAME_GROUP_SUB_SUB, (size_t)0)) < 0) TEST_ERROR; /* Create link to top group */ - if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR; + if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR; /* close sub sub group */ if( H5Gclose(gid_sub2) < 0) TEST_ERROR; @@ -4223,13 +4249,13 @@ test_copy_group_wide_loop(hid_t fapl) if ( (gid_sub2 = H5Gcreate(gid_sub, objname, (size_t)0)) < 0) TEST_ERROR; /* Create link to top group */ - if ( H5Glink2(gid, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR; + if ( H5Glink2(gid, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP) < 0) TEST_ERROR; /* Create link to sub-group */ - if ( H5Glink2(gid_sub, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR; + if ( H5Glink2(gid_sub, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP2) < 0) TEST_ERROR; /* Create link to self :-) */ - if ( H5Glink2(gid_sub2, ".", H5G_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR; + if ( H5Glink2(gid_sub2, ".", H5L_LINK_HARD, gid_sub2, NAME_GROUP_LOOP3) < 0) TEST_ERROR; /* close sub sub group */ if( H5Gclose(gid_sub2) < 0) TEST_ERROR; @@ -4364,13 +4390,16 @@ test_copy_group_links(hid_t fapl) if (H5Dclose(did) < 0) TEST_ERROR; /* make a hard link to the dataset */ - if (H5Glink(fid_src, H5G_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_HARD, NAME_LINK_DATASET, NAME_LINK_HARD) < 0) TEST_ERROR; /* make a soft link to the dataset */ - if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR; /* make a soft link to nowhere */ - if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR; + + /* make a dangling external link */ + if (H5Lcreate_external("filename", "obj_name", fid_src, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; /* close the group */ if ( H5Gclose(gid) < 0) TEST_ERROR; @@ -4496,7 +4525,7 @@ test_copy_soft_link(hid_t fapl) if (H5Dclose(did) < 0) TEST_ERROR; /* make a soft link to the dataset */ - if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_LINK_DATASET, NAME_LINK_SOFT) < 0) TEST_ERROR; /* close the group */ if ( H5Gclose(gid) < 0) TEST_ERROR; @@ -4555,6 +4584,141 @@ error: /*------------------------------------------------------------------------- + * Function: test_copy_ext_link + * + * Purpose: Create an external link in SRC file and copy it to DST file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: James Laird + * Friday, June 16, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_ext_link(hid_t fapl) +{ + hid_t fid_src = -1, fid_dst = -1, fid_ext = -1; /* File IDs */ + hid_t sid = -1; /* Dataspace ID */ + hid_t did = -1, did2 = -1; /* Dataset IDs */ + hid_t gid = -1; /* Group ID */ + hsize_t dim2d[2]; + int buf[DIM_SIZE_1][DIM_SIZE_2]; + int i, j; + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + char ext_filename[NAME_BUF_SIZE]; + + TESTING("H5Gcopy(): object through external link"); + + /* set initial data values */ + for (i=0; i<DIM_SIZE_1; i++) + for (j=0; j<DIM_SIZE_2; j++) + buf[i][j] = 10000 + 100*i+j; + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename); + h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename); + h5_fixname(FILENAME[2], fapl, ext_filename, sizeof dst_filename); + + /* Reset file address checking info */ + addr_reset(); + + /* create source file */ + if ( (fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* create group at the SRC file */ + if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR; + + /* attach attributes to the group */ + if ( test_copy_attach_attributes(gid, H5T_NATIVE_INT) < 0) TEST_ERROR; + + /* Set dataspace dimensions */ + dim2d[0]=DIM_SIZE_1; + dim2d[1]=DIM_SIZE_2; + + /* create dataspace */ + if ( (sid = H5Screate_simple(2, dim2d, NULL)) < 0) TEST_ERROR; + + /* add a dataset to the group */ + if ( (did = H5Dcreate(fid_src, NAME_LINK_DATASET, H5T_NATIVE_INT, sid, H5P_DEFAULT) ) < 0) TEST_ERROR; + if ( H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR; + + /* close dataspace */ + if ( H5Sclose(sid) < 0) TEST_ERROR; + /* close the dataset */ + if (H5Dclose(did) < 0) TEST_ERROR; + /* close the group */ + if ( H5Gclose(gid) < 0) TEST_ERROR; + + + /* create file to hold external links to the src file */ + if ( (fid_ext = H5Fcreate(ext_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* create group in the external file */ + if ( (gid = H5Gcreate(fid_ext, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR; + + /* Create an external link to the dataset */ + if ( H5Lcreate_external(src_filename, NAME_LINK_DATASET, fid_ext, NAME_LINK_EXTERN, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* close the group and file */ + if ( H5Gclose(gid) < 0) TEST_ERROR; + if (H5Fclose(fid_ext) < 0) TEST_ERROR; + + /* open the "extern" file with read-only */ + if ( (fid_ext = H5Fopen(ext_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; + + /* create destination file */ + if ( (fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + if ( H5Gclose(H5Gcreate(fid_dst, NAME_GROUP_UNCOPIED, (size_t)0)) < 0) TEST_ERROR; + + /* copy the dataset from SRC to DST */ + if ( H5Gcopy(fid_ext, NAME_LINK_EXTERN, fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR; + + /* open the dataset through the external link */ + if ( (did = H5Dopen(fid_ext, NAME_LINK_EXTERN)) < 0) TEST_ERROR; + + /* open the destination dataset */ + if ( (did2 = H5Dopen(fid_dst, NAME_DATASET_SIMPLE)) < 0) TEST_ERROR; + + /* Check if the datasets are equal */ + if ( compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR; + + /* close the destination dataset */ + if ( H5Dclose(did2) < 0) TEST_ERROR; + + /* close the source dataset */ + if ( H5Dclose(did) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + /* close the EXT file */ + if ( H5Fclose(fid_ext) < 0) TEST_ERROR; + + /* close the DST file */ + if ( H5Fclose(fid_dst) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + H5Dclose(did2); + H5Dclose(did); + H5Gclose(gid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + } H5E_END_TRY; + return 1; +} /* end test_copy_ext_link */ + + +/*------------------------------------------------------------------------- * Function: test_copy_exist * * Purpose: Create a simple dataset in SRC file and copy it onto an @@ -6197,14 +6361,14 @@ test_copy_option(hid_t fapl, unsigned flag, hbool_t crt_intermediate_grp, const if ((flag & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0) { /* Create group to copy */ if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK, (size_t)0)) < 0) TEST_ERROR; - if (H5Glink(fid_src, H5G_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR; - if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE) < 0) TEST_ERROR; if ( H5Gclose(gid) < 0) TEST_ERROR; /* Create group to compare with */ if ( (gid = H5Gcreate(fid_src, NAME_GROUP_LINK2, (size_t)0)) < 0) TEST_ERROR; - if (H5Glink(fid_src, H5G_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR; - if (H5Glink(fid_src, H5G_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_HARD, NAME_DATASET_SUB_SUB, NAME_LINK_SOFT2) < 0) TEST_ERROR; + if (H5Glink(fid_src, H5L_LINK_SOFT, "nowhere", NAME_LINK_SOFT_DANGLE2) < 0) TEST_ERROR; if ( H5Gclose(gid) < 0) TEST_ERROR; } @@ -6396,6 +6560,7 @@ main(void) nerrors += test_copy_group_wide_loop(fapl); nerrors += test_copy_group_links(fapl); nerrors += test_copy_soft_link(fapl); + nerrors += test_copy_ext_link(fapl); nerrors += test_copy_exist(fapl); nerrors += test_copy_path(fapl); nerrors += test_copy_same_file_named_datatype(fapl); diff --git a/test/stab.c b/test/stab.c index 2562423..b684f9e 100644 --- a/test/stab.c +++ b/test/stab.c @@ -330,7 +330,7 @@ lifecycle(hid_t fapl) /* Create group for testing lifecycle */ if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR - if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR + if((H5Llink(fid, LIFECYCLE_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Query group creation property settings */ if(H5Pget_local_heap_size_hint(gcpl, &lheap_size_hint) < 0) TEST_ERROR; @@ -789,7 +789,7 @@ no_compact(hid_t fapl) /* Create group for testing lifecycle */ if((gid = H5Gcreate_expand(fid, gcpl, H5P_DEFAULT)) < 0) TEST_ERROR - if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT)) < 0) TEST_ERROR + if((H5Llink(fid, NO_COMPACT_TOP_GROUP, gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR /* Close GCPL */ if(H5Pclose(gcpl) < 0) TEST_ERROR; @@ -920,7 +920,7 @@ gcpl_on_root(hid_t fapl) /* Create a group and intermediate groups, to check if root group settings are inherited */ if((gid2 = H5Gcreate_expand(gid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid, lcpl)) < 0) TEST_ERROR + if((H5Llink(fid, GCPL_ON_ROOT_BOTTOM_GROUP, gid2, lcpl, H5P_DEFAULT)) < 0) TEST_ERROR /* Close LCPL */ if(H5Pclose(lcpl) < 0) TEST_ERROR; diff --git a/test/testhdf5.c b/test/testhdf5.c index 925b8f8..eadc2bd 100644 --- a/test/testhdf5.c +++ b/test/testhdf5.c @@ -50,6 +50,7 @@ main(int argc, char *argv[]) AddTest("skiplist", test_skiplist, NULL, "Skip Lists", NULL); AddTest("refstr", test_refstr, NULL, "Reference Counted Strings", NULL); AddTest("file", test_file, cleanup_file, "Low-Level File I/O", NULL); + AddTest("objects", test_h5o, cleanup_file, "Generic Object Functions", NULL); AddTest("h5s", test_h5s, cleanup_h5s, "Dataspaces", NULL); AddTest("attr", test_attr, cleanup_attr, "Attributes", NULL); AddTest("select", test_select, cleanup_select, "Selections", NULL); diff --git a/test/testhdf5.h b/test/testhdf5.h index 2274b78..b4f1342 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -127,6 +127,7 @@ void test_tst(void); void test_heap(void); void test_refstr(void); void test_file(void); +void test_h5o(void); void test_h5t(void); void test_h5s(void); void test_h5d(void); @@ -148,6 +149,7 @@ void test_unicode(void); /* Prototypes for the cleanup routines */ void cleanup_metadata(void); void cleanup_file(void); +void cleanup_h5o(void); void cleanup_h5s(void); void cleanup_attr(void); void cleanup_select(void); diff --git a/test/th5o.c b/test/th5o.c new file mode 100644 index 0000000..fde15c7 --- /dev/null +++ b/test/th5o.c @@ -0,0 +1,601 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*********************************************************** +* +* Test program: th5o +* +* Test public H5O functions for accessing +* +*************************************************************/ + +#include "testhdf5.h" + +/*#include "H5private.h" +#include "H5Bprivate.h" +#include "H5Sprivate.h" +#include "H5Pprivate.h" +*/ + +#define TEST_FILENAME "th5o_file" + +#define RANK 2 +#define DIM0 5 +#define DIM1 10 + +/**************************************************************** +** +** test_h5o_open(): Test H5Oopen function. +** +****************************************************************/ +static void +test_h5o_open(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + hsize_t dims[RANK]; + H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ + hsize_t num_objs=-1; /* Number of objects in the group */ + H5T_class_t type_class; /* Class of the datatype */ + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group */ + grp = H5Gcreate(fid, "group", 0); + CHECK(grp, FAIL, "H5Gcreate"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit(fid, "group/datatype", dtype); + CHECK(ret, FAIL, "H5Tcommit"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Now make sure that H5Oopen can open all three types of objects */ + grp = H5Oopen(fid, "group", H5P_DEFAULT); + CHECK(grp, FAIL, "H5Oopen"); + dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT); + CHECK(dtype, FAIL, "H5Oopen"); + /* Check that we can use the group as a valid location */ + dset = H5Oopen(grp, "/dataset", H5P_DEFAULT); + CHECK(dset, FAIL, "H5Oopen"); + + /* Make sure that each is the right kind of ID */ + id_type = H5Iget_type(grp); + VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID"); + id_type = H5Iget_type(dtype); + VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID"); + id_type = H5Iget_type(dset); + VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID"); + + /* Do something more complex with each of the IDs to make sure they "work" */ + ret = H5Gget_num_objs(grp, &num_objs); + CHECK(ret, FAIL, "H5Gget_num_objs"); + VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */ + + type_class = H5Tget_class(dtype); + VERIFY(type_class, H5T_INTEGER, "H5Tget_class"); + + dspace = H5Dget_space(dset); + CHECK(dspace, FAIL, "H5Dget_space"); + + /* Close the IDs */ + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Trying to open objects with bogus names should fail gracefully */ + H5E_BEGIN_TRY { + grp = H5Oopen(fid, "bogus_group", H5P_DEFAULT); + VERIFY(grp, FAIL, "H5Oopen"); + dtype = H5Oopen(fid, "group/bogus_datatype", H5P_DEFAULT); + VERIFY(dtype, FAIL, "H5Oopen"); + dset = H5Oopen(fid, "/bogus_dataset", H5P_DEFAULT); + VERIFY(dset, FAIL, "H5Oopen"); + } H5E_END_TRY + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Trying to open an object with a bogus file ID should fail */ + H5E_BEGIN_TRY { + dset = H5Oopen(fid, "dataset", H5P_DEFAULT); + VERIFY(dset, FAIL, "H5Oopen"); + } H5E_END_TRY +} /* test_h5o_open() */ + + + +/**************************************************************** +** +** test_h5o_close(): Test H5Oclose function. +** +****************************************************************/ +static void +test_h5o_close(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + hsize_t dims[RANK]; + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group and close it with H5Oclose */ + grp = H5Gcreate(fid, "group", 0); + CHECK(grp, FAIL, "H5Gcreate"); + VERIFY(H5Iget_type(grp), H5I_GROUP, "H5Iget_type"); + ret = H5Oclose(grp); + CHECK(ret, FAIL, "H5Oclose"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit(fid, "group/datatype", dtype); + CHECK(ret, FAIL, "H5Tcommit"); + ret = H5Oclose(dtype); + CHECK(ret, FAIL, "H5Oclose"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate"); + ret = H5Oclose(dset); + CHECK(ret, FAIL, "H5Oclose"); + + /* Attempting to close the data space with H5Oclose should fail */ + H5E_BEGIN_TRY { + ret = H5Oclose(dspace); + VERIFY(ret, FAIL, "H5Oclose"); + } H5E_END_TRY + /* Close the dataspace for real */ + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Make sure that H5Oclose can close objects opened with H5Oopen */ + grp = H5Oopen(fid, "group", H5P_DEFAULT); + CHECK(grp, FAIL, "H5Oopen"); + dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT); + CHECK(dtype, FAIL, "H5Oopen"); + dset = H5Oopen(fid, "dataset", H5P_DEFAULT); + CHECK(dset, FAIL, "H5Oopen"); + + ret = H5Oclose(grp); + CHECK(ret, FAIL, "H5Oclose"); + ret = H5Oclose(dtype); + CHECK(ret, FAIL, "H5Oclose"); + ret = H5Oclose(dset); + CHECK(ret, FAIL, "H5Oclose"); + + /* Make sure H5Oclose can close objects opened with H5*open */ + grp = H5Gopen(fid, "group"); + CHECK(grp, FAIL, "H5Gopen"); + dtype = H5Topen(fid, "group/datatype"); + CHECK(dtype, FAIL, "H5Topen"); + dset = H5Dopen(fid, "dataset"); + CHECK(dset, FAIL, "H5Dopen"); + + ret = H5Oclose(grp); + CHECK(ret, FAIL, "H5Oclose"); + ret = H5Oclose(dtype); + CHECK(ret, FAIL, "H5Oclose"); + ret = H5Oclose(dset); + CHECK(ret, FAIL, "H5Oclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} + + +/**************************************************************** +** +** test_h5o_open_by_addr(): Test H5Oopen_by_addr function. +** +****************************************************************/ +static void +test_h5o_open_by_addr(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + H5L_linkinfo_t li; /* Buffer for H5Lget_linkinfo */ + haddr_t grp_addr; /* Addresses for objects */ + haddr_t dset_addr; + haddr_t dtype_addr; + hsize_t dims[RANK]; + H5I_type_t id_type; /* Type of IDs returned from H5Oopen */ + hsize_t num_objs=-1; /* Number of objects in the group */ + H5T_class_t type_class; /* Class of the datatype */ + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group */ + grp = H5Gcreate(fid, "group", 0); + CHECK(grp, FAIL, "H5Gcreate"); + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit(fid, "group/datatype", dtype); + CHECK(ret, FAIL, "H5Tcommit"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get address for each object */ + ret = H5Lget_linkinfo(fid, "group", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_linkinfo"); + grp_addr = li.u.address; + ret = H5Lget_linkinfo(fid, "group/datatype", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_linkinfo"); + dtype_addr = li.u.address; + ret = H5Lget_linkinfo(fid, "dataset", &li, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lget_linkinfo"); + dset_addr = li.u.address; + + /* Now make sure that H5Oopen_by_addr can open all three types of objects */ + grp = H5Oopen_by_addr(fid, grp_addr); + CHECK(grp, FAIL, "H5Oopen_by_addr"); + dtype = H5Oopen_by_addr(fid, dtype_addr); + CHECK(dtype, FAIL, "H5Oopen_by_addr"); + /* Check that we can use the group ID as a valid location */ + dset = H5Oopen_by_addr(grp, dset_addr); + CHECK(dset, FAIL, "H5Oopen_by_addr"); + + /* Make sure that each is the right kind of ID */ + id_type = H5Iget_type(grp); + VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID"); + id_type = H5Iget_type(dtype); + VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID"); + id_type = H5Iget_type(dset); + VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID"); + + /* Do something more complex with each of the IDs to make sure they "work" */ + ret = H5Gget_num_objs(grp, &num_objs); + CHECK(ret, FAIL, "H5Gget_num_objs"); + VERIFY(num_objs, 1, "H5Gget_num_objs"); /* There should be one object, the datatype */ + + type_class = H5Tget_class(dtype); + VERIFY(type_class, H5T_INTEGER, "H5Tget_class"); + + dspace = H5Dget_space(dset); + CHECK(dspace, FAIL, "H5Dget_space"); + + /* Close the IDs */ + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Try giving some bogus values to H5O_open_by_addr. */ + /* Try to open an object with a bad address */ + grp_addr += 20; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + /* For instance, an objectno smaller than the end of the file's superblock should + * trigger an error */ + grp_addr = 10; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + /* Likewise, an objectno larger than the size of the file should fail */ + grp_addr = 0; + grp_addr = 1000000000; + H5E_BEGIN_TRY{ + grp = H5Oopen_by_addr(fid, grp_addr); + }H5E_END_TRY + VERIFY(grp, FAIL, "H5Oopen_by_addr"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Also, trying to open an object without a valid location should fail */ + H5E_BEGIN_TRY{ + dtype = H5Oopen_by_addr(fid, dtype_addr); + }H5E_END_TRY + VERIFY(dtype, FAIL, "H5Oopen_by_addr"); +} /* test_h5o_open_by_addr() */ + + +/**************************************************************** +** +** test_h5o_refcount(): Test H5O refcounting functions. +** +****************************************************************/ +static void +test_h5o_refcount(void) +{ + hid_t fid; /* HDF5 File ID */ + hid_t grp, dset, dtype, dspace; /* Object identifiers */ + H5G_stat_t sb; /* Statbuffer for H5Gget_objinfo */ + hsize_t dims[RANK]; + herr_t ret; /* Value returned from API calls */ + + /* Create a new HDF5 file */ + fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a group, dataset, and committed datatype within the file */ + /* Create the group */ + grp = H5Gcreate(fid, "group", 0); + CHECK(grp, FAIL, "H5Gcreate"); + + /* Commit the type inside the group */ + dtype = H5Tcopy(H5T_NATIVE_INT); + CHECK(dtype, FAIL, "H5Tcopy"); + ret = H5Tcommit(fid, "datatype", dtype); + CHECK(ret, FAIL, "H5Tcommit"); + + /* Create the data space for the dataset. */ + dims[0] = DIM0; + dims[1] = DIM1; + dspace = H5Screate_simple(RANK, dims, NULL); + CHECK(dspace, FAIL, "H5Screate_simple"); + + /* Create the dataset. */ + dset = H5Dcreate(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT); + CHECK(dset, FAIL, "H5Dcreate"); + ret = H5Sclose(dspace); + CHECK(ret, FAIL, "H5Sclose"); + + /* Get ref counts for each object. They should all be 1, since each object has a hard link. */ + ret = H5Gget_objinfo(fid, "group", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + + /* Increment each object's reference count. */ + ret = H5Oincr_refcount(grp); + CHECK(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dtype); + CHECK(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dset); + CHECK(ret, FAIL, "H5Oincr_refcount"); + + /* Get ref counts for each object. They should all be 2 now. */ + ret = H5Gget_objinfo(fid, "group", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + + /* Decrement the reference counts and check that they decrease back to 1. */ + ret = H5Odecr_refcount(grp); + CHECK(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dtype); + CHECK(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dset); + CHECK(ret, FAIL, "H5Odecr_refcount"); + + ret = H5Gget_objinfo(fid, "group", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + + /* Increment the reference counts and then close the file to make sure the increment is permanant */ + ret = H5Oincr_refcount(grp); + CHECK(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dtype); + CHECK(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dset); + CHECK(ret, FAIL, "H5Oincr_refcount"); + + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file and check that the reference counts were really incremented */ + fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + grp = H5Gopen(fid, "group"); + CHECK(grp, FAIL, "H5Gopen"); + dtype = H5Topen(fid, "datatype"); + CHECK(dtype, FAIL, "H5Gopen"); + dset = H5Dopen(fid, "dataset"); + CHECK(dset, FAIL, "H5Gopen"); + + ret = H5Gget_objinfo(fid, "group", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 2, "reference count in H5Gget_objinfo"); + + /* Decrement the reference counts and close the file */ + ret = H5Odecr_refcount(grp); + CHECK(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dtype); + CHECK(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dset); + CHECK(ret, FAIL, "H5Odecr_refcount"); + + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Re-open the file and check that the reference counts were really decremented */ + fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + grp = H5Gopen(fid, "group"); + CHECK(grp, FAIL, "H5Gopen"); + dtype = H5Topen(fid, "datatype"); + CHECK(dtype, FAIL, "H5Gopen"); + dset = H5Dopen(fid, "dataset"); + CHECK(dset, FAIL, "H5Gopen"); + + ret = H5Gget_objinfo(fid, "group", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "datatype", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + ret = H5Gget_objinfo(fid, "dataset", FALSE, &sb); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(sb.nlink, 1, "reference count in H5Gget_objinfo"); + + /* Close the IDs */ + ret = H5Gclose(grp); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Tclose(dtype); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Dclose(dset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Make sure that bogus IDs return errors properly */ + H5E_BEGIN_TRY { + ret = H5Oincr_refcount(grp); + VERIFY(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dtype); + VERIFY(ret, FAIL, "H5Oincr_refcount"); + ret = H5Oincr_refcount(dset); + VERIFY(ret, FAIL, "H5Oincr_refcount"); + ret = H5Odecr_refcount(grp); + VERIFY(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dtype); + VERIFY(ret, FAIL, "H5Odecr_refcount"); + ret = H5Odecr_refcount(dset); + VERIFY(ret, FAIL, "H5Odecr_refcount"); + } H5E_END_TRY + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_h5o_refcount() */ + + +/**************************************************************** +** +** test_h5o(): Main H5O (generic object) testing routine. +** +****************************************************************/ +void +test_h5o(void) +{ + /* Output message about test being performed */ + MESSAGE(5, ("Testing Objects\n")); + + test_h5o_open(); /* Test generic open function */ + test_h5o_open_by_addr(); /* Test opening objects by address */ + test_h5o_close(); /* Test generic close function */ + test_h5o_refcount(); /* Test incrementing and decrementing reference count */ +} /* test_h5o() */ + + +/*------------------------------------------------------------------------- + * Function: cleanup_h5o + * + * Purpose: Cleanup temporary test files + * + * Return: none + * + * Programmer: James Laird + * June 3, 2006 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +cleanup_h5o(void) +{ + remove(TEST_FILENAME); +} diff --git a/test/titerate.c b/test/titerate.c index 0c41ce6..4850db0 100644 --- a/test/titerate.c +++ b/test/titerate.c @@ -854,10 +854,10 @@ static void test_links(void) CHECK(gid1, FAIL, "H5Gcreate"); /* create soft and hard links to the group "/g1". */ - ret = H5Glink (gid, H5G_LINK_SOFT, "something", "softlink"); + ret = H5Glink (gid, H5L_LINK_SOFT, "something", "softlink"); CHECK(ret, FAIL, "H5Glink"); - ret = H5Glink (gid, H5G_LINK_HARD, "/g1", "hardlink"); + ret = H5Glink (gid, H5L_LINK_HARD, "/g1", "hardlink"); CHECK(ret, FAIL, "H5Glink"); ret = H5Gget_num_objs(gid, &nobjs); diff --git a/test/tmisc.c b/test/tmisc.c index cc4d7b2..b89a9a6 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -2850,6 +2850,7 @@ test_misc18(void) #else /* H5_HAVE_LARGE_HSIZET */ VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo"); #endif /* H5_HAVE_LARGE_HSIZET */ + VERIFY(statbuf.linklen, 0, "H5Gget_objinfo"); /* Create second dataset */ did2 = H5Dcreate(fid, MISC18_DSET2_NAME, H5T_STD_U32LE, sid, H5P_DEFAULT); @@ -2866,6 +2867,7 @@ test_misc18(void) #else /* H5_HAVE_LARGE_HSIZET */ VERIFY(statbuf.ohdr.free, 160, "H5Gget_objinfo"); #endif /* H5_HAVE_LARGE_HSIZET */ + VERIFY(statbuf.linklen, 0, "H5Gget_objinfo"); /* Loop creating attributes on each dataset, flushing them to the file each time */ for(u=0; u<10; u++) { @@ -2905,6 +2907,7 @@ test_misc18(void) VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo"); VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo"); #endif /* H5_HAVE_LARGE_HSIZET */ + VERIFY(statbuf.linklen, 0, "H5Gget_objinfo"); /* Get object information for dataset #2 now */ ret = H5Gget_objinfo(fid,MISC18_DSET2_NAME,0,&statbuf); @@ -2920,6 +2923,7 @@ test_misc18(void) VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo"); VERIFY(statbuf.ohdr.free, 24, "H5Gget_objinfo"); #endif /* H5_HAVE_LARGE_HSIZET */ + VERIFY(statbuf.linklen, 0, "H5Gget_objinfo"); /* Close second dataset */ ret = H5Dclose(did2); @@ -3844,7 +3848,7 @@ test_misc23(void) tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id); CHECK(tmp_id, FAIL, "H5Gcreate_expand"); - status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id); + status = H5Llink(file_id, "/A/B01/grp", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); /* Query that the name of the new group is correct */ @@ -3870,7 +3874,7 @@ test_misc23(void) tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id); CHECK(tmp_id, FAIL, "H5Gcreate_expand"); - status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id); + status = H5Llink(file_id, "/A/B02/C02/grp", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Gclose(tmp_id); @@ -3880,7 +3884,7 @@ test_misc23(void) tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id); CHECK(tmp_id, FAIL, "H5Gcreate_expand"); - status = H5Llink(group_id, "B03/grp/", tmp_id, create_id); + status = H5Llink(group_id, "B03/grp/", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Gclose(tmp_id); @@ -3890,7 +3894,7 @@ test_misc23(void) if ( (tmp_id = H5Gcreate_expand(group_id, H5P_DEFAULT, access_id)) < 0) CHECK(tmp_id, FAIL, "H5Gcreate_expand"); - status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id); + status = H5Llink(group_id, "/A/B04/grp/", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Gclose(tmp_id); @@ -3900,7 +3904,7 @@ test_misc23(void) if ( (tmp_id = H5Gcreate_expand(file_id, H5P_DEFAULT, access_id)) < 0) CHECK(tmp_id, FAIL, "H5Gcreate_expand"); - status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id); + status = H5Llink(file_id, "/A/B05/C05/A", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Gclose(tmp_id); @@ -3924,50 +3928,50 @@ test_misc23(void) CHECK(status, FAIL, "H5Pset_create_intermediate_group"); - tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT); + tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Dcreate"); - status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id); + status = H5Llink(file_id, "/A/B06/dset", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Dclose(tmp_id); CHECK(status, FAIL, "H5Dclose"); - tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT); + tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Dcreate"); - status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id); + status = H5Llink(file_id, "/A/B07/B07/dset", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Dclose(tmp_id); CHECK(status, FAIL, "H5Dclose"); - tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT); + tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Dcreate"); - status = H5Llink(group_id, "B08/dset", tmp_id, create_id); + status = H5Llink(group_id, "B08/dset", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Dclose(tmp_id); CHECK(status, FAIL, "H5Dclose"); - tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT); + tmp_id = H5Dcreate_expand(group_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Dcreate"); - status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id); + status = H5Llink(group_id, "/A/B09/dset", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Dclose(tmp_id); CHECK(status, FAIL, "H5Dclose"); - tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT); + tmp_id = H5Dcreate_expand(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT); CHECK(tmp_id, FAIL, "H5Dcreate"); - status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id); + status = H5Llink(file_id, "/A/B10/C10/A/dset", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Dclose(tmp_id); @@ -4002,7 +4006,7 @@ test_misc23(void) status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id); CHECK(status, FAIL, "H5Tcommit_expand"); - status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id); + status = H5Llink(file_id, "/A/B11/dtype", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Tclose(tmp_id); @@ -4015,7 +4019,7 @@ test_misc23(void) status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id); CHECK(status, FAIL, "H5Tcommit_expand"); - status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id); + status = H5Llink(file_id, "/A/B12/C12/dtype", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Tclose(tmp_id); @@ -4028,7 +4032,7 @@ test_misc23(void) status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id); CHECK(status, FAIL, "H5Tcommit_expand"); - status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id); + status = H5Llink(group_id, "B13/C12/dtype", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Tclose(tmp_id); @@ -4041,7 +4045,7 @@ test_misc23(void) status = H5Tcommit_expand(group_id, tmp_id, H5P_DEFAULT, access_id); CHECK(status, FAIL, "H5Tcommit_expand"); - status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id); + status = H5Llink(group_id, "/A/B14/dtype", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Tclose(tmp_id); @@ -4054,7 +4058,7 @@ test_misc23(void) status = H5Tcommit_expand(file_id, tmp_id, H5P_DEFAULT, access_id); CHECK(status, FAIL, "H5Tcommit_expand"); - status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id); + status = H5Llink(file_id, "/A/B15/C15/A/dtype", tmp_id, create_id, H5P_DEFAULT); CHECK(status, FAIL, "H5Llink"); status = H5Tclose(tmp_id); @@ -4110,13 +4114,13 @@ test_misc24(void) CHECK(ret, FAIL, "H5Tcommit"); /* Create soft links to the objects created */ - ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5G_LINK_SOFT, file_id, MISC24_GROUP_LINK); + ret = H5Glink2(file_id, MISC24_GROUP_NAME, H5L_LINK_SOFT, file_id, MISC24_GROUP_LINK); CHECK(ret, FAIL, "H5Glink2"); - ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5G_LINK_SOFT, file_id, MISC24_DATASET_LINK); + ret = H5Glink2(file_id, MISC24_DATASET_NAME, H5L_LINK_SOFT, file_id, MISC24_DATASET_LINK); CHECK(ret, FAIL, "H5Glink2"); - ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5G_LINK_SOFT, file_id, MISC24_DATATYPE_LINK); + ret = H5Glink2(file_id, MISC24_DATATYPE_NAME, H5L_LINK_SOFT, file_id, MISC24_DATATYPE_LINK); CHECK(ret, FAIL, "H5Glink2"); /* Close IDs for objects */ diff --git a/test/unlink.c b/test/unlink.c index d86e4eb..1ad3790 100644 --- a/test/unlink.c +++ b/test/unlink.c @@ -19,8 +19,14 @@ * Purpose: Test H5Gunlink(). */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ + +/* Define this macro to indicate that the testing APIs should be available */ +#define H5G_TESTING + #include <time.h> #include "h5test.h" +#include "H5Gpkg.h" /* Groups */ const char *FILENAME[] = { "unlink", @@ -33,6 +39,7 @@ const char *FILENAME[] = { "resurrect_type", "resurrect_group", "unlink_chunked", + "full_group", NULL }; @@ -68,6 +75,9 @@ const char *FILENAME[] = { #define SLASHES_SOFTLINK_NAME "Soft///" #define SLASHES_SOFTLINK2_NAME "Soft2///" #define SLASHES_ROOTLINK_NAME "Root///" +#define FULL_GROUP_NUM_KEEP 2 +#define FULL_GROUP_NUM_DELETE_COMPACT 2 +#define FULL_GROUP_NUM_DELETE_DENSE 16 /*------------------------------------------------------------------------- @@ -170,7 +180,7 @@ test_many(hid_t file) TESTING("forward unlink"); for (i=0; i<how_many; i++) { sprintf(name, "obj_%05d", i); - if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error; + if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error; } for (i=0; i<how_many; i++) { sprintf(name, "obj_%05d", i); @@ -182,7 +192,7 @@ test_many(hid_t file) TESTING("backward unlink"); for (i=0; i<how_many; i++) { sprintf(name, "obj_%05d", i); - if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error; + if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error; } for (i=how_many-1; i>=0; --i) { sprintf(name, "obj_%05d", i); @@ -194,7 +204,7 @@ test_many(hid_t file) TESTING("inward unlink"); for (i=0; i<how_many; i++) { sprintf(name, "obj_%05d", i); - if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error; + if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error; } for (i=0; i<how_many; i++) { if (i%2) { @@ -210,7 +220,7 @@ test_many(hid_t file) TESTING("outward unlink"); for (i=0; i<how_many; i++) { sprintf(name, "obj_%05d", i); - if (H5Glink(work, H5G_LINK_HARD, "/test_many_foo", name)<0) goto error; + if (H5Glink(work, H5L_LINK_HARD, "/test_many_foo", name)<0) goto error; } for (i=how_many-1; i>=0; --i) { if (i%2) { @@ -259,7 +269,7 @@ test_symlink(hid_t file) /* Create a test group and symlink */ if ((work=H5Gcreate(file, "/test_symlink", 0))<0) TEST_ERROR; - if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link")<0) TEST_ERROR; + if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link")<0) TEST_ERROR; if (H5Gunlink(work, "link")<0) TEST_ERROR; /* Cleanup */ @@ -310,7 +320,7 @@ test_rename(hid_t file) /* Try renaming a symlink */ TESTING("symlink renaming"); - if (H5Glink(work, H5G_LINK_SOFT, "link_value", "link_one")<0) goto error; + if (H5Glink(work, H5L_LINK_SOFT, "link_value", "link_one")<0) goto error; if (H5Gmove(work, "link_one", "link_two")<0) goto error; PASSED(); @@ -368,9 +378,9 @@ test_new_move(void) if((grp_move=H5Gcreate(grp_1, "group_move", 0))<0) goto error; /* Create hard and soft links. */ - if(H5Glink2(grp_1, "group_move", H5G_LINK_HARD, H5G_SAME_LOC, "hard")<0) + if(H5Glink2(grp_1, "group_move", H5L_LINK_HARD, H5G_SAME_LOC, "hard")<0) goto error; - if(H5Glink2(grp_1, "/group1/group_move", H5G_LINK_SOFT, grp_2, "soft")<0) + if(H5Glink2(grp_1, "/group1/group_move", H5L_LINK_SOFT, grp_2, "soft")<0) goto error; /* Move a group within the file. Both of source and destination use @@ -1357,22 +1367,22 @@ test_link_slashes(void) if(H5Gclose(gid2)<0) TEST_ERROR; /* Create a hard link to the nested group */ - if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR; + if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR; /* Create a soft link with a relative path to the nested group */ - if(H5Glink2(gid, SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR; + if(H5Glink2(gid, SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK_NAME)<0) TEST_ERROR; /* Create a soft link with the full path to the nested group */ - if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR; + if(H5Glink2(gid, "////"SLASHES_GROUP_NAME""SLASHES_GROUP_NAME, H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_SOFTLINK2_NAME)<0) TEST_ERROR; /* Create a soft link to the root group */ - if(H5Glink2(gid, "////", H5G_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR; + if(H5Glink2(gid, "////", H5L_LINK_SOFT, H5G_SAME_LOC, SLASHES_ROOTLINK_NAME)<0) TEST_ERROR; /* Close the group */ if(H5Gclose(gid)<0) TEST_ERROR; /* Create a hard link to the existing group */ - if(H5Glink2(fid, SLASHES_GROUP_NAME, H5G_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR; + if(H5Glink2(fid, SLASHES_GROUP_NAME, H5L_LINK_HARD, H5G_SAME_LOC, SLASHES_HARDLINK_NAME)<0) TEST_ERROR; /* Close the file */ if(H5Fclose(fid)<0) TEST_ERROR; @@ -1861,7 +1871,7 @@ test_resurrect_dataset(void) if(H5Iget_name(d, NULL, 0) != 0) TEST_ERROR; /* Re-link the dataset to the group hierarchy (shouldn't get deleted now) */ - if(H5Glink2(d, ".", H5G_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR; + if(H5Glink2(d, ".", H5L_LINK_HARD, f, DATASET2NAME)<0) TEST_ERROR; /* Close things */ if(H5Dclose(d)<0) TEST_ERROR; @@ -1934,7 +1944,7 @@ test_resurrect_datatype(void) if(H5Iget_name(type, NULL, 0) != 0) TEST_ERROR; /* Re-link the datatype to the group hierarchy (shouldn't get deleted now) */ - if(H5Glink2(type, ".", H5G_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR; + if(H5Glink2(type, ".", H5L_LINK_HARD, file, TYPE2NAME) < 0) TEST_ERROR; /* Close things */ if(H5Tclose(type)<0) TEST_ERROR; @@ -2003,7 +2013,7 @@ test_resurrect_group(void) if(H5Iget_name(group, NULL, 0) != 0) TEST_ERROR; /* Re-link the group into the group hierarchy (shouldn't get deleted now) */ - if(H5Glink2(group, ".", H5G_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR; + if(H5Glink2(group, ".", H5L_LINK_HARD, file, GROUP2NAME)<0) TEST_ERROR; /* Close things */ if(H5Gclose(group)<0) TEST_ERROR; @@ -2121,6 +2131,269 @@ error: return 1; } /* end test_unlink_chunked_dataset() */ +#ifdef H5_GROUP_REVISION + +/*------------------------------------------------------------------------- + * Function: test_full_group_compact + * + * Purpose: Test deleting a compact group which still has valid objects in it + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Wednesday, January 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_full_group_compact(void) +{ + hid_t fapl_id = -1; + hid_t file_id = -1; + hid_t gid = -1, gid2 = -1; /* Group IDs */ + H5G_stat_t sb; /* Stat buffer for object */ + char objname[128]; /* Buffer for name of objects to create */ + char objname2[128]; /* Buffer for name of objects to create */ + char filename[1024]; /* Buffer for filename */ + off_t keep_size; /* Size of the file with objects to keep */ + off_t file_size; /* Size of each file created */ + unsigned u; /* Local index variable */ + + TESTING("unlinking non-empty compact group"); + + /* Create file */ + fapl_id = h5_fileaccess(); + h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename); + + /* Create the file */ + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR + + /* Create group to link objects to */ + if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR + + /* Create several objects to link to */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "keep %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Close group with objects to keep */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + /* Get the size of the file with only the objects to keep */ + if((keep_size = h5_get_file_size(filename)) == 0) TEST_ERROR + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR + + /* Create group to delete */ + if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error; + + /* Create external link (doesn't matter if it dangles) */ + if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Create soft link (doesn't matter if it dangles) */ + if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR + + /* Create hard links to objects in group to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + sprintf(objname2, "keep %u\n", u); + if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR + } /* end for */ + + /* Create several objects to delete */ + for(u = 0; u < FULL_GROUP_NUM_DELETE_COMPACT; u++) { + sprintf(objname, "delete %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Check on group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, NULL) != TRUE) TEST_ERROR; + if(H5G_has_stab_test(gid) == TRUE) TEST_ERROR; + + /* Close group with objects to delete */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Check reference count on objects to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR + if(sb.nlink != 2) TEST_ERROR + } /* end for */ + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR + + /* Delete the full group */ + if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR + + /* Check reference count on objects to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR + if(sb.nlink != 1) TEST_ERROR + } /* end for */ + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR + + /* Verify the file is correct size */ + if(file_size != keep_size) TEST_ERROR + + /* Close the file access property list */ + if(H5Pclose(fapl_id) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(file_id); + H5Pclose(fapl_id); + } H5E_END_TRY; + return 1; +} /* end test_full_group_compact() */ + + +/*------------------------------------------------------------------------- + * Function: test_full_group_dense + * + * Purpose: Test deleting a dense group which still has valid objects in it + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Wednesday, January 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_full_group_dense(void) +{ + hid_t fapl_id = -1; + hid_t file_id = -1; + hid_t gid = -1, gid2 = -1; /* Group IDs */ + H5G_stat_t sb; /* Stat buffer for object */ + char objname[128]; /* Buffer for name of objects to create */ + char objname2[128]; /* Buffer for name of objects to create */ + char filename[1024]; /* Buffer for filename */ + unsigned u; /* Local index variable */ + + TESTING("unlinking non-empty dense group"); + + /* Create file */ + fapl_id = h5_fileaccess(); + h5_fixname(FILENAME[10], fapl_id, filename, sizeof filename); + + /* Create the file */ + if((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id))<0) TEST_ERROR + + /* Create group to link objects to */ + if((gid = H5Gcreate(file_id, "/keep", (size_t)0)) < 0) TEST_ERROR + + /* Create several objects to link to */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "keep %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Close group with objects to keep */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Create group to delete */ + if((gid = H5Gcreate(file_id, "/delete", (size_t)0)) < 0) goto error; + + /* Create external link (doesn't matter if it dangles) */ + if(H5Lcreate_external("foo.h5", "/dst", gid, "external", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Create soft link (doesn't matter if it dangles) */ + if(H5Glink2(file_id, "/foo", H5L_LINK_SOFT, gid, "soft") < 0) TEST_ERROR + + /* Create hard links to objects in group to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + sprintf(objname2, "keep %u\n", u); + if(H5Glink2(file_id, objname, H5L_LINK_HARD, gid, objname2) < 0) TEST_ERROR + } /* end for */ + + /* Create several objects to delete */ + for(u = 0; u < FULL_GROUP_NUM_DELETE_DENSE; u++) { + sprintf(objname, "delete %u\n", u); + if((gid2 = H5Gcreate(gid, objname, (size_t)0)) < 0) TEST_ERROR + if(H5Gclose(gid2) < 0) TEST_ERROR + } /* end for */ + + /* Check on group's status */ + if(H5G_is_empty_test(gid) == TRUE) TEST_ERROR; + if(H5G_has_links_test(gid, NULL) == TRUE) TEST_ERROR; + if(H5G_has_stab_test(gid) != TRUE) TEST_ERROR; + + /* Close group with objects to delete */ + if(H5Gclose(gid) < 0) TEST_ERROR + + /* Check reference count on objects to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR + if(sb.nlink != 2) TEST_ERROR + } /* end for */ + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + + /* Re-open the file */ + if((file_id = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) TEST_ERROR + + /* Delete the full group */ + if(H5Gunlink(file_id, "/delete") < 0) TEST_ERROR + + /* Check reference count on objects to keep */ + for(u = 0; u < FULL_GROUP_NUM_KEEP; u++) { + sprintf(objname, "/keep/keep %u\n", u); + if(H5Gget_objinfo(file_id, objname, TRUE, &sb) < 0) TEST_ERROR + if(sb.nlink != 1) TEST_ERROR + } /* end for */ + + /* Close the file */ + if(H5Fclose(file_id) < 0) TEST_ERROR + + /* Close the file access property list */ + if(H5Pclose(fapl_id) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Gclose(gid2); + H5Gclose(gid); + H5Fclose(file_id); + H5Pclose(fapl_id); + } H5E_END_TRY; + return 1; +} /* end test_full_group_dense() */ +#endif /* H5_GROUP_REVISION */ + /*------------------------------------------------------------------------- * Function: main @@ -2209,13 +2482,20 @@ main(void) /* Test unlinking chunked datasets */ nerrors += test_unlink_chunked_dataset(); - /* Close */ - if (H5Pclose(fapl2)<0) TEST_ERROR; - if (H5Fclose(file)<0) TEST_ERROR; - if (nerrors) { - printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S"); +#ifdef H5_GROUP_REVISION + /* Test unlinked groups which still have objects in them */ + nerrors += test_full_group_compact(); + nerrors += test_full_group_dense(); +#endif /* H5_GROUP_REVISION */ + + /* Close */ + if (H5Pclose(fapl2)<0) TEST_ERROR; + if (H5Fclose(file)<0) TEST_ERROR; + if (nerrors) { + printf("***** %d FAILURE%s! *****\n", nerrors, 1==nerrors?"":"S"); exit(1); } + puts("All unlink tests passed."); h5_cleanup(FILENAME, fapl); } diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c index 11459a4..1811b9d 100644 --- a/tools/h5diff/h5diffgentest.c +++ b/tools/h5diff/h5diffgentest.c @@ -42,6 +42,26 @@ #define FILE8 "file8.h5" +#define MY_LINKCLASS 187 +/* A UD link traversal function. Shouldn't actually be called. */ +static hid_t UD_traverse(UNUSED const char * link_name, UNUSED hid_t cur_group, + UNUSED void * udata, UNUSED size_t udata_size, UNUSED hid_t lapl_id) +{ +return -1; +} +const H5L_link_class_t UD_link_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + MY_LINKCLASS, /* Link type id number */ + "UD link class", /* name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + + /*------------------------------------------------------------------------- * Function: write_attr * @@ -2153,7 +2173,7 @@ int test_basic(const char *file1, * Function: test_basic * * Purpose: Compare different HDF5 types (H5G_obj_t): - * H5G_DATASET, H5G_TYPE, H5G_GROUP, H5G_LINK + * H5G_DATASET, H5G_TYPE, H5G_GROUP, H5G_LINK, H5G_UDLINK * *------------------------------------------------------------------------- */ @@ -2222,8 +2242,16 @@ int test_types(const char *file1, *------------------------------------------------------------------------- */ - status = H5Glink(fid1, H5G_LINK_SOFT, "g1", "l1"); - status = H5Glink(fid1, H5G_LINK_SOFT, "g2", "l2"); + status = H5Glink(fid1, H5L_LINK_SOFT, "g1", "l1"); + status = H5Glink(fid1, H5L_LINK_SOFT, "g2", "l2"); + +/*------------------------------------------------------------------------- + * H5G_UDLINK + *------------------------------------------------------------------------- + */ + H5Lcreate_external("filename", "objname", fid1, "ext_link", H5P_DEFAULT, H5P_DEFAULT); + H5Lregister(UD_link_class); + H5Lcreate_ud(fid1, "ud_link", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); /*------------------------------------------------------------------------- * Close diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 4bd388a..7a49950 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -271,6 +271,10 @@ static const h5dump_header_t standardformat = { "", /*dataend */ SOFTLINK, /*softlinkbegin */ "", /*softlinkend */ + EXTLINK, /*extlinkbegin */ + "", /*extlinkend */ + UDLINK, /*udlinkbegin */ + "", /*udlinkend */ SUBSET, /*subsettingbegin */ "", /*subsettingend */ START, /*startbegin */ @@ -300,6 +304,10 @@ static const h5dump_header_t standardformat = { "}", /*datablockend */ "{", /*softlinkblockbegin */ "}", /*softlinkblockend */ + "{", /*extlinkblockbegin */ + "}", /*extlinkblockend */ + "{", /*udlinkblockbegin */ + "}", /*udlinkblockend */ "{", /*strblockbegin */ "}", /*strblockend */ "{", /*enumblockbegin */ @@ -1398,6 +1406,7 @@ dump_all(hid_t group, const char *name, void * op_data) hid_t obj; char *obj_path = NULL; /* Full path of object */ H5G_stat_t statbuf; + H5L_linkinfo_t linfo; /* Link information */ herr_t ret = SUCCEED; /* Stat the object */ @@ -1407,6 +1416,12 @@ dump_all(hid_t group, const char *name, void * op_data) ret = FAIL; goto done; } /* end if */ + if(H5Lget_linkinfo(group, name, &linfo, H5P_DEFAULT) < 0) { + error_msg(progname, "unable to get object information\n"); + d_status = EXIT_FAILURE; + ret = FAIL; + goto done; + } /* end if */ if (*(int *)op_data != H5G_UNKNOWN && statbuf.type != *(int *) op_data) goto done; @@ -1433,7 +1448,7 @@ dump_all(hid_t group, const char *name, void * op_data) indentation(indent + COL); } - if (H5Gget_linkval(group, name, statbuf.linklen, targbuf) < 0) { + if (H5Lget_linkval(group, name, statbuf.linklen, targbuf, H5P_DEFAULT) < 0) { error_msg(progname, "unable to get link value\n"); d_status = EXIT_FAILURE; ret = FAIL; @@ -1516,7 +1531,128 @@ dump_all(hid_t group, const char *name, void * op_data) HDfree(targbuf); break; } + case H5G_UDLINK: + { + indentation(indent); + switch(linfo.linkclass) + { + case H5L_LINK_EXTERNAL: + { + char *targbuf; + char *filename; + char *targname; + targbuf = HDmalloc(statbuf.linklen); + HDassert(targbuf); + if (!doxml) { + begin_obj(dump_header_format->extlinkbegin, name, + dump_header_format->extlinkblockbegin); + } + if (H5Lget_linkval(group, name, statbuf.linklen, targbuf, H5P_DEFAULT) < 0) { + error_msg(progname, "unable to get external link value\n"); + d_status = EXIT_FAILURE; + ret = FAIL; + } else { + if(H5Lunpack_elink_val(targbuf, &filename, &targname) < 0) { + error_msg(progname, "unable to unpack external link value\n"); + d_status = EXIT_FAILURE; + ret = FAIL; + } else { + if (!doxml) { + indentation(indent + COL); + printf("LINKCLASS %d\n", linfo.linkclass); + indentation(indent + COL); + printf("TARGETFILE \"%s\"\n", filename); + indentation(indent + COL); + printf("TARGETPATH \"%s\"\n", targname); + } + else /* XML */ + { + char linkxid[100]; + char parentxid[100]; + char *t_name = xml_escape_the_name(name); + char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/"); + char *t_obj_path = xml_escape_the_name(obj_path); + char *t_filename = xml_escape_the_name(filename); + char *t_targname = xml_escape_the_name(targname); + + /* Create OBJ-XIDs for the parent and object */ + xml_name_to_XID(t_obj_path, linkxid, sizeof(linkxid), 1); + xml_name_to_XID(prefix, parentxid, sizeof(parentxid), 1); + + printf("<%sExternalLink LinkName=\"%s\" " + "OBJ-XID=\"%s\" " + "H5SourcePath=\"%s\" " + "TargetFilename=\"%s\" " + "TargetPath=\"%s\" " + "Parents=\"%s\" H5ParentPaths=\"%s\" />\n", + xmlnsprefix, + t_name, /* LinkName */ + linkxid, /* OBJ-XID */ + t_obj_path, /* H5SourcePath */ + filename, /* TargetFilename */ + targname, /* TargetPath*/ + parentxid, /* Parents */ + t_prefix); /* H5ParentPaths */ + HDfree(t_prefix); + HDfree(t_name); + HDfree(t_filename); + HDfree(t_targname); + HDfree(t_obj_path); + } + } + } + if (!doxml) { + end_obj(dump_header_format->extlinkend, + dump_header_format->extlinkblockend); + } + HDfree(targbuf); + } + break; + default: + if (!doxml) { + begin_obj(dump_header_format->udlinkbegin, name, + dump_header_format->udlinkblockbegin); + indentation(indent + COL); + } + if (!doxml) { + printf("LINKCLASS %d\n", linfo.linkclass); + } + else /* XML */ + { + char linkxid[100]; + char parentxid[100]; + char *t_name = xml_escape_the_name(name); + char *t_prefix = xml_escape_the_name(HDstrcmp(prefix,"") ? prefix : "/"); + char *t_obj_path = xml_escape_the_name(obj_path); + + /* Create OBJ-XIDs for the parent and object */ + xml_name_to_XID(t_obj_path, linkxid, sizeof(linkxid), 1); + xml_name_to_XID(prefix, parentxid, sizeof(parentxid), 1); + printf("<%sUserDefined LinkName=\"%s\" " + "OBJ-XID=\"%s\" " + "H5SourcePath=\"%s\" " + "LinkClass=\"%d\" " + "Parents=\"%s\" H5ParentPaths=\"%s\" />\n", + xmlnsprefix, + t_name, /* LinkName */ + linkxid, /* OBJ-XID */ + t_obj_path, /* H5SourcePath */ + linfo.linkclass, /* LinkClass */ + parentxid, /* Parents */ + t_prefix); /* H5ParentPaths */ + HDfree(t_prefix); + HDfree(t_name); + HDfree(t_obj_path); + } + if (!doxml) { + indentation(indent); + end_obj(dump_header_format->udlinkend, + dump_header_format->udlinkblockend); + } + } + break; + } case H5G_GROUP: if ((obj = H5Gopen(group, name)) < 0) { error_msg(progname, "unable to dump group \"%s\"\n", name); @@ -2003,7 +2139,7 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset, int display_ai) /* Print all the values. */ if (obj_data == DATASET_DATA) { - hid_t f_type = H5Dget_type(obj_id); + hid_t f_type = H5Dget_type(obj_id); char string_prefix[64]; h5tool_format_t string_dataformat; @@ -2683,7 +2819,7 @@ set_output_file(const char *fname, int is_bin) else rawdatastream = NULL; } - + /* binary output */ if (is_bin) { @@ -2699,7 +2835,7 @@ set_output_file(const char *fname, int is_bin) return 0; } } - + return -1; } @@ -3044,7 +3180,7 @@ handle_groups(hid_t fid, char *group, void UNUSED * data) /*------------------------------------------------------------------------- * Function: handle_links * - * Purpose: Handle the links from the command. + * Purpose: Handle soft or UD links from the command. * * Return: void * @@ -3059,18 +3195,24 @@ static void handle_links(hid_t fid, char *links, void UNUSED * data) { H5G_stat_t statbuf; + H5L_linkinfo_t linfo; + char * elink_file; + char * elink_path; if (H5Gget_objinfo(fid, links, FALSE, &statbuf) < 0) { error_msg(progname, "unable to get obj info from \"%s\"\n", links); d_status = EXIT_FAILURE; - } else if (statbuf.type == H5G_LINK) { + } else if (H5Lget_linkinfo(fid, links, &linfo, H5P_DEFAULT) < 0) { + error_msg(progname, "unable to get link info from \"%s\"\n", links); + d_status = EXIT_FAILURE; + } else if (statbuf.type == H5G_LINK) { /* Soft link */ char *buf = HDmalloc(statbuf.linklen); begin_obj(dump_header_format->softlinkbegin, links, dump_header_format->softlinkblockbegin); indentation(COL); - if (H5Gget_linkval(fid, links, statbuf.linklen, buf) >= 0) { + if (H5Lget_linkval(fid, links, statbuf.linklen, buf, H5P_DEFAULT) >= 0) { printf("LINKTARGET \"%s\"\n", buf); } else { error_msg(progname, "h5dump error: unable to get link value for \"%s\"\n", @@ -3080,7 +3222,45 @@ handle_links(hid_t fid, char *links, void UNUSED * data) end_obj(dump_header_format->softlinkend, dump_header_format->softlinkblockend); - + HDfree(buf); + } else if (statbuf.type == H5G_UDLINK) { /* User-defined link */ + char *buf = HDmalloc(statbuf.linklen); + begin_obj(dump_header_format->udlinkbegin, links, + dump_header_format->udlinkblockbegin); + indentation(COL); + switch(linfo.linkclass) { + case H5L_LINK_EXTERNAL: + begin_obj(dump_header_format->extlinkbegin, links, + dump_header_format->extlinkblockbegin); + if (H5Lget_linkval(fid, links, statbuf.linklen, buf, H5P_DEFAULT) >= 0) { + if(H5Lunpack_elink_val(buf, &elink_file, &elink_path)>=0) { + indentation(COL); + printf("LINKCLASS %d\n", linfo.linkclass); + indentation(COL); + printf("TARGETFILE \"%s\"\n", elink_file); + indentation(COL); + printf("TARGETPATH \"%s\"\n", elink_path); + } else { + error_msg(progname, "h5dump error: unable to unpack external link value for \"%s\"\n", + links); + d_status = EXIT_FAILURE; + } + } else { + error_msg(progname, "h5dump error: unable to get external link value for \"%s\"\n", + links); + d_status = EXIT_FAILURE; + } + end_obj(dump_header_format->extlinkend, + dump_header_format->extlinkblockend); + break; + default: + begin_obj(dump_header_format->udlinkbegin, links, + dump_header_format->udlinkblockbegin); + indentation(COL); + printf("LINKCLASS %d\n", linfo.linkclass); + end_obj(dump_header_format->udlinkend, + dump_header_format->udlinkblockend); + } HDfree(buf); } else { error_msg(progname, "\"%s\" is not a link\n", links); @@ -5054,7 +5234,8 @@ xml_dump_group(hid_t gid, const char *name) H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); xtype = H5G_LINK; H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); - + xtype = H5G_UDLINK; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); } free(t_name); free(grpxid); @@ -5114,7 +5295,8 @@ xml_dump_group(hid_t gid, const char *name) H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); xtype = H5G_LINK; H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); - + xtype = H5G_UDLINK; + H5Giterate(gid, ".", NULL, dump_all, (void *) &xtype); } indent -= COL; diff --git a/tools/h5dump/h5dump.h b/tools/h5dump/h5dump.h index dbc5de9..08aa527 100644 --- a/tools/h5dump/h5dump.h +++ b/tools/h5dump/h5dump.h @@ -45,6 +45,8 @@ #define S_SIMPLE "SIMPLE" #define S_NULL "NULL" #define SOFTLINK "SOFTLINK" +#define EXTLINK "EXTERNAL_LINK" +#define UDLINK "USERDEFINED_LINK" #define STORAGELAYOUT "STORAGELAYOUT" #define START "START" #define STRIDE "STRIDE" @@ -91,6 +93,10 @@ typedef struct h5dump_header_t { const char *dataend; const char *softlinkbegin; const char *softlinkend; + const char *extlinkbegin; + const char *extlinkend; + const char *udlinkbegin; + const char *udlinkend; const char *subsettingbegin; const char *subsettingend; const char *startbegin; @@ -120,6 +126,10 @@ typedef struct h5dump_header_t { const char *datablockend; const char *softlinkblockbegin; const char *softlinkblockend; + const char *extlinkblockbegin; + const char *extlinkblockend; + const char *udlinkblockbegin; + const char *udlinkblockend; const char *strblockbegin; const char *strblockend; const char *enumblockbegin; diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index 89652f2..3a5272a 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -79,7 +79,8 @@ #define FILE50 "taindices.h5" #define FILE51 "tlonglinks.h5" #define FILE52 "tldouble.h5" - +#define FILE53 "textlink.h5" +#define FILE54 "tudlink.h5" @@ -120,6 +121,27 @@ const H5Z_class_t H5Z_MYFILTER[1] = {{ }}; +/* A UD link traversal function. Shouldn't actually be called. */ +static hid_t UD_traverse(UNUSED const char * link_name, UNUSED hid_t cur_group, + UNUSED void * udata, UNUSED size_t udata_size, UNUSED hid_t lapl_id) +{ +return -1; +} + +#define MY_LINKCLASS 187 + +const H5L_link_class_t UD_link_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + MY_LINKCLASS, /* Link type id number */ + "UD link class", /* name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + NULL, /* Copy callback */ + UD_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + #define LENSTR 50 #define LENSTR2 11 @@ -403,8 +425,8 @@ static void gent_softlink(void) fid = H5Fcreate(FILE4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); root = H5Gopen (fid, "/"); - H5Glink (root, H5G_LINK_SOFT, "somevalue", "slink1"); - H5Glink (root, H5G_LINK_SOFT, "linkvalue", "slink2"); + H5Glink (root, H5L_LINK_SOFT, "somevalue", "slink1"); + H5Glink (root, H5L_LINK_SOFT, "linkvalue", "slink2"); H5Gclose(root); H5Fclose(fid); @@ -441,19 +463,48 @@ static void gent_hardlink(void) H5Dclose(dataset); group = H5Gcreate (fid, "/g1", 0); - H5Glink (group, H5G_LINK_HARD, "/dset1", "dset2"); + H5Glink (group, H5L_LINK_HARD, "/dset1", "dset2"); H5Gclose(group); group = H5Gcreate (fid, "/g2", 0); - H5Glink (group, H5G_LINK_HARD, "/dset1", "dset3"); + H5Glink (group, H5L_LINK_HARD, "/dset1", "dset3"); H5Gclose(group); group = H5Gopen(fid, "/g1"); - H5Glink (group, H5G_LINK_HARD, "/g2", "g1.1"); + H5Glink (group, H5L_LINK_HARD, "/g2", "g1.1"); H5Gclose(group); H5Fclose(fid); } +static void gent_extlink(void) +{ + hid_t fid; + + /* This external link will dangle, but that's okay */ + fid = H5Fcreate(FILE53, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_external("filename", "objname", fid, "extlink1", H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_external("anotherfile", "anotherobj", fid, "extlink2", H5P_DEFAULT, H5P_DEFAULT); + + H5Fclose(fid); +} + +static void gent_udlink(void) +{ + hid_t fid; + char buf[4]; + + H5Lregister(UD_link_class); + + /* This ud link will dangle, but that's okay */ + fid = H5Fcreate(FILE54, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_ud(fid, "udlink1", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + strcpy(buf, "foo"); + H5Lcreate_ud(fid, "udlink2", MY_LINKCLASS, buf, 4, H5P_DEFAULT, H5P_DEFAULT); + + H5Fclose(fid); +} + + /* / / | \ \ @@ -830,9 +881,9 @@ static void gent_compound_dt2(void) { /* test compound data type */ / : g1 g2 attr1 attr2 g1 : g1.1 g1.2 g1.1 : dset1.1.1(attr1, attr2) dset1.1.2 -g1.2 : g1.2.1 +g1.2 : g1.2.1 extlink g1.2.1 : slink -g2 : dset2.1 dset2.2 +g2 : dset2.1 dset2.2 udlink */ @@ -926,9 +977,12 @@ float dset2_1[10], dset2_2[3][5]; H5Gclose(group); + /* external link */ + H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT); + /* soft link */ group = H5Gopen (fid, "/g1/g1.2/g1.2.1"); - H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink"); + H5Glink (group, H5L_LINK_SOFT, "somevalue", "slink"); H5Gclose(group); group = H5Gopen (fid, "/g2"); @@ -956,6 +1010,10 @@ float dset2_1[10], dset2_2[3][5]; H5Gclose(group); + /* user-defined link */ + H5Lregister(UD_link_class); + H5Lcreate_ud(fid, "/g2/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + H5Fclose(fid); } @@ -981,8 +1039,8 @@ hid_t fid, group; group = H5Gcreate (fid, "/g2", 0); H5Gclose(group); - H5Glink(fid, H5G_LINK_HARD, "/g2", "/g1/g1.1"); - H5Glink(fid, H5G_LINK_HARD, "/g1", "/g2/g2.1"); + H5Glink(fid, H5L_LINK_HARD, "/g2", "/g1/g1.1"); + H5Glink(fid, H5L_LINK_HARD, "/g1", "/g2/g2.1"); H5Fclose(fid); } @@ -1001,10 +1059,10 @@ hid_t fid, group; H5Gclose(group); /* create path from object at /g1 to object at /g2 and name it g1.1 */ - H5Glink (fid, H5G_LINK_HARD, "/g2", "/g1/g1.1"); + H5Glink (fid, H5L_LINK_HARD, "/g2", "/g1/g1.1"); /* create path from object at /g2 to object at /g1 and name it g2.1 */ - H5Glink (fid, H5G_LINK_SOFT, "/g1", "/g2/g2.1"); + H5Glink (fid, H5L_LINK_SOFT, "/g1", "/g2/g2.1"); H5Fclose(fid); @@ -1012,13 +1070,13 @@ hid_t fid, group; /* / - | | | \ \ \ - g1 g2 g3 g4 g5 g6 - / \ | | \ \ \ - g1.1 g1.2 slink2 link3 dset2 slink4 dset3 - | | (g1) (dset2) (dset3) - dset1 link1 - (dset1) + | | | \ \ \ \ \ + g1 g2 g3 g4 g5 g6 g7 g8 + / \ | | \ \ \ \ \ + g1.1 g1.2 slink2 link3 dset2 slink4 dset3 slink5 elink + | | (g1) (dset2) (dset3) (elink) udlink + dset1 link1 slink6 + (dset1) (udlink) */ static void gent_many(void) { @@ -1043,6 +1101,7 @@ static void gent_many(void) { hsize_t dim[4]; int idx[4] = {0,1,2,3}; /* normal indicies */ const int perm[4] = {0,1,2,3}; /* the 0'th and the 3'rd indices are permuted */ + herr_t ret; fid = H5Fcreate(FILE12, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); @@ -1150,11 +1209,11 @@ static void gent_many(void) { H5Gclose(group); group = H5Gcreate (fid, "/g1/g1.2", 0); - H5Glink (group, H5G_LINK_HARD, "/g1/g1.1/dset1", "link1"); + H5Glink (group, H5L_LINK_HARD, "/g1/g1.1/dset1", "link1"); H5Gclose(group); group = H5Gcreate (fid, "/g2", 0); - H5Glink (group, H5G_LINK_SOFT, "/g1", "slink2"); + H5Glink (group, H5L_LINK_SOFT, "/g1", "slink2"); H5Gclose(group); group = H5Gcreate (fid, "/g3", 0); @@ -1178,7 +1237,7 @@ static void gent_many(void) { H5Gclose(group); group = H5Gopen(fid, "/g3"); - H5Glink (group, H5G_LINK_HARD, "/g4/dset2", "link3"); + H5Glink (group, H5L_LINK_HARD, "/g4/dset2", "link3"); H5Gclose(group); group = H5Gcreate (fid, "/g5", 0); @@ -1201,10 +1260,26 @@ static void gent_many(void) { H5Gclose(group); group = H5Gopen(fid, "/g5"); - H5Glink (group, H5G_LINK_SOFT, "/g6/dset3", "slink4"); + H5Glink (group, H5L_LINK_SOFT, "/g6/dset3", "slink4"); H5Gclose(group); H5Pclose(create_plist); + group = H5Gcreate (fid, "/g7", 0); + H5Gclose(group); + group = H5Gcreate (fid, "/g8", 0); + H5Gclose(group); + + /* Create dangling external and UD links */ + H5Lcreate_external("somefile", "somepath", fid, "/g8/elink", H5P_DEFAULT, H5P_DEFAULT); + H5Lregister(UD_link_class); + H5Lcreate_ud(fid, "/g8/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + + /* Create links to external and UD links */ + ret= H5Glink (fid, H5L_LINK_SOFT, "/g8/elink", "/g7/slink5"); + HDassert(ret >= 0); + ret= H5Glink (fid, H5L_LINK_SOFT, "/g8/udlink", "/g7/slink6"); + HDassert(ret >= 0); + H5Fclose(fid); } @@ -4927,42 +5002,48 @@ static void gent_fcontents(void) /* hard link to "dset" */ gid1 = H5Gcreate (fid, "/g1", 0); - H5Glink (gid1, H5G_LINK_HARD, "/dset", "dset1"); + H5Glink (gid1, H5L_LINK_HARD, "/dset", "dset1"); H5Gclose(gid1); /* hard link to "dset" */ gid1 = H5Gcreate (fid, "/g2", 0); - H5Glink (gid1, H5G_LINK_HARD, "/dset", "dset2"); + H5Glink (gid1, H5L_LINK_HARD, "/dset", "dset2"); H5Gclose(gid1); /* hard link to "g2" */ gid1 = H5Gopen(fid, "/g1"); - H5Glink (gid1, H5G_LINK_HARD, "/g2", "g1.1"); + H5Glink (gid1, H5L_LINK_HARD, "/g2", "g1.1"); H5Gclose(gid1); /* hard link to "dset" */ - ret=H5Glink (fid, H5G_LINK_HARD, "/dset", "dset3"); + ret=H5Glink (fid, H5L_LINK_HARD, "/dset", "dset3"); assert(ret>=0); /* hard link to "dset" */ - ret=H5Glink (fid, H5G_LINK_HARD, "/dset", "dset4"); + ret=H5Glink (fid, H5L_LINK_HARD, "/dset", "dset4"); assert(ret>=0); /* soft link to itself */ - ret=H5Glink (fid, H5G_LINK_SOFT, "mylink", "mylink"); + ret=H5Glink (fid, H5L_LINK_SOFT, "mylink", "mylink"); assert(ret>=0); /* soft link to "dset" */ - ret=H5Glink (fid, H5G_LINK_SOFT, "/dset", "softlink"); + ret=H5Glink (fid, H5L_LINK_SOFT, "/dset", "softlink"); assert(ret>=0); + /* dangling external link */ + ret=H5Lcreate_external("fname", "oname", fid, "extlink", H5P_DEFAULT, H5P_DEFAULT); + assert(ret>=0); + /* dangling udlink */ + ret=H5Lcreate_ud(fid, "udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + assert(ret>=0); /*------------------------------------------------------------------------- * datatypes @@ -5397,11 +5478,11 @@ static void gent_longlinks(void) objname[F51_MAX_NAME_LEN] = '\0'; /* Create hard link to existing object */ - assert(H5Glink2(fid, "grp1", H5G_LINK_HARD, fid, objname) >= 0); + assert(H5Lcreate_hard(fid, "grp1", fid, objname, H5P_DEFAULT) >= 0); /* Create soft link to existing object */ objname[0] = 'b'; - assert(H5Glink2(fid, "grp1", H5G_LINK_SOFT, fid, objname) >= 0); + assert(H5Lcreate_soft("grp1", fid, objname, H5P_DEFAULT) >= 0); /* Create group with long name in existing group */ gid2=H5Gcreate(gid, objname, (size_t)0); @@ -5444,7 +5525,7 @@ static int gent_ldouble(void) if ((tid = H5Tcopy(H5T_NATIVE_LDOUBLE))<0) goto error; - if ((size = H5Tget_size(tid))<0) + if ((size = H5Tget_size(tid))==0) goto error; if ((did = H5Dcreate(fid, "dset", tid, sid, H5P_DEFAULT))<0) @@ -5483,6 +5564,8 @@ int main(void) gent_softlink(); gent_dataset(); gent_hardlink(); + gent_extlink(); + gent_udlink(); gent_compound_dt(); gent_all(); gent_loop(); diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in index 783634c..3f40976 100644 --- a/tools/h5dump/testh5dump.sh.in +++ b/tools/h5dump/testh5dump.sh.in @@ -125,10 +125,12 @@ TOOLTEST tattr-3.ddl --header -a /attr2 --attribute=/attr tattr.h5 # test for displaying attributes in shared datatype (also in group and dataset) TOOLTEST tnamed_dtype_attr.ddl tnamed_dtype_attr.h5 -# test for displaying soft links +# test for displaying soft links and user-defined links TOOLTEST tslink-1.ddl tslink.h5 +TOOLTEST tudlink-1.ddl tudlink.h5 # test for displaying the selected link TOOLTEST tslink-2.ddl -l slink2 tslink.h5 +TOOLTEST tudlink-2.ddl -l udlink2 tudlink.h5 # tests for hard links TOOLTEST thlink-1.ddl thlink.h5 diff --git a/tools/h5dump/testh5dumpxml.sh.in b/tools/h5dump/testh5dumpxml.sh.in index 21db71a..490832e 100755 --- a/tools/h5dump/testh5dumpxml.sh.in +++ b/tools/h5dump/testh5dumpxml.sh.in @@ -118,6 +118,8 @@ TOOLTEST tcompound_complex.h5.xml --xml tcompound_complex.h5 TOOLTEST tobjref.h5.xml --xml tobjref.h5 TOOLTEST topaque.h5.xml --xml topaque.h5 TOOLTEST tslink.h5.xml --xml tslink.h5 +TOOLTEST tudlink.h5.xml --xml tudlink.h5 +TOOLTEST textlink.h5.xml --xml textlink.h5 TOOLTEST tstr.h5.xml --xml tstr.h5 TOOLTEST tstr2.h5.xml --xml tstr2.h5 TOOLTEST tref.h5.xml --xml tref.h5 diff --git a/tools/h5jam/h5jam.c b/tools/h5jam/h5jam.c index 5e4d885..afa9ffa 100644 --- a/tools/h5jam/h5jam.c +++ b/tools/h5jam/h5jam.c @@ -15,7 +15,6 @@ #include <stdio.h> #include <fcntl.h> #include <sys/stat.h> - #ifdef H5_HAVE_UNISTD_H #include <unistd.h> #endif diff --git a/tools/h5jam/h5jamgentest.c b/tools/h5jam/h5jamgentest.c index a3a99ca..dd80c29 100644 --- a/tools/h5jam/h5jamgentest.c +++ b/tools/h5jam/h5jamgentest.c @@ -65,6 +65,8 @@ char pattern[11] = "abcdefghij"; */ +#define BUF_SIZE 1024 + #define LENSTR 50 #define LENSTR2 11 @@ -118,158 +120,63 @@ typedef struct s1_t { /* VL string datatype name */ #define VLSTR_TYPE "vl_string_type" +/* A UD link traversal function. Shouldn't actually be called. */ +static hid_t UD_traverse(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id) +{ +return -1; +} +#define MY_LINKCLASS 187 +const H5L_link_class_t UD_link_class[1] = {{ + H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */ + MY_LINKCLASS, /* Link type id number */ + "UD link class", /* name for debugging */ + NULL, /* Creation callback */ + NULL, /* Move/rename callback */ + UD_traverse, /* The actual traversal function */ + NULL, /* Deletion callback */ + NULL /* Query callback */ +}}; + -/* + +/* gent_ub + with no ub, identical to gent_all from h5dumpgentest.c + + FILENAME is the name of the file to create + UB_SIZE is the size the buffer should be + UB_FILL characters will be set to the PATTERN array, + the rest of the user block will be NULL. / : g1 g2 attr1 attr2 g1 : g1.1 g1.2 g1.1 : dset1.1.1(attr1, attr2) dset1.1.2 -g1.2 : g1.2.1 +g1.2 : g1.2.1 extlink g1.2.1 : slink -g2 : dset2.1 dset2.2 +g2 : dset2.1 dset2.2 udlink */ - -static void gent_all(void) { -hid_t fid, group, attr, dataset, space; -hsize_t dims[2]; -int data[2][2], dset1[10][10], dset2[20]; -char buf[60]; -int i, j; -float dset2_1[10], dset2_2[3][5]; - - fid = H5Fcreate(FILE7, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - - /* create groups */ - group = H5Gcreate (fid, "/g1", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g2", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.1", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.2", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0); - H5Gclose(group); - - /* root attributes */ - group = H5Gopen (fid, "/"); - - dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "abcdefghi"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 2; dims[1] = 2; - space = H5Screate_simple(2, dims, NULL); - attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT); - data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3; - H5Awrite(attr, H5T_NATIVE_INT, data); - H5Sclose(space); - H5Aclose(attr); - - H5Gclose(group); - - group = H5Gopen (fid, "/g1/g1.1"); - - /* dset1.1.1 */ - dims[0] = 10; dims[1] = 10; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT); - for (i = 0; i < 10; i++) - for (j = 0; j < 10; j++) - dset1[i][j] = j*i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1); - H5Sclose(space); - - /* attributes of dset1.1.1 */ - dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "1st attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "2nd attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - H5Dclose(dataset); - - /* dset1.1.2 */ - dims[0] = 20; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT); - for (i = 0; i < 20; i++) - dset2[i] = i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - /* soft link */ - group = H5Gopen (fid, "/g1/g1.2/g1.2.1"); - H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink"); - H5Gclose(group); - - group = H5Gopen (fid, "/g2"); - - /* dset2.1 */ - dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT); - for (i = 0; i < 10; i++) - dset2_1[i] = (float)(i*0.1+1); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1); - H5Sclose(space); - H5Dclose(dataset); - - /* dset2.2 */ - dims[0] = 3; dims[1] = 5; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT); - for (i = 0; i < 3; i++) - for (j = 0; j < 5; j++) - dset2_2[i][j] = (float)((i+1)*j*0.1); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - H5Fclose(fid); - -} - -static void gent_withub(void) { +static void gent_ub(const char * filename, int ub_size, int ub_fill) { hid_t fid, group, attr, dataset, space; hid_t create_plist; hsize_t dims[2]; int data[2][2], dset1[10][10], dset2[20]; -char buf[512]; +char buf[BUF_SIZE]; int i, j; -unsigned u; float dset2_1[10], dset2_2[3][5]; int fd; char *bp; - create_plist = H5Pcreate(H5P_FILE_CREATE); - H5Pset_userblock(create_plist,(hsize_t)512); - fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT); + if(ub_size > 0) + { + create_plist = H5Pcreate(H5P_FILE_CREATE); + H5Pset_userblock(create_plist,(hsize_t)ub_size); + fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT); + } + else + { + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + } /* create groups */ group = H5Gcreate (fid, "/g1", 0); @@ -351,153 +258,12 @@ char *bp; H5Gclose(group); - /* soft link */ - group = H5Gopen (fid, "/g1/g1.2/g1.2.1"); - H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink"); - H5Gclose(group); - - group = H5Gopen (fid, "/g2"); - - /* dset2.1 */ - dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT); - for (i = 0; i < 10; i++) - dset2_1[i] = (float)(i*0.1+1); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1); - H5Sclose(space); - H5Dclose(dataset); - - /* dset2.2 */ - dims[0] = 3; dims[1] = 5; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT); - for (i = 0; i < 3; i++) - for (j = 0; j < 5; j++) - dset2_2[i][j] = (float)((i+1)*j*0.1); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - H5Fclose(fid); - - - fd = HDopen(FILE8,O_RDWR, 0); - if (fd < 0) { - /* panic */ - } - /* fill buf with pattern */ - memset(buf,'\0',512); - bp = buf; - for (u = 0; u < strlen(pattern); u++) { - *bp++ = pattern[u%10]; - } - - HDwrite(fd,buf,512); - - close(fd); -} - -static void gent_withub513(void) { -hid_t fid, group, attr, dataset, space; -hid_t create_plist; -hsize_t dims[2]; -int data[2][2], dset1[10][10], dset2[20]; -char buf[1023]; -int i, j; -float dset2_1[10], dset2_2[3][5]; -int fd; -char *bp; - - create_plist = H5Pcreate(H5P_FILE_CREATE); - H5Pset_userblock(create_plist,(hsize_t)1024); - fid = H5Fcreate(FILE9, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT); - - /* create groups */ - group = H5Gcreate (fid, "/g1", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g2", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.1", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.2", 0); - H5Gclose(group); - - group = H5Gcreate (fid, "/g1/g1.2/g1.2.1", 0); - H5Gclose(group); - - /* root attributes */ - group = H5Gopen (fid, "/"); - - dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "abcdefghi"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 2; dims[1] = 2; - space = H5Screate_simple(2, dims, NULL); - attr = H5Acreate (group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT); - data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3; - H5Awrite(attr, H5T_NATIVE_INT, data); - H5Sclose(space); - H5Aclose(attr); - - H5Gclose(group); - - group = H5Gopen (fid, "/g1/g1.1"); - - /* dset1.1.1 */ - dims[0] = 10; dims[1] = 10; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT); - for (i = 0; i < 10; i++) - for (j = 0; j < 10; j++) - dset1[i][j] = j*i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1); - H5Sclose(space); - - /* attributes of dset1.1.1 */ - dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "1st attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate (dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT); - sprintf(buf, "2nd attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - H5Dclose(dataset); - - /* dset1.1.2 */ - dims[0] = 20; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT); - for (i = 0; i < 20; i++) - dset2[i] = i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); + /* external link */ + H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT); /* soft link */ group = H5Gopen (fid, "/g1/g1.2/g1.2.1"); - H5Glink (group, H5G_LINK_SOFT, "somevalue", "slink"); + H5Glink (group, H5L_LINK_SOFT, "somevalue", "slink"); H5Gclose(group); group = H5Gopen (fid, "/g2"); @@ -525,23 +291,32 @@ char *bp; H5Gclose(group); + /* user-defined link */ + H5Lregister(UD_link_class); + H5Lcreate_ud(fid, "/g2/udlink", MY_LINKCLASS, NULL, 0, H5P_DEFAULT, H5P_DEFAULT); + H5Fclose(fid); + /* If a user block is being used, write to it here */ + if(ub_size > 0) + { + HDassert(ub_size < BUF_SIZE); - fd = HDopen(FILE9,O_RDWR, 0); + fd = HDopen(filename,O_RDWR, 0); if (fd < 0) { /* panic */ } /* fill buf with pattern */ - memset(buf,'\0',1024); + memset(buf,'\0',ub_size); bp = buf; - for (i = 0; i < 513; i++) { + for (i = 0; i < ub_fill; i++) { *bp++ = pattern[i%10]; } - HDwrite(fd,buf,1024); + HDwrite(fd,buf,ub_size); close(fd); + } } static void @@ -636,9 +411,9 @@ create_binfile(UBBIN4,512); create_binfile(UBBIN5,513); */ - gent_all(); - gent_withub(); - gent_withub513(); + gent_ub(FILE7, 0, 0); + gent_ub(FILE8, 512, strlen(pattern)); + gent_ub(FILE9, 1024, 513); return 0; } diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index d279ea3..9a51ce2 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -1710,7 +1710,7 @@ datatype_list2(hid_t type, const char UNUSED *name) /*------------------------------------------------------------------------- - * Function: link_open + * Function: slink_open * * Purpose: This gets called to open a symbolic link. Since symbolic * links don't correspond to actual objects we simply print the @@ -1729,11 +1729,11 @@ datatype_list2(hid_t type, const char UNUSED *name) *------------------------------------------------------------------------- */ static hid_t -link_open(hid_t location, const char *name) +slink_open(hid_t location, const char *name) { char buf[64]; - if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1; + if (H5Lget_linkval (location, name, sizeof(buf), buf, H5P_DEFAULT)<0) return -1; if (NULL==HDmemchr(buf, 0, sizeof(buf))) { strcpy(buf+sizeof(buf)-4, "..."); } @@ -1741,6 +1741,59 @@ link_open(hid_t location, const char *name) return 0; } +/*------------------------------------------------------------------------- + * Function: udlink_open + * + * Purpose: This gets called to open a user-defined link. Since these + * links don't correspond to actual objects we simply print a message + * and return failure. + * + * Return: Success: 0 - an invalid object but successful return + * of this function. + * + * Failure: -1 + * + * Programmer: James Laird + * Tuesday, June 6, 2006 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hid_t +udlink_open(hid_t location, const char *name) +{ + H5L_linkinfo_t linfo; + char * buf = NULL; + char * filename = NULL; + char * path = NULL; + + if(H5Lget_linkinfo(location, name, &linfo, H5P_DEFAULT) < 0) return -1; + + switch(linfo.linkclass) + { + /* For external links, try to display info for the object it points to */ + case H5L_LINK_EXTERNAL: + if ((buf = HDmalloc(linfo.u.link_size))==NULL) goto error; + if (H5Lget_linkval (location, name, sizeof(buf), buf, H5P_DEFAULT)<0) goto error; + + if(H5Lunpack_elink_val(buf, &filename, &path) < 0) goto error; + fputs("file: ", stdout); + fputs(filename, stdout); + fputs(" path: ", stdout); + fputs(path, stdout); + break; + + default: + fputs("cannot follow UD links", stdout); + } + return 0; + +error: + if(buf) + HDfree(buf); + return -1; +} /*------------------------------------------------------------------------- @@ -1828,7 +1881,7 @@ list (hid_t group, const char *name, void *_iter) /* Show detailed information about the object, beginning with information * which is common to all objects. */ - if (verbose_g>0 && H5G_LINK!=sb.type) { + if (verbose_g>0 && H5G_LINK!=sb.type && H5G_UDLINK!=sb.type) { if (sb.type>=0) H5Aiterate(obj, NULL, list_attr, NULL); printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", sb.fileno[0], objno); @@ -2063,7 +2116,9 @@ main (int argc, const char *argv[]) NULL, group_list2); DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose, NULL, datatype_list2); - DISPATCH(H5G_LINK, "-> ", link_open, NULL, + DISPATCH(H5G_LINK, "-> ", slink_open, NULL, + NULL, NULL); + DISPATCH(H5G_UDLINK, "-> ", udlink_open, NULL, NULL, NULL); #if 0 diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh index 37581f7..c9aa901 100755 --- a/tools/h5ls/testh5ls.sh +++ b/tools/h5ls/testh5ls.sh @@ -118,6 +118,10 @@ TOOLTEST tdset-1.ls -w80 -r -d tdset.h5 # test for displaying soft links TOOLTEST tslink-1.ls -w80 -r tslink.h5 +# test for displaying external and user-defined links +TOOLTEST textlink-1.ls -w80 -r textlink.h5 +TOOLTEST tudlink-1.ls -w80 -r tudlink.h5 + # tests for hard links TOOLTEST thlink-1.ls -w80 thlink.h5 diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c index dee6c3f..e59b6d0 100644 --- a/tools/h5repack/h5repack_copy.c +++ b/tools/h5repack/h5repack_copy.c @@ -264,17 +264,17 @@ int do_copy_objects(hid_t fidin, trav_table_t *travt, pack_opt_t *options) /* repack options */ { - hid_t grp_in; /* group ID */ - hid_t grp_out; /* group ID */ - hid_t dset_in; /* read dataset ID */ - hid_t dset_out; /* write dataset ID */ - hid_t type_in; /* named type ID */ - hid_t type_out; /* named type ID */ - hid_t dcpl_id; /* dataset creation property list ID */ - hid_t dcpl_out; /* dataset creation property list ID */ - hid_t space_id; /* space ID */ - hid_t ftype_id; /* file data type ID */ - hid_t mtype_id; /* memory data type ID */ + hid_t grp_in=-1; /* group ID */ + hid_t grp_out=-1; /* group ID */ + hid_t dset_in=-1; /* read dataset ID */ + hid_t dset_out=-1; /* write dataset ID */ + hid_t type_in=-1; /* named type ID */ + hid_t type_out=-1; /* named type ID */ + hid_t dcpl_id=-1; /* dataset creation property list ID */ + hid_t dcpl_out=-1; /* dataset creation property list ID */ + hid_t space_id=-1; /* space ID */ + hid_t ftype_id=-1; /* file data type ID */ + hid_t mtype_id=-1; /* memory data type ID */ size_t msize; /* memory size of memory type */ void *buf=NULL; /* data buffer */ hsize_t nelmts; /* number of elements in dataset */ @@ -561,30 +561,18 @@ int do_copy_objects(hid_t fidin, /*------------------------------------------------------------------------- * H5G_LINK + * H5G_UDLINK + * + * Only handles external links; H5Lcopy will fail for other UD link types + * since we don't have creation or copy callbacks for them. *------------------------------------------------------------------------- */ case H5G_LINK: + case H5G_UDLINK: { - H5G_stat_t statbuf; - char *targbuf=NULL; - - if (H5Gget_objinfo(fidin,travt->objs[i].name,FALSE,&statbuf)<0) - goto error; - - targbuf = malloc(statbuf.linklen); - - if (H5Gget_linkval(fidin,travt->objs[i].name,statbuf.linklen,targbuf)<0) - goto error; - - if (H5Glink(fidout, - H5G_LINK_SOFT, - targbuf, /* current name of object */ - travt->objs[i].name /* new name of object */ - )<0) - goto error; - - free(targbuf); + if(H5Lcopy(fidin, travt->objs[i].name,fidout, travt->objs[i].name, H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; if (options->verbose) printf(FORMAT_OBJ,"link",travt->objs[i].name ); @@ -592,6 +580,14 @@ int do_copy_objects(hid_t fidin, } break; +/*------------------------------------------------------------------------- + *------------------------------------------------------------------------- + */ + { + + } + break; + default: goto error; } diff --git a/tools/h5repack/h5repack_list.c b/tools/h5repack/h5repack_list.c index 05156d4..5622811 100644 --- a/tools/h5repack/h5repack_list.c +++ b/tools/h5repack/h5repack_list.c @@ -198,6 +198,9 @@ void print_objlist(const char *filename, case H5G_LINK: printf(" %-10s %s\n", "link", info[i].name ); break; + case H5G_UDLINK: + printf(" %-10s %s\n", "User defined link", info[i].name ); + break; default: printf(" %-10s %s\n", "User defined object", info[i].name ); break; diff --git a/tools/h5repack/h5repack_refs.c b/tools/h5repack/h5repack_refs.c index 6e3156b..4884e04 100644 --- a/tools/h5repack/h5repack_refs.c +++ b/tools/h5repack/h5repack_refs.c @@ -93,7 +93,7 @@ int do_copy_refobjs(hid_t fidin, for ( j=0; j<travt->objs[i].nlinks; j++) { H5Glink(fidout, - H5G_LINK_HARD, + H5L_LINK_HARD, travt->objs[i].name, travt->objs[i].links[j].new_name); } @@ -339,7 +339,7 @@ int do_copy_refobjs(hid_t fidin, { for ( j=0; j<travt->objs[i].nlinks; j++){ H5Glink(fidout, - H5G_LINK_HARD, + H5L_LINK_HARD, travt->objs[i].name, travt->objs[i].links[j].new_name); } @@ -384,10 +384,12 @@ int do_copy_refobjs(hid_t fidin, /*------------------------------------------------------------------------- * H5G_LINK + * H5G_UDLINK *------------------------------------------------------------------------- */ case H5G_LINK: + case H5G_UDLINK: /*nothing to do */ break; diff --git a/tools/h5repack/testh5repack_dset.c b/tools/h5repack/testh5repack_dset.c index c345028..ca0f0ca 100644 --- a/tools/h5repack/testh5repack_dset.c +++ b/tools/h5repack/testh5repack_dset.c @@ -128,7 +128,7 @@ void write_dset_in(hid_t loc_id, /* create hard link */ - status = H5Glink(loc_id, H5G_LINK_HARD, "string", "string_link"); + status = H5Glink(loc_id, H5L_LINK_HARD, "string", "string_link"); /*------------------------------------------------------------------------- * H5T_BITFIELD diff --git a/tools/h5repack/testh5repack_main.c b/tools/h5repack/testh5repack_main.c index 58a7c2a..5299cd4 100644 --- a/tools/h5repack/testh5repack_main.c +++ b/tools/h5repack/testh5repack_main.c @@ -1170,7 +1170,6 @@ if (szip_can_encode) { SKIPPED(); #endif - /*------------------------------------------------------------------------- * end *------------------------------------------------------------------------- diff --git a/tools/h5repack/testh5repack_make.c b/tools/h5repack/testh5repack_make.c index 43b68b1..a74d466 100644 --- a/tools/h5repack/testh5repack_make.c +++ b/tools/h5repack/testh5repack_make.c @@ -259,7 +259,14 @@ int make_all_objects(hid_t loc_id) *------------------------------------------------------------------------- */ - H5Glink(loc_id, H5G_LINK_SOFT, "dset", "link"); + H5Glink(loc_id, H5L_LINK_SOFT, "dset", "link"); + +/*------------------------------------------------------------------------- + * H5G_UDLINK + *------------------------------------------------------------------------- + */ + /* Create an external link. Other UD links are not supported by h5repack */ + H5Lcreate_external("file", "path", loc_id, "ext_link", H5P_DEFAULT, H5P_DEFAULT); /*------------------------------------------------------------------------- * write a series of datasetes @@ -350,11 +357,11 @@ int make_hlinks(hid_t loc_id) if (write_dset(loc_id,2,dims,"dset",H5T_NATIVE_INT,buf)<0) return -1; - if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link1 to dset")<0) + if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link1 to dset")<0) return -1; - if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link2 to dset")<0) + if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link2 to dset")<0) return -1; - if (H5Glink(loc_id, H5G_LINK_HARD, "dset", "link3 to dset")<0) + if (H5Glink(loc_id, H5L_LINK_HARD, "dset", "link3 to dset")<0) return -1; @@ -370,9 +377,9 @@ int make_hlinks(hid_t loc_id) if ((group3_id = H5Gcreate(group2_id,"g3",0))<0) return -1; - if (H5Glink2(loc_id, "g1", H5G_LINK_HARD, group2_id, "link1 to g1")<0) + if (H5Glink2(loc_id, "g1", H5L_LINK_HARD, group2_id, "link1 to g1")<0) return -1; - if (H5Glink2(group1_id, "g2", H5G_LINK_HARD, group3_id, "link1 to g2")<0) + if (H5Glink2(group1_id, "g2", H5L_LINK_HARD, group3_id, "link1 to g2")<0) return -1; H5Gclose(group1_id); diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index e8c546e..4fed814 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -870,6 +870,7 @@ hsize_t diff_compare (hid_t file1_id, * H5G_DATASET Object is a dataset * H5G_TYPE Object is a named data type * H5G_LINK Object is a symbolic link + * H5G_UDLINK Object is a user-defined link * * Return: Number of differences found * @@ -1067,6 +1068,90 @@ hsize_t diff (hid_t file1_id, } break; + /*------------------------------------------------------------------------- + * H5G_UDLINK + *------------------------------------------------------------------------- + */ + case H5G_UDLINK: + { + char *buf1 = NULL; + char *buf2 = NULL; + H5L_linkinfo_t li1; + H5L_linkinfo_t li2; + + if (H5Lget_linkinfo (file1_id, path1, &li1, H5P_DEFAULT) < 0) + goto out; + if (H5Lget_linkinfo (file1_id, path1, &li2, H5P_DEFAULT) < 0) + goto out; + + /* Only external links will have a query function registered */ + if(li1.linkclass == H5L_LINK_EXTERNAL && li2.linkclass == H5L_LINK_EXTERNAL) + { + buf1 = HDmalloc (li1.u.link_size); + buf2 = HDmalloc (li2.u.link_size); + + if (H5Lget_linkval (file1_id, path1, li1.u.link_size, buf1, H5P_DEFAULT) < 0) + { + HDfree (buf1); HDfree (buf2); + goto out; + } + if (H5Lget_linkval (file2_id, path2, li2.u.link_size, buf2, H5P_DEFAULT) < 0) + { + HDfree (buf1); HDfree (buf2); + goto out; + } + + /* If the buffers are the same size, compare them */ + if(li1.u.link_size == li2.u.link_size) + { + if (H5Lget_linkval (file1_id, path1, li1.u.link_size, buf1, H5P_DEFAULT) < 0) + { + HDfree (buf1); HDfree (buf2); + goto out; + } + if (H5Lget_linkval (file2_id, path2, li2.u.link_size, buf2, H5P_DEFAULT) < 0) + { + HDfree (buf1); HDfree (buf2); + goto out; + } + ret = HDmemcmp (buf1, buf2, li1.u.link_size); + } + else + ret = 1; + + /* if "buf1" != "buf2" then the links are "different" */ + nfound = (ret != 0) ? 1 : 0; + + if (print_objname (options, nfound)) + parallel_print("External Link: <%s> and <%s>\n", path1, path2); + } + else + { + /* If one or both of these links isn't an external link, we can only + * compare information from H5Lget_linkinfo since we don't have a query + * function registered for them. */ + + /* If the link classes or the buffer length are not the + * same, the links are "different" + */ + if((li1.linkclass != li2.linkclass) || (li1.u.link_size != li2.u.link_size)) + nfound = 1; + else + nfound = 0; + + if (print_objname (options, nfound)) + parallel_print("User-defined Link: <%s> and <%s>\n", path1, path2); + } + + /* always print the number of differences found in verbose mode */ + if (options->m_verbose) + print_found(nfound); + + HDfree (buf1); + HDfree (buf2); + } + break; + default: nfound = 0; if (options->m_verbose) diff --git a/tools/lib/h5diff_util.c b/tools/lib/h5diff_util.c index c2c0659..4997c0c 100644 --- a/tools/lib/h5diff_util.c +++ b/tools/lib/h5diff_util.c @@ -269,6 +269,8 @@ get_type(int type) return("H5G_TYPE"); case H5G_LINK: return("H5G_LINK"); + case H5G_UDLINK: + return("H5G_UDLINK"); default: return("user defined type"); } diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index a4ccf63..cb62c71 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -594,12 +594,12 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai /* Setup */ memset(&buffer, 0, sizeof(h5tools_str_t)); size = H5Tget_size(type); - + if (info->line_ncols > 0) ncols = info->line_ncols; - + h5tools_simple_prefix(stream, info, ctx, (hsize_t)0, 0); - + for (i = 0; i < nelmts; i++, ctx->cur_elmt++, elmt_counter++) { /* Render the element */ h5tools_str_reset(&buffer); @@ -1340,7 +1340,7 @@ void init_acc_pos(h5tools_context_t *ctx, hsize_t *dims) * *------------------------------------------------------------------------- */ -static +static int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) { unsigned char *mem = (unsigned char*)_mem; @@ -1349,7 +1349,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) size = H5Tget_size(tid); - for (i = 0; i < nelmts; i++) + for (i = 0; i < nelmts; i++) { if (render_bin_output(stream,tid,mem + i * size)<0) { @@ -1357,7 +1357,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) return FAIL; } } - + return SUCCEED; } @@ -1377,7 +1377,7 @@ int do_bin_output(FILE *stream, hsize_t nelmts, hid_t tid, void *_mem) * *------------------------------------------------------------------------- */ -static +static int render_bin_output(FILE *stream, hid_t tid, void *_mem) { #if 0 @@ -1407,88 +1407,88 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) sprintf(fmt_ullong, "%%%su", H5_PRINTF_LL_WIDTH); } #endif - + size = H5Tget_size(tid); - - if (H5Tequal(tid, H5T_NATIVE_FLOAT)) + + if (H5Tequal(tid, H5T_NATIVE_FLOAT)) { memcpy(&tempfloat, mem, sizeof(float)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%g ", tempfloat); #else - if (1 != fwrite(&tempfloat, size, 1, stream)) + if (1 != fwrite(&tempfloat, size, 1, stream)) return FAIL; #endif - } - else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) + } + else if (H5Tequal(tid, H5T_NATIVE_DOUBLE)) { memcpy(&tempdouble, mem, sizeof(double)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%g ", tempdouble); #else - if (1 != fwrite(&tempdouble, size, 1, stream)) + if (1 != fwrite(&tempdouble, size, 1, stream)) return FAIL; #endif - } + } #if H5_SIZEOF_LONG_DOUBLE !=0 - else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) + else if (H5Tequal(tid, H5T_NATIVE_LDOUBLE)) { memcpy(&templdouble, mem, sizeof(long double)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%Lf ", templdouble); #else - if (1 != fwrite(&templdouble, size, 1, stream)) + if (1 != fwrite(&templdouble, size, 1, stream)) return FAIL; #endif } #endif - else if (H5T_STRING == H5Tget_class(tid)) + else if (H5T_STRING == H5Tget_class(tid)) { unsigned int i; H5T_str_t pad; char *s; - + pad = H5Tget_strpad(tid); - - if(H5Tis_variable_str(tid)) + + if(H5Tis_variable_str(tid)) { s = *(char**)mem; if(s!=NULL) size = HDstrlen(s); } - else + else { s = mem; size = H5Tget_size(tid); } - for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++) + for (i=0; i<size && (s[i] || pad!=H5T_STR_NULLTERM); i++) { memcpy(&tempuchar, &s[i], sizeof(unsigned char)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%d", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) + if (1 != fwrite(&tempuchar, size, 1, stream)) return FAIL; #endif } /* i */ } - else if (H5Tequal(tid, H5T_NATIVE_INT)) + else if (H5Tequal(tid, H5T_NATIVE_INT)) { memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) + if (1 != fwrite(&tempint, size, 1, stream)) return FAIL; #endif } - else if (H5Tequal(tid, H5T_NATIVE_UINT)) + else if (H5Tequal(tid, H5T_NATIVE_UINT)) { memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) + if (1 != fwrite(&tempuint, size, 1, stream)) return FAIL; #endif } @@ -1498,17 +1498,17 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%d ", tempschar); #else - if (1 != fwrite(&tempschar, size, 1, stream)) + if (1 != fwrite(&tempschar, size, 1, stream)) return FAIL; #endif - } + } else if (H5Tequal(tid, H5T_NATIVE_UCHAR)) { memcpy(&tempuchar, mem, sizeof(unsigned char)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%u ", tempuchar); #else - if (1 != fwrite(&tempuchar, size, 1, stream)) + if (1 != fwrite(&tempuchar, size, 1, stream)) return FAIL; #endif } @@ -1518,7 +1518,7 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%d ", tempshort); #else - if (1 != fwrite(&tempshort, size, 1, stream)) + if (1 != fwrite(&tempshort, size, 1, stream)) return FAIL; #endif } @@ -1528,7 +1528,7 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%u ", tempushort); #else - if (1 != fwrite(&tempushort, size, 1, stream)) + if (1 != fwrite(&tempushort, size, 1, stream)) return FAIL; #endif } @@ -1538,27 +1538,27 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) + if (1 != fwrite(&templong, size, 1, stream)) return FAIL; #endif - } + } else if (H5Tequal(tid, H5T_NATIVE_ULONG)) { memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) + if (1 != fwrite(&tempulong, size, 1, stream)) return FAIL; #endif - } + } else if (H5Tequal(tid, H5T_NATIVE_LLONG)) { memcpy(&templlong, mem, sizeof(long_long)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) + if (1 != fwrite(&templlong, size, 1, stream)) return FAIL; #endif } @@ -1568,29 +1568,29 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) + if (1 != fwrite(&tempullong, size, 1, stream)) return FAIL; #endif } - else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) + else if (H5Tequal(tid, H5T_NATIVE_HSSIZE)) { - if (sizeof(hssize_t) == sizeof(int)) + if (sizeof(hssize_t) == sizeof(int)) { memcpy(&tempint, mem, sizeof(int)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%d ", tempint); #else - if (1 != fwrite(&tempint, size, 1, stream)) + if (1 != fwrite(&tempint, size, 1, stream)) return FAIL; #endif } - else if (sizeof(hssize_t) == sizeof(long)) + else if (sizeof(hssize_t) == sizeof(long)) { memcpy(&templong, mem, sizeof(long)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%ld ", templong); #else - if (1 != fwrite(&templong, size, 1, stream)) + if (1 != fwrite(&templong, size, 1, stream)) return FAIL; #endif } @@ -1600,30 +1600,30 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, fmt_llong, templlong); #else - if (1 != fwrite(&templlong, size, 1, stream)) + if (1 != fwrite(&templlong, size, 1, stream)) return FAIL; #endif } - } - else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) + } + else if (H5Tequal(tid, H5T_NATIVE_HSIZE)) { - if (sizeof(hsize_t) == sizeof(int)) + if (sizeof(hsize_t) == sizeof(int)) { memcpy(&tempuint, mem, sizeof(unsigned int)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%u ", tempuint); #else - if (1 != fwrite(&tempuint, size, 1, stream)) + if (1 != fwrite(&tempuint, size, 1, stream)) return FAIL; #endif } - else if (sizeof(hsize_t) == sizeof(long)) + else if (sizeof(hsize_t) == sizeof(long)) { memcpy(&tempulong, mem, sizeof(unsigned long)); #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%lu ", tempulong); #else - if (1 != fwrite(&tempulong, size, 1, stream)) + if (1 != fwrite(&tempulong, size, 1, stream)) return FAIL; #endif } @@ -1633,57 +1633,57 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) #ifdef DEBUG_H5DUMP_BIN fprintf(stream, fmt_ullong, tempullong); #else - if (1 != fwrite(&tempullong, size, 1, stream)) + if (1 != fwrite(&tempullong, size, 1, stream)) return FAIL; #endif } } - else if (H5Tget_class(tid) == H5T_COMPOUND) + else if (H5Tget_class(tid) == H5T_COMPOUND) { unsigned j; hid_t memb; unsigned nmembs; size_t offset; - + nmembs = H5Tget_nmembers(tid); - - for (j = 0; j < nmembs; j++) + + for (j = 0; j < nmembs; j++) { offset = H5Tget_member_offset(tid, j); memb = H5Tget_member_type(tid, j); - + if (render_bin_output(stream,memb,mem + offset)<0) return FAIL; - + H5Tclose(memb); } } - else if (H5Tget_class(tid) == H5T_ENUM) + else if (H5Tget_class(tid) == H5T_ENUM) { unsigned int i; - if (1==size) + if (1==size) { #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) + if (1 != fwrite(&mem[0], size, 1, stream)) return FAIL; #endif - } - else + } + else { for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) return FAIL; #endif } /*i*/ }/*else 1 */ } - else if (H5Tget_class(tid) == H5T_ARRAY) + else if (H5Tget_class(tid) == H5T_ARRAY) { int k, ndims; hsize_t i, dims[H5S_MAX_RANK], temp_nelmts, nelmts; @@ -1703,63 +1703,63 @@ int render_bin_output(FILE *stream, hid_t tid, void *_mem) temp_nelmts *= dims[k]; nelmts = (size_t)temp_nelmts; } - + /* dump the array element */ - for (i = 0; i < nelmts; i++) + for (i = 0; i < nelmts; i++) { if (render_bin_output(stream,memb,mem + i * size)<0) return FAIL; } - + H5Tclose(memb); } - else if (H5Tget_class(tid) == H5T_VLEN) + else if (H5Tget_class(tid) == H5T_VLEN) { unsigned int i; hsize_t nelmts; hid_t memb; - + /* get the VL sequences's base datatype for each element */ memb = H5Tget_super(tid); size = H5Tget_size(memb); - + /* Get the number of sequence elements */ nelmts = ((hvl_t *)mem)->len; - - for (i = 0; i < nelmts; i++) + + for (i = 0; i < nelmts; i++) { /* dump the array element */ if (render_bin_output(stream,memb,((char *)(((hvl_t *)mem)->p)) + i * size)<0) return FAIL; - } + } H5Tclose(memb); } - else + else { size_t i; - if (1==size) + if (1==size) { #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "0x%02x", mem[0]); #else - if (1 != fwrite(&mem[0], size, 1, stream)) + if (1 != fwrite(&mem[0], size, 1, stream)) return FAIL; #endif - } - else + } + else { for (i = 0; i < size; i++) { #ifdef DEBUG_H5DUMP_BIN fprintf(stream, "%s%02x", i?":":"", mem[i]); #else - if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) + if (1 != fwrite(&mem[i], sizeof(char), 1, stream)) return FAIL; #endif } /*i*/ }/*else 1 */ } - + return SUCCEED; } diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c index f49cb07..5d6cfae 100644 --- a/tools/lib/h5tools_ref.c +++ b/tools/lib/h5tools_ref.c @@ -171,6 +171,12 @@ ref_path_table_lookup(const char *thepath) if(H5Gget_objinfo(thefile, thepath, TRUE, &sb)<0) /* fatal error ? */ return HADDR_UNDEF; + } else if(sb.type == H5G_UDLINK) + { + /* UD links can't be followed, so they always "dangle" like + * soft links. + */ + return HADDR_UNDEF; } /* end if */ objno = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long))); diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c index f5c6e91..2ff927c 100644 --- a/tools/lib/h5trav.c +++ b/tools/lib/h5trav.c @@ -462,7 +462,7 @@ static int traverse( hid_t loc_id, */ case H5G_LINK: - { + { /* increment */ inserted_objs++; @@ -489,9 +489,60 @@ static int traverse( hid_t loc_id, break; + /*------------------------------------------------------------------------- + * H5G_UDLINK + *------------------------------------------------------------------------- + */ + + case H5G_UDLINK: + { + H5L_linkinfo_t linkbuf; + + /* increment */ + inserted_objs++; + + /* add object to table */ + trav_table_add(HADDR_UNDEF, path, H5G_UDLINK, table ); + + /* Get type of link */ + H5E_BEGIN_TRY { + + /* get link class info */ + H5Lget_linkinfo( loc_id, path, &linkbuf, H5P_DEFAULT); + } H5E_END_TRY; + + if(linkbuf.linkclass == H5L_LINK_EXTERNAL) + { + if (statbuf.linklen>0) + { + char *targbuf; + char *objname; + + targbuf = HDmalloc(statbuf.linklen); + assert(targbuf); + H5Gget_linkval(loc_id,path,statbuf.linklen,targbuf); + H5Lunpack_elink_val(targbuf, NULL, &objname); + if (print) + printf(" %-10s %s -> %s %s\n", "ext link", path, targbuf, objname); + free(targbuf); + } + else + { + if (print) + printf(" %-10s %s ->\n", "udlink", path); + } + } + else /* Unknown user-defined type */ + { + if (print) + printf(" %-10s %s ->\n", "UD link type", path); + } + } + break; + default: - HDfprintf(stderr, "traverse: Unknown object!\n"); + HDfprintf(stderr, "traverse: Unknown object %d!\n", type); /* JAMES */ return (-1); break; @@ -548,6 +599,9 @@ void h5trav_printinfo(int nobjs, trav_info_t *travi) case H5G_LINK: printf(" %-10s %s\n", "link", travi[i].name ); break; + case H5G_UDLINK: + printf(" %-10s %s\n", "User defined link", travi[i].name ); + break; default: printf(" %-10s %s\n", "User defined object", travi[i].name ); break; diff --git a/tools/misc/h5stat.c b/tools/misc/h5stat.c index 4855e68..5d0f23b 100644 --- a/tools/misc/h5stat.c +++ b/tools/misc/h5stat.c @@ -608,7 +608,8 @@ printf("walk: fullname = %s\n", fullname); break; case H5G_LINK: - /* Gather statistics about this type of object */ + case H5G_UDLINK: + /* Gather statistics about links and UD links */ iter->uniq_links++; break; diff --git a/tools/testfiles/file3.h5 b/tools/testfiles/file3.h5 Binary files differindex 4750ce9..a9eff83 100644 --- a/tools/testfiles/file3.h5 +++ b/tools/testfiles/file3.h5 diff --git a/tools/testfiles/tall-1.ddl b/tools/testfiles/tall-1.ddl index 2fd5494..6069293 100644 --- a/tools/testfiles/tall-1.ddl +++ b/tools/testfiles/tall-1.ddl @@ -64,6 +64,11 @@ GROUP "/" { } } GROUP "g1.2" { + EXTERNAL_LINK "extlink" { + LINKCLASS 64 + TARGETFILE "somefile" + TARGETPATH "somepath" +} GROUP "g1.2.1" { SOFTLINK "slink" { LINKTARGET "somevalue" @@ -88,6 +93,9 @@ GROUP "/" { (2,0): 0, 0.3, 0.6, 0.9, 1.2 } } + USERDEFINED_LINK "udlink" { + LINKCLASS 187 + } } } } diff --git a/tools/testfiles/tall-2.ls b/tools/testfiles/tall-2.ls index e1b0bcf..5513214 100644 --- a/tools/testfiles/tall-2.ls +++ b/tools/testfiles/tall-2.ls @@ -15,6 +15,7 @@ Data: (0) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 /g1/g1.2 Group +/g1/g1.2/extlink -> file: somefile path: somepath /g1/g1.2/g1.2.1 Group /g1/g1.2/g1.2.1/slink -> somevalue /g2 Group @@ -25,3 +26,4 @@ Data: (0,0) 0, 0.1, 0.2, 0.3, 0.4, 0, 0.2, 0.4, 0.6, 0.8, 0, 0.3, 0.6, 0.9, (2,4) 1.2 +/g2/udlink -> cannot follow UD links diff --git a/tools/testfiles/tall-2A.ddl b/tools/testfiles/tall-2A.ddl index 604c307..b16feb8 100644 --- a/tools/testfiles/tall-2A.ddl +++ b/tools/testfiles/tall-2A.ddl @@ -48,6 +48,11 @@ GROUP "/" { } } GROUP "g1.2" { + EXTERNAL_LINK "extlink" { + LINKCLASS 64 + TARGETFILE "somefile" + TARGETPATH "somepath" +} GROUP "g1.2.1" { SOFTLINK "slink" { LINKTARGET "somevalue" @@ -64,6 +69,9 @@ GROUP "/" { DATATYPE H5T_IEEE_F32BE DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) } } + USERDEFINED_LINK "udlink" { + LINKCLASS 187 + } } } } diff --git a/tools/testfiles/tall-2A.h5.xml b/tools/testfiles/tall-2A.h5.xml index e83f0b3..586afb5 100644 --- a/tools/testfiles/tall-2A.h5.xml +++ b/tools/testfiles/tall-2A.h5.xml @@ -3,7 +3,7 @@ Expected output for 'h5dump --xml -A tall.h5' ############################# <?xml version="1.0" encoding="UTF-8"?> <hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd"> -<hdf5:RootGroup OBJ-XID="xid_928" H5Path="/"> +<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/"> <hdf5:Attribute Name="attr1"> <hdf5:Dataspace> <hdf5:SimpleDataspace Ndims="1"> @@ -40,9 +40,9 @@ Expected output for 'h5dump --xml -A tall.h5' </hdf5:DataFromFile> </hdf5:Data> </hdf5:Attribute> - <hdf5:Group Name="g1" OBJ-XID="xid_1576" H5Path="/g1" Parents="xid_928" H5ParentPaths="/" > - <hdf5:Group Name="g1.1" OBJ-XID="xid_3200" H5Path="/g1/g1.1" Parents="xid_1576" H5ParentPaths="/g1" > - <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5200" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_3200" H5ParentPaths="/g1/g1.1"> + <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Group Name="g1.1" OBJ-XID="xid_2512" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5432" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_2512" H5ParentPaths="/g1/g1.1"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -102,7 +102,7 @@ Expected output for 'h5dump --xml -A tall.h5' <hdf5:NoData/> </hdf5:Data> </hdf5:Dataset> - <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_5800" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_3200" H5ParentPaths="/g1/g1.1"> + <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_8272" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_2512" H5ParentPaths="/g1/g1.1"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -126,14 +126,15 @@ Expected output for 'h5dump --xml -A tall.h5' </hdf5:Data> </hdf5:Dataset> </hdf5:Group> - <hdf5:Group Name="g1.2" OBJ-XID="xid_4176" H5Path="/g1/g1.2" Parents="xid_1576" H5ParentPaths="/g1" > - <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4824" H5Path="/g1/g1.2/g1.2.1" Parents="xid_4176" H5ParentPaths="/g1/g1.2" > - <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4824" H5ParentPaths="/g1/g1.2/g1.2.1" /> + <hdf5:Group Name="g1.2" OBJ-XID="xid_3536" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4232" H5Path="/g1/g1.2/g1.2.1" Parents="xid_3536" H5ParentPaths="/g1/g1.2" > + <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4232" H5ParentPaths="/g1/g1.2/g1.2.1" /> </hdf5:Group> + <hdf5:ExternalLink LinkName="extlink" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g1/g1.2/extlink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_3536" H5ParentPaths="/g1/g1.2" /> </hdf5:Group> </hdf5:Group> - <hdf5:Group Name="g2" OBJ-XID="xid_2552" H5Path="/g2" Parents="xid_928" H5ParentPaths="/" > - <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8520" H5Path= "/g2/dset2.1" Parents="xid_2552" H5ParentPaths="/g2"> + <hdf5:Group Name="g2" OBJ-XID="xid_1816" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8872" H5Path= "/g2/dset2.1" Parents="xid_1816" H5ParentPaths="/g2"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -156,7 +157,7 @@ Expected output for 'h5dump --xml -A tall.h5' <hdf5:NoData/> </hdf5:Data> </hdf5:Dataset> - <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9120" H5Path= "/g2/dset2.2" Parents="xid_2552" H5ParentPaths="/g2"> + <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9472" H5Path= "/g2/dset2.2" Parents="xid_1816" H5ParentPaths="/g2"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -180,6 +181,7 @@ Expected output for 'h5dump --xml -A tall.h5' <hdf5:NoData/> </hdf5:Data> </hdf5:Dataset> + <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g2/udlink" LinkClass="187" Parents="xid_1816" H5ParentPaths="/g2" /> </hdf5:Group> </hdf5:RootGroup> </hdf5:HDF5-File> diff --git a/tools/testfiles/tall-2B.ddl b/tools/testfiles/tall-2B.ddl index 4969987..002156e 100644 --- a/tools/testfiles/tall-2B.ddl +++ b/tools/testfiles/tall-2B.ddl @@ -44,6 +44,11 @@ GROUP "/" { } } GROUP "g1.2" { + EXTERNAL_LINK "extlink" { + LINKCLASS 64 + TARGETFILE "somefile" + TARGETPATH "somepath" +} GROUP "g1.2.1" { SOFTLINK "slink" { LINKTARGET "somevalue" @@ -60,6 +65,9 @@ GROUP "/" { DATATYPE H5T_IEEE_F32BE DATASPACE SIMPLE { ( 3, 5 ) / ( 3, 5 ) } } + USERDEFINED_LINK "udlink" { + LINKCLASS 187 + } } } } diff --git a/tools/testfiles/tall.h5 b/tools/testfiles/tall.h5 Binary files differindex 2bc4993..0ed5ed2 100644 --- a/tools/testfiles/tall.h5 +++ b/tools/testfiles/tall.h5 diff --git a/tools/testfiles/tall.h5.xml b/tools/testfiles/tall.h5.xml index 22e6f51..ce740fe 100644 --- a/tools/testfiles/tall.h5.xml +++ b/tools/testfiles/tall.h5.xml @@ -3,7 +3,7 @@ Expected output for 'h5dump --xml tall.h5' ############################# <?xml version="1.0" encoding="UTF-8"?> <hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd"> -<hdf5:RootGroup OBJ-XID="xid_928" H5Path="/"> +<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/"> <hdf5:Attribute Name="attr1"> <hdf5:Dataspace> <hdf5:SimpleDataspace Ndims="1"> @@ -40,9 +40,9 @@ Expected output for 'h5dump --xml tall.h5' </hdf5:DataFromFile> </hdf5:Data> </hdf5:Attribute> - <hdf5:Group Name="g1" OBJ-XID="xid_1576" H5Path="/g1" Parents="xid_928" H5ParentPaths="/" > - <hdf5:Group Name="g1.1" OBJ-XID="xid_3200" H5Path="/g1/g1.1" Parents="xid_1576" H5ParentPaths="/g1" > - <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5200" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_3200" H5ParentPaths="/g1/g1.1"> + <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Group Name="g1.1" OBJ-XID="xid_2512" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Dataset Name="dset1.1.1" OBJ-XID="xid_5432" H5Path= "/g1/g1.1/dset1.1.1" Parents="xid_2512" H5ParentPaths="/g1/g1.1"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -113,7 +113,7 @@ Expected output for 'h5dump --xml tall.h5' </hdf5:DataFromFile> </hdf5:Data> </hdf5:Dataset> - <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_5800" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_3200" H5ParentPaths="/g1/g1.1"> + <hdf5:Dataset Name="dset1.1.2" OBJ-XID="xid_8272" H5Path= "/g1/g1.1/dset1.1.2" Parents="xid_2512" H5ParentPaths="/g1/g1.1"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -139,14 +139,15 @@ Expected output for 'h5dump --xml tall.h5' </hdf5:Data> </hdf5:Dataset> </hdf5:Group> - <hdf5:Group Name="g1.2" OBJ-XID="xid_4176" H5Path="/g1/g1.2" Parents="xid_1576" H5ParentPaths="/g1" > - <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4824" H5Path="/g1/g1.2/g1.2.1" Parents="xid_4176" H5ParentPaths="/g1/g1.2" > - <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4824" H5ParentPaths="/g1/g1.2/g1.2.1" /> + <hdf5:Group Name="g1.2" OBJ-XID="xid_3536" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Group Name="g1.2.1" OBJ-XID="xid_4232" H5Path="/g1/g1.2/g1.2.1" Parents="xid_3536" H5ParentPaths="/g1/g1.2" > + <hdf5:SoftLink LinkName="slink" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g1/g1.2/g1.2.1/slink" TargetPath="somevalue" Parents="xid_4232" H5ParentPaths="/g1/g1.2/g1.2.1" /> </hdf5:Group> + <hdf5:ExternalLink LinkName="extlink" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g1/g1.2/extlink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_3536" H5ParentPaths="/g1/g1.2" /> </hdf5:Group> </hdf5:Group> - <hdf5:Group Name="g2" OBJ-XID="xid_2552" H5Path="/g2" Parents="xid_928" H5ParentPaths="/" > - <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8520" H5Path= "/g2/dset2.1" Parents="xid_2552" H5ParentPaths="/g2"> + <hdf5:Group Name="g2" OBJ-XID="xid_1816" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Dataset Name="dset2.1" OBJ-XID="xid_8872" H5Path= "/g2/dset2.1" Parents="xid_1816" H5ParentPaths="/g2"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -171,7 +172,7 @@ Expected output for 'h5dump --xml tall.h5' </hdf5:DataFromFile> </hdf5:Data> </hdf5:Dataset> - <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9120" H5Path= "/g2/dset2.2" Parents="xid_2552" H5ParentPaths="/g2"> + <hdf5:Dataset Name="dset2.2" OBJ-XID="xid_9472" H5Path= "/g2/dset2.2" Parents="xid_1816" H5ParentPaths="/g2"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -199,6 +200,7 @@ Expected output for 'h5dump --xml tall.h5' </hdf5:DataFromFile> </hdf5:Data> </hdf5:Dataset> + <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g2/udlink" LinkClass="187" Parents="xid_1816" H5ParentPaths="/g2" /> </hdf5:Group> </hdf5:RootGroup> </hdf5:HDF5-File> diff --git a/tools/testfiles/tcontents.ddl b/tools/testfiles/tcontents.ddl index 43afb9d..935ff8c 100644 --- a/tools/testfiles/tcontents.ddl +++ b/tools/testfiles/tcontents.ddl @@ -3,11 +3,12 @@ Expected output for 'h5dump -n tfcontents1.h5' ############################# HDF5 "tfcontents1.h5" { FILE_CONTENTS { - datatype /#5696 + datatype /#6056 dataset /dset dataset /dset3 -> /dset dataset /dset4 -> /dset dataset /dsetmytype2 + ext link /extlink -> fname oname group /g1 dataset /g1/dset1 -> /dset group /g1/g1.1 @@ -16,5 +17,6 @@ FILE_CONTENTS { link /mylink -> mylink datatype /mytype link /softlink -> /dset + UD link type /udlink -> } } diff --git a/tools/testfiles/textlink.h5 b/tools/testfiles/textlink.h5 Binary files differnew file mode 100644 index 0000000..a851011 --- /dev/null +++ b/tools/testfiles/textlink.h5 diff --git a/tools/testfiles/textlink.h5.xml b/tools/testfiles/textlink.h5.xml new file mode 100644 index 0000000..fe6f68a --- /dev/null +++ b/tools/testfiles/textlink.h5.xml @@ -0,0 +1,10 @@ +############################# +Expected output for 'h5dump --xml textlink.h5' +############################# +<?xml version="1.0" encoding="UTF-8"?> +<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd"> +<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/"> + <hdf5:ExternalLink LinkName="extlink1" OBJ-XID="xid_18446744073709551614" H5SourcePath="/extlink1" TargetFilename="filename" TargetPath="objname" Parents="xid_96" H5ParentPaths="/" /> + <hdf5:ExternalLink LinkName="extlink2" OBJ-XID="xid_18446744073709551613" H5SourcePath="/extlink2" TargetFilename="anotherfile" TargetPath="anotherobj" Parents="xid_96" H5ParentPaths="/" /> +</hdf5:RootGroup> +</hdf5:HDF5-File> diff --git a/tools/testfiles/tfcontents1.h5 b/tools/testfiles/tfcontents1.h5 Binary files differindex a7cf2d3..8b043fb 100644 --- a/tools/testfiles/tfcontents1.h5 +++ b/tools/testfiles/tfcontents1.h5 diff --git a/tools/testfiles/tfcontents2.h5 b/tools/testfiles/tfcontents2.h5 Binary files differindex 216a885..1df0779 100644 --- a/tools/testfiles/tfcontents2.h5 +++ b/tools/testfiles/tfcontents2.h5 diff --git a/tools/testfiles/tmany.h5 b/tools/testfiles/tmany.h5 Binary files differindex 271f13a..0422f93 100644 --- a/tools/testfiles/tmany.h5 +++ b/tools/testfiles/tmany.h5 diff --git a/tools/testfiles/tmany.h5.xml b/tools/testfiles/tmany.h5.xml index 60ccb08..1f7fa70 100644 --- a/tools/testfiles/tmany.h5.xml +++ b/tools/testfiles/tmany.h5.xml @@ -3,10 +3,10 @@ Expected output for 'h5dump --xml tmany.h5' ############################# <?xml version="1.0" encoding="UTF-8"?> <hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd"> -<hdf5:RootGroup OBJ-XID="xid_696" H5Path="/"> - <hdf5:Group Name="g1" OBJ-XID="xid_1344" H5Path="/g1" Parents="xid_696" H5ParentPaths="/" > - <hdf5:Group Name="g1.1" OBJ-XID="xid_2320" H5Path="/g1/g1.1" Parents="xid_1344" H5ParentPaths="/g1" > - <hdf5:Dataset Name="dset1" OBJ-XID="xid_2696" H5Path= "/g1/g1.1/dset1" Parents="xid_2320" H5ParentPaths="/g1/g1.1"> +<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/"> + <hdf5:Group Name="g1" OBJ-XID="xid_792" H5Path="/g1" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Group Name="g1.1" OBJ-XID="xid_1816" H5Path="/g1/g1.1" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Dataset Name="dset1" OBJ-XID="xid_2840" H5Path= "/g1/g1.1/dset1" Parents="xid_1816" H5ParentPaths="/g1/g1.1"> <hdf5:StorageLayout> <hdf5:ChunkedLayout Ndims="1"> <hdf5:ChunkDimension DimSize="2" /> @@ -265,17 +265,17 @@ Expected output for 'h5dump --xml tmany.h5' </hdf5:Data> </hdf5:Dataset> </hdf5:Group> - <hdf5:Group Name="g1.2" OBJ-XID="xid_5832" H5Path="/g1/g1.2" Parents="xid_1344" H5ParentPaths="/g1" > - <hdf5:Dataset Name="link1" OBJ-XID="xid_2696-1" H5Path="/g1/g1.2/link1" Parents="xid_5832" H5ParentPaths="/g1/g1.2"> - <hdf5:DatasetPtr OBJ-XID="xid_2696" H5Path="/g1/g1.2/link1"/> + <hdf5:Group Name="g1.2" OBJ-XID="xid_6040" H5Path="/g1/g1.2" Parents="xid_792" H5ParentPaths="/g1" > + <hdf5:Dataset Name="link1" OBJ-XID="xid_2840-1" H5Path="/g1/g1.2/link1" Parents="xid_6040" H5ParentPaths="/g1/g1.2"> + <hdf5:DatasetPtr OBJ-XID="xid_2840" H5Path="/g1/g1.2/link1"/> </hdf5:Dataset> </hdf5:Group> </hdf5:Group> - <hdf5:Group Name="g2" OBJ-XID="xid_6808" H5Path="/g2" Parents="xid_696" H5ParentPaths="/" > - <hdf5:SoftLink LinkName="slink2" OBJ-XID="xid_1344" H5SourcePath="/g2/slink2" TargetPath="/g1" TargetObj="xid_1344" Parents="xid_6808" H5ParentPaths="/g2" /> + <hdf5:Group Name="g2" OBJ-XID="xid_6520" H5Path="/g2" Parents="xid_96" H5ParentPaths="/" > + <hdf5:SoftLink LinkName="slink2" OBJ-XID="xid_792" H5SourcePath="/g2/slink2" TargetPath="/g1" TargetObj="xid_792" Parents="xid_6520" H5ParentPaths="/g2" /> </hdf5:Group> - <hdf5:Group Name="g3" OBJ-XID="xid_7784" H5Path="/g3" Parents="xid_696" H5ParentPaths="/" > - <hdf5:Dataset Name="link3" OBJ-XID="xid_8480" H5Path= "/g3/link3" Parents="xid_7784" H5ParentPaths="/g3"> + <hdf5:Group Name="g3" OBJ-XID="xid_10160" H5Path="/g3" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Dataset Name="link3" OBJ-XID="xid_11552" H5Path= "/g3/link3" Parents="xid_10160" H5ParentPaths="/g3"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -311,16 +311,16 @@ Expected output for 'h5dump --xml tmany.h5' </hdf5:Data> </hdf5:Dataset> </hdf5:Group> - <hdf5:Group Name="g4" OBJ-XID="xid_8432" H5Path="/g4" Parents="xid_696" H5ParentPaths="/" > - <hdf5:Dataset Name="dset2" OBJ-XID="xid_8480-2" H5Path="/g4/dset2" Parents="xid_8432" H5ParentPaths="/g4"> - <hdf5:DatasetPtr OBJ-XID="xid_8480" H5Path="/g4/dset2"/> + <hdf5:Group Name="g4" OBJ-XID="xid_10856" H5Path="/g4" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Dataset Name="dset2" OBJ-XID="xid_11552-2" H5Path="/g4/dset2" Parents="xid_10856" H5ParentPaths="/g4"> + <hdf5:DatasetPtr OBJ-XID="xid_11552" H5Path="/g4/dset2"/> </hdf5:Dataset> </hdf5:Group> - <hdf5:Group Name="g5" OBJ-XID="xid_10248" H5Path="/g5" Parents="xid_696" H5ParentPaths="/" > - <hdf5:SoftLink LinkName="slink4" OBJ-XID="xid_10944" H5SourcePath="/g5/slink4" TargetPath="/g6/dset3" TargetObj="xid_10944" Parents="xid_10248" H5ParentPaths="/g5" /> + <hdf5:Group Name="g5" OBJ-XID="xid_8512" H5Path="/g5" Parents="xid_96" H5ParentPaths="/" > + <hdf5:SoftLink LinkName="slink4" OBJ-XID="xid_15872" H5SourcePath="/g5/slink4" TargetPath="/g6/dset3" TargetObj="xid_15872" Parents="xid_8512" H5ParentPaths="/g5" /> </hdf5:Group> - <hdf5:Group Name="g6" OBJ-XID="xid_10896" H5Path="/g6" Parents="xid_696" H5ParentPaths="/" > - <hdf5:Dataset Name="dset3" OBJ-XID="xid_10944" H5Path= "/g6/dset3" Parents="xid_10896" H5ParentPaths="/g6"> + <hdf5:Group Name="g6" OBJ-XID="xid_8560" H5Path="/g6" Parents="xid_96" H5ParentPaths="/" > + <hdf5:Dataset Name="dset3" OBJ-XID="xid_15872" H5Path= "/g6/dset3" Parents="xid_8560" H5ParentPaths="/g6"> <hdf5:StorageLayout> <hdf5:ContiguousLayout/> </hdf5:StorageLayout> @@ -356,5 +356,13 @@ Expected output for 'h5dump --xml tmany.h5' </hdf5:Data> </hdf5:Dataset> </hdf5:Group> + <hdf5:Group Name="g7" OBJ-XID="xid_12688" H5Path="/g7" Parents="xid_96" H5ParentPaths="/" > + <hdf5:SoftLink LinkName="slink5" OBJ-XID="xid_18446744073709551614" H5SourcePath="/g7/slink5" TargetPath="/g8/elink" Parents="xid_12688" H5ParentPaths="/g7" /> + <hdf5:SoftLink LinkName="slink6" OBJ-XID="xid_18446744073709551613" H5SourcePath="/g7/slink6" TargetPath="/g8/udlink" Parents="xid_12688" H5ParentPaths="/g7" /> + </hdf5:Group> + <hdf5:Group Name="g8" OBJ-XID="xid_720" H5Path="/g8" Parents="xid_96" H5ParentPaths="/" > + <hdf5:ExternalLink LinkName="elink" OBJ-XID="xid_18446744073709551612" H5SourcePath="/g8/elink" TargetFilename="somefile" TargetPath="somepath" Parents="xid_720" H5ParentPaths="/g8" /> + <hdf5:UserDefined LinkName="udlink" OBJ-XID="xid_18446744073709551611" H5SourcePath="/g8/udlink" LinkClass="187" Parents="xid_720" H5ParentPaths="/g8" /> + </hdf5:Group> </hdf5:RootGroup> </hdf5:HDF5-File> diff --git a/tools/testfiles/tudlink-1.ddl b/tools/testfiles/tudlink-1.ddl new file mode 100644 index 0000000..5f76c40 --- /dev/null +++ b/tools/testfiles/tudlink-1.ddl @@ -0,0 +1,13 @@ +############################# +Expected output for 'h5dump tudlink.h5' +############################# +HDF5 "tudlink.h5" { +GROUP "/" { + USERDEFINED_LINK "udlink1" { + LINKCLASS 187 + } + USERDEFINED_LINK "udlink2" { + LINKCLASS 187 + } +} +} diff --git a/tools/testfiles/tudlink-1.ls b/tools/testfiles/tudlink-1.ls new file mode 100644 index 0000000..e83fce7 --- /dev/null +++ b/tools/testfiles/tudlink-1.ls @@ -0,0 +1,5 @@ +############################# + output for 'h5ls -w80 -r tudlink.h5' +############################# +/udlink1 -> cannot follow UD links +/udlink2 -> cannot follow UD links diff --git a/tools/testfiles/tudlink-2.ddl b/tools/testfiles/tudlink-2.ddl new file mode 100644 index 0000000..9ae3a54 --- /dev/null +++ b/tools/testfiles/tudlink-2.ddl @@ -0,0 +1,9 @@ +############################# +Expected output for 'h5dump -l udlink2 tudlink.h5' +############################# +HDF5 "tudlink.h5" { +USERDEFINED_LINK "udlink2" { + USERDEFINED_LINK "udlink2" { + LINKCLASS 187 +} +} diff --git a/tools/testfiles/tudlink.h5 b/tools/testfiles/tudlink.h5 Binary files differnew file mode 100644 index 0000000..3b10447 --- /dev/null +++ b/tools/testfiles/tudlink.h5 diff --git a/tools/testfiles/tudlink.h5.xml b/tools/testfiles/tudlink.h5.xml new file mode 100644 index 0000000..aa5fb6c --- /dev/null +++ b/tools/testfiles/tudlink.h5.xml @@ -0,0 +1,10 @@ +############################# +Expected output for 'h5dump --xml tudlink.h5' +############################# +<?xml version="1.0" encoding="UTF-8"?> +<hdf5:HDF5-File xmlns:hdf5="http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdf.ncsa.uiuc.edu/DTDs/HDF5File http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.xsd"> +<hdf5:RootGroup OBJ-XID="xid_96" H5Path="/"> + <hdf5:UserDefined LinkName="udlink1" OBJ-XID="xid_18446744073709551614" H5SourcePath="/udlink1" LinkClass="187" Parents="xid_96" H5ParentPaths="/" /> + <hdf5:UserDefined LinkName="udlink2" OBJ-XID="xid_18446744073709551613" H5SourcePath="/udlink2" LinkClass="187" Parents="xid_96" H5ParentPaths="/" /> +</hdf5:RootGroup> +</hdf5:HDF5-File> diff --git a/tools/testfiles/twithub.h5 b/tools/testfiles/twithub.h5 Binary files differindex 105319f..2176034 100644 --- a/tools/testfiles/twithub.h5 +++ b/tools/testfiles/twithub.h5 diff --git a/tools/testfiles/twithub513.h5 b/tools/testfiles/twithub513.h5 Binary files differindex 8b6a2e2..fbb872a 100644 --- a/tools/testfiles/twithub513.h5 +++ b/tools/testfiles/twithub513.h5 |