diff options
103 files changed, 3751 insertions, 1039 deletions
@@ -1408,6 +1408,10 @@ ./tools/testfiles/tmulti-o.h5 ./tools/testfiles/tmulti-r.h5 ./tools/testfiles/tmulti-s.h5 +./tools/testfiles/tmultifile.ls +./tools/testfiles/tmultifile.ddl +./tools/testfiles/tqmarkfile.ddl +./tools/testfiles/tstarfile.ddl ./tools/testfiles/tnbit.ddl ./tools/testfiles/tnestcomp-1.ddl ./tools/testfiles/tnestedcomp.h5 @@ -1849,11 +1853,18 @@ ./tools/h5diff/testfiles/h5diff_458.txt ./tools/h5diff/testfiles/h5diff_459.txt ./tools/h5diff/testfiles/h5diff_465.txt +./tools/h5diff/testfiles/h5diff_466.txt +./tools/h5diff/testfiles/h5diff_467.txt +./tools/h5diff/testfiles/h5diff_468.txt +./tools/h5diff/testfiles/h5diff_469.txt ./tools/h5diff/testfiles/h5diff_480.txt ./tools/h5diff/testfiles/h5diff_481.txt ./tools/h5diff/testfiles/h5diff_482.txt ./tools/h5diff/testfiles/h5diff_483.txt ./tools/h5diff/testfiles/h5diff_484.txt +./tools/h5diff/testfiles/h5diff_485.txt +./tools/h5diff/testfiles/h5diff_486.txt +./tools/h5diff/testfiles/h5diff_487.txt ./tools/h5diff/testfiles/h5diff_500.txt ./tools/h5diff/testfiles/h5diff_501.txt ./tools/h5diff/testfiles/h5diff_502.txt @@ -1908,6 +1919,8 @@ ./tools/h5diff/testfiles/h5diff_exclude1-2.h5 ./tools/h5diff/testfiles/h5diff_exclude2-1.h5 ./tools/h5diff/testfiles/h5diff_exclude2-2.h5 +./tools/h5diff/testfiles/h5diff_exclude3-1.h5 +./tools/h5diff/testfiles/h5diff_exclude3-2.h5 ./tools/h5diff/testfiles/h5diff_comp_vl_strs.h5 ./tools/h5diff/testfiles/h5diff_dset_zero_dim_size1.h5 ./tools/h5diff/testfiles/h5diff_dset_zero_dim_size2.h5 @@ -1952,12 +1965,12 @@ ./tools/h5jam/getub.c # test files for jam -./tools/h5jam/testfiles/twithub.h5 -./tools/h5jam/testfiles/twithub513.h5 ./tools/h5jam/testfiles/h5jam-help.txt ./tools/h5jam/testfiles/h5unjam-help.txt -./tools/h5jam/testfiles/u10.txt ./tools/h5jam/testfiles/tall.h5 +./tools/h5jam/testfiles/twithub.h5 +./tools/h5jam/testfiles/twithub513.h5 +./tools/h5jam/testfiles/u10.txt ./tools/h5jam/testfiles/u511.txt ./tools/h5jam/testfiles/u512.txt ./tools/h5jam/testfiles/u513.txt @@ -1,4 +1,4 @@ -HDF5 version 1.9.110 currently under development +HDF5 version 1.9.112 currently under development Please refer to the release_docs/INSTALL file for installation instructions. ------------------------------------------------------------------------------ diff --git a/c++/src/Makefile.in b/c++/src/Makefile.in index 1903667..159bbf6 100644 --- a/c++/src/Makefile.in +++ b/c++/src/Makefile.in @@ -431,7 +431,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 # Include src directory diff --git a/config/lt_vers.am b/config/lt_vers.am index 4528e68..daf5dc6 100644 --- a/config/lt_vers.am +++ b/config/lt_vers.am @@ -17,7 +17,7 @@ # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 ## If the API changes *at all*, increment LT_VERS_INTERFACE and @@ -1,7 +1,7 @@ #! /bin/sh -# From configure.in Id: configure.in 22034 2012-03-07 16:05:24Z chaarawi . +# From configure.in Id: configure.in 22040 2012-03-11 15:52:04Z hdftest . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for HDF5 1.9.110. +# Generated by GNU Autoconf 2.68 for HDF5 1.9.112. # # Report bugs to <help@hdfgroup.org>. # @@ -571,8 +571,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='HDF5' PACKAGE_TARNAME='hdf5' -PACKAGE_VERSION='1.9.110' -PACKAGE_STRING='HDF5 1.9.110' +PACKAGE_VERSION='1.9.112' +PACKAGE_STRING='HDF5 1.9.112' PACKAGE_BUGREPORT='help@hdfgroup.org' PACKAGE_URL='' @@ -1464,7 +1464,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures HDF5 1.9.110 to adapt to many kinds of systems. +\`configure' configures HDF5 1.9.112 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1534,7 +1534,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of HDF5 1.9.110:";; + short | recursive ) echo "Configuration of HDF5 1.9.112:";; esac cat <<\_ACEOF @@ -1729,7 +1729,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -HDF5 configure 1.9.110 +HDF5 configure 1.9.112 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2818,7 +2818,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by HDF5 $as_me 1.9.110, which was +It was created by HDF5 $as_me 1.9.112, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3639,7 +3639,7 @@ fi # Define the identity of the package. PACKAGE='hdf5' - VERSION='1.9.110' + VERSION='1.9.112' cat >>confdefs.h <<_ACEOF @@ -30645,7 +30645,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by HDF5 $as_me 1.9.110, which was +This file was extended by HDF5 $as_me 1.9.112, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -30711,7 +30711,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -HDF5 config.status 1.9.110 +HDF5 config.status 1.9.112 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -33505,7 +33505,7 @@ Usage: $0 [OPTIONS] Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ -HDF5 config.lt 1.9.110 +HDF5 config.lt 1.9.112 configured by $0, generated by GNU Autoconf 2.68. Copyright (C) 2010 Free Software Foundation, Inc. diff --git a/configure.in b/configure.in index ea9ea21..6b7eeff 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,7 @@ dnl dnl NOTE: Don't forget to change the version number here when we do a dnl release!!! dnl -AC_INIT([HDF5], [1.9.110], [help@hdfgroup.org]) +AC_INIT([HDF5], [1.9.112], [help@hdfgroup.org]) AC_CONFIG_SRCDIR([src/H5.c]) AM_CONFIG_HEADER([src/H5config.h]) diff --git a/fortran/src/Makefile.in b/fortran/src/Makefile.in index ca53252..35fafee 100644 --- a/fortran/src/Makefile.in +++ b/fortran/src/Makefile.in @@ -478,7 +478,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 # Include src directory in both Fortran and C flags (C compiler is used diff --git a/hl/c++/src/Makefile.in b/hl/c++/src/Makefile.in index eba4308..6dae65a 100644 --- a/hl/c++/src/Makefile.in +++ b/hl/c++/src/Makefile.in @@ -421,7 +421,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 # Include src directory diff --git a/hl/fortran/src/H5LTf90proto.h b/hl/fortran/src/H5LTf90proto.h index 5525af9..205871c 100755 --- a/hl/fortran/src/H5LTf90proto.h +++ b/hl/fortran/src/H5LTf90proto.h @@ -149,6 +149,7 @@ H5_FCDLL void HD5packFstring (char *src, char *dest, size_t len); #define nh5ltget_attribute_ndims_c H5_FC_FUNC_(h5ltget_attribute_ndims_c, H5LTGET_ATTRIBUTE_NDIMS_C) #define nh5ltget_attribute_info_c H5_FC_FUNC_(h5ltget_attribute_info_c, H5LTGET_ATTRIBUTE_INFO_C) +#define nh5ltpath_valid_c H5_FC_FUNC_(h5ltpath_valid_c, H5LTPATH_VALID_C) /*------------------------------------------------------------------------- * Image @@ -1197,6 +1198,13 @@ nh5ltread_dataset_string_c (hid_t_f *loc_id, _fcd name, char *buf); +HDF5_HL_F90CSTUBDLL +int_f +nh5ltpath_valid_c(hid_t_f *loc_id, + _fcd path, + int_f *pathlen, + int_f *check_object_valid_c); + /*------------------------------------------------------------------------- * Image *------------------------------------------------------------------------- diff --git a/hl/fortran/src/H5LTfc.c b/hl/fortran/src/H5LTfc.c index 484acf1..c0b7695 100755 --- a/hl/fortran/src/H5LTfc.c +++ b/hl/fortran/src/H5LTfc.c @@ -2124,3 +2124,54 @@ done: return ret_value; } + +/*------------------------------------------------------------------------- +* Function: h5ltpath_valid_c +* +* Purpose: Calls h5ltpath_valid +* +* Return: Success: 0, Failure: -1 +* +* Programmer: M. Scot Breitenfeld +* +* Date: February 18, 2012 +* +* Comments: +* +* Modifications: +* +* +*------------------------------------------------------------------------- +*/ + +int_f +nh5ltpath_valid_c(hid_t_f *loc_id, + _fcd path, + int_f *pathlen, + int_f *check_object_valid_c) +{ + htri_t ret = -1; + char *c_path = NULL; + hbool_t check_object_valid; + + /* + * convert FORTRAN name to C name + */ + if( NULL == (c_path = (char *)HD5f2cstring(path, (int)*pathlen))) + goto done; + + check_object_valid = FALSE; + if(*check_object_valid_c == 1) + check_object_valid = TRUE; + + /* + * call H5LTpath_valid function. + */ + ret = H5LTpath_valid( (hid_t)*loc_id, c_path, check_object_valid ); + +done: + if(c_path != NULL) + free(c_path); + + return (int_f)ret; +} diff --git a/hl/fortran/src/H5LTff.f90 b/hl/fortran/src/H5LTff.f90 index cbc9b96..7d53ab7 100755 --- a/hl/fortran/src/H5LTff.f90 +++ b/hl/fortran/src/H5LTff.f90 @@ -6308,6 +6308,73 @@ CONTAINS errcode = h5ltget_attribute_info_c(loc_id,namelen,dset_name,attrlen,attr_name,dims,type_class,type_size) END SUBROUTINE h5ltget_attribute_info_f + + !------------------------------------------------------------------------- + ! Function: h5ltpath_valid_f + ! + ! Purpose: Validates a path + ! + ! Return: Success: 0, Failure: -1 + ! + ! Programmer: M. Scot Breitenfeld + ! + ! Date: February 18, 2012 + ! + ! Comments: + ! + ! Modifications: + ! + !------------------------------------------------------------------------- + + SUBROUTINE h5ltpath_valid_f(loc_id, path, check_object_valid, path_valid, errcode) + + IMPLICIT NONE + ! + !This definition is needed for Windows DLLs + !DEC$if defined(BUILD_HDF5_DLL) + !DEC$attributes dllexport :: h5ltpath_valid_f + !DEC$endif + ! + INTEGER(hid_t) , INTENT(IN) :: loc_id ! File or group identifier. + CHARACTER(LEN=*), INTENT(IN) :: path ! Path to the object to check, relative to loc_id. + LOGICAL , INTENT(IN) :: check_object_valid ! Indicates whether to check if the final component + ! of the path resolves to a valid object + LOGICAL , INTENT(OUT) :: path_valid ! Object status + INTEGER , INTENT(OUT) :: errcode ! Error code: 0 on success and -1 on failure + + INTEGER :: pathlen + INTEGER :: check_object_valid_c + INTEGER :: status + + INTERFACE + INTEGER FUNCTION h5ltpath_valid_c(loc_id, path, pathlen, check_object_valid_c) + USE h5global + !DEC$IF DEFINED(HDF5F90_WINDOWS) + !DEC$ATTRIBUTES C,reference,decorate,alias:'H5LTPATH_VALID_C'::h5ltpath_valid_c + !DEC$ENDIF + !DEC$ATTRIBUTES reference :: path + INTEGER(hid_t), INTENT(in) :: loc_id + CHARACTER(len=*), INTENT(in) :: path + INTEGER :: pathlen + INTEGER :: check_object_valid_c + END FUNCTION h5ltpath_valid_c + END INTERFACE + + check_object_valid_c = 0 + IF(check_object_valid) check_object_valid_c = 1 + + pathlen = LEN(path) + status = h5ltpath_valid_c(loc_id, path, pathlen, check_object_valid_c) + + path_valid = .FALSE. + errcode = 0 + IF(status.EQ.1)THEN + path_valid = .TRUE. + ELSE IF(status.LT.0)THEN + errcode = -1 + ENDIF + + END SUBROUTINE h5ltpath_valid_f ! end ! END MODULE H5LT diff --git a/hl/fortran/src/Makefile.in b/hl/fortran/src/Makefile.in index bbe420c..62d7309 100644 --- a/hl/fortran/src/Makefile.in +++ b/hl/fortran/src/Makefile.in @@ -436,7 +436,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/hl/src -I$(top_builddir)/hl/src \ -I$(top_srcdir)/fortran/src -I$(top_builddir)/fortran/src diff --git a/hl/fortran/test/tstlite.f90 b/hl/fortran/test/tstlite.f90 index b0e28f9..9329dba 100644 --- a/hl/fortran/test/tstlite.f90 +++ b/hl/fortran/test/tstlite.f90 @@ -1067,6 +1067,9 @@ SUBROUTINE test_datasets() INTEGER :: has ! general purpose integer INTEGER :: type_class INTEGER(SIZE_T) :: type_size + LOGICAL :: path_valid ! status of the path + CHARACTER(LEN=6) :: chr_exact + CHARACTER(LEN=8) :: chr_lg ! ! Initialize FORTRAN predefined datatypes. @@ -1118,6 +1121,7 @@ SUBROUTINE test_datasets() CALL passed() + !------------------------------------------------------------------------- ! real !------------------------------------------------------------------------- @@ -1207,9 +1211,60 @@ SUBROUTINE test_datasets() CALL passed() + CALL test_begin(' Test h5ltpath_valid_f ') + ! + ! test function h5ltpath_valid_f + ! + chr_exact = "/"//dsetname2 ! test character buffer the exact size needed + CALL h5ltpath_valid_f(file_id, chr_exact, .TRUE., path_valid, errcode) + IF(errcode.LT.0.OR..NOT.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + chr_lg = "/"//dsetname2 ! test character buffer larger then needed + CALL h5ltpath_valid_f(file_id, chr_lg, .TRUE., path_valid, errcode) + IF(errcode.LT.0.OR..NOT.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + CALL h5ltpath_valid_f(file_id, chr_lg, .FALSE., path_valid, errcode) + IF(errcode.LT.0.OR..NOT.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + ! Should fail, dataset does not exist + CALL h5ltpath_valid_f(file_id, "/"//dsetname2//"junk", .TRUE., path_valid, errcode) + IF(errcode.LT.0.OR.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + + CALL h5ltpath_valid_f(file_id, "/"//dsetname2//"junk", .FALSE., path_valid, errcode) + IF(errcode.LT.0.OR.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + + ! Create a dangling soft link + CALL h5lcreate_soft_f("/G2", file_id, "/G3", errcode) + + ! Should pass, does not check for dangled link + CALL h5ltpath_valid_f(file_id, "/G3", .FALSE., path_valid, errcode) + IF(.NOT.path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + + ! Should fail, dangled link + CALL h5ltpath_valid_f(file_id, "/G2", .TRUE., path_valid, errcode) + IF(path_valid)THEN + PRINT *, 'error in h5ltpath_valid_f' + STOP + ENDIF + CALL passed() CALL test_begin(' Get dataset dimensions/info ') @@ -1296,6 +1351,8 @@ SUBROUTINE test_attributes() CHARACTER(LEN=5), PARAMETER :: attrname5 = "attr5" ! Attribute name CHARACTER(LEN=8), PARAMETER :: buf1 = "mystring" ! Data buffer CHARACTER(LEN=8) :: bufr1 ! Data buffer + CHARACTER(LEN=10) :: bufr1_lg ! Data buffer + CHARACTER(LEN=6) :: bufr1_sm ! Data buffer INTEGER, DIMENSION(DIM1) :: buf2 ! Data buffer INTEGER, DIMENSION(DIM1) :: bufr2 ! Data buffer REAL, DIMENSION(DIM1) :: buf3 ! Data buffer @@ -1446,20 +1503,46 @@ SUBROUTINE test_attributes() CALL h5ltset_attribute_string_f(file_id,dsetname1,attrname5,buf1,errcode) ! - ! read attribute. + ! read attribute into a fortran character buf that is the same size as buf1. ! CALL h5ltget_attribute_string_f(file_id,dsetname1,attrname5,bufr1,errcode) ! ! compare read and write buffers. ! - IF ( buf1 .NE. bufr1 ) THEN PRINT *, 'read buffer differs from write buffer' PRINT *, buf1, ' and ', bufr1 STOP ENDIF + ! + ! read attribute into a fortran character buf that is larger then buf1. + ! + CALL h5ltget_attribute_string_f(file_id,dsetname1,attrname5,bufr1_lg,errcode) + + ! + ! compare read and write buffers, make sure C NULL character was removed. + ! + IF ( buf1(1:8) .NE. bufr1_lg(1:8) .AND. bufr1_lg(9:10) .NE. ' ' ) THEN + PRINT *, 'larger read buffer differs from write buffer' + PRINT *, buf1, ' and ', bufr1_lg + STOP + ENDIF + + ! + ! read attribute into a fortran character buf that is smaller then buf1. + ! + CALL h5ltget_attribute_string_f(file_id,dsetname1,attrname5,bufr1_sm,errcode) + + ! + ! compare read and write buffers. + ! + IF ( buf1(1:6) .NE. bufr1_sm(1:6) ) THEN + PRINT *, 'smaller read buffer differs from write buffer' + PRINT *, buf1, ' and ', bufr1_sm + STOP + ENDIF CALL passed() diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c index 1cc1017..eeaceeb 100644 --- a/hl/src/H5LT.c +++ b/hl/src/H5LT.c @@ -3030,4 +3030,110 @@ out: } - +htri_t +H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid) + { + char *tmp_path = NULL; /* Temporary copy of the path */ + char *curr_name; /* Pointer to current component of path name */ + char *delimit; /* Pointer to path delimiter during traversal */ + H5I_type_t obj_type; + htri_t link_exists, obj_exists; + size_t path_length; + htri_t ret_value; + + /* Initialize */ + ret_value = FALSE; + + /* Find the type of loc_id */ + if((obj_type = H5Iget_type(loc_id)) == H5I_BADID) { + ret_value = FAIL; + goto done; + } + + /* Find the length of the path */ + path_length = HDstrlen(path); + + /* Check if the identifier is the object itself, i.e. path is '.' */ + if(HDstrncmp(path, ".", path_length) == 0) { + if(check_object_valid) { + obj_exists = H5Oexists_by_name(loc_id, path, H5P_DEFAULT); + ret_value = obj_exists; + goto done; + } else { + ret_value = TRUE; /* Since the object is the identifier itself, + * we can only check if loc_id is a valid type */ + goto done; + } + } + + /* Duplicate the path to use */ + if(NULL == (tmp_path = HDstrdup(path))) { + ret_value = FAIL; + goto done; + } + + curr_name = tmp_path; + + /* check if absolute pathname */ + if(HDstrncmp(path, "/", 1) == 0) curr_name++; + + /* check if relative path name starts with "./" */ + if(HDstrncmp(path, "./", 2) == 0) curr_name += 2; + + while((delimit=HDstrchr(curr_name,'/'))!=NULL) { + /* Change the delimiter to terminate the string */ + *delimit='\0'; + + obj_exists = FALSE; + if((link_exists = H5Lexists(loc_id, tmp_path, H5P_DEFAULT)) < 0) { + ret_value = FAIL; + goto done; + } + + /* If target link does not exist then no reason to + * continue checking the path */ + if(link_exists != TRUE) { + ret_value = FALSE; + goto done; + } + + /* Determine if link resolves to an actual object */ + if((obj_exists = H5Oexists_by_name(loc_id, tmp_path, H5P_DEFAULT)) < 0) { + ret_value = FAIL; + goto done; + } + + if(obj_exists != TRUE) + break; + + /* Change the delimiter back to '/' */ + *delimit='/'; + + /* Advance the pointer in the path to the start of the next component */ + curr_name = delimit + 1; + + } /* end while */ + + /* Should be pointing to the last component in the path name now... */ + + /* Check if link does not exist */ + if((link_exists = H5Lexists(loc_id, tmp_path, H5P_DEFAULT)) < 0) { + ret_value = FAIL; + } else { + ret_value = link_exists; + /* Determine if link resolves to an actual object for check_object_valid TRUE */ + if(check_object_valid == TRUE && link_exists == TRUE) { + if((obj_exists = H5Oexists_by_name(loc_id, tmp_path, H5P_DEFAULT)) < 0) { + ret_value = FAIL; + } else { + ret_value = obj_exists; + } + } + } + +done: + if(tmp_path != NULL) + HDfree(tmp_path); + + return ret_value; + } diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h index 7fb873a..6efae68 100644 --- a/hl/src/H5LTpublic.h +++ b/hl/src/H5LTpublic.h @@ -340,8 +340,9 @@ H5_HLDLL herr_t H5LTdtype_to_text(hid_t dtype, char *str, H5LT_lang_t lang_type, *------------------------------------------------------------------------- */ -H5_HLDLL herr_t H5LTfind_attribute( hid_t loc_id, const char *name ); +H5_HLDLL herr_t H5LTfind_attribute( hid_t loc_id, const char *name ); +H5_HLDLL htri_t H5LTpath_valid(hid_t loc_id, const char *path, hbool_t check_object_valid); #ifdef __cplusplus } diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in index 0509b75..2623b3a 100644 --- a/hl/src/Makefile.in +++ b/hl/src/Makefile.in @@ -420,7 +420,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 # This library is our main target. diff --git a/hl/test/COPYING b/hl/test/COPYING index 6903daf..6903daf 100755..100644 --- a/hl/test/COPYING +++ b/hl/test/COPYING diff --git a/hl/test/test_lite.c b/hl/test/test_lite.c index 4944143..eb00cd7 100644 --- a/hl/test/test_lite.c +++ b/hl/test/test_lite.c @@ -21,6 +21,8 @@ #define FILE_NAME "test_lite1.h5" #define FILE_NAME2 "test_lite2.h5" +#define FILE_NAME3 "test_lite3.h5" +#define FILE_NAME4 "test_lite4.h5" #define INPUT_FILE "dtype_file.txt" #define DSET0_NAME "2D int array" @@ -1805,6 +1807,339 @@ out: } /*------------------------------------------------------------------------- + * test H5LTpath_valid function + *------------------------------------------------------------------------- + */ +static int test_valid_path(void) +{ + hid_t file_id, group; + herr_t status; + FILE *fp = NULL; + htri_t path_valid; + char path[10]; + const char *data_string_in = "test"; + + TESTING("H5LTpath_valid"); + + /* Create a new file using default properties. */ + + /************************************************************** + * The file structure should look like this: + * + * +----------------------------------+ + * | / | + * +----------------------------------+ + * / | \ \ + * / | \ \ + * / | \ \ + * / | \ G8 (dangled external link) + * / DS \ + * / \ + * G1 G2 + * | --> DS1 | + * / \--> DS3 / \ + * / / \ + * G2 DS4 G7 + * | (hard link (dangled soft link + * | to /G1/DS3) to /G1/G20 ) + * | + * | + * | --- Gcyc (soft link to /G1) + * / \ + * / \ + * G5 \ + * (soft link G6 (external link /G1 in FILENAME4) + * to /G2) + * + ****************************************************************/ + + file_id = H5Fcreate(FILE_NAME3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create dataset "/DS" + */ + if(H5LTmake_dataset_string(file_id, "DS", data_string_in)<0) + goto out; + + /* + * Create an external dangled link + */ + if(H5Lcreate_external("NonExistant_File.h5", "G8", file_id, "DangledExternalLink", H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + + /* + * Create a group named "G2" in the file. + */ + if((group = H5Gcreate2(file_id, "G2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))<0) + goto out; + + /* + * Create a dataset named "G2/DS4" in the file. + */ + if(H5LTmake_dataset_string(group, "/G2/DS4", data_string_in)<0) + goto out; + + /* + * Create a soft link + */ + if(H5Lcreate_soft("/G1/G20", file_id, "/G2/G7", H5P_DEFAULT, H5P_DEFAULT) <0) + goto out; + + if(H5Gclose(group)<0) + goto out; + + /* + * Create a group named "G1" in the file. + */ + if((group = H5Gcreate2(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))<0) + goto out; + + /* + * Create a group named "G1/DS1" in the file. + */ + if(H5LTmake_dataset_string(group, "/G1/DS1", data_string_in)<0) + goto out; + + if(H5Gclose(group)<0) + goto out; + + /* + * Create a hard link + */ + if(H5Lcreate_hard(file_id, "/G2/DS4", file_id, "/G1/DS3",H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + /* + * Create a group named "/G1/G2" in the file. + */ + if((group = H5Gcreate2(file_id, "/G1/G2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))<0) + goto out; + + /* + * Create a soft link + */ + if(H5Lcreate_soft("/G2", file_id, "/G1/G2/G5", H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + + /* + * Create a cyclic soft link + */ + if(H5Lcreate_soft("/G1", file_id, "/G1/G2/Gcyc", H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + + if(H5Gclose(group)<0) + goto out; + + /* + * Create a group named "/G1/G2/G6" in the file. + */ + if((group = H5Gcreate2(file_id, "/G1/G2/G6", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))<0) + goto out; + + /* + * Create an external link + */ + if(H5Lcreate_external( FILE_NAME4, "G1", group, "ExternalLink", H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + + if(H5Gclose(group)<0) + goto out; + /* + * Close the file. + */ + status = H5Fclose (file_id); + + /* Create another file for checking external links */ + + /************************************************************** + * The file structure should look like this: + * + * +----+ + * | / | + * +----+ + * | + * | + * | + * G1 + * / \ + * / \ + * DS1 G2 + * (dangled soft link to /G1/G20) + * + ****************************************************************/ + + /* Make external link file */ + file_id = H5Fcreate(FILE_NAME4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* + * Create a group named "G1" in the file. + */ + if((group = H5Gcreate2(file_id, "G1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))<0) + goto out; + /* + * Create a dataset named "G1/DS1" in the file. + */ + if(H5LTmake_dataset_string(group, "/G1/DS1", data_string_in)<0) + goto out; + + /* + * Create a dangling soft link + */ + + if(H5Lcreate_soft("/G1/G2", file_id, "/G1/G20", H5P_DEFAULT, H5P_DEFAULT)<0) + goto out; + + if(H5Gclose(group)<0) + goto out; + + H5Fclose(file_id); + + /* Open input file */ + if((file_id = H5Fopen(FILE_NAME3,H5F_ACC_RDONLY, H5P_DEFAULT))<0) + goto out; + + /************************************** + * CHECK ABSOLUTE PATHS + **************************************/ + if( (path_valid = H5LTpath_valid(file_id, "/G1", TRUE)) != TRUE) { + goto out; + } + + if((path_valid = H5LTpath_valid(file_id, "/G1/DS1", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/DS3", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G5", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/Gcyc/DS1", FALSE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/Gcyc/DS1", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G2", TRUE)) != TRUE) + goto out; + + /* check soft link points to a valid object*/ + if( (path_valid = H5LTpath_valid(file_id, "/G2/DS4", TRUE)) != TRUE) + goto out; + + /* check if path exist, but not the object */ + if( (path_valid = H5LTpath_valid(file_id, "/G2/G7", FALSE)) != TRUE ) + goto out; + /* check if path exist and if the object exists. It should fail + * since it is a dangling soft link + */ + if( (path_valid = H5LTpath_valid(file_id, "/G2/G7", TRUE)) == TRUE) + goto out; + + /* check soft links */ + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G5/DS4", TRUE)) != TRUE) + goto out; + + /************************************** + * CHECK RELATIVE PATHS + ***************************************/ + + if( (group = H5Gopen2(file_id, "/G1", H5P_DEFAULT)) < 0) + goto out; + + /* The identifier (file id) is the object itself, i.e. "." */ + + if((path_valid = H5LTpath_valid(file_id, ".", FALSE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, ".", TRUE)) != TRUE) + goto out; + + /* The identifier (group id) is the object itself, i.e. "." */ + + if( (path_valid = H5LTpath_valid(group, ".", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(group, "DS3", FALSE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(group, "DS3", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(group, "G2/G5", TRUE)) != TRUE) + goto out; + + /* Check the "./" case */ + if( (path_valid = H5LTpath_valid(group, "./DS3", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(group, "./G2/G5", TRUE)) != TRUE) + goto out; + + /* Should fail, does not exist */ + if( (path_valid = H5LTpath_valid(group, "./G2/G20", FALSE)) == TRUE) + goto out; + + /* Should fail, does not exist */ + if( (path_valid = H5LTpath_valid(group, "./G2/G20", TRUE)) == TRUE) + goto out; + + if(H5Gclose(group)<0) + goto out; + + /***************************** + * Check external links + *****************************/ + + /* The dangled external link path is valid */ + if( (path_valid = H5LTpath_valid(file_id, "/DangledExternalLink", FALSE)) != TRUE) + goto out; + + /* The file however does not exists, so the link dangles -> should return false */ + if( (path_valid = H5LTpath_valid(file_id, "/DangledExternalLink", TRUE)) == TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G6/ExternalLink", FALSE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G6/ExternalLink", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/Gcyc/G2/G6/ExternalLink/DS1", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/Gcyc/G2/G6/ExternalLink/G20", FALSE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G6/ExternalLink/DS1", TRUE)) != TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G6/ExternalLink/G20", FALSE)) != TRUE) + goto out; + + /* Should fail, does not exist */ + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/G6/ExternalLink/G20", TRUE)) == TRUE) + goto out; + + if( (path_valid = H5LTpath_valid(file_id, "/G1/G2/Gcyc/G2/G6/ExternalLink/G20", TRUE)) == TRUE) + goto out; + + + if(H5Fclose(file_id)<0) + goto out; + + PASSED(); + return 0; + + out: + H5_FAILED(); + return -1; +} + + +/*------------------------------------------------------------------------- * the main program *------------------------------------------------------------------------- */ @@ -1819,7 +2154,7 @@ int main( void ) nerrors += test_attr(); /* test text-dtype functions */ - nerrors += test_text_dtype(); + nerrors += test_valid_path(); /* check for errors */ if (nerrors) @@ -1832,4 +2167,3 @@ error: } - diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index baf9f50..f0f296c 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -1,4 +1,4 @@ -HDF5 version 1.9.110 currently under development +HDF5 version 1.9.112 currently under development ================================================================================ @@ -241,18 +241,26 @@ New Features Tools: ------ - - h5repack: Improved performance for hanlding big chunked dataset - (size > 128MB). It would perform much better prior to the - improvement, especially for cases that chunk dimentions - looks like "1024x5x1" (compare to "1x5x1024"). When bigger numbers + - h5dump: Added capability for "-a" option to show attributes containing "/" + by using an escape character. For example, for a dataset "/dset" + containing attribute "speed(m/h)", use "h5dump -a "/dset/speed(\/h)" + to show the content of the attribute. See details at HDFFV-7523 + (PC -- 2012/03/12) + - h5dump: Added ability to apply command options across multiple files using a + wildcard in the filename. Example; "h5dump -H -d Dataset1 tarr*.h5". + HDFFV-7876 (ADB - 2012/03/12). + - h5repack: Improved performance for big chunked datasets (size > 128MB) + when used with layout (-l) or compression (-f) option. + It would perform much better prior to the improvement, + especially for cases that chunk dimentions looks like + "1024x5x1" (compare to "1x5x1024"). When bigger numbers are toward front and smaller number is toward back in chunk - dimentions. + dimentions. HDFFV-7862 (JKM - 2012/03/01) - h5dump: Added new option --no-compact-subset. This option will not interpret the '[' character as starting the compact form of subsetting. This is useful when the "h5dump error: unable to open dataset "datset_name"" message is output because a dataset - name contains a '[' character.(JIRA HDFFV-7689). - (ADB - 2012/01/31) + name contains a '[' character. HDFFV-7689 (ADB - 2012/01/31) - h5dump: Corrected schema location: <hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/HDF5/XML/schema/HDF5-File" @@ -341,6 +349,10 @@ New Features h5dsget_scale_name_f h5dsget_num_scales_f (EIP for SB - 2011/10/13) + + - New API: h5ltpath_valid (Fortran: h5ltpath_valid_f) which checks + if a path is correct and determines if a link resolves to a valid + object and does not dangle. (MSB- 2012/3/15) Documentation ------------- @@ -356,10 +368,15 @@ Bug Fixes since HDF5-1.8.0 release Library ------- - + - H5Pset_data_transform had seg fault in some cases like x*-100. It + works correctly now and handles other cases like 100-x or 2/x. + (SLU - 2012/3/15. Issue 7922) + - Fixed rare corruption bugs that could occur when using the new object + header format. (NAF - 2012/3/15 - HDFFV-7879) - Creating a dataset in a read-only file caused seg fault when the file - is closed. It's fixed. The error stack is returned correctly - now. (SLU - 2012/1/25. Issue 7756) + is closed. It's fixed. The attemp to create a dataset will fail + with the error stack indicating the file is read-only. (SLU - + 2012/1/25. Issue 7756) - Fixed a seg fault that could occur when shrinking a dataset with chunks larger than 1 MB. (NAF - 2011/11/30 - HDFFV-7833) - The library allowed the conversion of strings between ASCII and UTF8 @@ -649,6 +666,21 @@ Bug Fixes since HDF5-1.8.0 release Tools ----- + - h5diff: If unique objects exists only in one file and try to exclude + the unique objects with --exclude-path option, h5diff missed + excluding some objects. + Fixed to exclude objects correctly in such case. + HDFFV-7837 (JKM 2012/03/20) + - h5dump: Added tools library error stack to properly catch error + information generated within the library. + HDFFV-7958 (ADB 2012/03/12) + - h5dump: Dangling links no longer throw error message, change process + when open link fails. + HDFFV-7839 (ADB 2012/03/12) + - h5diff: When two symbolic dangling links are compared with + --follow-symlinks option, the result should be same. It worked for + comparing two files, but didn't work for comparing two objects. + HDFFV-7835 (JKM 2012/03/09) - h5dump: Refactored code to remove duplicated functions. Split XML functions from DDL functions. Corrected indentation and formatting errors. Also fixed subsetting counting overflow (HDFFV-5874). Verified diff --git a/src/H5Dint.c b/src/H5Dint.c index f105e0a..9a80bfc 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1596,15 +1596,20 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al switch(layout->type) { case H5D_CONTIGUOUS: if(!(*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) { - /* Reserve space in the file for the entire array */ - if(H5D_contig_alloc(f, dxpl_id, &layout->storage.u.contig/*out*/) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage") + /* Check if we have a zero-sized dataset */ + if(layout->storage.u.contig.size > 0) { + /* Reserve space in the file for the entire array */ + if(H5D_contig_alloc(f, dxpl_id, &layout->storage.u.contig/*out*/) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage") + + /* Indicate that we should initialize storage space */ + must_init_space = TRUE; + } /* end if */ + else + layout->storage.u.contig.addr = HADDR_UNDEF; /* Indicate that we set the storage addr */ addr_set = TRUE; - - /* Indicate that we should initialize storage space */ - must_init_space = TRUE; } /* end if */ break; diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 64cb1bb..940d4c7 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -38,8 +38,24 @@ /* The driver identification number, initialized at runtime */ static hid_t H5FD_CORE_g = 0; -/* - * The description of a file belonging to this driver. The `eoa' and `eof' +/* Since Windows doesn't follow the rest of the world when it comes + * to POSIX I/O types, some typedefs and constants are needed to avoid + * making the code messy with #ifdefs. + * NOTE: These are only used when writing data to the backing store on + * file close. + */ +#ifdef H5_HAVE_WIN32_API +typedef unsigned int h5_core_io_t; +typedef int h5_core_io_ret_t; +static int H5_CORE_MAX_IO_BYTES_g = INT_MAX; +#else +/* Unix, everyone else */ +typedef size_t h5_core_io_t; +typedef ssize_t h5_core_io_ret_t; +static size_t H5_CORE_MAX_IO_BYTES_g = SSIZET_MAX; +#endif /* H5_HAVE_WIN32_API */ + +/* The description of a file belonging to this driver. The `eoa' and `eof' * determine the amount of hdf5 address space in use and the high-water mark * of the file (the current size of the underlying memory). */ @@ -54,8 +70,7 @@ typedef struct H5FD_core_t { int fd; /*backing store file descriptor */ /* Information for determining uniqueness of a file with a backing store */ #ifndef H5_HAVE_WIN32_API - /* - * On most systems the combination of device and i-node number uniquely + /* On most systems the combination of device and i-node number uniquely * identify a file. */ dev_t device; /*file device number */ @@ -65,18 +80,26 @@ typedef struct H5FD_core_t { ino_t inode; /*file i-node number */ #endif /*H5_VMS*/ #else - /* - * On H5_HAVE_WIN32_API the low-order word of a unique identifier associated with the - * file and the volume serial number uniquely identify a file. This number - * (which, both? -rpm) may change when the system is restarted or when the - * file is opened. After a process opens a file, the identifier is - * constant until the file is closed. An application can use this - * identifier and the volume serial number to determine whether two - * handles refer to the same file. + /* Files in windows are uniquely identified by the volume serial + * number and the file index (both low and high parts). + * + * There are caveats where these numbers can change, especially + * on FAT file systems. On NTFS, however, a file should keep + * those numbers the same until renamed or deleted (though you + * can use ReplaceFile() on NTFS to keep the numbers the same + * while renaming). + * + * See the MSDN "BY_HANDLE_FILE_INFORMATION Structure" entry for + * more information. + * + * http://msdn.microsoft.com/en-us/library/aa363788(v=VS.85).aspx */ - DWORD fileindexlo; - DWORD fileindexhi; -#endif + DWORD nFileIndexLow; + DWORD nFileIndexHigh; + DWORD dwVolumeSerialNumber; + + HANDLE hFile; /* Native windows file handle */ +#endif /* H5_HAVE_WIN32_API */ hbool_t dirty; /*changes not saved? */ } H5FD_core_t; @@ -89,8 +112,7 @@ typedef struct H5FD_core_fapl_t { /* Allocate memory in multiples of this size by default */ #define H5FD_CORE_INCREMENT 8192 -/* - * These macros check for overflow of various quantities. These macros +/* These macros check for overflow of various quantities. These macros * assume that file_offset_t is signed and haddr_t and size_t are unsigned. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' @@ -200,8 +222,6 @@ H5FD_core_init_interface(void) * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t @@ -258,15 +278,6 @@ H5FD_core_term(void) * Programmer: Robb Matzke * Thursday, February 19, 1998 * - * Modifications: - * Robb Matzke, 1999-10-19 - * Added the BACKING_STORE argument. If set then the entire file - * contents are flushed to a file with the same name as this - * core file. - * - * Raymond Lu, 2001-10-25 - * Changed the file access list to the new generic list. - * *------------------------------------------------------------------------- */ herr_t @@ -305,14 +316,6 @@ done: * Programmer: Robb Matzke * Tuesday, August 10, 1999 * - * Modifications: - * Robb Matzke, 1999-10-19 - * Added the BACKING_STORE argument. - * - * Raymond Lu - * 2001-10-25 - * Changed file access list to the new generic property list. - * *------------------------------------------------------------------------- */ herr_t @@ -355,8 +358,6 @@ done: * Programmer: Robb Matzke * Friday, August 13, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static void * @@ -396,16 +397,6 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Robb Matzke, 1999-10-19 - * The backing store file is created and opened if specified. - * - * Raymond Lu, 2006-11-30 - * Enabled the driver to read an existing file depending on - * the setting of the backing_store and file open flags. - * - * Allen Byrne, 2008-1-23 - * changed if of fapl_id to assert *------------------------------------------------------------------------- */ static H5FD_t * @@ -417,7 +408,6 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, H5FD_core_fapl_t *fa=NULL; H5P_genplist_t *plist; /* Property list pointer */ #ifdef H5_HAVE_WIN32_API - HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif h5_stat_t sb; @@ -461,8 +451,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, if(name && *name) file->name = H5MM_xstrdup(name); - /* - * The increment comes from either the file access property list or the + /* The increment comes from either the file access property list or the * default value. But if the file access property list was zero then use * the default value instead. */ @@ -474,10 +463,16 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, if(fd >= 0) { /* Retrieve information for determining uniqueness of file */ #ifdef H5_HAVE_WIN32_API - filehandle = _get_osfhandle(fd); - (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo); - file->fileindexhi = fileinfo.nFileIndexHigh; - file->fileindexlo = fileinfo.nFileIndexLow; + file->hFile = (HANDLE)_get_osfhandle(fd); + if(INVALID_HANDLE_VALUE == file->hFile) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file handle") + + if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file information") + + file->nFileIndexHigh = fileinfo.nFileIndexHigh; + file->nFileIndexLow = fileinfo.nFileIndexLow; + file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber; #else /* H5_HAVE_WIN32_API */ file->device = sb.st_dev; #ifdef H5_VMS @@ -496,7 +491,7 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, size_t size; /* Retrieve file size */ - size = (size_t)sb.st_size; + size = (size_t)sb.st_size; /* Check if we should allocate the memory buffer and read in existing data */ if(size) { @@ -507,9 +502,40 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, /* Set up data structures */ file->eof = size; - /* Read in existing data */ - if(HDread(file->fd, file->mem, size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file") + /* Read in existing data, being careful of interrupted system calls, + * partial results, and the end of the file. + */ + while(size > 0) { + + h5_core_io_t bytes_in = 0; /* # of bytes to read */ + h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */ + + /* Trying to read more bytes than the return type can handle is + * undefined behavior in POSIX. + */ + if(size > H5_CORE_MAX_IO_BYTES_g) + bytes_in = H5_CORE_MAX_IO_BYTES_g; + else + bytes_in = (h5_core_io_t)size; + + do { + bytes_read = HDread(file->fd, file->mem, bytes_in); + } while(-1 == bytes_read && EINTR == errno); + + if(-1 == bytes_read) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + + HDassert(bytes_read >= 0); + HDassert((size_t)bytes_read <= size); + + size -= (size_t)bytes_read; + + } /* end while */ } /* end if */ } /* end if */ @@ -578,13 +604,6 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Neil Fortner - * Tuesday, March 9, 2010 - * Modified function to compare low level file information if - * a backing store is opened for both files, similar to the - * sec2 file driver. - * *------------------------------------------------------------------------- */ static int @@ -599,11 +618,14 @@ H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2) if(f1->fd >= 0 && f2->fd >= 0) { /* Compare low level file information for backing store */ #ifdef H5_HAVE_WIN32_API - if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) - if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + if(f1->dwVolumeSerialNumber < f2->dwVolumeSerialNumber) HGOTO_DONE(-1) + if(f1->dwVolumeSerialNumber > f2->dwVolumeSerialNumber) HGOTO_DONE(1) - if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) - if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + if(f1->nFileIndexHigh < f2->nFileIndexHigh) HGOTO_DONE(-1) + if(f1->nFileIndexHigh > f2->nFileIndexHigh) HGOTO_DONE(1) + + if(f1->nFileIndexLow < f2->nFileIndexLow) HGOTO_DONE(-1) + if(f1->nFileIndexLow > f2->nFileIndexLow) HGOTO_DONE(1) #else #ifdef H5_DEV_T_IS_SCALAR @@ -702,11 +724,6 @@ H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */) * Programmer: Robb Matzke * Monday, August 2, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static haddr_t @@ -734,11 +751,6 @@ H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static herr_t @@ -775,8 +787,6 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static haddr_t @@ -800,8 +810,6 @@ H5FD_core_get_eof(const H5FD_t *_file) * Programmer: Raymond Lu * Sept. 16, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t @@ -867,8 +875,6 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -881,8 +887,8 @@ H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hadd FUNC_ENTER_NOAPI_NOINIT - assert(file && file->pub.cls); - assert(buf); + HDassert(file && file->pub.cls); + HDassert(buf); /* Check for overflow conditions */ if (HADDR_UNDEF == addr) @@ -934,8 +940,6 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1005,10 +1009,6 @@ done: * Programmer: Robb Matzke * Friday, October 15, 1999 * - * Modifications: - * Raymond Lu, 2006-11-30 - * Added a condition check for backing store flag, for an - * existing file can be opened for read and write now. *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1027,19 +1027,40 @@ H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) if (0!=HDlseek(file->fd, (off_t)0, SEEK_SET)) HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "error seeking in backing store") + + while (size > 0) { - while (size) { - ssize_t n; - - H5_CHECK_OVERFLOW(size,hsize_t,size_t); - n = HDwrite(file->fd, ptr, (size_t)size); - if (n<0 && EINTR==errno) - continue; - if (n<0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "error writing backing store") - ptr += (size_t)n; - size -= (size_t)n; - } + h5_core_io_t bytes_in = 0; /* # of bytes to write */ + h5_core_io_ret_t bytes_wrote = -1; /* # of bytes written */ + + /* Trying to write more bytes than the return type can handle is + * undefined behavior in POSIX. + */ + if(size > H5_CORE_MAX_IO_BYTES_g) + bytes_in = H5_CORE_MAX_IO_BYTES_g; + else + bytes_in = (h5_core_io_t)size; + + do { + bytes_wrote = HDwrite(file->fd, ptr, bytes_in); + } while(-1 == bytes_wrote && EINTR == errno); + + if(-1 == bytes_wrote) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to backing store failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', ptr = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), ptr, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + + HDassert(bytes_wrote > 0); + HDassert((size_t)bytes_wrote <= size); + + size -= (size_t)bytes_wrote; + ptr = (unsigned char *)ptr + bytes_wrote; + + } /* end while */ + file->dirty = FALSE; } @@ -1094,6 +1115,43 @@ if(file->eof < new_eof) /* Update backing store, if using it */ if(file->fd >= 0 && file->backing_store) { +#ifdef H5_HAVE_WIN32_API + LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */ + DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer() + * Only used as an error code here. + */ + DWORD dwError; /* DWORD error code from GetLastError() */ + BOOL bError; /* Boolean error flag */ + + /* Windows uses this odd QuadPart union for 32/64-bit portability */ + li.QuadPart = (__int64)file->eoa; + + /* Extend the file to make sure it's large enough. + * + * Since INVALID_SET_FILE_POINTER can technically be a valid return value + * from SetFilePointer(), we also need to check GetLastError(). + */ + dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN); + if(INVALID_SET_FILE_POINTER == dwPtrLow) { + dwError = GetLastError(); + if(dwError != NO_ERROR ) + HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer") + } + + bError = SetEndOfFile(file->hFile); + if(0 == bError) + HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#else /* H5_HAVE_WIN32_API */ +#ifdef H5_VMS + /* Reset seek offset to the beginning of the file, so that the file isn't + * re-extended later. This may happen on Open VMS. */ + if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") +#endif + if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#endif /* H5_HAVE_WIN32_API */ + #ifdef H5_VMS /* Reset seek offset to the beginning of the file, so that the file isn't * re-extended later. This may happen on Open VMS. */ @@ -1112,4 +1170,3 @@ if(file->eof < new_eof) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_core_truncate() */ - diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index d780ceb..6dbe831 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -876,6 +876,100 @@ fprintf(stderr, "leaving H5FD_mpio_fapl_free\n"); /*------------------------------------------------------------------------- + * Function: H5FD_set_mpio_atomicity + * + * Purpose: Sets the atomicity mode + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * Feb 14, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_set_mpio_atomicity(H5FD_t *_file, hbool_t flag) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + int mpi_code; /* MPI return code */ + int temp_flag; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_set_mpio_atomicity\n"); +#endif + + if (FALSE == flag) + temp_flag = 0; + else + temp_flag = 1; + + /* set atomicity value */ + if (MPI_SUCCESS != (mpi_code=MPI_File_set_atomicity(file->f, temp_flag))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_atomicity", mpi_code) + +done: +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_set_mpio_atomicity\n"); +#endif + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_get_mpio_atomicity + * + * Purpose: Returns the atomicity mode + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * Feb 14, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_get_mpio_atomicity(H5FD_t *_file, hbool_t *flag) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + int mpi_code; /* MPI return code */ + int temp_flag; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_get_mpio_atomicity\n"); +#endif + + /* get atomicity value */ + if (MPI_SUCCESS != (mpi_code=MPI_File_get_atomicity(file->f, &temp_flag))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_get_atomicity", mpi_code) + + if (0 != temp_flag) + *flag = TRUE; + else + *flag = FALSE; + +done: +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_get_mpio_atomicity\n"); +#endif + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5FD_mpio_open * * Purpose: Opens a file with name NAME. The FLAGS are a bit field with diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index fe770d2..4f7d059 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -105,6 +105,10 @@ H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle); H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr); H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file); +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5FD_set_mpio_atomicity(H5FD_t *file, hbool_t flag); +H5_DLL herr_t H5FD_get_mpio_atomicity(H5FD_t *file, hbool_t *flag); +#endif /* H5_HAVE_PARALLEL */ #endif /* !_H5FDprivate_H */ diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index 4fd04f6..0f612be 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -38,6 +38,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FDmpi.h" /* MPI-based file drivers */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5Iprivate.h" /* IDs */ /****************/ @@ -177,5 +179,85 @@ H5F_mpi_get_size(const H5F_t *f) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_mpi_get_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fset_mpi_atomicity + * + * Purpose: Sets the atomicity mode + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * Feb 14, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag) +{ + H5F_t *file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iMi", file_id, flag); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Check VFD */ + if(!IS_H5FD_MPIO(file)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect VFL driver, must use MPI-I/O driver") + + /* set atomicity value */ + if (H5FD_set_mpio_atomicity (file->shared->lf, flag) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set atomicity flag") + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Fget_mpi_atomicity + * + * Purpose: Returns the atomicity mode + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * Feb 14, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag) +{ + H5F_t *file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iMi", file_id, flag); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Check VFD */ + if(!IS_H5FD_MPIO(file)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect VFL driver, must use MPI-I/O driver") + + /* get atomicity value */ + if (H5FD_get_mpio_atomicity (file->shared->lf, flag) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get atomicity flag") + +done: + FUNC_LEAVE_API(ret_value) +} #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 75a3547..d88538b 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -208,6 +208,10 @@ H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo); H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info/*out*/); H5_DLL herr_t H5Fclear_elink_file_cache(hid_t file_id); +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag); +H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); +#endif /* H5_HAVE_PARALLEL */ /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index a21c2b8..05322af 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -559,26 +559,27 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, /* Check for changing the chunk #0 data size enough to need adjusting the flags */ if(oh->version > H5O_VERSION_1 && chunkno == 0) { uint64_t chunk0_size; /* Size of chunk 0's data */ + size_t orig_prfx_size = (size_t)1 << (oh->flags & H5O_HDR_CHUNK0_SIZE); /* Original prefix size */ HDassert(oh->chunk[0].size >= (size_t)H5O_SIZEOF_HDR(oh)); chunk0_size = oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh); - /* Check for moving from a 1-byte to a 2-byte size encoding */ - if(chunk0_size <= 255 && (chunk0_size + delta) > 255) { - extra_prfx_size = 1; - new_size_flags = H5O_HDR_CHUNK0_2; + /* Check for moving to a 8-byte size encoding */ + if(orig_prfx_size < 8 && (chunk0_size + delta) > 4294967295) { + extra_prfx_size = 8 - orig_prfx_size; + new_size_flags = H5O_HDR_CHUNK0_8; adjust_size_flags = TRUE; } /* end if */ - /* Check for moving from a 2-byte to a 4-byte size encoding */ - else if(chunk0_size <= 65535 && (chunk0_size + delta) > 65535) { - extra_prfx_size = 2; + /* Check for moving to a 4-byte size encoding */ + else if(orig_prfx_size < 4 && (chunk0_size + delta) > 65535) { + extra_prfx_size = 4 - orig_prfx_size; new_size_flags = H5O_HDR_CHUNK0_4; adjust_size_flags = TRUE; } /* end if */ - /* Check for moving from a 4-byte to a 8-byte size encoding */ - else if(chunk0_size <= 4294967295 && (chunk0_size + delta) > 4294967295) { - extra_prfx_size = 4; - new_size_flags = H5O_HDR_CHUNK0_8; + /* Check for moving to a 2-byte size encoding */ + else if(orig_prfx_size < 2 && (chunk0_size + delta) > 255) { + extra_prfx_size = 2 - orig_prfx_size; + new_size_flags = H5O_HDR_CHUNK0_2; adjust_size_flags = TRUE; } /* end if */ } /* end if */ @@ -646,17 +647,18 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno, /* Wipe new space for chunk */ HDmemset(oh->chunk[chunkno].image + old_size, 0, oh->chunk[chunkno].size - old_size); + /* Move chunk 0 data up if the size flags changed */ + if(adjust_size_flags) + HDmemmove(oh->chunk[0].image + H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh), + oh->chunk[0].image + H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh) - extra_prfx_size, + old_size - (size_t)H5O_SIZEOF_HDR(oh) + extra_prfx_size); + /* Spin through existing messages, adjusting them */ for(u = 0; u < oh->nmesgs; u++) { /* Adjust raw addresses for messages in this chunk to reflect new 'image' address */ - if(oh->mesg[u].chunkno == chunkno) { + if(oh->mesg[u].chunkno == chunkno) oh->mesg[u].raw = oh->chunk[chunkno].image + extra_prfx_size + (oh->mesg[u].raw - old_image); - /* Flag message as dirty directly */ - /* (we mark the entire chunk dirty when we update its size) */ - oh->mesg[u].dirty = TRUE; - } /* endif */ - /* Find continuation message which points to this chunk and adjust chunk's size */ /* (Chunk 0 doesn't have a continuation message that points to it and * it's size is directly encoded in the object header) */ @@ -1330,8 +1332,9 @@ H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u) move_end = cont_msg->raw + cont_msg->raw_size; cont_chunkno = cont_msg->chunkno; - /* Convert continuation message into a null message */ - if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, TRUE) < 0) + /* Convert continuation message into a null message. Do not delete + * the target chunk yet, so we can still copy messages from it. */ + if(H5O_release_mesg(f, dxpl_id, oh, cont_msg, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to convert into null message") /* Protect chunk */ @@ -1353,7 +1356,6 @@ H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u) HDmemcpy(move_start, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), move_size); curr_msg->raw = move_start + H5O_SIZEOF_MSGHDR_OH(oh); curr_msg->chunkno = cont_chunkno; - curr_msg->dirty = TRUE; chk_dirtied = TRUE; /* Adjust location to move messages to */ @@ -1361,6 +1363,10 @@ H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u) } /* end else */ } /* end if */ + /* Delete the target chunk */ + if(H5O_chunk_delete(f, dxpl_id, oh, deleted_chunkno) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove chunk from cache") + HDassert(move_start <= (move_end + gap_size)); /* Check if there is space remaining in the continuation message */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 337287d..dd649ff 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -974,8 +974,7 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list") /* copy the object from the source file to the destination file */ - if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info, NULL, NULL) - < 0) + if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, &cpy_info, NULL, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") done: diff --git a/src/H5Odbg.c b/src/H5Odbg.c index bd30b90..5c07b64 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -106,7 +106,7 @@ H5O_assert(const H5O_t *oh) /* Initialize the tracking variables */ hdr_size = 0; - meta_space = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); + meta_space = (size_t)H5O_SIZEOF_HDR(oh) + (size_t)(H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); mesg_space = 0; free_space = 0; @@ -140,7 +140,7 @@ H5O_assert(const H5O_t *oh) /* Check for correct chunk #0 size flags */ if(oh->version > H5O_VERSION_1) { - uint64_t chunk0_size = oh->chunk[0].size - H5O_SIZEOF_HDR(oh); + uint64_t chunk0_size = oh->chunk[0].size - (size_t)H5O_SIZEOF_HDR(oh); if(chunk0_size <= 255) HDassert((oh->flags & H5O_HDR_CHUNK0_SIZE) == H5O_HDR_CHUNK0_1); @@ -154,13 +154,21 @@ H5O_assert(const H5O_t *oh) /* Loop over all messages in object header */ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + uint8_t *curr_hdr; /* Start of current message header */ + size_t curr_tot_size; /* Total size of current message (including header) */ + + curr_hdr = curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh); + curr_tot_size = curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh); + /* Accumulate information, based on the type of message */ if(H5O_NULL_ID == curr_msg->type->id) - free_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + free_space += curr_tot_size; else if(H5O_CONT_ID == curr_msg->type->id) { H5O_cont_t *cont = (H5O_cont_t *)curr_msg->native; hbool_t found_chunk = FALSE; /* Found a chunk that matches */ + HDassert(cont); + /* Increment # of continuation messages found */ cont_msgs_found++; @@ -175,11 +183,14 @@ H5O_assert(const H5O_t *oh) } /* end for */ HDassert(found_chunk); - meta_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + meta_space += curr_tot_size; } /* end if */ else { - meta_space += H5O_SIZEOF_MSGHDR_OH(oh); + meta_space += (size_t)H5O_SIZEOF_MSGHDR_OH(oh); mesg_space += curr_msg->raw_size; + + /* Make sure the message has a native form if it is marked dirty */ + HDassert(curr_msg->native || !curr_msg->dirty); } /* end else */ /* Make certain that the message is in a valid chunk */ @@ -190,17 +201,19 @@ H5O_assert(const H5O_t *oh) HDassert(oh->chunk[curr_msg->chunkno].gap == 0); /* Make certain that the message is completely in a chunk message area */ - HDassert(curr_msg->raw_size <= (oh->chunk[curr_msg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap)); + HDassert(curr_tot_size <= (oh->chunk[curr_msg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap)); if(curr_msg->chunkno == 0) - HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); + HDassert(curr_hdr >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); else - HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_CHKHDR_OH(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); + HDassert(curr_hdr >= oh->chunk[curr_msg->chunkno].image + (H5O_SIZEOF_CHKHDR_OH(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); HDassert(curr_msg->raw + curr_msg->raw_size <= (oh->chunk[curr_msg->chunkno].image + oh->chunk[curr_msg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[curr_msg->chunkno].gap)); /* Make certain that no other messages overlap this message */ for(v = 0, tmp_msg = &oh->mesg[0]; v < oh->nmesgs; v++, tmp_msg++) { if(u != v) - HDassert(!(tmp_msg->raw >= curr_msg->raw && tmp_msg->raw < (curr_msg->raw + curr_msg->raw_size))); + HDassert(!((tmp_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) >= curr_hdr + && (tmp_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)) + < (curr_hdr + curr_tot_size))); } /* end for */ } /* end for */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index e4d6486..1b17bff 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -241,6 +241,8 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, mesg->ops = H5D_LOPS_CHUNK; break; + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: default: HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class") } /* end switch */ @@ -342,6 +344,8 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi UINT32ENCODE(p, mesg->u.chunk.dim[u]); break; + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: default: HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "Invalid layout class") } /* end switch */ @@ -556,6 +560,8 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: default: HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "not valid storage type") } /* end switch */ @@ -641,6 +647,8 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, } /* end if */ break; + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: default: HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class") } /* end switch */ @@ -737,6 +745,8 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, "Data Size:", mesg->storage.u.compact.size); break; + case H5D_LAYOUT_ERROR: + case H5D_NLAYOUTS: default: HDfprintf(stream, "%*s%-*s %s (%u)\n", indent, "", fwidth, "Type:", "Unknown", (unsigned)mesg->type); diff --git a/src/H5Omessage.c b/src/H5Omessage.c index a3d02d1..f12c835 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -2161,9 +2161,8 @@ H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg) /* Make certain that null messages aren't in chunks w/gaps */ if(H5O_NULL_ID == msg_id) HDassert(oh->chunk[mesg->chunkno].gap == 0); - - /* Unknown messages should always have a native pointer */ - if(mesg->type == H5O_MSG_UNKNOWN) + else + /* Non-null messages should always have a native pointer */ HDassert(mesg->native); #endif /* NDEBUG */ @@ -86,7 +86,7 @@ H5S_init_interface(void) /* Allow MPI buf-and-file-type optimizations? */ const char *s = HDgetenv ("HDF5_MPI_OPT_TYPES"); if (s && HDisdigit(*s)) - H5S_mpi_opt_types_g = (int)HDstrtol (s, NULL, 0); + H5S_mpi_opt_types_g = (hbool_t)HDstrtol (s, NULL, 0); } #endif /* H5_HAVE_PARALLEL */ @@ -186,6 +186,7 @@ H5S_create(H5S_class_t type) new_ds->extent.nelem = 0; break; + case H5S_NO_CLASS: default: HDassert("unknown dataspace (extent) type" && 0); break; @@ -512,6 +513,7 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max) dst->max = NULL; break; + case H5S_NO_CLASS: default: HDassert("unknown dataspace type" && 0); break; @@ -712,6 +714,7 @@ H5S_get_npoints_max(const H5S_t *ds) } break; + case H5S_NO_CLASS: default: assert("unknown dataspace class" && 0); HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0, "internal error (unknown dataspace class)") @@ -796,6 +799,7 @@ H5S_get_simple_extent_ndims(const H5S_t *ds) ret_value = (int)ds->extent.rank; break; + case H5S_NO_CLASS: default: HDassert("unknown dataspace class" && 0); HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)") @@ -894,6 +898,7 @@ H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[]) } /* end for */ break; + case H5S_NO_CLASS: default: HDassert("unknown dataspace class" && 0); HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)") @@ -1827,7 +1832,7 @@ H5S_set_extent(H5S_t *space, const hsize_t *size) /* Check for invalid dimension size modification */ if(space->extent.max && H5S_UNLIMITED != space->extent.max[u] && space->extent.max[u] < size[u]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "dimension cannot exceed the existing maximal size") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "dimension cannot exceed the existing maximal size (new: %llu max: %llu)", (unsigned long long)size[u], (unsigned long long)space->extent.max[u]) /* Indicate that dimension size can be modified */ ret_value = TRUE; diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index 5a707b5..48948a7 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -94,6 +94,8 @@ static H5Z_node *H5Z_parse_term(H5Z_token *current, H5Z_datval_ptrs* dat_val_poi static H5Z_node *H5Z_parse_factor(H5Z_token *current, H5Z_datval_ptrs* dat_val_pointers); static H5Z_node *H5Z_new_node(H5Z_token_type type); static void H5Z_do_op(H5Z_node* tree); +static hbool_t H5Z_op_is_numbs(H5Z_node* _tree); +static hbool_t H5Z_op_is_numbs2(H5Z_node* _tree); static hid_t H5Z_xform_find_type(const H5T_t* type); static herr_t H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_type, H5Z_result* res); static void H5Z_xform_destroy_parse_tree(H5Z_node *tree); @@ -105,41 +107,57 @@ static void H5Z_XFORM_DEBUG(H5Z_node *tree); static void H5Z_print(H5Z_node *tree, FILE *stream); #endif /* H5Z_XFORM_DEBUG */ - +/* PGCC (11.8-0) has trouble with the command *p++ = *p OP tree_val. It increments P first before + * doing the operation. So I break down the command into two lines: + * *p = *p OP tree_val; p++; + * Actually, the behavior of *p++ = *p OP tree_val is undefined. (SLU - 2012/3/19) + */ #define H5Z_XFORM_DO_OP1(RESL,RESR,TYPE,OP,SIZE) \ { \ - if( (((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type != H5Z_XFORM_SYMBOL)) || (((RESR).type == H5Z_XFORM_SYMBOL) && ((RESL).type != H5Z_XFORM_SYMBOL))) \ + size_t u; \ + \ + if(((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type != H5Z_XFORM_SYMBOL)) \ + { \ + TYPE* p; \ + double tree_val; \ + \ + tree_val = ((RESR).type==H5Z_XFORM_INTEGER ? (double)(RESR).value.int_val : (RESR).value.float_val); \ + p = (TYPE*)(RESL).value.dat_val; \ + \ + for(u=0; u<(SIZE); u++) { \ + *p = *p OP tree_val; \ + p++; \ + } \ + } \ + else if(((RESR).type == H5Z_XFORM_SYMBOL) && ((RESL).type != H5Z_XFORM_SYMBOL)) \ { \ - size_t u; \ TYPE* p; \ double tree_val; \ \ - if((RESL).type == H5Z_XFORM_SYMBOL) \ - { \ - tree_val = ((RESR).type==H5Z_XFORM_INTEGER ? (double)(RESR).value.int_val : (RESR).value.float_val); \ - p = (TYPE*)(RESL).value.dat_val; \ - } \ + /* The case that the left operand is nothing, like -x or +x */ \ + if((RESL).type == H5Z_XFORM_ERROR) \ + tree_val = 0; \ else \ - { \ tree_val = ((RESL).type==H5Z_XFORM_INTEGER ? (double)(RESL).value.int_val : (RESL).value.float_val); \ - p = (TYPE*)(RESR).value.dat_val; \ - } \ - \ - for(u=0; u<(SIZE); u++) \ - *p++ OP tree_val; \ - } \ + \ + p = (TYPE*)(RESR).value.dat_val; \ + for(u=0; u<(SIZE); u++) { \ + *p = tree_val OP *p; \ + p++; \ + } \ + } \ else if( ((RESL).type == H5Z_XFORM_SYMBOL) && ((RESR).type==H5Z_XFORM_SYMBOL)) \ { \ - size_t u; \ TYPE* pl = (TYPE*)(RESL).value.dat_val; \ TYPE* pr = (TYPE*)(RESR).value.dat_val; \ \ - for(u=0; u<(SIZE); u++) \ - *pl++ OP *pr++; \ + for(u=0; u<(SIZE); u++) { \ + *pl = *pl OP *pr; \ + pl++; pr++; \ + } \ } \ else \ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unexpected type conversion operation") \ - \ } /* Due to the undefined nature of embedding macros/conditionals within macros, we employ @@ -277,7 +295,47 @@ static void H5Z_print(H5Z_node *tree, FILE *stream); H5V_array_fill(array, &val, sizeof(TYPE), (SIZE)); \ } - +/* The difference of this macro from H5Z_XFORM_DO_OP3 is that it handles the operations when the left operand is empty, like -x or +x. + * The reason that it's seperated from H5Z_XFORM_DO_OP3 is because compilers don't accept operations like *x or /x. So in H5Z_do_op, + * these two macros are called in different ways. (SLU 2012/3/20) + */ +#define H5Z_XFORM_DO_OP6(OP) \ +{ \ + if(!tree->lchild && (tree->rchild->type==H5Z_XFORM_INTEGER)) \ + { \ + tree->type = H5Z_XFORM_INTEGER; \ + tree->value.int_val = OP tree->rchild->value.int_val; \ + H5MM_xfree(tree->rchild); \ + tree->rchild = NULL; \ + } \ + else if(!tree->lchild && (tree->rchild->type==H5Z_XFORM_FLOAT)) \ + { \ + tree->type = H5Z_XFORM_FLOAT; \ + tree->value.float_val = OP tree->rchild->value.float_val; \ + H5MM_xfree(tree->rchild); \ + tree->rchild = NULL; \ + } \ + else if((tree->lchild->type == H5Z_XFORM_INTEGER) && (tree->rchild->type==H5Z_XFORM_INTEGER)) \ + { \ + tree->type = H5Z_XFORM_INTEGER; \ + tree->value.int_val = tree->lchild->value.int_val OP tree->rchild->value.int_val; \ + H5MM_xfree(tree->lchild); \ + H5MM_xfree(tree->rchild); \ + tree->lchild = NULL; \ + tree->rchild = NULL; \ + } \ + else if( ( (tree->lchild->type == H5Z_XFORM_FLOAT) || (tree->lchild->type == H5Z_XFORM_INTEGER)) && \ + ( (tree->rchild->type == H5Z_XFORM_FLOAT) || (tree->rchild->type == H5Z_XFORM_INTEGER))) \ + { \ + tree->type = H5Z_XFORM_FLOAT; \ + tree->value.float_val = ((tree->lchild->type == H5Z_XFORM_FLOAT) ? tree->lchild->value.float_val : (double)tree->lchild->value.int_val) OP \ + ((tree->rchild->type == H5Z_XFORM_FLOAT) ? tree->rchild->value.float_val : (double)tree->rchild->value.int_val); \ + H5MM_xfree(tree->lchild); \ + H5MM_xfree(tree->rchild); \ + tree->lchild = NULL; \ + tree->rchild = NULL; \ + } \ +} /* * Programmer: Bill Wendling <wendling@ncsa.uiuc.edu> @@ -1027,6 +1085,9 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ /* check args */ HDassert(tree); + HDmemset(&resl, 0, sizeof(H5Z_result)); + HDmemset(&resr, 0, sizeof(H5Z_result)); + if (tree->type == H5Z_XFORM_INTEGER) { res->type = H5Z_XFORM_INTEGER; res->value.int_val = tree->value.int_val; @@ -1044,7 +1105,7 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ res->value.dat_val = *((void**)(tree->value.dat_val)); } /* end if */ else { - if(H5Z_xform_eval_full(tree->lchild, array_size, array_type, &resl) < 0) + if(tree->lchild && H5Z_xform_eval_full(tree->lchild, array_size, array_type, &resl) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") if(H5Z_xform_eval_full(tree->rchild, array_size, array_type, &resr) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error while performing data transform") @@ -1059,19 +1120,19 @@ H5Z_xform_eval_full(H5Z_node *tree, const size_t array_size, const hid_t array_ switch (tree->type) { case H5Z_XFORM_PLUS: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, +=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, +, array_size) break; case H5Z_XFORM_MINUS: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, -=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, -, array_size) break; case H5Z_XFORM_MULT: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, *=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, *, array_size) break; case H5Z_XFORM_DIVIDE: - H5Z_XFORM_TYPE_OP(resl, resr, array_type, /=, array_size) + H5Z_XFORM_TYPE_OP(resl, resr, array_type, /, array_size) break; default: @@ -1257,6 +1318,63 @@ H5Z_xform_copy_tree(H5Z_node* tree, H5Z_datval_ptrs* dat_val_pointers, H5Z_datva /*------------------------------------------------------------------------- + * Function: H5Z_op_is_numbs + * Purpose: Internal function to facilitate the condition check in + * H5Z_xform_reduce_tree to reduce the bulkiness of the code. + * Return: TRUE or FALSE + * Programmer: Raymond Lu + * 15 March 2012 + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5Z_op_is_numbs(H5Z_node* _tree) +{ + hbool_t ret_value = FALSE; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + assert(_tree); + + if(((_tree->lchild->type == H5Z_XFORM_INTEGER) || (_tree->lchild->type == H5Z_XFORM_FLOAT)) && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))) + ret_value = TRUE; + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Z_op_is_numbs2 + * Purpose: Internal function to facilitate the condition check in + * H5Z_xform_reduce_tree to reduce the bulkiness of the code. + * The difference from H5Z_op_is_numbs is that the left child + * can be empty, like -x or +x. + * Return: TRUE or FALSE + * Programmer: Raymond Lu + * 15 March 2012 + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5Z_op_is_numbs2(H5Z_node* _tree) +{ + hbool_t ret_value = FALSE; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + assert(_tree); + + if((!_tree->lchild && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))) || + ((_tree->lchild && ((_tree->lchild->type == H5Z_XFORM_INTEGER) || (_tree->lchild->type == H5Z_XFORM_FLOAT))) && (_tree->rchild && ((_tree->rchild->type == H5Z_XFORM_INTEGER) || (_tree->rchild->type == H5Z_XFORM_FLOAT))))) + ret_value = TRUE; + + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5Z_xform_reduce_tree * Purpose: Simplifies parse tree passed in by performing any obvious * and trivial arithemtic calculations. @@ -1274,22 +1392,37 @@ H5Z_xform_reduce_tree(H5Z_node* tree) FUNC_ENTER_NOAPI_NOINIT_NOERR if(tree) { - if((tree->type == H5Z_XFORM_PLUS) || (tree->type == H5Z_XFORM_DIVIDE) ||(tree->type == H5Z_XFORM_MULT) ||(tree->type == H5Z_XFORM_MINUS)) + if((tree->type == H5Z_XFORM_DIVIDE) || (tree->type == H5Z_XFORM_MULT)) { - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs(tree)) + H5Z_do_op(tree); + else + { + H5Z_xform_reduce_tree(tree->lchild); + if(H5Z_op_is_numbs(tree)) + H5Z_do_op(tree); + else { + H5Z_xform_reduce_tree(tree->rchild); + if(H5Z_op_is_numbs(tree)) + H5Z_do_op(tree); + } + } + } else if((tree->type == H5Z_XFORM_PLUS) || (tree->type == H5Z_XFORM_MINUS)) { + if(H5Z_op_is_numbs2(tree)) H5Z_do_op(tree); else { H5Z_xform_reduce_tree(tree->lchild); - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs2(tree)) H5Z_do_op(tree); else { H5Z_xform_reduce_tree(tree->rchild); - if(((tree->lchild->type == H5Z_XFORM_INTEGER) || (tree->lchild->type == H5Z_XFORM_FLOAT)) && ((tree->rchild->type == H5Z_XFORM_INTEGER) || (tree->rchild->type == H5Z_XFORM_FLOAT))) + if(H5Z_op_is_numbs2(tree)) H5Z_do_op(tree); } } } + } FUNC_LEAVE_NOAPI_VOID; @@ -1307,7 +1440,11 @@ H5Z_xform_reduce_tree(H5Z_node* tree) * Programmer: Leon Arber * April 1, 2004. * Modifications: -* + * Raymond Lu + * 15 March 2012 + * I added a new macro H5Z_XFORM_DO_OP6 to handle the special + * operations like -x or +x when the left operand is empty. + * *------------------------------------------------------------------------- */ static void @@ -1320,9 +1457,9 @@ H5Z_do_op(H5Z_node* tree) else if(tree->type == H5Z_XFORM_MULT) H5Z_XFORM_DO_OP3(*) else if(tree->type == H5Z_XFORM_PLUS) - H5Z_XFORM_DO_OP3(+) + H5Z_XFORM_DO_OP6(+) else if(tree->type == H5Z_XFORM_MINUS) - H5Z_XFORM_DO_OP3(-) + H5Z_XFORM_DO_OP6(-) FUNC_LEAVE_NOAPI_VOID; } diff --git a/src/H5public.h b/src/H5public.h index 562dd5e..1f44ff3 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -75,10 +75,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 110 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 112 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.110" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.112" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/Makefile.in b/src/Makefile.in index 1a763b2..c9c1089 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -485,7 +485,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 100 +LT_VERS_REVISION = 102 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) diff --git a/test/COPYING b/test/COPYING index 6903daf..6903daf 100755..100644 --- a/test/COPYING +++ b/test/COPYING diff --git a/test/corrupt_stab_msg.h5 b/test/corrupt_stab_msg.h5 Binary files differindex 4fa287c..4fa287c 100755..100644 --- a/test/corrupt_stab_msg.h5 +++ b/test/corrupt_stab_msg.h5 diff --git a/test/cross_read.c b/test/cross_read.c index 308a0c1..308a0c1 100755..100644 --- a/test/cross_read.c +++ b/test/cross_read.c diff --git a/test/dtransform.c b/test/dtransform.c index 5d5cefe..2bcbe8c 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -23,6 +23,7 @@ static int init_test(hid_t file_id); static int test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy); static int test_trivial(const hid_t dxpl_id_simple); static int test_poly(const hid_t dxpl_id_polynomial); +static int test_specials(hid_t file); static int test_set(void); static int test_getset(const hid_t dxpl_id_simple); @@ -50,14 +51,14 @@ const float windchillFfloat[ROWS][COLS] = const int transformData[ROWS][COLS] = { {36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, 28, 34, 40, 46, 52, 57, 63 }, - {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 0 } , - {32, 25, 19, 13, 6, 0, 7, 13, 19, 26, 32, 39, 45, 51, 58, 64, 71, 5 }, + {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 1 } , + {32, 25, 19, 13, 6, 2, 7, 13, 19, 26, 32, 39, 45, 51, 58, 64, 71, 5 }, {30, 24, 17, 11, 4, 2, 9, 15, 22, 29, 35, 42, 48, 55, 61, 68, 2, 9 }, {29, 23, 16, 9, 3, 4, 11, 17, 24, 31, 37, 44, 51, 58, 64, 71, 6, 12 }, {28, 22, 15, 8, 1, 5, 12, 19, 26, 33, 39, 46, 53, 60, 67, 1, 8, 15 }, - {28, 21, 14, 7, 0, 7, 14, 21, 27, 34, 41, 48, 55, 62, 69, 4, 10, 17 }, + {28, 21, 14, 7, 6, 7, 14, 21, 27, 34, 41, 48, 55, 62, 69, 4, 10, 17 }, {27, 20, 13, 6, 1, 8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 6, 12, 19 }, - {26, 19, 12, 5, 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 0, 7, 14, 21 }, + {26, 19, 12, 5, 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 5, 7, 14, 21 }, {26, 19, 12, 4, 3, 10, 17, 24, 31, 38, 45, 52, 60, 67, 2, 9, 16, 23}, {25, 18, 11, 4, 3, 11, 18, 25, 32, 39, 46, 54, 61, 68, 3, 10, 17, 25}, {25, 17, 10, 3, 4, 11, 19, 26, 33, 40, 48, 55, 62, 69, 4, 12, 19, 26} @@ -97,6 +98,22 @@ const int transformData[ROWS][COLS] = PASSED(); \ } +#define COMPARE_INT(VAR1,VAR2) \ +{ \ + size_t i,j; \ + \ + for(i=0; i<ROWS; i++) \ + for(j=0; j<COLS; j++) \ + { \ + if( (VAR1)[i][j] != (VAR2)[i][j] ) \ + { \ + H5_FAILED(); \ + fprintf(stderr, " ERROR: data failed to match computed data\n"); \ + goto error; \ + } \ + } \ +} + #define TEST_TYPE_CONTIG(XFORM, TYPE, HDF_TYPE, TEST_STR, COMPARE_DATA, SIGNED) \ { \ TYPE array[ROWS][COLS]; \ @@ -332,6 +349,7 @@ int main(void) if(test_trivial(dxpl_id_simple) < 0) TEST_ERROR; if(test_poly(dxpl_id_polynomial) < 0) TEST_ERROR; if(test_getset(dxpl_id_c_to_f) < 0) TEST_ERROR; + if(test_specials(file_id) < 0) TEST_ERROR; /* Close the objects we opened/created */ if(H5Dclose(dset_id_int) < 0) TEST_ERROR; @@ -502,6 +520,160 @@ error: } static int +test_specials(hid_t file) +{ + hid_t dxpl_id, dset_id, dataspace; + hsize_t dim[2] = { ROWS, COLS }; + int read_buf[ROWS][COLS]; + int data_res[ROWS][COLS]; + int row, col; + const char* special1 = "x*-100"; + const char* special2 = "100-x"; + const char* special3 = "1000/x"; + const char* special4 = "-x"; + const char* special5 = "+x"; + + TESTING("data transform of some special cases") + + if((dataspace = H5Screate_simple(2, dim, NULL)) < 0) + TEST_ERROR + + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR; + + /*----------------------------- + * Operation 1: x*-100 + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special1) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col] * -100; + + if((dset_id = H5Dcreate2(file, "/special1", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 2: 100-x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special2) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = 100 - transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special2", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 3: 1000/x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special3) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = 1000 / transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special3", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 4: -x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special4) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = -1 * transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special4", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + /*----------------------------- + * Operation 5: +x + *----------------------------*/ + if(H5Pset_data_transform(dxpl_id, special5) < 0) TEST_ERROR; + + for(row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col]; + + if((dset_id = H5Dcreate2(file, "/special5", H5T_NATIVE_INT, + dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR + if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + dxpl_id, transformData) < 0) + TEST_ERROR + if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if(H5Dclose(dset_id) < 0) + TEST_ERROR + + + if(H5Pclose(dxpl_id) < 0) + TEST_ERROR + if(H5Sclose(dataspace) < 0) + TEST_ERROR + + PASSED(); + return 0; + +error: + return -1; +} + +static int test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy) { int windchillC; diff --git a/test/fheap.c b/test/fheap.c index f2960a3..b55c60b 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -415,13 +415,20 @@ add_obj(H5HF_t *fh, hid_t dxpl, size_t obj_off, if(keep_ids) { /* Check for needing to increase size of heap ID array */ if(keep_ids->num_ids + 1 > keep_ids->alloc_ids) { + unsigned char *tmp_ids; + size_t *tmp_lens; + size_t *tmp_offs; + keep_ids->alloc_ids = MAX(1024, (keep_ids->alloc_ids * 2)); - if(NULL == (keep_ids->ids = (unsigned char *)H5MM_realloc(keep_ids->ids, id_len * keep_ids->alloc_ids))) + if(NULL == (tmp_ids = (unsigned char *)H5MM_realloc(keep_ids->ids, id_len * keep_ids->alloc_ids))) TEST_ERROR - if(NULL == (keep_ids->lens = (size_t *)H5MM_realloc(keep_ids->lens, sizeof(size_t) * keep_ids->alloc_ids))) + keep_ids->ids = tmp_ids; + if(NULL == (tmp_lens = (size_t *)H5MM_realloc(keep_ids->lens, sizeof(size_t) * keep_ids->alloc_ids))) TEST_ERROR - if(NULL == (keep_ids->offs = (size_t *)H5MM_realloc(keep_ids->offs, sizeof(size_t) * keep_ids->alloc_ids))) + keep_ids->lens = tmp_lens; + if(NULL == (tmp_offs = (size_t *)H5MM_realloc(keep_ids->offs, sizeof(size_t) * keep_ids->alloc_ids))) TEST_ERROR + keep_ids->offs = tmp_offs; } /* end if */ /* Append the object info onto the array */ diff --git a/test/gen_cross.c b/test/gen_cross.c index d960499..d960499 100755..100644 --- a/test/gen_cross.c +++ b/test/gen_cross.c diff --git a/test/istore.c b/test/istore.c index 3ae8da7..0c970bc 100644 --- a/test/istore.c +++ b/test/istore.c @@ -54,6 +54,42 @@ hsize_t zero[H5O_LAYOUT_NDIMS]; /*------------------------------------------------------------------------- + * Function: is_sparse + * + * Purpose: Determines if the file system of the current working + * directory supports holes. + * + * Return: Success: Non-zero if holes are supported; zero + * otherwise. + * + * Failure: zero + * + * Programmer: Robb Matzke + * Wednesday, July 15, 1998 + * + *------------------------------------------------------------------------- + */ +static int +is_sparse(void) +{ + int fd; + h5_stat_t sb; + + if ((fd=HDopen("x.h5", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) return 0; + if (HDlseek(fd, (off_t)(1024*1024), SEEK_SET)!=1024*1024) return 0; + if (5!=HDwrite(fd, "hello", (size_t)5)) return 0; + if (HDclose(fd) < 0) return 0; + if (HDstat("x.h5", &sb) < 0) return 0; + if (HDremove("x.h5") < 0) return 0; +#ifdef H5_HAVE_STAT_ST_BLOCKS + return ((unsigned long)sb.st_blocks*512 < (unsigned long)sb.st_size); +#else + return (0); +#endif +} + + +/*------------------------------------------------------------------------- * Function: print_array * * Purpose: Prints the values in an array @@ -565,6 +601,7 @@ main(int argc, char *argv[]) unsigned size_of_test; unsigned u; /* Local index variable */ char filename[1024]; + int has_sparse_support = 0; /* Parse arguments or assume these tests (`small', `medium' ) */ if (1 == argc) { @@ -598,6 +635,12 @@ main(int argc, char *argv[]) /* Set the random # seed */ HDsrandom((unsigned)HDtime(NULL)); + /* Check to see if the file system supports POSIX-style sparse files. + * Windows NTFS does not, so we want to avoid tests which create + * very large files. + */ + has_sparse_support = is_sparse(); + /* Reset library */ h5_reset(); fapl = h5_fileaccess(); @@ -656,7 +699,10 @@ main(int argc, char *argv[]) status = test_sparse(file, "sparse", (size_t)2000, (size_t)4, (size_t)2, (size_t)3); nerrors += status < 0 ? 1 : 0; } - if (size_of_test & TEST_LARGE) { + if (has_sparse_support && size_of_test & TEST_LARGE) { + /* This test is skipped if there is no POSIX-style sparse file support + * e.g.: Windows NTFS filesystems + */ status = test_sparse(file, "sparse", (size_t)800, (size_t)50, (size_t)50, (size_t)50); nerrors += status < 0 ? 1 : 0; } diff --git a/test/objcopy.c b/test/objcopy.c index 5c20ee8..5c20ee8 100755..100644 --- a/test/objcopy.c +++ b/test/objcopy.c diff --git a/test/reserved.c b/test/reserved.c index bb6d328..bb6d328 100755..100644 --- a/test/reserved.c +++ b/test/reserved.c diff --git a/test/tattr.c b/test/tattr.c index 60d4ddb..1285f0e 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -128,6 +128,8 @@ float attr_data5=(float)-5.123; /* Test data for 5th attribute */ #define ATTR7_NAME "attr 1 - 000000" #define ATTR8_NAME "attr 2" +#define LINK1_NAME "Link1" + #define NATTR_MANY_OLD 350 #define NATTR_MANY_NEW 35000 @@ -10216,7 +10218,339 @@ test_attr_bug6(hid_t fcpl, hid_t fapl) ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); -} +} /* test_attr_bug6() */ + +/**************************************************************** +** +** test_attr_bug7(): Test basic H5A (attribute) code. +** (Really tests object header allocation code). +** Tests creating and deleting attributes in such a way as +** to change the size of the "chunk #0 size" field. +** Includes testing "skipping" a possible size of the +** field, i.e. going from 1 to 4 bytes or 4 to 1 byte. +** +****************************************************************/ +static void +test_attr_bug7(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t aid; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t tid; /* Datatype ID */ + hsize_t dims_s = 140; /* Small attribute dimensions */ + hsize_t dims_l = 65480; /* Large attribute dimensions */ + H5A_info_t ainfo; /* Attribute info */ + herr_t ret; /* Generic return status */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing adding and deleting large attributes\n")); + + + /* Create committed datatype to operate on. Use a committed datatype so that + * there is nothing after the object header and the first chunk can expand and + * contract as necessary. */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + tid = H5Tcopy(H5T_STD_I32LE); + CHECK(tid, FAIL, "H5Tcopy"); + ret = H5Tcommit2(fid, TYPE1_NAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* + * Create small attribute + */ + sid = H5Screate_simple(1, &dims_s, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + aid = H5Acreate2(tid, ATTR1_NAME, H5T_STD_I8LE, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Close file */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check attribute */ + tid = H5Topen2(fid, TYPE1_NAME, H5P_DEFAULT); + CHECK(tid, FAIL, "H5Topen2"); + ret = H5Aget_info_by_name(tid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + + /* + * Create another small attribute. Should cause chunk size field to expand by + * 1 byte (1->2). + */ + aid = H5Acreate2(tid, ATTR2_NAME, H5T_STD_I8LE, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Close file */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check attributes */ + tid = H5Topen2(fid, TYPE1_NAME, H5P_DEFAULT); + CHECK(tid, FAIL, "H5Topen2"); + ret = H5Aget_info_by_name(tid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + ret = H5Aget_info_by_name(tid, ".", ATTR2_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + + /* + * Create large attribute. Should cause chunk size field to expand by 2 bytes + * (2->4). + */ + ret = H5Sset_extent_simple(sid, 1, &dims_l, NULL); + CHECK(ret, FAIL, "H5Sset_extent_simple"); + aid = H5Acreate2(tid, ATTR3_NAME, H5T_STD_I8LE, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Close file */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check attributes */ + tid = H5Topen2(fid, TYPE1_NAME, H5P_DEFAULT); + CHECK(tid, FAIL, "H5Topen2"); + ret = H5Aget_info_by_name(tid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + ret = H5Aget_info_by_name(tid, ".", ATTR2_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + ret = H5Aget_info_by_name(tid, ".", ATTR3_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_l) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_l); + + /* + * Delete last two attributes - should merge into a null message that is too + * large, causing the chunk size field to shrink by 3 bytes (4->1). + */ + ret = H5Sset_extent_simple(sid, 1, &dims_l, NULL); + CHECK(ret, FAIL, "H5Sset_extent_simple"); + ret = H5Adelete(tid, ATTR2_NAME); + CHECK(ret, FAIL, "H5Adelete"); + ret = H5Adelete(tid, ATTR3_NAME); + CHECK(ret, FAIL, "H5Adelete"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check attribute */ + tid = H5Topen2(fid, TYPE1_NAME, H5P_DEFAULT); + CHECK(tid, FAIL, "H5Topen2"); + ret = H5Aget_info_by_name(tid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + + /* + * Create large attribute. Should cause chunk size field to expand by 3 bytes + * (1->4). + */ + aid = H5Acreate2(tid, ATTR2_NAME, H5T_STD_I8LE, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Close file */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check attributes */ + tid = H5Topen2(fid, TYPE1_NAME, H5P_DEFAULT); + CHECK(tid, FAIL, "H5Topen2"); + ret = H5Aget_info_by_name(tid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_s) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_s); + ret = H5Aget_info_by_name(tid, ".", ATTR2_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims_l) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims_l); + + /* Close IDs */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_bug7() */ + +/**************************************************************** +** +** test_attr_bug8(): Test basic H5A (attribute) code. +** (Really tests object header code). +** Tests adding a link and attribute to a group in such a +** way as to cause the "chunk #0 size" field to expand +** when some object header messages are not loaded into +** cache. Before the bug was fixed, this would prevent +** these messages from being shifted to the correct +** position as the expansion algorithm marked them dirty, +** invalidating the raw form, when there was no native +** form to encode. +** +****************************************************************/ +static void +test_attr_bug8(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t aid; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + hid_t gid; /* Group ID */ + hid_t oid; /* Object ID */ + hsize_t dims = 256; /* Attribute dimensions */ + H5O_info_t oinfo; /* Object info */ + H5A_info_t ainfo; /* Attribute info */ + haddr_t root_addr; /* Root group address */ + herr_t ret; /* Generic return status */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing attribute expanding object header with undecoded messages\n")); + + + /* Create committed datatype to operate on. Use a committed datatype so that + * there is nothing after the object header and the first chunk can expand and + * contract as necessary. */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + gid = H5Gcreate2(fid, GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Get root group address */ + ret = H5Oget_info(fid, &oinfo); + CHECK(ret, FAIL, "H5Oget_info"); + root_addr = oinfo.addr; + + /* + * Create link to root group + */ + ret = H5Lcreate_hard(fid, "/", gid, LINK1_NAME, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Lcreate_hard"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check link */ + gid = H5Gopen2(fid, GROUP1_NAME, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gopen2"); + oid = H5Oopen(gid, LINK1_NAME, H5P_DEFAULT); + CHECK(oid, FAIL, "H5Oopen"); + ret = H5Oget_info(oid, &oinfo); + CHECK(ret, FAIL, "H5Oget_info"); + if(oinfo.addr != root_addr) + TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)oinfo.addr, (long long unsigned)root_addr); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Oclose(oid); + CHECK(ret, FAIL, "H5Oclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* + * Create attribute. Should cause chunk size field to expand by 1 byte + * (1->2). + */ + gid = H5Gopen2(fid, GROUP1_NAME, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gopen2"); + sid = H5Screate_simple(1, &dims, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + aid = H5Acreate2(gid, ATTR1_NAME, H5T_STD_I8LE, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Close file */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Check link and attribute */ + gid = H5Gopen2(fid, GROUP1_NAME, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gopen2"); + oid = H5Oopen(gid, LINK1_NAME, H5P_DEFAULT); + CHECK(oid, FAIL, "H5Oopen"); + ret = H5Oget_info(oid, &oinfo); + CHECK(ret, FAIL, "H5Oget_info"); + if(oinfo.addr != root_addr) + TestErrPrintf("incorrect link target address: addr: %llu, expected: %llu\n", (long long unsigned)oinfo.addr, (long long unsigned)root_addr); + ret = H5Aget_info_by_name(gid, ".", ATTR1_NAME, &ainfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Aget_info_by_name"); + if(ainfo.data_size != dims) + TestErrPrintf("attribute data size different: data_size=%llu, should be %llu\n", (long long unsigned)ainfo.data_size, (long long unsigned)dims); + + /* Close IDs */ + ret = H5Oclose(oid); + CHECK(ret, FAIL, "H5Oclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_bug8() */ /**************************************************************** ** @@ -10364,6 +10698,8 @@ test_attr(void) test_attr_bug4(my_fcpl, my_fapl); /* Test attributes on named datatypes */ test_attr_bug5(my_fcpl, my_fapl); /* Test opening/closing attributes through different file handles */ test_attr_bug6(my_fcpl, my_fapl); /* Test reading empty attribute */ + test_attr_bug7(my_fcpl, my_fapl); /* Test creating and deleting large attributes in ohdr chunk 0 */ + test_attr_bug8(my_fcpl, my_fapl); /* Test attribute expanding object header with undecoded messages */ } /* end for */ } /* end if */ else { @@ -10388,6 +10724,10 @@ test_attr(void) test_attr_bug4(fcpl, my_fapl); /* Test attributes on named datatypes */ test_attr_bug5(fcpl, my_fapl); /* Test opening/closing attributes through different file handles */ test_attr_bug6(fcpl, my_fapl); /* Test reading empty attribute */ + /* Skip test_attr_bug7 because it is specific to the new object + * header format and in fact fails if used with the old format, due + * to the attributes being larger than 64K */ + test_attr_bug8(fcpl, my_fapl); /* Test attribute expanding object header with undecoded messages */ } /* end else */ } /* end for */ diff --git a/test/th5s.c b/test/th5s.c index c17d96e..87aa0f1 100644 --- a/test/th5s.c +++ b/test/th5s.c @@ -544,70 +544,13 @@ test_h5s_zero_dim(void) hssize_t nelem; /* Number of elements */ H5S_sel_type sel_type; /* Type of selection currently */ H5S_class_t stype; /* dataspace type */ + H5D_alloc_time_t alloc_time; /* Space allocation time */ herr_t ret; /* Generic return value */ unsigned int i, j, k; /* Output message about test being performed */ MESSAGE(5, ("Testing Dataspace with zero dimension size\n")); - /* Make sure we can create the space with the dimension size 0 (starting from v1.8.7). - * The dimension doesn't need to be unlimited. */ - sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); - CHECK(sid1, FAIL, "H5Screate_simple"); - - ret = H5Sclose(sid1); - CHECK(ret, FAIL, "H5Sclose"); - - sid1 = H5Screate(H5S_SIMPLE); - CHECK(sid1, FAIL, "H5Screate"); - - /* SID1 has the 1st dimension size as zero. The maximal dimension will be - * the same as the dimension because of the NULL passed in. */ - ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL); - CHECK(ret, FAIL, "H5Sset_extent_simple"); - - /* Check that the dataspace actually has 0 elements */ - nelem = H5Sget_simple_extent_npoints(sid1); - VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); - - /* Check that the dataspace was created with an "all" selection */ - sel_type = H5Sget_select_type(sid1); - VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type"); - - /* Check that the dataspace has 0 elements selected */ - nelem = H5Sget_select_npoints(sid1); - VERIFY(nelem, 0, "H5Sget_select_npoints"); - - /* Change to "none" selection */ - ret = H5Sselect_none(sid1); - CHECK(ret, FAIL, "H5Sselect_none"); - - /* Check that the dataspace has 0 elements selected */ - nelem = H5Sget_select_npoints(sid1); - VERIFY(nelem, 0, "H5Sget_select_npoints"); - - /* Try to select all dataspace */ - ret = H5Sselect_all(sid1); - CHECK(ret, FAIL, "H5Sselect_all"); - - /* Check that the dataspace has 0 elements selected */ - nelem = H5Sget_select_npoints(sid1); - VERIFY(nelem, 0, "H5Sget_select_npoints"); - - /* Create the dataspace for chunked dataset with the first dimension size as zero. - * The maximal dimensions are bigger than the dimensions for later expansion. */ - sid_chunk = H5Screate_simple(SPACE1_RANK, dims1, max_dims); - CHECK(sid_chunk, FAIL, "H5Screate_simple"); - - /*============================================ - * Make sure we can use 0-dimension to create - * contiguous, chunked, compact, and external - * datasets, and also attribute. - *============================================ - */ - fid1 = H5Fcreate(ZEROFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fcreate"); - /* Initialize the data */ for(i=0; i<SPACE1_DIM2; i++) for(j=0; j<SPACE1_DIM3; j++) { @@ -622,509 +565,588 @@ test_h5s_zero_dim(void) for(k=0; k<SPACE1_DIM3; k++) wdata_real[i][j][k] = i + j + k; - - /*===================== Contiguous dataset =======================*/ - dset1 = H5Dcreate2(fid1, BASICDATASET, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dcreate2"); - - /* Write "nothing" to the dataset */ - ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata); - CHECK(ret, FAIL, "H5Dwrite"); - - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); - - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); - - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); + /* Test with different space allocation times */ + for(alloc_time = H5D_ALLOC_TIME_EARLY; alloc_time <= H5D_ALLOC_TIME_INCR; alloc_time++) { + + /* Make sure we can create the space with the dimension size 0 (starting from v1.8.7). + * The dimension doesn't need to be unlimited. */ + dims1[0] = 0; + dims1[1] = SPACE1_DIM2; + dims1[2] = SPACE1_DIM3; + sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL); + CHECK(sid1, FAIL, "H5Screate_simple"); + + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + sid1 = H5Screate(H5S_SIMPLE); + CHECK(sid1, FAIL, "H5Screate"); + + /* SID1 has the 1st dimension size as zero. The maximal dimension will be + * the same as the dimension because of the NULL passed in. */ + ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL); + CHECK(ret, FAIL, "H5Sset_extent_simple"); + + /* Check that the dataspace actually has 0 elements */ + nelem = H5Sget_simple_extent_npoints(sid1); + VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); + + /* Check that the dataspace was created with an "all" selection */ + sel_type = H5Sget_select_type(sid1); + VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type"); + + /* Check that the dataspace has 0 elements selected */ + nelem = H5Sget_select_npoints(sid1); + VERIFY(nelem, 0, "H5Sget_select_npoints"); + + /* Change to "none" selection */ + ret = H5Sselect_none(sid1); + CHECK(ret, FAIL, "H5Sselect_none"); + + /* Check that the dataspace has 0 elements selected */ + nelem = H5Sget_select_npoints(sid1); + VERIFY(nelem, 0, "H5Sget_select_npoints"); + + /* Try to select all dataspace */ + ret = H5Sselect_all(sid1); + CHECK(ret, FAIL, "H5Sselect_all"); + + /* Check that the dataspace has 0 elements selected */ + nelem = H5Sget_select_npoints(sid1); + VERIFY(nelem, 0, "H5Sget_select_npoints"); + + /* Create the dataspace for chunked dataset with the first dimension size as zero. + * The maximal dimensions are bigger than the dimensions for later expansion. */ + sid_chunk = H5Screate_simple(SPACE1_RANK, dims1, max_dims); + CHECK(sid_chunk, FAIL, "H5Screate_simple"); + + /*============================================ + * Make sure we can use 0-dimension to create + * contiguous, chunked, compact, and external + * datasets, and also attribute. + *============================================ + */ + fid1 = H5Fcreate(ZEROFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fcreate"); + + /*===================== Contiguous dataset =======================*/ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plist_id, FAIL, "H5Pcreate"); + + ret = H5Pset_alloc_time(plist_id, alloc_time); + CHECK(ret, FAIL, "H5Pset_alloc_time"); + + dset1 = H5Dcreate2(fid1, BASICDATASET, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); + + ret = H5Pclose(plist_id); + CHECK(ret, FAIL, "H5Pclose"); + + /* Write "nothing" to the dataset */ + ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata); + CHECK(ret, FAIL, "H5Dwrite"); + + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); + + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); + + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); + } } } - } - /* Write "nothing" to the dataset (with type conversion :-) */ - ret = H5Dwrite(dset1, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_short); - CHECK(ret, FAIL, "H5Dwrite"); + /* Write "nothing" to the dataset (with type conversion :-) */ + ret = H5Dwrite(dset1, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_short); + CHECK(ret, FAIL, "H5Dwrite"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata_short); - CHECK(ret, FAIL, "H5Dread"); + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata_short); + CHECK(ret, FAIL, "H5Dread"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata_short[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata_short[i][j]); + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata_short[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata_short[i][j]); + } } } - } - - /* Select a hyperslab beyond its current dimension sizes, then try to write - * the data. It should fail. */ - ret = H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL); - CHECK(ret, FAIL, "H5Sselect_hyperslab"); - - H5E_BEGIN_TRY { - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, wdata); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Dwrite"); - - /* Change to "none" selection */ - ret = H5Sselect_none(sid1); - CHECK(ret, FAIL, "H5Sselect_none"); - - /* Select a point beyond the dimension size, then try to write the data. - * It should fail. */ - coord[0][0]=2; coord[0][1]=5; coord[0][2]=3; - ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord); - CHECK(ret, FAIL, "H5Sselect_elements"); - H5E_BEGIN_TRY { - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, &val); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Dwrite"); + /* Select a hyperslab beyond its current dimension sizes, then try to write + * the data. It should fail. */ + ret = H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL); + CHECK(ret, FAIL, "H5Sselect_hyperslab"); - /* Restore the selection to all */ - ret = H5Sselect_all(sid1); - CHECK(ret, FAIL, "H5Sselect_all"); + H5E_BEGIN_TRY { + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, wdata); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dwrite"); - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); + /* Change to "none" selection */ + ret = H5Sselect_none(sid1); + CHECK(ret, FAIL, "H5Sselect_none"); - /*=================== Chunked dataset ====================*/ - plist_id = H5Pcreate(H5P_DATASET_CREATE); - CHECK(plist_id, FAIL, "H5Pcreate"); + /* Select a point beyond the dimension size, then try to write the data. + * It should fail. */ + coord[0][0]=2; coord[0][1]=5; coord[0][2]=3; + ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord); + CHECK(ret, FAIL, "H5Sselect_elements"); - ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims); - CHECK(ret, FAIL, "H5Pset_chunk"); + H5E_BEGIN_TRY { + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, &val); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dwrite"); - dset1 = H5Dcreate2(fid1, BASICDATASET1, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dcreate2"); + /* Restore the selection to all */ + ret = H5Sselect_all(sid1); + CHECK(ret, FAIL, "H5Sselect_all"); - /* Write "nothing" to the dataset */ - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); - CHECK(ret, FAIL, "H5Dwrite"); + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + /*=================== Chunked dataset ====================*/ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plist_id, FAIL, "H5Pcreate"); - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); + ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims); + CHECK(ret, FAIL, "H5Pset_chunk"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); - } - } + // ret = H5Pset_alloc_time(plist_id, alloc_time); + // CHECK(ret, FAIL, "H5Pset_alloc_time"); - /* Now extend the dataset to SPACE1_DIM1*SPACE1_DIM2*SPACE1_DIM3 and make sure - * we can write data to it */ - ret = H5Dset_extent(dset1, extend_dims); - CHECK(ret, FAIL, "H5Dset_extent"); + dset1 = H5Dcreate2(fid1, BASICDATASET1, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real); - CHECK(ret, FAIL, "H5Dwrite"); + /* Write "nothing" to the dataset */ + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); + CHECK(ret, FAIL, "H5Dwrite"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_real); - CHECK(ret, FAIL, "H5Dread"); + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); - /* Check results */ - for(i=0; i<SPACE1_DIM1; i++) { - for(j=0; j<SPACE1_DIM2; j++) { - for(k=0; k<SPACE1_DIM3; k++) { - if(rdata_real[i][j][k] != wdata_real[i][j][k]) { + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { H5_FAILED(); - printf("element [%d][%d][%d] is %d but should have been %d\n", - i, j, k, rdata_real[i][j][k], wdata_real[i][j][k]); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); } - } } - } - - /* Now shrink the first dimension size of the dataset to 0 and make sure no data is in it */ - extend_dims[0] = 0; - ret = H5Dset_extent(dset1, extend_dims); - CHECK(ret, FAIL, "H5Dset_extent"); - - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); - - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); + /* Now extend the dataset to SPACE1_DIM1*SPACE1_DIM2*SPACE1_DIM3 and make sure + * we can write data to it */ + extend_dims[0] = SPACE1_DIM1; + ret = H5Dset_extent(dset1, extend_dims); + CHECK(ret, FAIL, "H5Dset_extent"); + + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real); + CHECK(ret, FAIL, "H5Dwrite"); + + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); + + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_real); + CHECK(ret, FAIL, "H5Dread"); + + /* Check results */ + for(i=0; i<SPACE1_DIM1; i++) { + for(j=0; j<SPACE1_DIM2; j++) { + for(k=0; k<SPACE1_DIM3; k++) { + if(rdata_real[i][j][k] != wdata_real[i][j][k]) { + H5_FAILED(); + printf("element [%d][%d][%d] is %d but should have been %d\n", + i, j, k, rdata_real[i][j][k], wdata_real[i][j][k]); + } + } } - } + } - /* Now extend the first dimension size of the dataset to SPACE1_DIM1*3 past the maximal size. - * It is supposed to fail. */ - extend_dims[0] = SPACE1_DIM1*3; - H5E_BEGIN_TRY { + /* Now shrink the first dimension size of the dataset to 0 and make sure no data is in it */ + extend_dims[0] = 0; ret = H5Dset_extent(dset1, extend_dims); - } H5E_END_TRY; - VERIFY(ret, FAIL, "H5Dset_extent"); - - ret = H5Pclose(plist_id); - CHECK(ret, FAIL, "H5Pclose"); - - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); - - /*=================== Compact dataset =====================*/ - plist_id = H5Pcreate(H5P_DATASET_CREATE); - CHECK(plist_id, FAIL, "H5Pcreate"); - - ret = H5Pset_layout(plist_id, H5D_COMPACT); - CHECK(ret, FAIL, "H5Pset_layout"); - - ret = H5Pset_alloc_time(plist_id, H5D_ALLOC_TIME_EARLY); - CHECK(ret, FAIL, "H5Pset_alloc_time"); + CHECK(ret, FAIL, "H5Dset_extent"); - dset1 = H5Dcreate2(fid1, BASICDATASET2, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dcreate2"); - - /* Write "nothing" to the dataset */ - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); - CHECK(ret, FAIL, "H5Dwrite"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); + } + } - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); - } - } + /* Now extend the first dimension size of the dataset to SPACE1_DIM1*3 past the maximal size. + * It is supposed to fail. */ + extend_dims[0] = SPACE1_DIM1*3; + H5E_BEGIN_TRY { + ret = H5Dset_extent(dset1, extend_dims); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Dset_extent"); - ret = H5Pclose(plist_id); - CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(plist_id); + CHECK(ret, FAIL, "H5Pclose"); - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); - /*=========== Contiguous dataset with external storage ============*/ - plist_id = H5Pcreate(H5P_DATASET_CREATE); - CHECK(plist_id, FAIL, "H5Pcreate"); + /*=================== Compact dataset =====================*/ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plist_id, FAIL, "H5Pcreate"); - ret = H5Pset_layout(plist_id, H5D_CONTIGUOUS); - CHECK(ret, FAIL, "H5Pset_layout"); + ret = H5Pset_layout(plist_id, H5D_COMPACT); + CHECK(ret, FAIL, "H5Pset_layout"); - /* Change the DCPL for contiguous layout with external storage. The size of the reserved - * space in the external file is the size of the dataset (zero because one dimension size is zero). - * There's no need to clean up the external file since the library doesn't create it - * until the data is written to it. */ - ret = H5Pset_external(plist_id, EXTFILE_NAME, (off_t)0, (hsize_t)0); - CHECK(ret, FAIL, "H5Pset_external"); + /* Don't set the allocation time for compact storage datasets (must be early) */ - dset1 = H5Dcreate2(fid1, BASICDATASET3, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dcreate2"); + dset1 = H5Dcreate2(fid1, BASICDATASET2, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); - /* Write "nothing" to the dataset */ - ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata); - CHECK(ret, FAIL, "H5Dwrite"); + /* Write "nothing" to the dataset */ + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata); + CHECK(ret, FAIL, "H5Dwrite"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); - } + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); + } } - } - - ret = H5Pclose(plist_id); - CHECK(ret, FAIL, "H5Pclose"); - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); + ret = H5Pclose(plist_id); + CHECK(ret, FAIL, "H5Pclose"); - /*=============== Create an attribute for the file ================*/ - attr = H5Acreate2(fid1, NULLATTR, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Acreate2"); + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); - /* Write "nothing" to the attribute */ - ret = H5Awrite(attr, H5T_NATIVE_INT, wdata); - CHECK(ret, FAIL, "H5Awrite"); + /*=========== Contiguous dataset with external storage ============*/ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plist_id, FAIL, "H5Pcreate"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + /* Change the DCPL for contiguous layout with external storage. The size of the reserved + * space in the external file is the size of the dataset (zero because one dimension size is zero). + * There's no need to clean up the external file since the library doesn't create it + * until the data is written to it. */ + ret = H5Pset_external(plist_id, EXTFILE_NAME, (off_t)0, (hsize_t)0); + CHECK(ret, FAIL, "H5Pset_external"); - /* Try reading from the attribute (make certain our buffer is unmodified) */ - ret = H5Aread(attr, H5T_NATIVE_INT, rdata); - CHECK(ret, FAIL, "H5Aread"); + ret = H5Pset_alloc_time(plist_id, alloc_time); + CHECK(ret, FAIL, "H5Pset_alloc_time"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); - } - } - } + dset1 = H5Dcreate2(fid1, BASICDATASET3, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); - /* Write "nothing" to the attribute (with type conversion :-) */ - ret = H5Awrite(attr, H5T_NATIVE_SHORT, wdata_short); - CHECK(ret, FAIL, "H5Awrite"); + /* Write "nothing" to the dataset */ + ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata); + CHECK(ret, FAIL, "H5Dwrite"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - /* Try reading from the attribute (with type conversion :-) (make certain our buffer is unmodified) */ - ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short); - CHECK(ret, FAIL, "H5Aread"); + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata_short[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata_short[i][j]); + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); + } } } - } - - /* Close attribute */ - ret = H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); - - /*=============================================================== - * Extend the dimension to make it a normal dataspace (3x15x13). - * Verify that data can be written to and read from the chunked - * dataset now. - *=============================================================== - */ - dims1[0]=SPACE1_DIM1; - ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,max_dims); - CHECK(ret, FAIL, "H5Sset_extent_simple"); - - nelem = H5Sget_simple_extent_npoints(sid_chunk); - CHECK(nelem, FAIL, "H5Sget_simple_extent_npoints"); - VERIFY(nelem, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3, - "H5Sget_simple_extent_npoints"); - - rank = H5Sget_simple_extent_ndims(sid_chunk); - CHECK(rank, FAIL, "H5Sget_simple_extent_ndims"); - VERIFY(rank, SPACE1_RANK, "H5Sget_simple_extent_ndims"); - - rank = H5Sget_simple_extent_dims(sid_chunk, tdims, NULL); - CHECK(rank, FAIL, "H5Sget_simple_extent_dims"); - VERIFY(HDmemcmp(tdims, dims1, SPACE1_RANK * sizeof(hsize_t)), 0, - "H5Sget_simple_extent_dims"); - /* Set it to chunked dataset */ - plist_id = H5Pcreate(H5P_DATASET_CREATE); - CHECK(plist_id, FAIL, "H5Pcreate"); + ret = H5Pclose(plist_id); + CHECK(ret, FAIL, "H5Pclose"); - ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims); - CHECK(ret, FAIL, "H5Pset_chunk"); + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); - dset1 = H5Dcreate2(fid1, BASICDATASET4, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dcreate2"); + /*=============== Create an attribute for the file ================*/ + attr = H5Acreate2(fid1, NULLATTR, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate2"); - ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real); - CHECK(ret, FAIL, "H5Dwrite"); + /* Write "nothing" to the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_INT, wdata); + CHECK(ret, FAIL, "H5Awrite"); - ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); - CHECK(ret, FAIL, "H5Fflush"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_real); - CHECK(ret, FAIL, "H5Dread"); + /* Try reading from the attribute (make certain our buffer is unmodified) */ + ret = H5Aread(attr, H5T_NATIVE_INT, rdata); + CHECK(ret, FAIL, "H5Aread"); - /* Check results */ - for(i=0; i<SPACE1_DIM1; i++) { - for(j=0; j<SPACE1_DIM2; j++) { - for(k=0; k<SPACE1_DIM3; k++) { - if(rdata_real[i][j][k] != wdata_real[i][j][k]) { + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { H5_FAILED(); - printf("element [%d][%d][%d] is %d but should have been %d\n", - i, j, k, rdata_real[i][j][k], wdata_real[i][j][k]); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); } } } - } - - ret = H5Pclose(plist_id); - CHECK(ret, FAIL, "H5Pclose"); - - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); - - /* Change the dimensions to make them zero size again (0x0x0). Verify that - * no element is in the dataspace. */ - dims1[0]=dims1[1]=dims1[2]=0; - ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,NULL); - CHECK(ret, FAIL, "H5Sset_extent_simple"); - - /* Check that the dataspace actually has 0 elements */ - nelem = H5Sget_simple_extent_npoints(sid_chunk); - VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); - - /* Check that the dataspace was created with an "all" selection */ - sel_type = H5Sget_select_type(sid_chunk); - VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type"); - - /* Check that the dataspace has 0 elements selected */ - nelem = H5Sget_select_npoints(sid_chunk); - VERIFY(nelem, 0, "H5Sget_select_npoints"); - - /* Change to "none" selection */ - ret = H5Sselect_none(sid_chunk); - CHECK(ret, FAIL, "H5Sselect_none"); - - /* Check that the dataspace has 0 elements selected */ - nelem = H5Sget_select_npoints(sid_chunk); - VERIFY(nelem, 0, "H5Sget_select_npoints"); - - ret = H5Sclose(sid_chunk); - CHECK(ret, FAIL, "H5Sclose"); - - ret = H5Sclose(sid1); - CHECK(ret, FAIL, "H5Sclose"); - - ret = H5Fclose(fid1); - CHECK(ret, FAIL, "H5Fclose"); - - /*============================================ - * Reopen the file to check the data space - *============================================ - */ - fid1 = H5Fopen(ZEROFILE, H5F_ACC_RDONLY, H5P_DEFAULT); - CHECK(fid1, FAIL, "H5Fopen"); - - /* Reopen the chunked dataset */ - dset1 = H5Dopen2(fid1, BASICDATASET1, H5P_DEFAULT); - CHECK(dset1, FAIL, "H5Dopen2"); - /* Get the space of the dataset and querry it */ - sid1 = H5Dget_space(dset1); - CHECK(sid1, FAIL, "H5Dget_space"); + /* Write "nothing" to the attribute (with type conversion :-) */ + ret = H5Awrite(attr, H5T_NATIVE_SHORT, wdata_short); + CHECK(ret, FAIL, "H5Awrite"); - /* Verify the class type of dataspace */ - stype = H5Sget_simple_extent_type(sid1); - VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type"); + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); - /* Verify there is zero element in the dataspace */ - nelem = H5Sget_simple_extent_npoints(sid1); - VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); + /* Try reading from the attribute (with type conversion :-) (make certain our buffer is unmodified) */ + ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short); + CHECK(ret, FAIL, "H5Aread"); - /* Verify the dimension sizes are correct */ - rank = H5Sget_simple_extent_dims(sid1, tdims, NULL); - CHECK(rank, FAIL, "H5Sget_simple_extent_dims"); - VERIFY(tdims[0], 0, "H5Sget_simple_extent_dims"); - VERIFY(tdims[1], SPACE1_DIM2, "H5Sget_simple_extent_dims"); - VERIFY(tdims[2], SPACE1_DIM3, "H5Sget_simple_extent_dims"); + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata_short[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata_short[i][j]); + } + } + } - /* Try reading from the dataset (make certain our buffer is unmodified) */ - ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); - CHECK(ret, FAIL, "H5Dread"); + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /*=============================================================== + * Extend the dimension to make it a normal dataspace (3x15x13). + * Verify that data can be written to and read from the chunked + * dataset now. + *=============================================================== + */ + dims1[0]=SPACE1_DIM1; + ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,max_dims); + CHECK(ret, FAIL, "H5Sset_extent_simple"); + + nelem = H5Sget_simple_extent_npoints(sid_chunk); + CHECK(nelem, FAIL, "H5Sget_simple_extent_npoints"); + VERIFY(nelem, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3, + "H5Sget_simple_extent_npoints"); + + rank = H5Sget_simple_extent_ndims(sid_chunk); + CHECK(rank, FAIL, "H5Sget_simple_extent_ndims"); + VERIFY(rank, SPACE1_RANK, "H5Sget_simple_extent_ndims"); + + rank = H5Sget_simple_extent_dims(sid_chunk, tdims, NULL); + CHECK(rank, FAIL, "H5Sget_simple_extent_dims"); + VERIFY(HDmemcmp(tdims, dims1, SPACE1_RANK * sizeof(hsize_t)), 0, + "H5Sget_simple_extent_dims"); + + /* Set it to chunked dataset */ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + CHECK(plist_id, FAIL, "H5Pcreate"); + + ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims); + CHECK(ret, FAIL, "H5Pset_chunk"); + + ret = H5Pset_alloc_time(plist_id, alloc_time); + CHECK(ret, FAIL, "H5Pset_alloc_time"); + + dset1 = H5Dcreate2(fid1, BASICDATASET4, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dcreate2"); + + ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real); + CHECK(ret, FAIL, "H5Dwrite"); + + ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "H5Fflush"); + + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_real); + CHECK(ret, FAIL, "H5Dread"); + + /* Check results */ + for(i=0; i<SPACE1_DIM1; i++) { + for(j=0; j<SPACE1_DIM2; j++) { + for(k=0; k<SPACE1_DIM3; k++) { + if(rdata_real[i][j][k] != wdata_real[i][j][k]) { + H5_FAILED(); + printf("element [%d][%d][%d] is %d but should have been %d\n", + i, j, k, rdata_real[i][j][k], wdata_real[i][j][k]); + } + } + } + } - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata[i][j]); + ret = H5Pclose(plist_id); + CHECK(ret, FAIL, "H5Pclose"); + + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); + + /* Change the dimensions to make them zero size again (0x0x0). Verify that + * no element is in the dataspace. */ + dims1[0]=dims1[1]=dims1[2]=0; + ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,NULL); + CHECK(ret, FAIL, "H5Sset_extent_simple"); + + /* Check that the dataspace actually has 0 elements */ + nelem = H5Sget_simple_extent_npoints(sid_chunk); + VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); + + /* Check that the dataspace was created with an "all" selection */ + sel_type = H5Sget_select_type(sid_chunk); + VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type"); + + /* Check that the dataspace has 0 elements selected */ + nelem = H5Sget_select_npoints(sid_chunk); + VERIFY(nelem, 0, "H5Sget_select_npoints"); + + /* Change to "none" selection */ + ret = H5Sselect_none(sid_chunk); + CHECK(ret, FAIL, "H5Sselect_none"); + + /* Check that the dataspace has 0 elements selected */ + nelem = H5Sget_select_npoints(sid_chunk); + VERIFY(nelem, 0, "H5Sget_select_npoints"); + + ret = H5Sclose(sid_chunk); + CHECK(ret, FAIL, "H5Sclose"); + + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); + + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + + /*============================================ + * Reopen the file to check the data space + *============================================ + */ + fid1 = H5Fopen(ZEROFILE, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid1, FAIL, "H5Fopen"); + + /* Reopen the chunked dataset */ + dset1 = H5Dopen2(fid1, BASICDATASET1, H5P_DEFAULT); + CHECK(dset1, FAIL, "H5Dopen2"); + + /* Get the space of the dataset and querry it */ + sid1 = H5Dget_space(dset1); + CHECK(sid1, FAIL, "H5Dget_space"); + + /* Verify the class type of dataspace */ + stype = H5Sget_simple_extent_type(sid1); + VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type"); + + /* Verify there is zero element in the dataspace */ + nelem = H5Sget_simple_extent_npoints(sid1); + VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); + + /* Verify the dimension sizes are correct */ + rank = H5Sget_simple_extent_dims(sid1, tdims, NULL); + CHECK(rank, FAIL, "H5Sget_simple_extent_dims"); + VERIFY(tdims[0], 0, "H5Sget_simple_extent_dims"); + VERIFY(tdims[1], SPACE1_DIM2, "H5Sget_simple_extent_dims"); + VERIFY(tdims[2], SPACE1_DIM3, "H5Sget_simple_extent_dims"); + + /* Try reading from the dataset (make certain our buffer is unmodified) */ + ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata); + CHECK(ret, FAIL, "H5Dread"); + + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata[i][j]); + } } } - } - /* Close the dataset and its dataspace */ - ret = H5Dclose(dset1); - CHECK(ret, FAIL, "H5Dclose"); + /* Close the dataset and its dataspace */ + ret = H5Dclose(dset1); + CHECK(ret, FAIL, "H5Dclose"); - ret = H5Sclose(sid1); - CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid1); + CHECK(ret, FAIL, "H5Sclose"); - /* Open the attribute for the file */ - attr = H5Aopen(fid1, NULLATTR, H5P_DEFAULT); - CHECK(attr, FAIL, "H5Aopen"); + /* Open the attribute for the file */ + attr = H5Aopen(fid1, NULLATTR, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Aopen"); - /* Get the space of the dataset */ - attr_sid = H5Aget_space(attr); - CHECK(attr_sid, FAIL, "H5Aget_space"); + /* Get the space of the dataset */ + attr_sid = H5Aget_space(attr); + CHECK(attr_sid, FAIL, "H5Aget_space"); - /* Verify the class type of dataspace */ - stype = H5Sget_simple_extent_type(attr_sid); - VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type"); + /* Verify the class type of dataspace */ + stype = H5Sget_simple_extent_type(attr_sid); + VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type"); - /* Verify there is zero element in the dataspace */ - nelem = H5Sget_simple_extent_npoints(attr_sid); - VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); + /* Verify there is zero element in the dataspace */ + nelem = H5Sget_simple_extent_npoints(attr_sid); + VERIFY(nelem, 0, "H5Sget_simple_extent_npoints"); - /* Try reading from the attribute (make certain our buffer is unmodified) */ - ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short); - CHECK(ret, FAIL, "H5Aread"); + /* Try reading from the attribute (make certain our buffer is unmodified) */ + ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short); + CHECK(ret, FAIL, "H5Aread"); - /* Check results */ - for(i=0; i<SPACE1_DIM2; i++) { - for(j=0; j<SPACE1_DIM3; j++) { - if(rdata_short[i][j] != 7) { - H5_FAILED(); - printf("element [%d][%d] is %d but should have been 7\n", - i, j, rdata_short[i][j]); + /* Check results */ + for(i=0; i<SPACE1_DIM2; i++) { + for(j=0; j<SPACE1_DIM3; j++) { + if(rdata_short[i][j] != 7) { + H5_FAILED(); + printf("element [%d][%d] is %d but should have been 7\n", + i, j, rdata_short[i][j]); + } } } - } - /* Close attribute */ - ret=H5Aclose(attr); - CHECK(ret, FAIL, "H5Aclose"); + /* Close attribute */ + ret=H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); - /* Close the dataspace */ - ret = H5Sclose(attr_sid); - CHECK(ret, FAIL, "H5Sclose"); + /* Close the dataspace */ + ret = H5Sclose(attr_sid); + CHECK(ret, FAIL, "H5Sclose"); - ret = H5Fclose(fid1); - CHECK(ret, FAIL, "H5Fclose"); -} /* test_h5s_zero_dim() */ + ret = H5Fclose(fid1); + CHECK(ret, FAIL, "H5Fclose"); + } /* end for */ +} /* test_h5s_zero_dim() */ /**************************************************************** diff --git a/testpar/t_dset.c b/testpar/t_dset.c index d2f061d..33cf765 100644 --- a/testpar/t_dset.c +++ b/testpar/t_dset.c @@ -3047,3 +3047,328 @@ actual_io_mode_tests(void) { test_actual_io_mode(TEST_ACTUAL_IO_RESET); return; } + +/* + * Test consistency semantics of atomic mode + */ + +/* + * Example of using the parallel HDF5 library to create a dataset, + * where process 0 writes and the other processes read at the same + * time. If atomic mode is set correctly, the other processes should + * read the old values in the dataset or the new ones. + */ + +void +dataset_atomicity(void) +{ + hid_t fid; /* HDF5 file ID */ + hid_t acc_tpl; /* File access templates */ + hid_t sid; /* Dataspace ID */ + hid_t dataset1; /* Dataset IDs */ + hbool_t use_gpfs = FALSE; /* Use GPFS hints */ + hsize_t dims[RANK]; /* dataset dim sizes */ + int *write_buf = NULL; /* data buffer */ + int *read_buf = NULL; /* data buffer */ + int buf_size; + hid_t dataset2; + hid_t file_dataspace; /* File dataspace ID */ + hid_t mem_dataspace; /* Memory dataspace ID */ + hsize_t start[RANK]; + hsize_t stride[RANK]; + hsize_t count[RANK]; + hsize_t block[RANK]; + const char *filename; + herr_t ret; /* Generic return value */ + int mpi_size, mpi_rank; + int i, j, k; + hbool_t atomicity = FALSE; + MPI_Comm comm = MPI_COMM_WORLD; + MPI_Info info = MPI_INFO_NULL; + + dim0 = 64; dim1 = 32; + filename = GetTestParameters(); + if(VERBOSE_MED) + printf("Independent write test on file %s\n", filename); + + /* set up MPI parameters */ + MPI_Comm_size(MPI_COMM_WORLD,&mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank); + + buf_size = dim0 * dim1; + /* allocate memory for data buffer */ + write_buf = (int *)calloc(buf_size, sizeof(int)); + VRFY((write_buf != NULL), "write_buf malloc succeeded"); + /* allocate memory for data buffer */ + read_buf = (int *)calloc(buf_size, sizeof(int)); + VRFY((read_buf != NULL), "read_buf malloc succeeded"); + + /* setup file access template */ + acc_tpl = create_faccess_plist(comm, info, facc_type, use_gpfs); + VRFY((acc_tpl >= 0), ""); + + /* create the file collectively */ + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); + VRFY((fid >= 0), "H5Fcreate succeeded"); + + /* Release file-access template */ + ret = H5Pclose(acc_tpl); + VRFY((ret >= 0), "H5Pclose succeeded"); + + /* setup dimensionality object */ + dims[0] = dim0; + dims[1] = dim1; + sid = H5Screate_simple (RANK, dims, NULL); + VRFY((sid >= 0), "H5Screate_simple succeeded"); + + /* create datasets */ + dataset1 = H5Dcreate2(fid, DATASETNAME5, H5T_NATIVE_INT, sid, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + VRFY((dataset1 >= 0), "H5Dcreate2 succeeded"); + + dataset2 = H5Dcreate2(fid, DATASETNAME6, H5T_NATIVE_INT, sid, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + VRFY((dataset2 >= 0), "H5Dcreate2 succeeded"); + + /* initialize datasets to 0s */ + if (0 == mpi_rank) { + ret = H5Dwrite(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, write_buf); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded"); + + ret = H5Dwrite(dataset2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, + H5P_DEFAULT, write_buf); + VRFY((ret >= 0), "H5Dwrite dataset2 succeeded"); + } + + ret = H5Dclose(dataset1); + VRFY((ret >= 0), "H5Dclose succeeded"); + ret = H5Dclose(dataset2); + VRFY((ret >= 0), "H5Dclose succeeded"); + ret = H5Sclose(sid); + VRFY((ret >= 0), "H5Sclose succeeded"); + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded"); + + MPI_Barrier (comm); + + /* make sure setting atomicity fails on a serial file ID */ + /* open the file collectively */ + fid=H5Fopen(filename,H5F_ACC_RDWR,H5P_DEFAULT); + VRFY((fid >= 0), "H5Fopen succeeed"); + + /* should fail */ + ret = H5Fset_mpi_atomicity (fid , TRUE); + VRFY((ret == FAIL), "H5Fset_mpi_atomicity failed"); + + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded"); + + MPI_Barrier (comm); + + /* setup file access template */ + acc_tpl = create_faccess_plist(comm, info, facc_type, use_gpfs); + VRFY((acc_tpl >= 0), ""); + + /* open the file collectively */ + fid=H5Fopen(filename,H5F_ACC_RDWR,acc_tpl); + VRFY((fid >= 0), "H5Fopen succeeded"); + + /* Release file-access template */ + ret = H5Pclose(acc_tpl); + VRFY((ret >= 0), "H5Pclose succeeded"); + + ret = H5Fset_mpi_atomicity (fid , TRUE); + VRFY((ret >= 0), "H5Fset_mpi_atomicity succeeded"); + + /* open dataset1 (contiguous case) */ + dataset1 = H5Dopen2(fid, DATASETNAME5, H5P_DEFAULT); + VRFY((dataset1 >= 0), "H5Dopen2 succeeded"); + + if (0 == mpi_rank) { + for (i=0 ; i<buf_size ; i++) { + write_buf[i] = 5; + } + } + else { + for (i=0 ; i<buf_size ; i++) { + read_buf[i] = 8; + } + } + + /* check that the atomicity flag is set */ + ret = H5Fget_mpi_atomicity (fid , &atomicity); + VRFY((ret >= 0), "atomcity get failed"); + VRFY((atomicity == TRUE), "atomcity set failed"); + + MPI_Barrier (comm); + + /* Process 0 writes contiguously to the entire dataset */ + if (0 == mpi_rank) { + ret = H5Dwrite(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, write_buf); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded"); + } + /* The other processes read the entire dataset */ + else { + ret = H5Dread(dataset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf); + VRFY((ret >= 0), "H5Dwrite() dataset multichunk write succeeded"); + } + + if(VERBOSE_MED) { + i=0;j=0;k=0; + for (i=0 ; i<dim0 ; i++) { + printf ("\n"); + for (j=0 ; j<dim1 ; j++) + printf ("%d ", read_buf[k++]); + } + } + + /* The processes that read the dataset must either read all values + as 0 (read happened before process 0 wrote to dataset 1), or 5 + (read happened after process 0 wrote to dataset 1) */ + if (0 != mpi_rank) { + int compare = read_buf[0]; + + VRFY((compare == 0 || compare == 5), + "Atomicity Test Failed Process %d: Value read should be 0 or 5\n"); + for (i=1; i<buf_size; i++) { + if (read_buf[i] != compare) { + printf("Atomicity Test Failed Process %d: read_buf[%d] is %d, should be %d\n", mpi_rank, i, read_buf[i], compare); + nerrors ++; + } + } + } + + ret = H5Dclose(dataset1); + VRFY((ret >= 0), "H5D close succeeded"); + + /* release data buffers */ + if(write_buf) free(write_buf); + if(read_buf) free(read_buf); + + /* open dataset2 (non-contiguous case) */ + dataset2 = H5Dopen2(fid, DATASETNAME6, H5P_DEFAULT); + VRFY((dataset2 >= 0), "H5Dopen2 succeeded"); + + /* allocate memory for data buffer */ + write_buf = (int *)calloc(buf_size, sizeof(int)); + VRFY((write_buf != NULL), "write_buf malloc succeeded"); + /* allocate memory for data buffer */ + read_buf = (int *)calloc(buf_size, sizeof(int)); + VRFY((read_buf != NULL), "read_buf malloc succeeded"); + + for (i=0 ; i<buf_size ; i++) { + write_buf[i] = 5; + } + for (i=0 ; i<buf_size ; i++) { + read_buf[i] = 8; + } + + atomicity = FALSE; + /* check that the atomicity flag is set */ + ret = H5Fget_mpi_atomicity (fid , &atomicity); + VRFY((ret >= 0), "atomcity get failed"); + VRFY((atomicity == TRUE), "atomcity set failed"); + + + block[0] = dim0/mpi_size - 1; + block[1] = dim1/mpi_size - 1; + stride[0] = block[0] + 1; + stride[1] = block[1] + 1; + count[0] = mpi_size; + count[1] = mpi_size; + start[0] = 0; + start[1] = 0; + + /* create a file dataspace */ + file_dataspace = H5Dget_space (dataset2); + VRFY((file_dataspace >= 0), "H5Dget_space succeeded"); + ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded"); + + /* create a memory dataspace */ + mem_dataspace = H5Screate_simple (RANK, dims, NULL); + VRFY((mem_dataspace >= 0), ""); + + ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded"); + + MPI_Barrier (comm); + + /* Process 0 writes to the dataset */ + if (0 == mpi_rank) { + ret = H5Dwrite(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, + H5P_DEFAULT, write_buf); + VRFY((ret >= 0), "H5Dwrite dataset2 succeeded"); + } + /* All processes wait for the write to finish. This works because + atomicity is set to true */ + MPI_Barrier (comm); + /* The other processes read the entire dataset */ + if (0 != mpi_rank) { + ret = H5Dread(dataset2, H5T_NATIVE_INT, mem_dataspace, file_dataspace, + H5P_DEFAULT, read_buf); + VRFY((ret >= 0), "H5Dread dataset2 succeeded"); + } + + if(VERBOSE_MED) { + if (mpi_rank == 1) { + i=0;j=0;k=0; + for (i=0 ; i<dim0 ; i++) { + printf ("\n"); + for (j=0 ; j<dim1 ; j++) + printf ("%d ", read_buf[k++]); + } + printf ("\n"); + } + } + + /* The processes that read the dataset must either read all values + as 5 (read happened after process 0 wrote to dataset 1) */ + if (0 != mpi_rank) { + int compare; + i=0;j=0;k=0; + + compare = 5; + + for (i=0 ; i<dim0 ; i++) { + if (i >= mpi_rank*(block[0]+1)) { + break; + } + if ((i+1)%(block[0]+1)==0) { + k += dim1; + continue; + } + for (j=0 ; j<dim1 ; j++) { + if (j >= mpi_rank*(block[1]+1)) { + k += dim1 - mpi_rank*(block[1]+1); + break; + } + if ((j+1)%(block[1]+1)==0) { + k++; + continue; + } + else if (compare != read_buf[k]) { + printf("Atomicity Test Failed Process %d: read_buf[%d] is %d, should be %d\n", mpi_rank, k, read_buf[k], compare); + nerrors++; + } + k ++; + } + } + } + + ret = H5Dclose(dataset2); + VRFY((ret >= 0), "H5Dclose succeeded"); + ret = H5Sclose(file_dataspace); + VRFY((ret >= 0), "H5Sclose succeeded"); + ret = H5Sclose(mem_dataspace); + VRFY((ret >= 0), "H5Sclose succeeded"); + + /* release data buffers */ + if(write_buf) free(write_buf); + if(read_buf) free(read_buf); + + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded"); + +} diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c index e3c72ef..4ec05ca 100644 --- a/testpar/testphdf5.c +++ b/testpar/testphdf5.c @@ -512,6 +512,18 @@ int main(int argc, char **argv) /* Parse command line arguments */ TestParseCmdLine(argc, argv); + if((mpi_size < 2)&& MAINPROCESS ) { + printf("Atomicity tests need at least 2 processes to participate\n"); + printf("8 is more recommended.. Atomicity tests will be skipped \n"); + } + else if (facc_type != FACC_MPIO && MAINPROCESS) { + printf("Atomicity tests will not work with a non MPIO VFD\n"); + } + else if(mpi_size >= 2 && facc_type == FACC_MPIO){ + AddTest("atomicity", dataset_atomicity, NULL, + "dataset atomic updates", PARATESTFILE); + } + if (facc_type == FACC_MPIPOSIX && MAINPROCESS){ printf("===================================\n" " Using MPIPOSIX driver\n" diff --git a/testpar/testphdf5.h b/testpar/testphdf5.h index 11656f9..15ef75f 100644 --- a/testpar/testphdf5.h +++ b/testpar/testphdf5.h @@ -43,6 +43,8 @@ enum H5TEST_COLL_CHUNK_API {API_NONE=0,API_LINK_HARD, #define DATASETNAME2 "Data2" #define DATASETNAME3 "Data3" #define DATASETNAME4 "Data4" +#define DATASETNAME5 "Data5" +#define DATASETNAME6 "Data6" /* Hyperslab layout styles */ #define BYROW 1 /* divide into slabs of rows */ @@ -225,6 +227,7 @@ void independent_group_read(void); void test_fapl_mpio_dup(void); void test_fapl_mpiposix_dup(void); void test_split_comm_access(void); +void dataset_atomicity(void); void dataset_writeInd(void); void dataset_writeAll(void); void extend_writeInd(void); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index fad517c..6cdfcac 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SOURCE_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # If testing was NOT enabled, then we need to build the tools library diff --git a/tools/h5copy/CMakeLists.txt b/tools/h5copy/CMakeLists.txt index 7006283..f9e7c12 100644 --- a/tools/h5copy/CMakeLists.txt +++ b/tools/h5copy/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5COPY) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5copy and test executables diff --git a/tools/h5diff/CMakeLists.txt b/tools/h5diff/CMakeLists.txt index 3f73bd7..dfd1800 100644 --- a/tools/h5diff/CMakeLists.txt +++ b/tools/h5diff/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5DIFF) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5diff executables @@ -131,11 +130,18 @@ IF (BUILD_TESTING) h5diff_458.txt h5diff_459.txt h5diff_465.txt + h5diff_466.txt + h5diff_467.txt + h5diff_468.txt + h5diff_469.txt h5diff_480.txt h5diff_481.txt h5diff_482.txt h5diff_483.txt h5diff_484.txt + h5diff_485.txt + h5diff_486.txt + h5diff_487.txt h5diff_50.txt h5diff_51.txt h5diff_52.txt @@ -250,6 +256,8 @@ IF (BUILD_TESTING) h5diff_exclude1-2.h5 h5diff_exclude2-1.h5 h5diff_exclude2-2.h5 + h5diff_exclude3-1.h5 + h5diff_exclude3-2.h5 h5diff_comp_vl_strs.h5 h5diff_attr_v_level1.h5 h5diff_attr_v_level2.h5 @@ -487,6 +495,9 @@ IF (BUILD_TESTING) # different structure and obj names SET (EXCLUDE_FILE2_1 h5diff_exclude2-1.h5) SET (EXCLUDE_FILE2_2 h5diff_exclude2-2.h5) + # Only one file contains unique objs. Common objs are same. + SET (EXCLUDE_FILE3_1 h5diff_exclude3-1.h5) + SET (EXCLUDE_FILE3_2 h5diff_exclude3-2.h5) # compound type with multiple vlen string types SET (COMP_VL_STRS_FILE h5diff_comp_vl_strs.h5) # container types (array,vlen) with multiple nested compound types @@ -658,6 +669,14 @@ IF (BUILD_TESTING) h5diff_459.out.err h5diff_465.out h5diff_465.out.err + h5diff_466.out + h5diff_466.out.err + h5diff_467.out + h5diff_467.out.err + h5diff_468.out + h5diff_468.out.err + h5diff_469.out + h5diff_469.out.err h5diff_480.out h5diff_480.out.err h5diff_481.out @@ -1267,7 +1286,16 @@ ADD_H5_TEST (h5diff_459 2 --follow-symlinks -v --no-dangling-links ${FILE15} $ # dangling link --follow-symlinks (obj vs obj) # (HDFFV-7836) -ADD_H5_TEST (h5diff_465 1 --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1) +ADD_H5_TEST (h5diff_465 0 --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1) +# (HDFFV-7835) +# soft dangling vs. soft dangling +ADD_H5_TEST (h5diff_466 0 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1) +# soft link vs. soft dangling +ADD_H5_TEST (h5diff_467 1 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link2) +# ext dangling vs. ext dangling +ADD_H5_TEST (h5diff_468 0 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_link4) +# ext link vs. ext dangling +ADD_H5_TEST (h5diff_469 1 -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_link2) # ############################################################################## # # test for group diff recursivly @@ -1339,6 +1367,16 @@ ADD_H5_TEST (h5diff_483 1 -v --exclude-path "/group1" ${EXCLUDE_FILE2_1} ${EXCLU # Exclude from group compare ADD_H5_TEST (h5diff_484 0 -v --exclude-path "/dset3" ${EXCLUDE_FILE1_1} ${EXCLUDE_FILE1_2} /group1) +# +# Only one file contains unique objs. Common objs are same. +# (HDFFV-7837) +# +ADD_H5_TEST (h5diff_485 0 -v --exclude-path "/group1" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5) +ADD_H5_TEST (h5diff_486 0 -v --exclude-path "/group1" h5diff_exclude3-2.h5 h5diff_exclude3-1.h5) +ADD_H5_TEST (h5diff_487 1 -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5) + + + # ############################################################################## # # diff various multiple vlen and fixed strings in a compound type dataset # ############################################################################## diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c index d58e1b4..b57c98a 100644 --- a/tools/h5diff/h5diffgentest.c +++ b/tools/h5diff/h5diffgentest.c @@ -77,6 +77,9 @@ hsize_t H5TOOLS_MALLOCSIZE = (128 * 1024 * 1024); /* different structure and obj names */ #define EXCLUDE_FILE2_1 "h5diff_exclude2-1.h5" #define EXCLUDE_FILE2_2 "h5diff_exclude2-2.h5" +/* only one file has unique objs */ +#define EXCLUDE_FILE3_1 "h5diff_exclude3-1.h5" +#define EXCLUDE_FILE3_2 "h5diff_exclude3-2.h5" /* compound type with multiple vlen string types */ #define COMP_VL_STRS_FILE "h5diff_comp_vl_strs.h5" /* attribute compre with verbose level */ @@ -144,6 +147,7 @@ static int test_group_recurse(const char *fname1, const char *fname2); static int test_group_recurse2(void); static int test_exclude_obj1(const char *fname1, const char *fname2); static int test_exclude_obj2(const char *fname1, const char *fname2); +static int test_exclude_obj3(const char *fname1, const char *fname2); static int test_comp_vlen_strings(const char *fname1, const char *grp_name, int is_file_new); static int test_attributes_verbose_level(const char *fname1, const char *fname2); static int test_enums(const char *fname); @@ -213,6 +217,7 @@ int main(void) test_exclude_obj1(EXCLUDE_FILE1_1, EXCLUDE_FILE1_2); test_exclude_obj2(EXCLUDE_FILE2_1, EXCLUDE_FILE2_2); + test_exclude_obj3(EXCLUDE_FILE3_1, EXCLUDE_FILE3_2); /* diff various multiple vlen and fixlen string types in a compound dataset */ test_comp_vlen_strings(COMP_VL_STRS_FILE, "group", 1); @@ -3344,6 +3349,100 @@ out: /*------------------------------------------------------------------------- * +* Purpose: Create test files for excluding obj. +* Only one file contains unique objs. Common objs are same. +* Test : exclude unique objs to verify the rest are same +* - HDFFV-7837 +* +* Programmer: Jonathan Kim (Mar, 19, 2012) +* +*-------------------------------------------------------------------------*/ +static int test_exclude_obj3(const char *fname1, const char *fname2) +{ + hid_t fid1=0; + hid_t fid2=0; + hid_t gid1=0; + hsize_t dims2[2] = {2,4}; + int data1[4][2] = {{0,0},{0,0},{0,0},{0,0}}; + herr_t status = SUCCEED; + + /*----------------------------------------------------------------------- + * Create file(s) + *------------------------------------------------------------------------*/ + fid1 = H5Fcreate (fname1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid1 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname1); + status = FAIL; + goto out; + } + + fid2 = H5Fcreate (fname2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid2 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Group + *------------------------------------------------------------------------*/ + /* file1 */ + gid1 = H5Gcreate2(fid1, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + /*----------------------------------------------------------------------- + * Datasets + *------------------------------------------------------------------------*/ + /* file1 */ + status = write_dset(fid1,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid1,2,dims2,"dset",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + status = write_dset(fid2,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + +out: + /*----------------------------------------------------------------------- + * Close + *-----------------------------------------------------------------------*/ + if(fid1) + H5Fclose(fid1); + if(fid2) + H5Fclose(fid2); + if(gid1) + H5Gclose(gid1); + + return status; +} + +/*------------------------------------------------------------------------- +* * Purpose: Create test files for multiple variable length string/string array * along with fixed length string/string array types in * a compound type dataset. @@ -4717,7 +4816,6 @@ static void test_non_comparables (const char * fname, int make_diffs) int rank_attr; char data1_str[DIM_ARRY][STR_SIZE]= {"ab","cd","ef"}; herr_t status = SUCCEED; - int i; void *dset_data_ptr1=NULL; void *dset_data_ptr2=NULL; void *dset_data_ptr3=NULL; diff --git a/tools/h5diff/testfiles/h5diff_465.txt b/tools/h5diff/testfiles/h5diff_465.txt index 827e88e..eca5994 100644 --- a/tools/h5diff/testfiles/h5diff_465.txt +++ b/tools/h5diff/testfiles/h5diff_465.txt @@ -1,2 +1 @@ -1 differences found -EXIT CODE: 1 +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_466.txt b/tools/h5diff/testfiles/h5diff_466.txt new file mode 100644 index 0000000..3e00ca3 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_466.txt @@ -0,0 +1,5 @@ +obj1 </soft_link1> is a dangling link. +obj2 </soft_link1> is a dangling link. +dangling link: </soft_link1> and </soft_link1> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_467.txt b/tools/h5diff/testfiles/h5diff_467.txt new file mode 100644 index 0000000..f5195c0 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_467.txt @@ -0,0 +1,3 @@ +obj2 </soft_link2> is a dangling link. +1 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_468.txt b/tools/h5diff/testfiles/h5diff_468.txt new file mode 100644 index 0000000..75b16c6 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_468.txt @@ -0,0 +1,5 @@ +obj1 </ext_link4> is a dangling link. +obj2 </ext_link4> is a dangling link. +dangling link: </ext_link4> and </ext_link4> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_469.txt b/tools/h5diff/testfiles/h5diff_469.txt new file mode 100644 index 0000000..594fd80 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_469.txt @@ -0,0 +1,3 @@ +obj2 </ext_link2> is a dangling link. +1 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_485.txt b/tools/h5diff/testfiles/h5diff_485.txt new file mode 100644 index 0000000..4175809 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_485.txt @@ -0,0 +1,11 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + +group : </> and </> +0 differences found +dataset: </dset1> and </dset1> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_486.txt b/tools/h5diff/testfiles/h5diff_486.txt new file mode 100644 index 0000000..4175809 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_486.txt @@ -0,0 +1,11 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + +group : </> and </> +0 differences found +dataset: </dset1> and </dset1> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_487.txt b/tools/h5diff/testfiles/h5diff_487.txt new file mode 100644 index 0000000..8555a71 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_487.txt @@ -0,0 +1,12 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + x /group1 + +group : </> and </> +0 differences found +dataset: </dset1> and </dset1> +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_exclude3-1.h5 b/tools/h5diff/testfiles/h5diff_exclude3-1.h5 Binary files differnew file mode 100644 index 0000000..f9cc83d --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_exclude3-1.h5 diff --git a/tools/h5diff/testfiles/h5diff_exclude3-2.h5 b/tools/h5diff/testfiles/h5diff_exclude3-2.h5 Binary files differnew file mode 100644 index 0000000..f811905 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_exclude3-2.h5 diff --git a/tools/h5diff/testh5diff.sh b/tools/h5diff/testh5diff.sh index aa0f502..27fb253 100755 --- a/tools/h5diff/testh5diff.sh +++ b/tools/h5diff/testh5diff.sh @@ -111,6 +111,8 @@ $SRC_H5DIFF_TESTFILES/h5diff_exclude1-1.h5 $SRC_H5DIFF_TESTFILES/h5diff_exclude1-2.h5 $SRC_H5DIFF_TESTFILES/h5diff_exclude2-1.h5 $SRC_H5DIFF_TESTFILES/h5diff_exclude2-2.h5 +$SRC_H5DIFF_TESTFILES/h5diff_exclude3-1.h5 +$SRC_H5DIFF_TESTFILES/h5diff_exclude3-2.h5 $SRC_H5DIFF_TESTFILES/h5diff_comp_vl_strs.h5 $SRC_H5DIFF_TESTFILES/compounds_array_vlen1.h5 $SRC_H5DIFF_TESTFILES/compounds_array_vlen2.h5 @@ -201,6 +203,10 @@ $SRC_H5DIFF_TESTFILES/h5diff_457.txt $SRC_H5DIFF_TESTFILES/h5diff_458.txt $SRC_H5DIFF_TESTFILES/h5diff_459.txt $SRC_H5DIFF_TESTFILES/h5diff_465.txt +$SRC_H5DIFF_TESTFILES/h5diff_466.txt +$SRC_H5DIFF_TESTFILES/h5diff_467.txt +$SRC_H5DIFF_TESTFILES/h5diff_468.txt +$SRC_H5DIFF_TESTFILES/h5diff_469.txt $SRC_H5DIFF_TESTFILES/h5diff_480.txt $SRC_H5DIFF_TESTFILES/h5diff_481.txt $SRC_H5DIFF_TESTFILES/h5diff_482.txt @@ -943,6 +949,15 @@ TOOLTEST h5diff_459.txt --follow-symlinks -v --no-dangling-links h5diff_extlin # dangling link --follow-symlinks (obj vs obj) # (HDFFV-7836) TOOLTEST h5diff_465.txt --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1 +# (HDFFV-7835) +# soft dangling vs. soft dangling +TOOLTEST h5diff_466.txt -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link1 +# soft link vs. soft dangling +TOOLTEST h5diff_467.txt -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /soft_link2 +# ext dangling vs. ext dangling +TOOLTEST h5diff_468.txt -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_link4 +# ext link vs. ext dangling +TOOLTEST h5diff_469.txt -v --follow-symlinks h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 /ext_link2 # ############################################################################## # # test for group diff recursivly @@ -1014,6 +1029,15 @@ TOOLTEST h5diff_483.txt -v --exclude-path "/group1" h5diff_exclude2-1.h5 h5diff_ # Exclude from group compare TOOLTEST h5diff_484.txt -v --exclude-path "/dset3" h5diff_exclude1-1.h5 h5diff_exclude1-2.h5 /group1 +# +# Only one file contains unique objs. Common objs are same. +# (HDFFV-7837) +# +TOOLTEST h5diff_485.txt -v --exclude-path "/group1" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5 +TOOLTEST h5diff_486.txt -v --exclude-path "/group1" h5diff_exclude3-2.h5 h5diff_exclude3-1.h5 +TOOLTEST h5diff_487.txt -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5 + + # ############################################################################## # # diff various multiple vlen and fixed strings in a compound type dataset # ############################################################################## diff --git a/tools/h5dump/CMakeLists.txt b/tools/h5dump/CMakeLists.txt index a5432c4..a6e452d 100644 --- a/tools/h5dump/CMakeLists.txt +++ b/tools/h5dump/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5DUMP) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5dump executables @@ -128,6 +127,9 @@ IF (BUILD_TESTING) tlonglinks.ddl tloop-1.ddl tmulti.ddl + tmultifile.ddl +# tqmarkfile.ddl +# tstarfile.ddl tnamed_dtype_attr.ddl tnestcomp-1.ddl tnbit.ddl @@ -832,6 +834,12 @@ IF (BUILD_TESTING) tloop-1.out.err tmulti.out tmulti.out.err + tmultifile.out + tmultifile.out.err +# tqmarkfile.out +# tqmarkfile.out.err +# tstarfile.out +# tstarfile.out.err tnamed_dtype_attr.out tnamed_dtype_attr.out.err tnestcomp-1.out @@ -938,7 +946,7 @@ IF (BUILD_TESTING) # test for displaying attributes ADD_H5_TEST (tattr-1 0 --enable-error-stack tattr.h5) # test for displaying the selected attributes of string type and scalar space - ADD_H5_TEST (tattr-2 0 --enable-error-stack -a /attr1 --attribute /attr4 --attribute=/attr5 tattr.h5) + ADD_H5_TEST (tattr-2 0 --enable-error-stack -a /\\\\/attr1 --attribute /attr4 --attribute=/attr5 tattr.h5) # test for header and error messages ADD_H5_MASK_TEST (tattr-3 1 --enable-error-stack --header -a /attr2 --attribute=/attr tattr.h5) # test for displaying attributes in shared datatype (also in group and dataset) @@ -1015,6 +1023,11 @@ IF (BUILD_TESTING) ADD_H5_TEST (tarray7 0 --enable-error-stack tarray7.h5) ADD_H5_TEST (tarray8 0 --enable-error-stack tarray8.h5) + # test for wildcards in filename (does not work with cmake) + #ADD_H5_MASK_TEST (tstarfile 0 --enable-error-stack -H -d Dataset1 tarr*.h5) + #ADD_H5_MASK_TEST (tqmarkfile 0 --enable-error-stack -H -d Dataset1 tarray?.h5) + ADD_H5_TEST (tmultifile 0 --enable-error-stack -H -d Dataset1 tarray2.h5 tarray3.h5 tarray4.h5 tarray5.h5 tarray6.h5 tarray7.h5) + # test for files with empty data ADD_H5_TEST (tempty 0 --enable-error-stack tempty.h5) diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c index 64c5e7c..2799d95 100644 --- a/tools/h5dump/h5dump.c +++ b/tools/h5dump/h5dump.c @@ -231,7 +231,7 @@ static void usage(const char *prog) { HDfflush(rawoutstream); - HDfprintf(rawoutstream, "usage: %s [OPTIONS] file\n", prog); + HDfprintf(rawoutstream, "usage: %s [OPTIONS] files\n", prog); HDfprintf(rawoutstream, " OPTIONS\n"); HDfprintf(rawoutstream, " -h, --help Print a usage message and exit\n"); HDfprintf(rawoutstream, " -n, --contents Print a list of the file contents and exit\n"); @@ -243,6 +243,9 @@ usage(const char *prog) HDfprintf(rawoutstream, " -e, --escape Escape non printing characters\n"); HDfprintf(rawoutstream, " -V, --version Print version number and exit\n"); HDfprintf(rawoutstream, " -a P, --attribute=P Print the specified attribute\n"); + HDfprintf(rawoutstream, " If an attribute name contains a slash (/), escape the\n"); + HDfprintf(rawoutstream, " slash with a preceding backslash (\\).\n"); + HDfprintf(rawoutstream, " (See example section below.)\n"); HDfprintf(rawoutstream, " -d P, --dataset=P Print the specified dataset\n"); HDfprintf(rawoutstream, " -y, --noindex Do not print array indices with the data\n"); HDfprintf(rawoutstream, " -p, --properties Print dataset filters, storage layout and fill value\n"); @@ -316,6 +319,10 @@ usage(const char *prog) HDfprintf(rawoutstream, "\n"); HDfprintf(rawoutstream, " h5dump -a /bar_none/foo quux.h5\n"); HDfprintf(rawoutstream, "\n"); + HDfprintf(rawoutstream, " Attribute \"high/low\" of the group /bar_none in the file quux.h5\n"); + HDfprintf(rawoutstream, "\n"); + HDfprintf(rawoutstream, " h5dump -a \"/bar_none/high\\/low\" quux.h5\n"); + HDfprintf(rawoutstream, "\n"); HDfprintf(rawoutstream, " 2) Selecting a subset from dataset /foo in file quux.h5\n"); HDfprintf(rawoutstream, "\n"); HDfprintf(rawoutstream, " h5dump -d /foo -s \"0,1\" -S \"1,1\" -c \"2,3\" -k \"2,2\" quux.h5\n"); @@ -329,6 +336,10 @@ usage(const char *prog) HDfprintf(rawoutstream, "\n"); HDfprintf(rawoutstream, " h5dump -d /dset -M 0,1,4,3 quux.h5\n"); HDfprintf(rawoutstream, "\n"); + HDfprintf(rawoutstream, " 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5\n"); + HDfprintf(rawoutstream, "\n"); + HDfprintf(rawoutstream, " h5dump -d /foo multi1.h5 multi2.h5 multi3.h5\n"); + HDfprintf(rawoutstream, "\n"); } @@ -1369,11 +1380,13 @@ main(int argc, const char *argv[]) hid_t fid = -1; hid_t gid = -1; H5E_auto2_t func; + H5E_auto2_t tools_func; H5O_info_t oi; - struct handler_t *hand; + struct handler_t *hand = NULL; int i; unsigned u; void *edata; + void *tools_edata; char *fname = NULL; h5tools_setprogname(PROGRAMNAME); @@ -1388,6 +1401,10 @@ main(int argc, const char *argv[]) /* Initialize h5tools lib */ h5tools_init(); + /* Disable tools error reporting */ + H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata); + H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL); + if((hand = parse_command_line(argc, argv))==NULL) { goto done; } @@ -1398,8 +1415,10 @@ main(int argc, const char *argv[]) goto done; } - if (enable_error_stack) + if (enable_error_stack) { H5Eset_auto2(H5E_DEFAULT, func, edata); + H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata); + } /* Check for conflicting options */ if (doxml) { @@ -1442,169 +1461,186 @@ main(int argc, const char *argv[]) h5tools_setstatus(EXIT_FAILURE); goto done; } - fname = HDstrdup(argv[opt_ind]); + while(opt_ind < argc) { + fname = HDstrdup(argv[opt_ind++]); - fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0); + fid = h5tools_fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT, driver, NULL, 0); - if (fid < 0) { - error_msg("unable to open file \"%s\"\n", fname); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - - /* allocate and initialize internal data structure */ - init_prefix(&prefix, prefix_len); + if (fid < 0) { + error_msg("unable to open file \"%s\"\n", fname); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } - /* Prepare to find objects that might be targets of a reference */ - fill_ref_path_table(fid); + /* allocate and initialize internal data structure */ + init_prefix(&prefix, prefix_len); - if(doxml) { - /* initialize XML */ - /* reset prefix! */ - HDstrcpy(prefix, ""); + /* Prepare to find objects that might be targets of a reference */ + fill_ref_path_table(fid); - /* make sure the URI is initialized to something */ - if (xml_dtd_uri == NULL) { - if (useschema) { - xml_dtd_uri = DEFAULT_XSD; + if(doxml) { + /* initialize XML */ + /* reset prefix! */ + HDstrcpy(prefix, ""); + + /* make sure the URI is initialized to something */ + if (xml_dtd_uri == NULL) { + if (useschema) { + xml_dtd_uri = DEFAULT_XSD; + } + else { + xml_dtd_uri = DEFAULT_DTD; + xmlnsprefix = ""; + } } else { - xml_dtd_uri = DEFAULT_DTD; - xmlnsprefix = ""; - } - } - else { - if (useschema && HDstrcmp(xmlnsprefix,"")) { - error_msg("Cannot set Schema URL for a qualified namespace--use -X or -U option with -D \n"); - h5tools_setstatus(EXIT_FAILURE); - goto done; + if (useschema && HDstrcmp(xmlnsprefix,"")) { + error_msg("Cannot set Schema URL for a qualified namespace--use -X or -U option with -D \n"); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } } } - } - /* Get object info for root group */ - if(H5Oget_info_by_name(fid, "/", &oi, H5P_DEFAULT) < 0) { - error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - - /* Initialize object tables */ - if(table_list_add(fid, oi.fileno) < 0) { - error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } - group_table = table_list.tables[0].group_table; - dset_table = table_list.tables[0].dset_table; - type_table = table_list.tables[0].type_table; - - /* does there exist unamed committed datatype */ - for (u = 0; u < type_table->nobjs; u++) - if (!type_table->objs[u].recorded) { - unamedtype = 1; - break; - } /* end if */ + /* Get object info for root group */ + if(H5Oget_info_by_name(fid, "/", &oi, H5P_DEFAULT) < 0) { + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } - /* start to dump - display file header information */ - if (!doxml) { - begin_obj(h5tools_dump_header_format->filebegin, fname, h5tools_dump_header_format->fileblockbegin); - } - else { - HDfprintf(rawoutstream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + /* Initialize object tables */ + if(table_list_add(fid, oi.fileno) < 0) { + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + group_table = table_list.tables[0].group_table; + dset_table = table_list.tables[0].dset_table; + type_table = table_list.tables[0].type_table; + + /* does there exist unamed committed datatype */ + for (u = 0; u < type_table->nobjs; u++) + if (!type_table->objs[u].recorded) { + unamedtype = 1; + break; + } /* end if */ + + /* start to dump - display file header information */ + if (!doxml) { + begin_obj(h5tools_dump_header_format->filebegin, fname, h5tools_dump_header_format->fileblockbegin); + } + else { + HDfprintf(rawoutstream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); - /* alternative first element, depending on schema or DTD. */ - if (useschema) { - if (HDstrcmp(xmlnsprefix,"") == 0) { - HDfprintf(rawoutstream, "<HDF5-File xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"%s\">\n", - xml_dtd_uri); + /* alternative first element, depending on schema or DTD. */ + if (useschema) { + if (HDstrcmp(xmlnsprefix,"") == 0) { + HDfprintf(rawoutstream, "<HDF5-File xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"%s\">\n", + xml_dtd_uri); + } + else { + /* TO DO: make -url option work in this case (may need new option) */ + char *ns; + char *indx; + + ns = HDstrdup(xmlnsprefix); + indx = HDstrrchr(ns,(int)':'); + if (indx) *indx = '\0'; + + HDfprintf(rawoutstream, "<%sHDF5-File xmlns:%s=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xsi:schemaLocation=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File " + "http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd\">\n",xmlnsprefix,ns); + HDfree(ns); + } } else { -/* TO DO: make -url option work in this case (may need new option) */ - char *ns; - char *indx; - - ns = HDstrdup(xmlnsprefix); - indx = HDstrrchr(ns,(int)':'); - if (indx) *indx = '\0'; - - HDfprintf(rawoutstream, "<%sHDF5-File xmlns:%s=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File\" " - "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " - "xsi:schemaLocation=\"http://hdfgroup.org/HDF5/XML/schema/HDF5-File " - "http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd\">\n",xmlnsprefix,ns); - HDfree(ns); + HDfprintf(rawoutstream, "<!DOCTYPE HDF5-File PUBLIC \"HDF5-File.dtd\" \"%s\">\n", xml_dtd_uri); + HDfprintf(rawoutstream, "<HDF5-File>\n"); } - } - else { - HDfprintf(rawoutstream, "<!DOCTYPE HDF5-File PUBLIC \"HDF5-File.dtd\" \"%s\">\n", xml_dtd_uri); - HDfprintf(rawoutstream, "<HDF5-File>\n"); } - } - if (!doxml) { - if (display_fi) { - HDfprintf(rawoutstream, "\n"); - dump_fcontents(fid); - end_obj(h5tools_dump_header_format->fileend,h5tools_dump_header_format->fileblockend); - HDfprintf(rawoutstream, "\n"); - goto done; + if (!doxml) { + if (display_fi) { + HDfprintf(rawoutstream, "\n"); + dump_fcontents(fid); + end_obj(h5tools_dump_header_format->fileend,h5tools_dump_header_format->fileblockend); + HDfprintf(rawoutstream, "\n"); + goto done; + } + + if (display_bb) + dump_fcpl(fid); } - if (display_bb) - dump_fcpl(fid); - } + if(display_all) { + if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) { + error_msg("unable to open root group\n"); + h5tools_setstatus(EXIT_FAILURE); + } + else { + if (!doxml) + dump_indent += COL; + dump_function_table->dump_group_function(gid, "/" ); + if (!doxml) + dump_indent -= COL; + HDfprintf(rawoutstream, "\n"); + } + + if(H5Gclose(gid) < 0) { + error_msg("unable to close root group\n"); + h5tools_setstatus(EXIT_FAILURE); + } - if(display_all) { - if((gid = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) { - error_msg("unable to open root group\n"); - h5tools_setstatus(EXIT_FAILURE); } else { - if (!doxml) - dump_indent += COL; - dump_function_table->dump_group_function(gid, "/" ); - if (!doxml) - dump_indent -= COL; + /* Note: this option is not supported for XML */ + if(doxml) { + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } /* end if */ + + for(i = 0; i < argc; i++) { + if(hand[i].func) { + hand[i].func(fid, hand[i].obj, hand[i].subset_info, 1, NULL); + } + } HDfprintf(rawoutstream, "\n"); } - if(H5Gclose(gid) < 0) { - error_msg("unable to close root group\n"); - h5tools_setstatus(EXIT_FAILURE); + if (!doxml) { + end_obj(h5tools_dump_header_format->fileend, h5tools_dump_header_format->fileblockend); + HDfprintf(rawoutstream, "\n"); + } + else { + HDfprintf(rawoutstream, "</%sHDF5-File>\n", xmlnsprefix); } + /* Free tables for objects */ + table_list_free(); - } - else { - /* Note: this option is not supported for XML */ - if(doxml) { - error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); - h5tools_setstatus(EXIT_FAILURE); - goto done; - } /* end if */ + if(fid >=0) + if (H5Fclose(fid) < 0) + h5tools_setstatus(EXIT_FAILURE); - for(i = 0; i < argc; i++) { - if(hand[i].func) { - hand[i].func(fid, hand[i].obj, hand[i].subset_info, 1, NULL); - } - } - HDfprintf(rawoutstream, "\n"); - } + if(prefix) + HDfree(prefix); + if(fname) + HDfree(fname); + } /* end while */ - if (!doxml) { - end_obj(h5tools_dump_header_format->fileend, h5tools_dump_header_format->fileblockend); - HDfprintf(rawoutstream, "\n"); - } - else { - HDfprintf(rawoutstream, "</%sHDF5-File>\n", xmlnsprefix); - } + if(hand) + free_handler(hand, argc); + + /* To Do: clean up XML table */ + + leave(h5tools_getstatus()); done: /* Free tables for objects */ table_list_free(); - if(hand) - free_handler(hand, argc); - if(fid >=0) if (H5Fclose(fid) < 0) h5tools_setstatus(EXIT_FAILURE); @@ -1614,6 +1650,9 @@ done: if(fname) HDfree(fname); + if(hand) + free_handler(hand, argc); + /* To Do: clean up XML table */ H5Eset_auto2(H5E_DEFAULT, func, edata); diff --git a/tools/h5dump/h5dump_ddl.c b/tools/h5dump/h5dump_ddl.c index be56c9b..b8deaf9 100644 --- a/tools/h5dump/h5dump_ddl.c +++ b/tools/h5dump/h5dump_ddl.c @@ -1322,7 +1322,7 @@ handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe hid_t oid = -1; hid_t attr_id = -1; char *obj_name; - const char *attr_name; + char *attr_name; int j; h5tools_str_t buffer; /* string into which to render */ h5tools_context_t ctx; /* print context */ @@ -1337,7 +1337,7 @@ handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe /* find the last / */ while(j >= 0) { - if (attr[j] == '/') + if (attr[j] == '/' && (j==0 || (j>0 && attr[j-1]!='\\'))) break; j--; } @@ -1372,9 +1372,12 @@ handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe string_dataformat.do_escape = display_escape; outputformat = &string_dataformat; - attr_name = attr + j + 1; + //attr_name = attr + j + 1; + // need to replace escape characters + attr_name = h5tools_str_replace(attr + j + 1, "\\/", "/"); - /* Open the object with the attribute */ + + /* handle error case: cannot open the object with the attribute */ if((oid = H5Oopen(fid, obj_name, H5P_DEFAULT)) < 0) { /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); @@ -1415,7 +1418,7 @@ handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe attr_data_output = display_attr_data; h5dump_type_table = type_table; - h5tools_dump_attribute(rawoutstream, outputformat, &ctx, oid, attr, attr_id, display_ai, display_char); + h5tools_dump_attribute(rawoutstream, outputformat, &ctx, oid, attr_name, attr_id, display_ai, display_char); h5dump_type_table = NULL; if(attr_id < 0) { @@ -1428,6 +1431,7 @@ handle_attributes(hid_t fid, const char *attr, void UNUSED * data, int UNUSED pe } /* end if */ HDfree(obj_name); + HDfree(attr_name); dump_indent -= COL; return; @@ -1435,6 +1439,9 @@ error: h5tools_setstatus(EXIT_FAILURE); if(obj_name) HDfree(obj_name); + + if (attr_name) + HDfree(attr_name); H5E_BEGIN_TRY { H5Oclose(oid); diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index 5b97434..b28f3de 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -426,7 +426,7 @@ gent_attribute(void) /* attribute 1 */ dims[0] = 24; space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(root, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); + attr = H5Acreate2(root, "/attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); sprintf(buf, "attribute of root group"); H5Awrite(attr, H5T_NATIVE_SCHAR, buf); H5Sclose(space); diff --git a/tools/h5dump/testh5dump.sh.in b/tools/h5dump/testh5dump.sh.in index 1141cf7..25a30c5 100644 --- a/tools/h5dump/testh5dump.sh.in +++ b/tools/h5dump/testh5dump.sh.in @@ -50,6 +50,7 @@ if test -z "$srcdir"; then fi # source dirs SRC_TOOLS="$srcdir/../" + SRC_TOOLS_TESTFILES="$SRC_TOOLS/testfiles" # testfiles source dirs for tools SRC_H5LS_TESTFILES="$SRC_TOOLS_TESTFILES" @@ -244,6 +245,9 @@ $SRC_H5DUMP_TESTFILES/tlarge_objname.ddl $SRC_H5DUMP_TESTFILES/tlonglinks.ddl $SRC_H5DUMP_TESTFILES/tloop-1.ddl $SRC_H5DUMP_TESTFILES/tmulti.ddl +$SRC_H5DUMP_TESTFILES/tmultifile.ddl +$SRC_H5DUMP_TESTFILES/tqmarkfile.ddl +$SRC_H5DUMP_TESTFILES/tstarfile.ddl $SRC_H5DUMP_TESTFILES/tnamed_dtype_attr.ddl $SRC_H5DUMP_TESTFILES/tnestcomp-1.ddl $SRC_H5DUMP_TESTFILES/tnbit.ddl @@ -718,7 +722,7 @@ TOOLTEST3 tdset-2.ddl --enable-error-stack -H -d dset1 -d /dset2 --dataset=dset3 # test for displaying attributes TOOLTEST tattr-1.ddl --enable-error-stack tattr.h5 # test for displaying the selected attributes of string type and scalar space -TOOLTEST tattr-2.ddl --enable-error-stack -a /attr1 --attribute /attr4 --attribute=/attr5 tattr.h5 +TOOLTEST tattr-2.ddl --enable-error-stack -a "/\/attr1" --attribute /attr4 --attribute=/attr5 tattr.h5 # test for header and error messages TOOLTEST3 tattr-3.ddl --enable-error-stack --header -a /attr2 --attribute=/attr tattr.h5 # test for displaying at least 9 attributes on root from a BE machine @@ -794,6 +798,11 @@ TOOLTEST tarray6.ddl --enable-error-stack tarray6.h5 TOOLTEST tarray7.ddl --enable-error-stack tarray7.h5 TOOLTEST tarray8.ddl --enable-error-stack tarray8.h5 +# test for wildcards in filename (does not work with cmake) +# inconsistent across platforms TOOLTEST3 tstarfile.ddl --enable-error-stack -H -d Dataset1 tarr*.h5 +TOOLTEST3 tqmarkfile.ddl --enable-error-stack -H -d Dataset1 tarray?.h5 +TOOLTEST tmultifile.ddl --enable-error-stack -H -d Dataset1 tarray2.h5 tarray3.h5 tarray4.h5 tarray5.h5 tarray6.h5 tarray7.h5 + # test for files with empty data TOOLTEST tempty.ddl --enable-error-stack tempty.h5 diff --git a/tools/h5import/CMakeLists.txt b/tools/h5import/CMakeLists.txt index bb8de26..76dcf26 100644 --- a/tools/h5import/CMakeLists.txt +++ b/tools/h5import/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5IMPORT) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5import executables diff --git a/tools/h5jam/CMakeLists.txt b/tools/h5jam/CMakeLists.txt index 9a74ebc..a03d139 100644 --- a/tools/h5jam/CMakeLists.txt +++ b/tools/h5jam/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5JAM) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5jam executables diff --git a/tools/h5ls/CMakeLists.txt b/tools/h5ls/CMakeLists.txt index ad37da0..0dec21c 100644 --- a/tools/h5ls/CMakeLists.txt +++ b/tools/h5ls/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5LS) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) #----------------------------------------------------------------------------- # Add the h5ls executable @@ -29,111 +28,105 @@ IF (BUILD_TESTING) # -------------------------------------------------------------------- # Copy all the test files from source directory to test directory # -------------------------------------------------------------------- - SET (LIST_EXPECT_OUTPUT_FILES - help-1.ls - help-2.ls - help-3.ls - nosuchfile.ls - tall-1.ls - tall-2.ls - tarray1.ls - tattr2.ls - tattrreg_le.ls - tattrreg_be.ls - tcomp-1.ls - tdataregbe.ls - tdataregle.ls - tdset-1.ls - tempty.ls - textlink-1.ls - textlinksrc-1.ls - textlinksrc-2.ls - textlinksrc-3.ls - textlinksrc-4.ls - textlinksrc-5.ls - textlinksrc-6.ls - textlinksrc-7.ls - textlinksrc-1-old.ls - textlinksrc-2-old.ls - textlinksrc-3-old.ls - textlinksrc-6-old.ls - textlinksrc-7-old.ls - tsoftlinks-1.ls - tsoftlinks-2.ls - tsoftlinks-3.ls - tsoftlinks-4.ls - tsoftlinks-5.ls - textlinksrc-nodangle-1.ls - textlinksrc-nodangle-2.ls - tgrp_comments.ls - tsoftlinks-nodangle-1.ls - thlinks-nodangle-1.ls - tgroup.ls - tgroup-1.ls - tgroup-2.ls - tgroup-3.ls - thlink-1.ls - tloop-1.ls - tnestcomp-1.ls - tnestcomp-2.ls - tnestcomp-3.ls - tnestcomp-4.ls - tsaf.ls - tslink-1.ls - tstr-1.ls - tudlink-1.ls - tvldtypes1.ls - tvldtypes2le.ls - tvldtypes2be.ls - ) SET (LIST_HDF5_TEST_FILES - tall.h5 - tarray1.h5 - tattr2.h5 - tattrreg.h5 - tcompound.h5 - tdatareg.h5 - tdset.h5 - tempty.h5 - textlink.h5 - textlinksrc.h5 - textlinktar.h5 - tgroup.h5 - tgrp_comments.h5 - thlink.h5 - tloop.h5 - tnestedcomp.h5 - tsaf.h5 - tslink.h5 - tsoftlinks.h5 - tstr.h5 - tudlink.h5 - tvldtypes1.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tall.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tarray1.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tattr2.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tattrreg.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tcompound.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tdatareg.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tdset.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tempty.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlink.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinktar.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgroup.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgrp_comments.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/thlink.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tloop.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tnestedcomp.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsaf.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tslink.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tstr.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tudlink.h5 + ${HDF5_TOOLS_SRC_DIR}/testfiles/tvldtypes1.h5 ) - # copy the list of expected output files - FOREACH (out_file ${LIST_EXPECT_OUTPUT_FILES}) - SET (out_dest "${PROJECT_BINARY_DIR}/${out_file}") - #MESSAGE (STATUS " Translating ${out_file}") - ADD_CUSTOM_COMMAND ( - TARGET h5ls - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different ${HDF5_TOOLS_SRC_DIR}/testfiles/${out_file} ${out_dest} - ) - ENDFOREACH (out_file ${LIST_EXPECT_OUTPUT_FILES}) + SET (LIST_OTHER_TEST_FILES + ${HDF5_TOOLS_SRC_DIR}/testfiles/help-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/help-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/help-3.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/nosuchfile.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tall-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tall-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tarray1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tattr2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tattrreg_le.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tattrreg_be.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tcomp-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tdataregbe.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tdataregle.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tdset-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tempty.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlink-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-3.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-4.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-5.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-6.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-7.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-1-old.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-2-old.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-3-old.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-6-old.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-7-old.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-3.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-4.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-5.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-nodangle-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/textlinksrc-nodangle-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgrp_comments.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsoftlinks-nodangle-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/thlinks-nodangle-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgroup.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgroup-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgroup-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tgroup-3.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/thlink-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tloop-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tmultifile.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tnestcomp-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tnestcomp-2.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tnestcomp-3.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tnestcomp-4.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tsaf.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tslink-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tstr-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tudlink-1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tvldtypes1.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tvldtypes2le.ls + ${HDF5_TOOLS_SRC_DIR}/testfiles/tvldtypes2be.ls + ) + + FILE (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - # copy the list of hdf5 test files - FOREACH (h5_file ${LIST_HDF5_TEST_FILES}) - SET (h5_dest "${PROJECT_BINARY_DIR}/${h5_file}") - #MESSAGE (STATUS " Copying ${h5_file}") + # copy the list of test files + FOREACH (listfiles ${LIST_HDF5_TEST_FILES} ${LIST_OTHER_TEST_FILES}) + GET_FILENAME_COMPONENT(fname "${listfiles}" NAME) + SET (dest "${PROJECT_BINARY_DIR}/testfiles/${fname}") + #MESSAGE (STATUS " Copying ${listfiles} to ${dest}") ADD_CUSTOM_COMMAND ( TARGET h5ls POST_BUILD COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different ${HDF5_TOOLS_SRC_DIR}/testfiles/${h5_file} ${h5_dest} + ARGS -E copy_if_different ${listfiles} ${dest} ) - ENDFOREACH (h5_file ${LIST_HDF5_TEST_FILES}) + ENDFOREACH (listfiles ${LIST_HDF5_TEST_FILES} ${LIST_OTHER_TEST_FILES}) + ############################################################################## ############################################################################## @@ -145,6 +138,7 @@ IF (BUILD_TESTING) # If using memchecker add tests without using scripts IF (HDF5_ENABLE_USING_MEMCHECKER) ADD_TEST (NAME H5LS-${resultfile} COMMAND $<TARGET_FILE:h5ls> ${ARGN}) + SET_TESTS_PROPERTIES (H5LS-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") IF (${resultcode} STREQUAL "1") SET_TESTS_PROPERTIES (H5LS-${resultfile} PROPERTIES WILL_FAIL "true") ENDIF (${resultcode} STREQUAL "1") @@ -156,14 +150,14 @@ IF (BUILD_TESTING) ADD_TEST ( NAME H5LS-clear-${resultfile}-objects COMMAND ${CMAKE_COMMAND} - -E remove ${resultfile}.out ${resultfile}.out.err + -E remove ./testfiles/${resultfile}.out ./testfiles/${resultfile}.out.err ) ADD_TEST ( NAME H5LS-${resultfile} COMMAND "${CMAKE_COMMAND}" -D "TEST_PROGRAM=$<TARGET_FILE:h5ls>" -D "TEST_ARGS=${ARGN}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" -D "TEST_OUTPUT=${resultfile}.out" -D "TEST_EXPECT=${resultcode}" -D "TEST_REFERENCE=${resultfile}.ls" @@ -361,6 +355,11 @@ IF (BUILD_TESTING) # when used file with no dangling links - expected exit code 0 ADD_H5_TEST (thlinks-nodangle-1 0 -w80 --follow-symlinks --no-dangling-links thlink.h5) +# test for wildcards in filename (does not work with cmake) +# ADD_H5_TEST (tstarfile 0 -w80 t*link.h5) +# ADD_H5_TEST (tqmarkfile 0 -w80 t?link.h5) + ADD_H5_TEST (tmultifile 0 -w80 thlink.h5 tslink.h5) + # tests for hard links ADD_H5_TEST (thlink-1 0 -w80 thlink.h5) diff --git a/tools/h5ls/testh5ls.sh.in b/tools/h5ls/testh5ls.sh.in index e2c204b..110c651 100644 --- a/tools/h5ls/testh5ls.sh.in +++ b/tools/h5ls/testh5ls.sh.in @@ -25,13 +25,13 @@ H5LS_BIN=`pwd`/$H5LS # The path of the tool binary CMP='cmp -s' DIFF='diff -c' CP='cp' -NLINES=20 # Max. lines of output to display if test fails +NLINES=20 # Max. lines of output to display if test fails WORDS_BIGENDIAN="@WORDS_BIGENDIAN@" nerrors=0 verbose=yes -h5haveexitcode=yes # default is yes +h5haveexitcode=yes # default is yes # The build (current) directory might be different than the source directory. if test -z "$srcdir"; then srcdir=. @@ -131,6 +131,7 @@ $SRC_H5LS_TESTFILES/tgroup-2.ls $SRC_H5LS_TESTFILES/tgroup-3.ls $SRC_H5LS_TESTFILES/thlink-1.ls $SRC_H5LS_TESTFILES/tloop-1.ls +$SRC_H5LS_TESTFILES/tmultifile.ls $SRC_H5LS_TESTFILES/tnestcomp-1.ls $SRC_H5LS_TESTFILES/tnestcomp-2.ls $SRC_H5LS_TESTFILES/tnestcomp-3.ls @@ -322,6 +323,11 @@ TOOLTEST tsoftlinks-nodangle-1.ls 1 -w80 --follow-symlinks --no-dangling-links t # when used file with no dangling links - expected exit code 0 TOOLTEST thlinks-nodangle-1.ls 0 -w80 --follow-symlinks --no-dangling-links thlink.h5 +# test for wildcards in filename (does not work with cmake) +# this h5ls test script does not pass the filename properly like the h5dump test script??? +#TOOLTEST tstarfile.ls 0 -w80 t*link.h5 +#TOOLTEST tqmarkfile.ls 0 -w80 t?link.h5 +TOOLTEST tmultifile.ls 0 -w80 thlink.h5 tslink.h5 # tests for hard links TOOLTEST thlink-1.ls 0 -w80 thlink.h5 diff --git a/tools/h5stat/CMakeLists.txt b/tools/h5stat/CMakeLists.txt index b0984a6..8c621c9 100644 --- a/tools/h5stat/CMakeLists.txt +++ b/tools/h5stat/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_H5STAT) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the h5stat executables diff --git a/tools/lib/CMakeLists.txt b/tools/lib/CMakeLists.txt index a75596d..837a14e 100644 --- a/tools/lib/CMakeLists.txt +++ b/tools/lib/CMakeLists.txt @@ -4,8 +4,6 @@ PROJECT (HDF5_TOOLS_LIB) #----------------------------------------------------------------------------- # Define Sources #----------------------------------------------------------------------------- -#INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -#INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) SET (H5_TOOLS_LIB_SRCS ${HDF5_TOOLS_LIB_SOURCE_DIR}/h5diff.c diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index bc8acd5..cef30dd 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -270,12 +270,12 @@ static int is_exclude_path (char * path, h5trav_type_t type, diff_opt_t *options /* search objects in exclude list */ while (NULL != exclude_path_ptr) { - /* if given object is group, exclude its members as well */ + /* if exclude path is is group, exclude its members as well */ if (exclude_path_ptr->obj_type == H5TRAV_TYPE_GROUP) { ret_cmp = HDstrncmp(exclude_path_ptr->obj_path, path, HDstrlen(exclude_path_ptr->obj_path)); - if (ret_cmp == 0) + if (ret_cmp == 0) /* found matching members */ { /* check if given path belong to an excluding group, if so * exclude it as well. @@ -295,12 +295,13 @@ static int is_exclude_path (char * path, h5trav_type_t type, diff_opt_t *options else { ret_cmp = HDstrcmp(exclude_path_ptr->obj_path, path); - if (ret_cmp == 0) + if (ret_cmp == 0) /* found matching object */ { /* excluded non-group object */ ret = 1; - /* assign type as scan progress, which is sufficient to - * determine type for excluding groups from the above if. */ + /* remember the type of this maching object. + * if it's group, it can be used for excluding its member + * objects in this while() loop */ exclude_path_ptr->obj_type = type; break; /* while */ } @@ -443,9 +444,11 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch infile[1] = 0; while(curr1 < info1->nused) { + path1_lp = (info1->paths[curr1].path) + path1_offset; + type1_l = info1->paths[curr1].type; + if(!is_exclude_path(path1_lp, type1_l, options)) { - path1_lp = (info1->paths[curr1].path) + path1_offset; trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); } curr1++; @@ -456,9 +459,11 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch infile[1] = 1; while(curr2 < info2->nused) { + path2_lp = (info2->paths[curr2].path) + path2_offset; + type2_l = info2->paths[curr2].type; + if (!is_exclude_path(path2_lp, type2_l, options)) { - path2_lp = (info2->paths[curr2].path) + path2_offset; trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); } curr2++; @@ -644,8 +649,8 @@ hsize_t h5diff(const char *fname1, char filenames[2][MAX_FILENAME]; hsize_t nfound = 0; int i; - //int i1, i2; - int l_ret; + int l_ret1 = -1; + int l_ret2 = -1; const char * obj1fullname = NULL; const char * obj2fullname = NULL; /* init to group type */ @@ -862,6 +867,10 @@ hsize_t h5diff(const char *fname1, } + /* get any symbolic links info */ + l_ret1 = H5tools_get_symlink_info(file1_id, obj1fullname, &trg_linfo1, TRUE); + l_ret2 = H5tools_get_symlink_info(file2_id, obj2fullname, &trg_linfo2, TRUE); + /*--------------------------------------------- * check for following symlinks */ @@ -874,13 +883,12 @@ hsize_t h5diff(const char *fname1, /*------------------------------- * check symbolic link (object1) */ - l_ret = H5tools_get_symlink_info(file1_id, obj1fullname, &trg_linfo1, TRUE); /* dangling link */ - if (l_ret == 0) + if (l_ret1 == 0) { if (options->no_dangle_links) { - /* gangling link is error */ + /* treat dangling link is error */ if(options->m_verbose) parallel_print("Warning: <%s> is a dangling link.\n", obj1fullname); options->err_stat = 1; @@ -890,30 +898,33 @@ hsize_t h5diff(const char *fname1, { if(options->m_verbose) parallel_print("obj1 <%s> is a dangling link.\n", obj1fullname); - nfound++; - print_found(nfound); - goto out; + if (l_ret1 != 0 || l_ret2 != 0) + { + nfound++; + print_found(nfound); + goto out; + } } } - else if(l_ret < 0) /* fail */ + else if(l_ret1 < 0) /* fail */ { parallel_print ("Object <%s> could not be found in <%s>\n", obj1fullname, fname1); options->err_stat = 1; goto out; } - else if(l_ret != 2) /* symbolic link */ + else if(l_ret1 != 2) /* symbolic link */ obj1type = trg_linfo1.trg_type; /*------------------------------- * check symbolic link (object2) */ - l_ret = H5tools_get_symlink_info(file2_id, obj2fullname, &trg_linfo2, TRUE); + /* dangling link */ - if (l_ret == 0) + if (l_ret2 == 0) { if (options->no_dangle_links) { - /* gangling link is error */ + /* treat dangling link is error */ if(options->m_verbose) parallel_print("Warning: <%s> is a dangling link.\n", obj2fullname); options->err_stat = 1; @@ -923,18 +934,21 @@ hsize_t h5diff(const char *fname1, { if(options->m_verbose) parallel_print("obj2 <%s> is a dangling link.\n", obj2fullname); - nfound++; - print_found(nfound); - goto out; + if (l_ret1 != 0 || l_ret2 != 0) + { + nfound++; + print_found(nfound); + goto out; + } } } - else if(l_ret < 0) /* fail */ + else if(l_ret2 < 0) /* fail */ { parallel_print ("Object <%s> could not be found in <%s>\n", obj2fullname, fname2); options->err_stat = 1; goto out; } - else if(l_ret != 2) /* symbolic link */ + else if(l_ret2 != 2) /* symbolic link */ obj2type = trg_linfo2.trg_type; } /* end of if follow symlinks */ @@ -947,8 +961,10 @@ hsize_t h5diff(const char *fname1, if(!(options->m_verbose || options->m_report)) { - if (h5tools_is_obj_same(file1_id,obj1fullname,file2_id,obj2fullname)!=0) - goto out; + /* if no danglink links */ + if ( l_ret1 > 0 && l_ret2 > 0 ) + if (h5tools_is_obj_same(file1_id,obj1fullname,file2_id,obj2fullname)!=0) + goto out; } diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index 30b8f33..17639bc 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -35,6 +35,7 @@ #define ALIGN(A,Z) ((((A) + (Z) - 1) / (Z)) * (Z)) /* global variables */ +hid_t H5tools_ERR_STACK_g = 0; hid_t H5tools_ERR_CLS_g = -1; hid_t H5E_tools_g = -1; hid_t H5E_tools_min_id_g = -1; @@ -115,6 +116,7 @@ h5tools_init(void) /* register the error class */ HDsnprintf(lib_str, sizeof(lib_str), "%d.%d.%d",H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); + H5tools_ERR_STACK_g = H5Ecreate_stack(); H5TOOLS_INIT_ERROR() if (!rawdatastream) @@ -149,7 +151,12 @@ h5tools_init(void) void h5tools_close(void) { + H5E_auto2_t tools_func; + void *tools_edata; if (h5tools_init_g) { + H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata); + if(tools_func!=NULL) + H5Eprint2(H5tools_ERR_STACK_g, rawerrorstream); if (rawdatastream && rawdatastream != stdout) { if (fclose(rawdatastream)) perror("closing rawdatastream"); @@ -173,7 +180,7 @@ h5tools_close(void) term_ref_path_table(); H5TOOLS_CLOSE_ERROR() - + H5Eclose_stack(H5tools_ERR_STACK_g); /* Shut down the library */ H5close(); diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index 2a2267e..9188225 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -232,8 +232,8 @@ h5tools_dump_init(void) * indicates whether the data supplied in this call falls at the * beginning or end of the total data to be printed (START_OF_DATA and * END_OF_DATA). - * Return: - * None + * Return: Success: SUCCEED + * Failure: FAIL * Programmer: * Robb Matzke, Monday, April 26, 1999 * Modifications: @@ -256,11 +256,12 @@ h5tools_dump_init(void) * new field sm_pos in h5tools_context_t, the current stripmine element position *------------------------------------------------------------------------- */ -void +int h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, h5tools_context_t *ctx/*in,out*/, unsigned flags, hsize_t nelmts, hid_t type, void *_mem) { + HERR_INIT(int, SUCCEED) unsigned char *mem = (unsigned char*) _mem; hsize_t i; /*element counter */ size_t size; /*size of each datum */ @@ -357,8 +358,10 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Dclose failed"); } /* if (region_id >= 0) */ - else - HERROR(H5E_tools_g, H5E_tools_min_id_g, "H5Rdereference failed"); + else { + /* if (region_id < 0) - could mean that no reference was written do not throw failure */ + H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, H5E_tools_g, H5E_tools_min_id_g, "H5Rdereference failed"); + } ctx->need_prefix = TRUE; @@ -386,6 +389,9 @@ h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t contai h5tools_str_close(&buffer); }/* else bin */ + +CATCH + return ret_value; } /*------------------------------------------------------------------------- @@ -1226,7 +1232,8 @@ h5tools_print_simple_subset(FILE *stream, const h5tool_format_t *info, h5tools_c ctx->need_prefix = TRUE; - h5tools_dump_simple_data(stream, info, dset, ctx, flags, sm_nelmts, p_type, sm_buf); + if(h5tools_dump_simple_data(stream, info, dset, ctx, flags, sm_nelmts, p_type, sm_buf) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "h5tools_dump_simple_data failed"); /* Reclaim any VL memory, if necessary */ if (vl_data) @@ -1484,7 +1491,8 @@ static int h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, hid_t dset, hid_t p_type) { - hid_t f_space; /* file data space */ + HERR_INIT(herr_t, SUCCEED) + hid_t f_space = -1; /* file data space */ hsize_t elmtno; /* counter */ size_t i; /* counter */ int carry; /* counter carry value */ @@ -1501,7 +1509,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont hsize_t sm_nbytes; /* bytes per stripmine */ hsize_t sm_nelmts; /* elements per stripmine*/ unsigned char *sm_buf = NULL; /* buffer for raw data */ - hid_t sm_space; /* stripmine data space */ + hid_t sm_space = -1; /* stripmine data space */ /* Hyperslab info */ hsize_t hs_offset[H5S_MAX_RANK]; /* starting offset */ @@ -1514,13 +1522,12 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont f_space = H5Dget_space(dset); if (f_space == FAIL) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Dget_space failed"); ctx->ndims = H5Sget_simple_extent_ndims(f_space); if ((size_t)ctx->ndims > NELMTS(sm_size)) { - H5Sclose(f_space); - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "ctx->ndims > NELMTS(sm_size) failed"); } /* Assume entire data space to be printed */ @@ -1542,9 +1549,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont ctx->size_last_dim = 0; if (p_nelmts == 0) { - /* nothing to print */ - H5Sclose(f_space); - return SUCCEED; + H5_LEAVE(SUCCEED); /* nothing to print */ } /* Check if we have VL data in the dataset's datatype */ @@ -1606,10 +1611,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont /* Read the data */ if (H5Dread(dset, p_type, sm_space, f_space, H5P_DEFAULT, sm_buf) < 0) { - H5Sclose(f_space); - H5Sclose(sm_space); - HDfree(sm_buf); - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "H5Dread failed"); } /* Print the data */ @@ -1620,7 +1622,8 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont indices */ ctx->sm_pos = elmtno; - h5tools_dump_simple_data(stream, info, dset, ctx, flags, hs_nelmts, p_type, sm_buf); + if(h5tools_dump_simple_data(stream, info, dset, ctx, flags, hs_nelmts, p_type, sm_buf) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "h5tools_dump_simple_data failed"); /* Reclaim any VL memory, if necessary */ if (vl_data) @@ -1640,13 +1643,17 @@ h5tools_dump_simple_dset(FILE *stream, const h5tool_format_t *info, h5tools_cont ctx->continuation++; } - HDfree(sm_buf); +CATCH + if(sm_buf) + HDfree(sm_buf); done: - H5Sclose(sm_space); - H5Sclose(f_space); + if(sm_space >= 0 && H5Sclose(sm_space) < 0) + H5E_THROW(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); + if(f_space >= 0 && H5Sclose(f_space) < 0) + H5E_THROW(H5E_tools_g, H5E_tools_min_id_g, "H5Sclose failed"); - return SUCCEED; + return ret_value; } /*------------------------------------------------------------------------- @@ -1664,13 +1671,14 @@ static int h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx, hid_t obj_id, hid_t type, hid_t space, void *mem) { + HERR_INIT(herr_t, SUCCEED) int i; /*counters */ hsize_t nelmts; /*total selected elmts */ ctx->ndims = H5Sget_simple_extent_ndims(space); if ((size_t) ctx->ndims > NELMTS(ctx->p_min_idx)) - return FAIL; + H5E_THROW(FAIL, H5E_tools_min_id_g, "ctx->ndims > NELMTS(ctx->p_min_idx) failed"); /* Assume entire data space to be printed */ for (i = 0; i < ctx->ndims; i++) @@ -1682,7 +1690,7 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, h5tools_conte nelmts *= ctx->p_max_idx[i] - ctx->p_min_idx[i]; if (nelmts == 0) - return SUCCEED; /*nothing to print*/ + H5_LEAVE(SUCCEED); /* nothing to print */ if (ctx->ndims > 0) { HDassert(ctx->p_max_idx[ctx->ndims - 1] == (hsize_t) ((int) ctx->p_max_idx[ctx->ndims - 1])); ctx->size_last_dim = (int) (ctx->p_max_idx[ctx->ndims - 1]); @@ -1693,9 +1701,11 @@ h5tools_dump_simple_mem(FILE *stream, const h5tool_format_t *info, h5tools_conte if (ctx->ndims > 0) init_acc_pos(ctx, ctx->p_max_idx); - h5tools_dump_simple_data(stream, info, obj_id, ctx, START_OF_DATA | END_OF_DATA, nelmts, type, mem); + if(h5tools_dump_simple_data(stream, info, obj_id, ctx, START_OF_DATA | END_OF_DATA, nelmts, type, mem) < 0) + HERROR(H5E_tools_g, H5E_tools_min_id_g, "h5tools_dump_simple_data failed"); - return SUCCEED; +CATCH + return ret_value; } /*------------------------------------------------------------------------- diff --git a/tools/lib/h5tools_dump.h b/tools/lib/h5tools_dump.h index c94d0e1..55e046b 100644 --- a/tools/lib/h5tools_dump.h +++ b/tools/lib/h5tools_dump.h @@ -44,10 +44,10 @@ H5TOOLS_DLL int h5tools_dump_dset(FILE *stream, const h5tool_format_t *info, H5TOOLS_DLL int h5tools_dump_mem(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, hid_t obj_id, hid_t type, hid_t space, void *mem); -H5TOOLS_DLL void h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, +H5TOOLS_DLL int h5tools_dump_simple_data(FILE *stream, const h5tool_format_t *info, hid_t container, h5tools_context_t *ctx/*in,out*/, unsigned flags, hsize_t nelmts, hid_t type, void *_mem); -H5TOOLS_DLL void h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, +H5TOOLS_DLL void h5tools_dump_datatype(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, hid_t type); H5TOOLS_DLL void h5tools_dump_dataspace(FILE *stream, const h5tool_format_t *info, h5tools_context_t *ctx/*in,out*/, hid_t space); diff --git a/tools/lib/h5tools_error.h b/tools/lib/h5tools_error.h index 207218e..ae549fd 100644 --- a/tools/lib/h5tools_error.h +++ b/tools/lib/h5tools_error.h @@ -22,6 +22,7 @@ #include "H5Epublic.h" /* tools-HDF5 Error variables */ +H5TOOLS_DLLVAR hid_t H5tools_ERR_STACK_g; H5TOOLS_DLLVAR hid_t H5tools_ERR_CLS_g; H5TOOLS_DLLVAR hid_t H5E_tools_g; H5TOOLS_DLLVAR hid_t H5E_tools_min_id_g; @@ -66,7 +67,11 @@ H5TOOLS_DLLVAR hid_t H5E_tools_min_id_g; * HERROR macro, used to facilitate error reporting . The arguments are the major * error number, the minor error number, and a description of the error. */ -#define HERROR(maj_id, min_id, str) H5Epush2(H5E_DEFAULT, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, maj_id, min_id, str) +#define HERROR(maj_id, min_id, str) { \ + H5Epush2(H5tools_ERR_STACK_g, __FILE__, FUNC, __LINE__, H5tools_ERR_CLS_g, maj_id, min_id, str); \ + ret_value = FAIL; \ +} + /* Macro for "catching" flow of control when an error occurs. Note that the * H5_LEAVE macro won't jump back here once it's past this point. diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index b0a3ed8..0de126d 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -1363,3 +1363,52 @@ h5tools_str_is_zero(const void *_mem, size_t size) return TRUE; } + +/*------------------------------------------------------------------------- + * Function: h5tools_str_replace + * + * Purpose: replace all occurrences of substring. + * + * Return: char * + * + * Programmer: Peter Cao + * March 8, 2012 + * + * Notes: + * Applications need to call free() to free the memoery allocated for + * the return string + * + *------------------------------------------------------------------------- + */ +char * +h5tools_str_replace ( const char *string, const char *substr, const char *replacement ) +{ + char *tok = NULL; + char *newstr = NULL; + char *oldstr = NULL; + char *head = NULL; + + if ( substr == NULL || replacement == NULL ) + return strdup (string); + + newstr = strdup (string); + head = newstr; + while ( (tok = strstr ( head, substr ))){ + oldstr = newstr; + newstr = HDmalloc ( strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) + 1 ); + + if ( newstr == NULL ){ + HDfree (oldstr); + return NULL; + } + memcpy ( newstr, oldstr, tok - oldstr ); + memcpy ( newstr + (tok - oldstr), replacement, strlen ( replacement ) ); + memcpy ( newstr + (tok - oldstr) + strlen( replacement ), tok + strlen ( substr ), strlen ( oldstr ) - strlen ( substr ) - ( tok - oldstr ) ); + memset ( newstr + strlen ( oldstr ) - strlen ( substr ) + strlen ( replacement ) , 0, 1 ); + /* move back head right after the last replacement */ + head = newstr + (tok - oldstr) + strlen( replacement ); + HDfree (oldstr); + } + + return newstr; +} diff --git a/tools/lib/h5tools_str.h b/tools/lib/h5tools_str.h index 9527a56..38697c6 100644 --- a/tools/lib/h5tools_str.h +++ b/tools/lib/h5tools_str.h @@ -47,5 +47,7 @@ H5TOOLS_DLL void h5tools_str_sprint_region(h5tools_str_t *str, const h5tool_ H5TOOLS_DLL char *h5tools_str_sprint(h5tools_str_t *str, const h5tool_format_t *info, hid_t container, hid_t type, void *vp, h5tools_context_t *ctx); +H5TOOLS_DLL char *h5tools_str_replace ( const char *string, const char *substr, + const char *replacement ); #endif /* H5TOOLS_STR_H__ */ diff --git a/tools/misc/CMakeLists.txt b/tools/misc/CMakeLists.txt index 3e70163..72930c9 100644 --- a/tools/misc/CMakeLists.txt +++ b/tools/misc/CMakeLists.txt @@ -5,7 +5,6 @@ PROJECT (HDF5_TOOLS_MISC) # Setup include Directories #----------------------------------------------------------------------------- INCLUDE_DIRECTORIES (${HDF5_TOOLS_SRC_DIR}/lib) -INCLUDE_DIRECTORIES (${HDF5_PROJECT_DIR}/test) # -------------------------------------------------------------------- # Add the misc executables diff --git a/tools/testfiles/filter_fail.ddl b/tools/testfiles/filter_fail.ddl index 9cc2de5..75534e2 100644 --- a/tools/testfiles/filter_fail.ddl +++ b/tools/testfiles/filter_fail.ddl @@ -25,3 +25,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): major: Data filters minor: Read failed h5dump error: unable to print data +H5tools-DIAG: Error detected in HDF5:tools (version (number)) thread (IDs): + #000: (file name) line (number) in h5tools_dump_simple_dset(): H5Dread failed + major: Failure in tools library + minor: error in function diff --git a/tools/testfiles/h5dump-help.txt b/tools/testfiles/h5dump-help.txt index ca16c42..d8551ca 100644 --- a/tools/testfiles/h5dump-help.txt +++ b/tools/testfiles/h5dump-help.txt @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,3 +101,7 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + diff --git a/tools/testfiles/tarray6.h5 b/tools/testfiles/tarray6.h5 Binary files differindex b4af19b..7eb078c 100644 --- a/tools/testfiles/tarray6.h5 +++ b/tools/testfiles/tarray6.h5 diff --git a/tools/testfiles/tattr-1.ddl b/tools/testfiles/tattr-1.ddl index d353577..b58731b 100644 --- a/tools/testfiles/tattr-1.ddl +++ b/tools/testfiles/tattr-1.ddl @@ -1,6 +1,6 @@ HDF5 "tattr.h5" { GROUP "/" { - ATTRIBUTE "attr1" { + ATTRIBUTE "/attr1" { DATATYPE H5T_STD_I8BE DATASPACE SIMPLE { ( 24 ) / ( 24 ) } DATA { diff --git a/tools/testfiles/tattr-2.ddl b/tools/testfiles/tattr-2.ddl index 79ba8c3..328b54f 100644 --- a/tools/testfiles/tattr-2.ddl +++ b/tools/testfiles/tattr-2.ddl @@ -7,14 +7,14 @@ ATTRIBUTE "/attr1" { (14): 111, 111, 116, 32, 103, 114, 111, 117, 112, 0 } } -ATTRIBUTE "/attr4" { +ATTRIBUTE "attr4" { DATATYPE H5T_STD_I32BE DATASPACE SCALAR DATA { (0): 100 } } -ATTRIBUTE "/attr5" { +ATTRIBUTE "attr5" { DATATYPE H5T_STRING { STRSIZE 17; STRPAD H5T_STR_NULLTERM; diff --git a/tools/testfiles/tattr-3.ddl b/tools/testfiles/tattr-3.ddl index c0dd123..a19f69a 100644 --- a/tools/testfiles/tattr-3.ddl +++ b/tools/testfiles/tattr-3.ddl @@ -1,9 +1,9 @@ HDF5 "tattr.h5" { -ATTRIBUTE "/attr2" { +ATTRIBUTE "attr2" { DATATYPE H5T_STD_I32BE DATASPACE SIMPLE { ( 10 ) / ( 10 ) } } -ATTRIBUTE "/attr" { +ATTRIBUTE "attr" { } } HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): @@ -13,4 +13,4 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): #001: (file name) line (number) in H5O_attr_open_by_name(): can't locate attribute: 'attr' major: Attribute minor: Object not found -h5dump error: unable to open attribute "/attr" +h5dump error: unable to open attribute "attr" diff --git a/tools/testfiles/tattr.h5 b/tools/testfiles/tattr.h5 Binary files differindex fd14b58..d61def5 100644 --- a/tools/testfiles/tattr.h5 +++ b/tools/testfiles/tattr.h5 diff --git a/tools/testfiles/tattr.h5.xml b/tools/testfiles/tattr.h5.xml index 57fa276..fceea99 100644 --- a/tools/testfiles/tattr.h5.xml +++ b/tools/testfiles/tattr.h5.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/HDF5/XML/schema/HDF5-File" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdfgroup.org/HDF5/XML/schema/HDF5-File http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd"> <hdf5:RootGroup OBJ-XID="xid_928" H5Path="/"> - <hdf5:Attribute Name="attr1"> + <hdf5:Attribute Name="/attr1"> <hdf5:Dataspace> <hdf5:SimpleDataspace Ndims="1"> <hdf5:Dimension DimSize="24" MaxDimSize="24"/> diff --git a/tools/testfiles/tmultifile.ddl b/tools/testfiles/tmultifile.ddl new file mode 100644 index 0000000..cf94f2c --- /dev/null +++ b/tools/testfiles/tmultifile.ddl @@ -0,0 +1,42 @@ +HDF5 "tarray2.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [3][4][5] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray3.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_ARRAY { [6][3] H5T_STD_I32LE } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray4.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_IEEE_F32LE "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray5.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_ARRAY { [4] H5T_IEEE_F32LE } "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray6.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_STD_U32LE} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray7.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_ARRAY { [4] H5T_STD_U32LE }} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} diff --git a/tools/testfiles/tmultifile.ls b/tools/testfiles/tmultifile.ls new file mode 100644 index 0000000..3fee937 --- /dev/null +++ b/tools/testfiles/tmultifile.ls @@ -0,0 +1,6 @@ +dset1 Dataset {5} +g1 Group +g2 Group +g3 Group, same as / +slink1 Soft Link {somevalue} +slink2 Soft Link {linkvalue} diff --git a/tools/testfiles/tnofilename-with-packed-bits.ddl b/tools/testfiles/tnofilename-with-packed-bits.ddl index 4a7f0b9..050a3a3 100644 --- a/tools/testfiles/tnofilename-with-packed-bits.ddl +++ b/tools/testfiles/tnofilename-with-packed-bits.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: missing file name diff --git a/tools/testfiles/tpbitsIncomplete.ddl b/tools/testfiles/tpbitsIncomplete.ddl index 88dac0a..5608d2b 100644 --- a/tools/testfiles/tpbitsIncomplete.ddl +++ b/tools/testfiles/tpbitsIncomplete.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Bad mask list(0,2,2,1,0,2,2,) diff --git a/tools/testfiles/tpbitsLengthExceeded.ddl b/tools/testfiles/tpbitsLengthExceeded.ddl index 35055f4..f89b65f 100644 --- a/tools/testfiles/tpbitsLengthExceeded.ddl +++ b/tools/testfiles/tpbitsLengthExceeded.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Packed Bit offset+length value(65) too large. Max is 64 diff --git a/tools/testfiles/tpbitsLengthPositive.ddl b/tools/testfiles/tpbitsLengthPositive.ddl index 3daeab4..ba32aa6 100644 --- a/tools/testfiles/tpbitsLengthPositive.ddl +++ b/tools/testfiles/tpbitsLengthPositive.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Packed Bit length value(0) must be positive. diff --git a/tools/testfiles/tpbitsMaxExceeded.ddl b/tools/testfiles/tpbitsMaxExceeded.ddl index 2b3b68f..16f953d 100644 --- a/tools/testfiles/tpbitsMaxExceeded.ddl +++ b/tools/testfiles/tpbitsMaxExceeded.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Too many masks requested (max. 8). Mask list(0,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1) diff --git a/tools/testfiles/tpbitsOffsetExceeded.ddl b/tools/testfiles/tpbitsOffsetExceeded.ddl index 6ccdc26..446fe2d 100644 --- a/tools/testfiles/tpbitsOffsetExceeded.ddl +++ b/tools/testfiles/tpbitsOffsetExceeded.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Packed Bit offset value(64) must be between 0 and 63 diff --git a/tools/testfiles/tpbitsOffsetNegative.ddl b/tools/testfiles/tpbitsOffsetNegative.ddl index eb41bd7..747cf99 100644 --- a/tools/testfiles/tpbitsOffsetNegative.ddl +++ b/tools/testfiles/tpbitsOffsetNegative.ddl @@ -1,4 +1,4 @@ -usage: h5dump [OPTIONS] file +usage: h5dump [OPTIONS] files OPTIONS -h, --help Print a usage message and exit -n, --contents Print a list of the file contents and exit @@ -10,6 +10,9 @@ usage: h5dump [OPTIONS] file -e, --escape Escape non printing characters -V, --version Print version number and exit -a P, --attribute=P Print the specified attribute + If an attribute name contains a slash (/), escape the + slash with a preceding backslash (\). + (See example section below.) -d P, --dataset=P Print the specified dataset -y, --noindex Do not print array indices with the data -p, --properties Print dataset filters, storage layout and fill value @@ -81,6 +84,10 @@ usage: h5dump [OPTIONS] file h5dump -a /bar_none/foo quux.h5 + Attribute "high/low" of the group /bar_none in the file quux.h5 + + h5dump -a "/bar_none/high\/low" quux.h5 + 2) Selecting a subset from dataset /foo in file quux.h5 h5dump -d /foo -s "0,1" -S "1,1" -c "2,3" -k "2,2" quux.h5 @@ -94,4 +101,8 @@ usage: h5dump [OPTIONS] file h5dump -d /dset -M 0,1,4,3 quux.h5 + 5) Dataset foo in files multi1.h5 multi2.h5 multi3.h5 + + h5dump -d /foo multi1.h5 multi2.h5 multi3.h5 + h5dump error: Bad mask list(-1,1) diff --git a/tools/testfiles/tqmarkfile.ddl b/tools/testfiles/tqmarkfile.ddl new file mode 100644 index 0000000..e7771cb --- /dev/null +++ b/tools/testfiles/tqmarkfile.ddl @@ -0,0 +1,83 @@ +HDF5 "tarray1.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray2.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [3][4][5] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray3.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_ARRAY { [6][3] H5T_STD_I32LE } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray4.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_IEEE_F32LE "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray5.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_ARRAY { [4] H5T_IEEE_F32LE } "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray6.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_STD_U32LE} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray7.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_ARRAY { [4] H5T_STD_U32LE }} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray8.h5" { +} +HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): + #000: (file name) line (number) in H5Dopen2(): not found + major: Dataset + minor: Object not found + #001: (file name) line (number) in H5G_loc_find(): can't find object + major: Symbol table + minor: Object not found + #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + major: Symbol table + minor: Object not found + #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + major: Symbol table + minor: Callback failed + #004: (file name) line (number) in H5G_loc_find_cb(): object 'Dataset1' doesn't exist + major: Symbol table + minor: Object not found +HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): + #000: (file name) line (number) in H5Lget_info(): unable to get link info + major: Symbol table + minor: Object not found + #001: (file name) line (number) in H5L_get_info(): name doesn't exist + major: Symbol table + minor: Object already exists + #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + major: Symbol table + minor: Object not found + #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + major: Symbol table + minor: Callback failed + #004: (file name) line (number) in H5L_get_info_cb(): name doesn't exist + major: Symbol table + minor: Object not found +h5dump error: unable to get link info from "Dataset1" diff --git a/tools/testfiles/tstarfile.ddl b/tools/testfiles/tstarfile.ddl new file mode 100644 index 0000000..77b80e0 --- /dev/null +++ b/tools/testfiles/tstarfile.ddl @@ -0,0 +1,89 @@ +HDF5 "tarray1_big.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [1000] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 2000 ) / ( 2000 ) } +} +} +HDF5 "tarray1.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray2.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [3][4][5] H5T_STD_I32LE } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray3.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_ARRAY { [6][3] H5T_STD_I32LE } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray4.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_IEEE_F32LE "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray5.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_COMPOUND { + H5T_STD_I32LE "i"; + H5T_ARRAY { [4] H5T_IEEE_F32LE } "f"; + } } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray6.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_STD_U32LE} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray7.h5" { +DATASET "Dataset1" { + DATATYPE H5T_ARRAY { [4] H5T_VLEN { H5T_ARRAY { [4] H5T_STD_U32LE }} } + DATASPACE SIMPLE { ( 4 ) / ( 4 ) } +} +} +HDF5 "tarray8.h5" { +} +HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): + #000: (file name) line (number) in H5Dopen2(): not found + major: Dataset + minor: Object not found + #001: (file name) line (number) in H5G_loc_find(): can't find object + major: Symbol table + minor: Object not found + #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + major: Symbol table + minor: Object not found + #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + major: Symbol table + minor: Callback failed + #004: (file name) line (number) in H5G_loc_find_cb(): object 'Dataset1' doesn't exist + major: Symbol table + minor: Object not found +HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs): + #000: (file name) line (number) in H5Lget_info(): unable to get link info + major: Symbol table + minor: Object not found + #001: (file name) line (number) in H5L_get_info(): name doesn't exist + major: Symbol table + minor: Object already exists + #002: (file name) line (number) in H5G_traverse(): internal path traversal failed + major: Symbol table + minor: Object not found + #003: (file name) line (number) in H5G_traverse_real(): traversal operator failed + major: Symbol table + minor: Callback failed + #004: (file name) line (number) in H5L_get_info_cb(): name doesn't exist + major: Symbol table + minor: Object not found +h5dump error: unable to get link info from "Dataset1" diff --git a/vms/src/h5pubconf.h b/vms/src/h5pubconf.h index bd34b49..2df95ef 100644 --- a/vms/src/h5pubconf.h +++ b/vms/src/h5pubconf.h @@ -505,7 +505,7 @@ #define H5_PACKAGE_NAME "HDF5" /* Define to the full name and version of this package. */ -#define H5_PACKAGE_STRING "HDF5 1.9.110" +#define H5_PACKAGE_STRING "HDF5 1.9.112" /* Define to the one symbol short name of this package. */ #define H5_PACKAGE_TARNAME "hdf5" @@ -514,7 +514,7 @@ #define H5_PACKAGE_URL "" /* Define to the version of this package. */ -#define H5_PACKAGE_VERSION "1.9.110" +#define H5_PACKAGE_VERSION "1.9.112" /* Width for printf() for type `long long' or `__int64', use `ll' */ #define H5_PRINTF_LL_WIDTH "ll" @@ -677,7 +677,7 @@ /* #undef H5_USING_MEMCHECKER */ /* Version number of package */ -#define H5_VERSION "1.9.110" +#define H5_VERSION "1.9.112" /* Define if vsnprintf() returns the correct value for formatted strings that don't fit into size allowed */ diff --git a/windows/src/H5pubconf.h b/windows/src/H5pubconf.h index ee9f18c..7a681fe 100644 --- a/windows/src/H5pubconf.h +++ b/windows/src/H5pubconf.h @@ -530,7 +530,7 @@ #define H5_PACKAGE_NAME "HDF5" /* Define to the full name and version of this package. */ -#define H5_PACKAGE_STRING "HDF5 1.9.110" +#define H5_PACKAGE_STRING "HDF5 1.9.112" /* Define to the one symbol short name of this package. */ #define H5_PACKAGE_TARNAME "hdf5" @@ -539,7 +539,7 @@ #define H5_PACKAGE_URL "" /* Define to the version of this package. */ -#define H5_PACKAGE_VERSION "1.9.110" +#define H5_PACKAGE_VERSION "1.9.112" /* Width for printf() for type `long long' or `__int64', use `ll' */ #define H5_PRINTF_LL_WIDTH "I64" @@ -710,7 +710,7 @@ /* #undef H5_USING_MEMCHECKER */ /* Version number of package */ -#define H5_VERSION "1.9.110" +#define H5_VERSION "1.9.112" /* Define if vsnprintf() returns the correct value for formatted strings that don't fit into size allowed */ |