diff options
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 |