diff options
56 files changed, 2442 insertions, 663 deletions
@@ -1529,6 +1529,7 @@ ./tools/h5diff/testfiles/h5diff_57.txt ./tools/h5diff/testfiles/h5diff_58.txt ./tools/h5diff/testfiles/h5diff_600.txt +./tools/h5diff/testfiles/h5diff_601.txt ./tools/h5diff/testfiles/h5diff_603.txt ./tools/h5diff/testfiles/h5diff_604.txt ./tools/h5diff/testfiles/h5diff_605.txt @@ -1607,7 +1608,21 @@ ./tools/h5diff/testfiles/h5diff_457.txt ./tools/h5diff/testfiles/h5diff_458.txt ./tools/h5diff/testfiles/h5diff_459.txt - +./tools/h5diff/testfiles/h5diff_500.txt +./tools/h5diff/testfiles/h5diff_501.txt +./tools/h5diff/testfiles/h5diff_502.txt +./tools/h5diff/testfiles/h5diff_503.txt +./tools/h5diff/testfiles/h5diff_504.txt +./tools/h5diff/testfiles/h5diff_505.txt +./tools/h5diff/testfiles/h5diff_506.txt +./tools/h5diff/testfiles/h5diff_507.txt +./tools/h5diff/testfiles/h5diff_508.txt +./tools/h5diff/testfiles/h5diff_509.txt +./tools/h5diff/testfiles/h5diff_510.txt +./tools/h5diff/testfiles/h5diff_511.txt +./tools/h5diff/testfiles/h5diff_512.txt +./tools/h5diff/testfiles/h5diff_513.txt +./tools/h5diff/testfiles/h5diff_514.txt ./tools/h5diff/testfiles/h5diff_attr1.h5 ./tools/h5diff/testfiles/h5diff_attr2.h5 @@ -1629,6 +1644,8 @@ ./tools/h5diff/testfiles/h5diff_softlinks.h5 ./tools/h5diff/testfiles/h5diff_danglelinks1.h5 ./tools/h5diff/testfiles/h5diff_danglelinks2.h5 +./tools/h5diff/testfiles/h5diff_grp_recurse1.h5 +./tools/h5diff/testfiles/h5diff_grp_recurse2.h5 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 172f87a..85c4fe2 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -466,6 +466,9 @@ Bug Fixes since HDF5-1.8.0 release Tools ----- + - Fixed to compare member objects and groups recursively when two + files or groups are specified to be compared. Bug#1975 + (JKM 2010/9/16) - Make h5repack be able to convert a layout to COMPACT for small size dataset as default. bug#1896 (JKM 2010/09/15) - Change h5ls not to manipulate special characters in object name or diff --git a/tools/h5copy/h5copy.c b/tools/h5copy/h5copy.c index d850f85..eb16754 100644 --- a/tools/h5copy/h5copy.c +++ b/tools/h5copy/h5copy.c @@ -416,7 +416,7 @@ main (int argc, const char *argv[]) if(verbose) linkinfo.opt.msg_mode = 1; - li_ret = H5tools_get_link_info(fid_src, oname_src, &linkinfo, 1); + li_ret = H5tools_get_symlink_info(fid_src, oname_src, &linkinfo, 1); if (li_ret == 0) /* dangling link */ { if(H5Lcopy(fid_src, oname_src, diff --git a/tools/h5copy/testh5copy.sh b/tools/h5copy/testh5copy.sh index e98e67e..a54816e 100644 --- a/tools/h5copy/testh5copy.sh +++ b/tools/h5copy/testh5copy.sh @@ -294,17 +294,17 @@ COPY_OBJECTS() TOOLTEST -i $TESTFILE -o $FILEOUT -v -s /grp_dsets/simple -d /grp_dsets/simple_group echo "Test copying & renaming group" - TOOLTEST_FAIL -i $TESTFILE -o $FILEOUT -v -s grp_dsets -d grp_rename + TOOLTEST -i $TESTFILE -o $FILEOUT -v -s grp_dsets -d grp_rename echo "Test copying 'full' group hierarchy into group in destination file" - TOOLTEST_FAIL -i $TESTFILE -o $FILEOUT -v -s grp_dsets -d /grp_rename/grp_dsets + TOOLTEST -i $TESTFILE -o $FILEOUT -v -s grp_dsets -d /grp_rename/grp_dsets echo "Test copying objects into group hier. that doesn't exist yet in destination file" TOOLTEST -i $TESTFILE -o $FILEOUT -vp -s simple -d /A/B1/simple TOOLTEST -i $TESTFILE -o $FILEOUT -vp -s simple -d /A/B2/simple2 TOOLTEST -i $TESTFILE -o $FILEOUT -vp -s /grp_dsets/simple -d /C/D/simple - TOOLTEST_FAIL -i $TESTFILE -o $FILEOUT -vp -s /grp_dsets -d /E/F/grp_dsets - TOOLTEST_FAIL -i $TESTFILE -o $FILEOUT -vp -s /grp_nested -d /G/H/grp_nested + TOOLTEST -i $TESTFILE -o $FILEOUT -vp -s /grp_dsets -d /E/F/grp_dsets + TOOLTEST -i $TESTFILE -o $FILEOUT -vp -s /grp_nested -d /G/H/grp_nested # Verify that the file created above is correct H5LSTEST $FILEOUT diff --git a/tools/h5diff/CMakeLists.txt b/tools/h5diff/CMakeLists.txt index 820c3d0..c31f650 100644 --- a/tools/h5diff/CMakeLists.txt +++ b/tools/h5diff/CMakeLists.txt @@ -123,7 +123,21 @@ IF (BUILD_TESTING) h5diff_56.txt h5diff_57.txt h5diff_58.txt + h5diff_500.txt + h5diff_501.txt + h5diff_503.txt + h5diff_504.txt + h5diff_505.txt + h5diff_506.txt + h5diff_507.txt + h5diff_508.txt + h5diff_509.txt + h5diff_510.txt + h5diff_512.txt + h5diff_513.txt + h5diff_514.txt h5diff_600.txt + h5diff_601.txt h5diff_603.txt h5diff_604.txt h5diff_605.txt @@ -174,6 +188,8 @@ IF (BUILD_TESTING) h5diff_ext2softlink_trg.h5 h5diff_danglelinks1.h5 h5diff_danglelinks2.h5 + h5diff_grp_recurse1.h5 + h5diff_grp_recurse2.h5 ) FOREACH (txt_file ${HDF5_REFERENCE_FILES}) @@ -278,6 +294,8 @@ SET (FILE17 h5diff_ext2softlink_src.h5) SET (FILE18 h5diff_ext2softlink_trg.h5) SET (DANGLE_LINK_FILE1 h5diff_danglelinks1.h5) SET (DANGLE_LINK_FILE2 h5diff_danglelinks2.h5) +SET (GRP_RECURSE_FILE1 h5diff_grp_recurse1.h5) +SET (GRP_RECURSE_FILE2 h5diff_grp_recurse2.h5) # ############################################################################ # # Common usage @@ -402,6 +420,9 @@ ADD_H5_TEST (h5diff_58 1 -v ${FILE7} ${FILE8} refreg) # 6.0: Check if the command line number of arguments is less than 3 ADD_H5_TEST (h5diff_600 1 ${FILE1}) +# 6.1: Check if non-exist object name is specified +ADD_H5_TEST (h5diff_601 2 ${FILE1} ${FILE1} nono_obj) + # ############################################################################## # # -d @@ -659,6 +680,42 @@ ADD_H5_TEST (h5diff_458 2 --follow-symlinks -v --no-dangling-links ${FILE15} $ # dangling link found for ext links (obj to obj). Both dangle links ADD_H5_TEST (h5diff_459 2 --follow-symlinks -v --no-dangling-links ${FILE15} ${FILE15} /ext_link_noexist1 /ext_link_noexist2) + +# ############################################################################## +# # test for group diff recursivly +# ############################################################################## +# root +ADD_H5_TEST (h5diff_500 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} / /) +ADD_H5_TEST (h5diff_501 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} / /) + +# root vs group +ADD_H5_TEST (h5diff_502 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} / /grp1/grp2/grp3) + +# group vs group (same name and structure) +ADD_H5_TEST (h5diff_503 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1 /grp1) + +# group vs group (different name and structure) +ADD_H5_TEST (h5diff_504 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1/grp2 /grp1/grp2/grp3) + +# groups vs soft-link +ADD_H5_TEST (h5diff_505 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1 /slink_grp1) +ADD_H5_TEST (h5diff_506 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1/grp2 /slink_grp2) + +# groups vs ext-link +ADD_H5_TEST (h5diff_507 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1 /elink_grp1) +ADD_H5_TEST (h5diff_508 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp1 /elink_grp1) + +# soft-link vs ext-link +ADD_H5_TEST (h5diff_509 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_grp1 /elink_grp1) +ADD_H5_TEST (h5diff_510 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_grp1 /elink_grp1) + +# circled ext links +ADD_H5_TEST (h5diff_511 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp10 /grp11) +ADD_H5_TEST (h5diff_512 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /grp10 /grp11) + +# circled soft2ext-link vs soft2ext-link +ADD_H5_TEST (h5diff_513 -v ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_grp10 /slink_grp11) +ADD_H5_TEST (h5diff_514 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_FILE2} /slink_grp10 /slink_grp11) ENDIF (BUILD_TESTING) diff --git a/tools/h5diff/h5diff_common.c b/tools/h5diff/h5diff_common.c index 9b6037e..b897a7f 100644 --- a/tools/h5diff/h5diff_common.c +++ b/tools/h5diff/h5diff_common.c @@ -351,7 +351,7 @@ check_d_input( const char *str ) void usage(void) { - printf("usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] \n"); + printf("usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] \n"); printf(" file1 File name of the first HDF5 file\n"); printf(" file2 File name of the second HDF5 file\n"); printf(" [obj1] Name of an HDF5 object, in absolute path\n"); @@ -425,18 +425,29 @@ void usage(void) printf("\n"); - printf(" Compare criteria\n"); - printf(" If no objects [obj1[obj2]] are specified, h5diff only compares objects\n"); - printf(" with the same absolute path in both files\n"); + printf(" File comparison:\n"); + printf(" If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as\n"); + printf(" a comparison of the two files' root groups. That is, h5diff first compares\n"); + printf(" the names of root group members, generates a report of root group objects\n"); + printf(" that appear in only one file or in both files, and recursively compares\n"); + printf(" common objects.\n"); printf("\n"); - printf(" The compare criteria is:\n"); - printf(" 1) datasets: numerical array differences\n"); - printf(" 2) groups: name string difference\n"); - printf(" 3) datatypes: the return value of H5Tequal\n"); - printf(" 4) links: name string difference of the linked value as default\n"); - printf(" (refer to --follow-symlinks option).\n"); + printf(" Object comparison:\n"); + printf(" 1) Groups \n"); + printf(" First compares the names of member objects (relative path, from the\n"); + printf(" specified group) and generates a report of objects that appear in only\n"); + printf(" one group or in both groups. Common objects are then compared recursively.\n"); + printf(" 2) Datasets \n"); + printf(" Array rank and dimensions, datatypes, and data values are compared.\n"); + printf(" 3) Datatypes \n"); + printf(" The comparison is based on the return value of H5Tequal.\n"); + printf(" 4) Symbolic links \n"); + printf(" The paths to the target objects are compared.\n"); + printf(" (The option --follow-symlinks overrides the default behavior when\n"); + printf(" symbolic links are compared.).\n"); printf("\n"); + printf(" Exit code:\n"); printf(" 0 if no differences, 1 if differences found, 2 if error\n"); printf("\n"); diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c index 504c000..1f6cb2a 100644 --- a/tools/h5diff/h5diffgentest.c +++ b/tools/h5diff/h5diffgentest.c @@ -55,6 +55,8 @@ #define FILE18 "h5diff_ext2softlink_trg.h5" #define DANGLE_LINK_FILE1 "h5diff_danglelinks1.h5" #define DANGLE_LINK_FILE2 "h5diff_danglelinks2.h5" +#define GRP_RECURSE_FILE1 "h5diff_grp_recurse1.h5" +#define GRP_RECURSE_FILE2 "h5diff_grp_recurse2.h5" #define UIMAX 4294967295u /*Maximum value for a variable of type unsigned int */ #define STR_SIZE 3 @@ -99,6 +101,7 @@ static int test_linked_softlinks(const char *fname1); static int test_external_links(const char *fname1, const char *fname2); static int test_ext2soft_links(const char *fname1, const char *fname2); static int test_dangle_links(const char *fname1, const char *fname2); +static int test_group_recurse(const char *fname1, const char *fname2); /* called by test_attributes() and test_datasets() */ static void write_attr_in(hid_t loc_id,const char* dset_name,hid_t fid,int make_diffs); @@ -148,6 +151,8 @@ int main(void) test_dangle_links(DANGLE_LINK_FILE1, DANGLE_LINK_FILE2); + test_group_recurse(GRP_RECURSE_FILE1, GRP_RECURSE_FILE2); + return 0; } @@ -1829,6 +1834,464 @@ out: } /*------------------------------------------------------------------------- +* +* Purpose: For testing comparing group member objects recursively +* +* Programmer: Jonathan Kim (Aug 19, 2010) +* +*-------------------------------------------------------------------------*/ +static int test_group_recurse(const char *fname1, const char *fname2) +{ + hid_t fid1=0; + hid_t fid2=0; + hid_t gid1_f1=0, gid2_f1=0, gid3_f1=0, gid10_f1=0; + hid_t gid1_f2=0, gid2_f2=0, gid3_f2=0, gid11_f2=0; + hsize_t dims2[2] = {2,4}; + int data1[4][2] = {{0,1},{0,1},{1,0},{1,0}}; + int data2[4][2] = {{0,2},{0,2},{2,0},{2,0}}; + int data3[4][2] = {{0,3},{0,3},{3,0},{3,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; + } + + /*----------------------------------------------------------------------- + * Groups + *------------------------------------------------------------------------*/ + /* file1 */ + gid1_f1 = H5Gcreate2(fid1, "/grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid1_f1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + gid2_f1 = H5Gcreate2(fid1, "/grp1/grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid2_f1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + gid3_f1 = H5Gcreate2(fid1, "/grp1/grp2/grp3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid3_f1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + gid10_f1 = H5Gcreate2(fid1, "/grp10", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid10_f1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + gid1_f2 = H5Gcreate2(fid2, "/grp1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid1_f2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + gid2_f2 = H5Gcreate2(fid2, "/grp1/grp2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid2_f2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + gid3_f2 = H5Gcreate2(fid2, "/grp1/grp2/grp3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid3_f2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + gid11_f2 = H5Gcreate2(fid2, "/grp11", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid11_f2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + /*----------------------------------------------------------------------- + * Datasets under root + *------------------------------------------------------------------------*/ + /* 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(fid1,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(fid1,2,dims2,"dset3",H5T_NATIVE_INT,data3); + 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; + } + + status = write_dset(fid2,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(fid2,2,dims2,"dset3",H5T_NATIVE_INT,data3); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + /*----------------------------------------------------------------------- + * Datasets under group + *------------------------------------------------------------------------*/ + /* file1 */ + status = write_dset(gid1_f1,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(gid2_f1,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(gid2_f1,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid3_f1,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(gid3_f1,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid3_f1,2,dims2,"dset3",H5T_NATIVE_INT,data3); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid10_f1,2,dims2,"dset4",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid10_f1,2,dims2,"dset5",H5T_NATIVE_INT,data3); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + status = write_dset(gid1_f2,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid2_f2,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + status = write_dset(gid2_f2,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid3_f2,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + status = write_dset(gid3_f2,2,dims2,"dset2",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid3_f2,2,dims2,"dset3",H5T_NATIVE_INT,data3); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid11_f2,2,dims2,"dset4",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid11_f2,2,dims2,"dset5",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Soft Links + *------------------------------------------------------------------------*/ + /* file 1 */ + status = H5Lcreate_soft("/grp1", fid1, "slink_grp1", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname1); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp1/grp2", fid1, "slink_grp2", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname1); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp1/grp2/grp3", fid1, "slink_grp3", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname1); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp10", fid1, "slink_grp10", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname1); + status = FAIL; + goto out; + } + + /* file 2 */ + status = H5Lcreate_soft("/grp1", fid2, "slink_grp1", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname2); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp1/grp2", fid2, "slink_grp2", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname2); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp1/grp2/grp3", fid2, "slink_grp3", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname2); + status = FAIL; + goto out; + } + + status = H5Lcreate_soft("/grp11", fid2, "slink_grp11", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_soft failed.\n", fname2); + status = FAIL; + goto out; + } + + /*----------------------------------------------------------------------- + * External Links + *------------------------------------------------------------------------*/ + /* file1 */ + status = H5Lcreate_external(fname2, "/grp1", fid1, "elink_grp1", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname1); + status = FAIL; + goto out; + } + + status = H5Lcreate_external(fname2, "/grp1/grp2", fid1, "elink_grp2", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname1); + status = FAIL; + goto out; + } + + status = H5Lcreate_external(fname2, "/grp1/grp2/grp3", fid1, "elink_grp3", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + status = H5Lcreate_external(fname1, "/grp1", fid2, "elink_grp1", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname2); + status = FAIL; + goto out; + } + + status = H5Lcreate_external(fname1, "/grp1/grp2", fid2, "elink_grp2", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname2); + status = FAIL; + goto out; + } + + status = H5Lcreate_external(fname1, "/grp1/grp2/grp3", fid2, "elink_grp3", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname2); + status = FAIL; + goto out; + } + + /*------------------------------ + * external circle route test + * file1/grp11 <-> file2/grp10 via elink_grp_circle link + */ + /* file1 */ + status = H5Lcreate_external(fname2, "/grp11", gid10_f1, "elink_grp_circle", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname1); + status = FAIL; + goto out; + } + /* file2 */ + status = H5Lcreate_external(fname1, "/grp10", gid11_f2, "elink_grp_circle", H5P_DEFAULT, H5P_DEFAULT); + if (status < 0) + { + fprintf(stderr, "Error: %s> H5Lcreate_external failed.\n", fname2); + status = FAIL; + goto out; + } + + +out: + /*----------------------------------------------------------------------- + * Close + *-----------------------------------------------------------------------*/ + if(fid1) + H5Fclose(fid1); + if(fid2) + H5Fclose(fid2); + if(gid1_f1) + H5Gclose(gid1_f1); + if(gid2_f1) + H5Gclose(gid2_f1); + if(gid3_f1) + H5Gclose(gid3_f1); + if(gid1_f2) + H5Gclose(gid1_f2); + if(gid2_f2) + H5Gclose(gid2_f2); + if(gid3_f2) + H5Gclose(gid3_f2); + + return status; +} + +/*------------------------------------------------------------------------- * Function: write_attr_in * * Purpose: write attributes in LOC_ID (dataset, group, named datatype) diff --git a/tools/h5diff/ph5diff_main.c b/tools/h5diff/ph5diff_main.c index 531503d..f6b0dba 100644 --- a/tools/h5diff/ph5diff_main.c +++ b/tools/h5diff/ph5diff_main.c @@ -135,7 +135,7 @@ ph5diff_worker(int nID) { struct diff_args args; hid_t file1_id, file2_id; - char filenames[2][1024]; + char filenames[2][MAX_FILENAME]; char out_data[PRINT_DATA_MAX_SIZE] = {0}; struct diffs_found diffs; int i; @@ -144,7 +144,7 @@ ph5diff_worker(int nID) MPI_Comm_rank(MPI_COMM_WORLD, &nID); outBuffOffset = 0; - MPI_Recv(filenames, 1024*2, MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); + MPI_Recv(filenames, MAX_FILENAME*2, MPI_CHAR, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Status); if(Status.MPI_TAG == MPI_TAG_PARALLEL) { /* disable error reporting */ @@ -175,7 +175,7 @@ ph5diff_worker(int nID) /*Recv parameters for diff from manager task */ MPI_Recv(&args, sizeof(args), MPI_BYTE, 0, MPI_TAG_ARGS, MPI_COMM_WORLD, &Status); /*Do the diff */ - diffs.nfound = diff(file1_id, args.name, file2_id, args.name, &(args.options), args.type); + diffs.nfound = diff(file1_id, args.name1, file2_id, args.name2, &(args.options), args.type); diffs.not_cmp = args.options.not_cmp; /*If print buffer has something in it, request print token.*/ diff --git a/tools/h5diff/testfiles/h5diff_10.txt b/tools/h5diff/testfiles/h5diff_10.txt index d3ee9a6..224f9bc 100644 --- a/tools/h5diff/testfiles/h5diff_10.txt +++ b/tools/h5diff/testfiles/h5diff_10.txt @@ -1,4 +1,4 @@ -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -69,16 +69,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_23.txt b/tools/h5diff/testfiles/h5diff_23.txt index 5a46ea2..bd1cadb 100644 --- a/tools/h5diff/testfiles/h5diff_23.txt +++ b/tools/h5diff/testfiles/h5diff_23.txt @@ -1,3 +1,8 @@ + +group1 group2 +--------------------------------------- + x x + group : </g1> and </g1> 0 differences found EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_26.txt b/tools/h5diff/testfiles/h5diff_26.txt index 8e1fcc3..54a5121 100644 --- a/tools/h5diff/testfiles/h5diff_26.txt +++ b/tools/h5diff/testfiles/h5diff_26.txt @@ -1,3 +1,8 @@ + +group1 group2 +--------------------------------------- + x x + group : </g1> and </g2> -1 differences found -EXIT CODE: 1 +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_400.txt b/tools/h5diff/testfiles/h5diff_400.txt index 97db70d..8b3c03c 100644 --- a/tools/h5diff/testfiles/h5diff_400.txt +++ b/tools/h5diff/testfiles/h5diff_400.txt @@ -3,10 +3,9 @@ file1 file2 --------------------------------------- x x / x x /softlink_dset1_1 - x x /softlink_dset1_2 x x /softlink_dset2 x x /softlink_group1 - x x /softlink_group2 + x x /softlink_group1/dset x x /softlink_noexist x x /target_dset1 x x /target_dset2 @@ -15,25 +14,13 @@ file1 file2 group : </> and </> 0 differences found -link : </softlink_dset1_1> and </softlink_dset1_1> dataset: </softlink_dset1_1> and </softlink_dset1_1> 0 differences found -0 differences found -link : </softlink_dset1_2> and </softlink_dset1_2> -dataset: </softlink_dset1_2> and </softlink_dset1_2> -0 differences found -0 differences found -link : </softlink_dset2> and </softlink_dset2> dataset: </softlink_dset2> and </softlink_dset2> 0 differences found -0 differences found -link : </softlink_group1> and </softlink_group1> group : </softlink_group1> and </softlink_group1> 0 differences found -0 differences found -link : </softlink_group2> and </softlink_group2> -group : </softlink_group2> and </softlink_group2> -0 differences found +dataset: </softlink_group1/dset> and </softlink_group1/dset> 0 differences found dangling link: </softlink_noexist> and </softlink_noexist> 0 differences found diff --git a/tools/h5diff/testfiles/h5diff_404.txt b/tools/h5diff/testfiles/h5diff_404.txt index c9a476d..db317d1 100644 --- a/tools/h5diff/testfiles/h5diff_404.txt +++ b/tools/h5diff/testfiles/h5diff_404.txt @@ -5,27 +5,25 @@ file1 file2 x x /ext_link_dset1 x x /ext_link_dset2 x x /ext_link_grp1 + x x /ext_link_grp1/x_dset x x /ext_link_grp2 + x x /ext_link_grp2/x_dset x x /ext_link_noexist1 x x /ext_link_noexist2 group : </> and </> 0 differences found -external link: </ext_link_dset1> and </ext_link_dset1> dataset: </ext_link_dset1> and </ext_link_dset1> 0 differences found -0 differences found -external link: </ext_link_dset2> and </ext_link_dset2> dataset: </ext_link_dset2> and </ext_link_dset2> 0 differences found -0 differences found -external link: </ext_link_grp1> and </ext_link_grp1> group : </ext_link_grp1> and </ext_link_grp1> 0 differences found +dataset: </ext_link_grp1/x_dset> and </ext_link_grp1/x_dset> 0 differences found -external link: </ext_link_grp2> and </ext_link_grp2> group : </ext_link_grp2> and </ext_link_grp2> 0 differences found +dataset: </ext_link_grp2/x_dset> and </ext_link_grp2/x_dset> 0 differences found dangling link: </ext_link_noexist1> and </ext_link_noexist1> 0 differences found diff --git a/tools/h5diff/testfiles/h5diff_410.txt b/tools/h5diff/testfiles/h5diff_410.txt index b0924f6..6087bb8 100644 --- a/tools/h5diff/testfiles/h5diff_410.txt +++ b/tools/h5diff/testfiles/h5diff_410.txt @@ -23,54 +23,30 @@ file1 file2 group : </> and </> 0 differences found -link : </softlink1_to_dset1> and </softlink1_to_dset1> dataset: </softlink1_to_dset1> and </softlink1_to_dset1> 0 differences found -0 differences found -link : </softlink1_to_slink1> and </softlink1_to_slink1> dataset: </softlink1_to_slink1> and </softlink1_to_slink1> 0 differences found -0 differences found -link : </softlink1_to_slink2> and </softlink1_to_slink2> dataset: </softlink1_to_slink2> and </softlink1_to_slink2> 0 differences found -0 differences found -link : </softlink2_to_dset2> and </softlink2_to_dset2> dataset: </softlink2_to_dset2> and </softlink2_to_dset2> 0 differences found -0 differences found -link : </softlink2_to_slink1> and </softlink2_to_slink1> dataset: </softlink2_to_slink1> and </softlink2_to_slink1> 0 differences found -0 differences found -link : </softlink2_to_slink2> and </softlink2_to_slink2> dataset: </softlink2_to_slink2> and </softlink2_to_slink2> 0 differences found -0 differences found -link : </softlink3_to_group1> and </softlink3_to_group1> group : </softlink3_to_group1> and </softlink3_to_group1> 0 differences found -0 differences found -link : </softlink3_to_slink1> and </softlink3_to_slink1> group : </softlink3_to_slink1> and </softlink3_to_slink1> 0 differences found -0 differences found -link : </softlink3_to_slink2> and </softlink3_to_slink2> group : </softlink3_to_slink2> and </softlink3_to_slink2> 0 differences found -0 differences found -link : </softlink4_to_group2> and </softlink4_to_group2> group : </softlink4_to_group2> and </softlink4_to_group2> 0 differences found -0 differences found -link : </softlink4_to_slink1> and </softlink4_to_slink1> group : </softlink4_to_slink1> and </softlink4_to_slink1> 0 differences found -0 differences found -link : </softlink4_to_slink2> and </softlink4_to_slink2> group : </softlink4_to_slink2> and </softlink4_to_slink2> 0 differences found -0 differences found dataset: </target_dset1> and </target_dset1> 0 differences found dataset: </target_dset2> and </target_dset2> diff --git a/tools/h5diff/testfiles/h5diff_414.txt b/tools/h5diff/testfiles/h5diff_414.txt index e7a991a..a47349e 100644 --- a/tools/h5diff/testfiles/h5diff_414.txt +++ b/tools/h5diff/testfiles/h5diff_414.txt @@ -1,3 +1,9 @@ + +group1 group2 +--------------------------------------- + x x + x /dset + group : </target_group> and </softlink3_to_slink2> -1 differences found +0 differences found EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_415.txt b/tools/h5diff/testfiles/h5diff_415.txt index 1e97319..30cc947 100644 --- a/tools/h5diff/testfiles/h5diff_415.txt +++ b/tools/h5diff/testfiles/h5diff_415.txt @@ -1,3 +1,9 @@ + +group1 group2 +--------------------------------------- + x x + x /dset + group : </softlink3_to_slink2> and </target_group> -1 differences found +0 differences found EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_416.txt b/tools/h5diff/testfiles/h5diff_416.txt index e4e98b0..551a6c3 100644 --- a/tools/h5diff/testfiles/h5diff_416.txt +++ b/tools/h5diff/testfiles/h5diff_416.txt @@ -1,3 +1,8 @@ + +group1 group2 +--------------------------------------- + x x + group : </softlink3_to_slink2> and </softlink4_to_slink2> -1 differences found -EXIT CODE: 1 +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_453.txt b/tools/h5diff/testfiles/h5diff_453.txt index 9c4d61b..8a5ca52 100644 --- a/tools/h5diff/testfiles/h5diff_453.txt +++ b/tools/h5diff/testfiles/h5diff_453.txt @@ -3,10 +3,9 @@ file1 file2 --------------------------------------- x x / x x /softlink_dset1_1 - x x /softlink_dset1_2 x x /softlink_dset2 x x /softlink_group1 - x x /softlink_group2 + x x /softlink_group1/dset x x /softlink_noexist x x /target_dset1 x x /target_dset2 @@ -15,25 +14,13 @@ file1 file2 group : </> and </> 0 differences found -link : </softlink_dset1_1> and </softlink_dset1_1> dataset: </softlink_dset1_1> and </softlink_dset1_1> 0 differences found -0 differences found -link : </softlink_dset1_2> and </softlink_dset1_2> -dataset: </softlink_dset1_2> and </softlink_dset1_2> -0 differences found -0 differences found -link : </softlink_dset2> and </softlink_dset2> dataset: </softlink_dset2> and </softlink_dset2> 0 differences found -0 differences found -link : </softlink_group1> and </softlink_group1> group : </softlink_group1> and </softlink_group1> 0 differences found -0 differences found -link : </softlink_group2> and </softlink_group2> -group : </softlink_group2> and </softlink_group2> -0 differences found +dataset: </softlink_group1/dset> and </softlink_group1/dset> 0 differences found Warning: </softlink_noexist> is a dangling link. dataset: </target_dset1> and </target_dset1> diff --git a/tools/h5diff/testfiles/h5diff_456.txt b/tools/h5diff/testfiles/h5diff_456.txt index f20e403..9317988 100644 --- a/tools/h5diff/testfiles/h5diff_456.txt +++ b/tools/h5diff/testfiles/h5diff_456.txt @@ -5,27 +5,25 @@ file1 file2 x x /ext_link_dset1 x x /ext_link_dset2 x x /ext_link_grp1 + x x /ext_link_grp1/x_dset x x /ext_link_grp2 + x x /ext_link_grp2/x_dset x x /ext_link_noexist1 x x /ext_link_noexist2 group : </> and </> 0 differences found -external link: </ext_link_dset1> and </ext_link_dset1> dataset: </ext_link_dset1> and </ext_link_dset1> 0 differences found -0 differences found -external link: </ext_link_dset2> and </ext_link_dset2> dataset: </ext_link_dset2> and </ext_link_dset2> 0 differences found -0 differences found -external link: </ext_link_grp1> and </ext_link_grp1> group : </ext_link_grp1> and </ext_link_grp1> 0 differences found +dataset: </ext_link_grp1/x_dset> and </ext_link_grp1/x_dset> 0 differences found -external link: </ext_link_grp2> and </ext_link_grp2> group : </ext_link_grp2> and </ext_link_grp2> 0 differences found +dataset: </ext_link_grp2/x_dset> and </ext_link_grp2/x_dset> 0 differences found Warning: </ext_link_noexist1> is a dangling link. Warning: </ext_link_noexist2> is a dangling link. diff --git a/tools/h5diff/testfiles/h5diff_500.txt b/tools/h5diff/testfiles/h5diff_500.txt new file mode 100644 index 0000000..7d688d2 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_500.txt @@ -0,0 +1,72 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + x x /dset2 + x x /dset3 + x x /elink_grp1 + x x /elink_grp2 + x x /elink_grp3 + x x /grp1 + x x /grp1/dset1 + x x /grp1/grp2 + x x /grp1/grp2/dset1 + x x /grp1/grp2/dset2 + x x /grp1/grp2/grp3 + x x /grp1/grp2/grp3/dset1 + x x /grp1/grp2/grp3/dset2 + x x /grp1/grp2/grp3/dset3 + x /grp10 + x /grp10/dset4 + x /grp10/dset5 + x /grp10/elink_grp_circle + x /grp11 + x /grp11/dset4 + x /grp11/dset5 + x /grp11/elink_grp_circle + x x /slink_grp1 + x /slink_grp10 + x /slink_grp11 + x x /slink_grp2 + x x /slink_grp3 + +group : </> and </> +0 differences found +dataset: </dset1> and </dset1> +0 differences found +dataset: </dset2> and </dset2> +0 differences found +dataset: </dset3> and </dset3> +0 differences found +external link: </elink_grp1> and </elink_grp1> +1 differences found +external link: </elink_grp2> and </elink_grp2> +1 differences found +external link: </elink_grp3> and </elink_grp3> +1 differences found +group : </grp1> and </grp1> +0 differences found +dataset: </grp1/dset1> and </grp1/dset1> +0 differences found +group : </grp1/grp2> and </grp1/grp2> +0 differences found +dataset: </grp1/grp2/dset1> and </grp1/grp2/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </grp1/grp2/dset2> +0 differences found +group : </grp1/grp2/grp3> and </grp1/grp2/grp3> +0 differences found +dataset: </grp1/grp2/grp3/dset1> and </grp1/grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/grp3/dset2> and </grp1/grp2/grp3/dset2> +0 differences found +dataset: </grp1/grp2/grp3/dset3> and </grp1/grp2/grp3/dset3> +0 differences found +link : </slink_grp1> and </slink_grp1> +0 differences found +link : </slink_grp2> and </slink_grp2> +0 differences found +link : </slink_grp3> and </slink_grp3> +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_501.txt b/tools/h5diff/testfiles/h5diff_501.txt new file mode 100644 index 0000000..75e91da --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_501.txt @@ -0,0 +1,188 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + x x /dset2 + x x /dset3 + x x /elink_grp1 + x x /elink_grp1/dset1 + x x /elink_grp1/grp2 + x x /elink_grp1/grp2/dset1 + x x /elink_grp1/grp2/dset2 + x x /elink_grp1/grp2/grp3 + x x /elink_grp1/grp2/grp3/dset1 + x x /elink_grp1/grp2/grp3/dset2 + x x /elink_grp1/grp2/grp3/dset3 + x x /elink_grp2 + x x /elink_grp2/dset1 + x x /elink_grp2/dset2 + x x /elink_grp2/grp3 + x x /elink_grp2/grp3/dset1 + x x /elink_grp2/grp3/dset2 + x x /elink_grp2/grp3/dset3 + x x /elink_grp3 + x x /elink_grp3/dset1 + x x /elink_grp3/dset2 + x x /elink_grp3/dset3 + x x /grp1 + x x /grp1/dset1 + x x /grp1/grp2 + x x /grp1/grp2/dset1 + x x /grp1/grp2/dset2 + x x /grp1/grp2/grp3 + x x /grp1/grp2/grp3/dset1 + x x /grp1/grp2/grp3/dset2 + x x /grp1/grp2/grp3/dset3 + x /grp10 + x /grp10/dset4 + x /grp10/dset5 + x /grp10/elink_grp_circle + x /grp10/elink_grp_circle/dset4 + x /grp10/elink_grp_circle/dset5 + x /grp10/elink_grp_circle/elink_grp_circle + x /grp10/elink_grp_circle/elink_grp_circle/dset4 + x /grp10/elink_grp_circle/elink_grp_circle/dset5 + x /grp11 + x /grp11/dset4 + x /grp11/dset5 + x /grp11/elink_grp_circle + x /grp11/elink_grp_circle/dset4 + x /grp11/elink_grp_circle/dset5 + x /grp11/elink_grp_circle/elink_grp_circle + x /grp11/elink_grp_circle/elink_grp_circle/dset4 + x /grp11/elink_grp_circle/elink_grp_circle/dset5 + x x /slink_grp1 + x x /slink_grp1/dset1 + x x /slink_grp1/grp2 + x x /slink_grp1/grp2/dset1 + x x /slink_grp1/grp2/dset2 + x x /slink_grp1/grp2/grp3 + x x /slink_grp1/grp2/grp3/dset1 + x x /slink_grp1/grp2/grp3/dset2 + x x /slink_grp1/grp2/grp3/dset3 + x /slink_grp10 + x /slink_grp10/dset4 + x /slink_grp10/dset5 + x /slink_grp11 + x /slink_grp11/dset4 + x /slink_grp11/dset5 + x x /slink_grp2 + x x /slink_grp2/dset1 + x x /slink_grp2/dset2 + x x /slink_grp2/grp3 + x x /slink_grp2/grp3/dset1 + x x /slink_grp2/grp3/dset2 + x x /slink_grp2/grp3/dset3 + x x /slink_grp3 + x x /slink_grp3/dset1 + x x /slink_grp3/dset2 + x x /slink_grp3/dset3 + +group : </> and </> +0 differences found +dataset: </dset1> and </dset1> +0 differences found +dataset: </dset2> and </dset2> +0 differences found +dataset: </dset3> and </dset3> +0 differences found +group : </elink_grp1> and </elink_grp1> +0 differences found +dataset: </elink_grp1/dset1> and </elink_grp1/dset1> +0 differences found +group : </elink_grp1/grp2> and </elink_grp1/grp2> +0 differences found +dataset: </elink_grp1/grp2/dset1> and </elink_grp1/grp2/dset1> +0 differences found +dataset: </elink_grp1/grp2/dset2> and </elink_grp1/grp2/dset2> +0 differences found +group : </elink_grp1/grp2/grp3> and </elink_grp1/grp2/grp3> +0 differences found +dataset: </elink_grp1/grp2/grp3/dset1> and </elink_grp1/grp2/grp3/dset1> +0 differences found +dataset: </elink_grp1/grp2/grp3/dset2> and </elink_grp1/grp2/grp3/dset2> +0 differences found +dataset: </elink_grp1/grp2/grp3/dset3> and </elink_grp1/grp2/grp3/dset3> +0 differences found +group : </elink_grp2> and </elink_grp2> +0 differences found +dataset: </elink_grp2/dset1> and </elink_grp2/dset1> +0 differences found +dataset: </elink_grp2/dset2> and </elink_grp2/dset2> +0 differences found +group : </elink_grp2/grp3> and </elink_grp2/grp3> +0 differences found +dataset: </elink_grp2/grp3/dset1> and </elink_grp2/grp3/dset1> +0 differences found +dataset: </elink_grp2/grp3/dset2> and </elink_grp2/grp3/dset2> +0 differences found +dataset: </elink_grp2/grp3/dset3> and </elink_grp2/grp3/dset3> +0 differences found +group : </elink_grp3> and </elink_grp3> +0 differences found +dataset: </elink_grp3/dset1> and </elink_grp3/dset1> +0 differences found +dataset: </elink_grp3/dset2> and </elink_grp3/dset2> +0 differences found +dataset: </elink_grp3/dset3> and </elink_grp3/dset3> +0 differences found +group : </grp1> and </grp1> +0 differences found +dataset: </grp1/dset1> and </grp1/dset1> +0 differences found +group : </grp1/grp2> and </grp1/grp2> +0 differences found +dataset: </grp1/grp2/dset1> and </grp1/grp2/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </grp1/grp2/dset2> +0 differences found +group : </grp1/grp2/grp3> and </grp1/grp2/grp3> +0 differences found +dataset: </grp1/grp2/grp3/dset1> and </grp1/grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/grp3/dset2> and </grp1/grp2/grp3/dset2> +0 differences found +dataset: </grp1/grp2/grp3/dset3> and </grp1/grp2/grp3/dset3> +0 differences found +group : </slink_grp1> and </slink_grp1> +0 differences found +dataset: </slink_grp1/dset1> and </slink_grp1/dset1> +0 differences found +group : </slink_grp1/grp2> and </slink_grp1/grp2> +0 differences found +dataset: </slink_grp1/grp2/dset1> and </slink_grp1/grp2/dset1> +0 differences found +dataset: </slink_grp1/grp2/dset2> and </slink_grp1/grp2/dset2> +0 differences found +group : </slink_grp1/grp2/grp3> and </slink_grp1/grp2/grp3> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset1> and </slink_grp1/grp2/grp3/dset1> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset2> and </slink_grp1/grp2/grp3/dset2> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset3> and </slink_grp1/grp2/grp3/dset3> +0 differences found +group : </slink_grp2> and </slink_grp2> +0 differences found +dataset: </slink_grp2/dset1> and </slink_grp2/dset1> +0 differences found +dataset: </slink_grp2/dset2> and </slink_grp2/dset2> +0 differences found +group : </slink_grp2/grp3> and </slink_grp2/grp3> +0 differences found +dataset: </slink_grp2/grp3/dset1> and </slink_grp2/grp3/dset1> +0 differences found +dataset: </slink_grp2/grp3/dset2> and </slink_grp2/grp3/dset2> +0 differences found +dataset: </slink_grp2/grp3/dset3> and </slink_grp2/grp3/dset3> +0 differences found +group : </slink_grp3> and </slink_grp3> +0 differences found +dataset: </slink_grp3/dset1> and </slink_grp3/dset1> +0 differences found +dataset: </slink_grp3/dset2> and </slink_grp3/dset2> +0 differences found +dataset: </slink_grp3/dset3> and </slink_grp3/dset3> +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_502.txt b/tools/h5diff/testfiles/h5diff_502.txt new file mode 100644 index 0000000..d3de6e5 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_502.txt @@ -0,0 +1,36 @@ + +group1 group2 +--------------------------------------- + x + x / + x x /dset1 + x x /dset2 + x x /dset3 + x /elink_grp1 + x /elink_grp2 + x /elink_grp3 + x /grp1 + x /grp1/dset1 + x /grp1/grp2 + x /grp1/grp2/dset1 + x /grp1/grp2/dset2 + x /grp1/grp2/grp3 + x /grp1/grp2/grp3/dset1 + x /grp1/grp2/grp3/dset2 + x /grp1/grp2/grp3/dset3 + x /grp10 + x /grp10/dset4 + x /grp10/dset5 + x /grp10/elink_grp_circle + x /slink_grp1 + x /slink_grp10 + x /slink_grp2 + x /slink_grp3 + +dataset: </dset1> and </grp1/grp2/grp3/dset1> +0 differences found +dataset: </dset2> and </grp1/grp2/grp3/dset2> +0 differences found +dataset: </dset3> and </grp1/grp2/grp3/dset3> +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_503.txt b/tools/h5diff/testfiles/h5diff_503.txt new file mode 100644 index 0000000..cf01598 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_503.txt @@ -0,0 +1,32 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset1 + x x /grp2 + x x /grp2/dset1 + x x /grp2/dset2 + x x /grp2/grp3 + x x /grp2/grp3/dset1 + x x /grp2/grp3/dset2 + x x /grp2/grp3/dset3 + +group : </grp1> and </grp1> +0 differences found +dataset: </grp1/dset1> and </grp1/dset1> +0 differences found +group : </grp1/grp2> and </grp1/grp2> +0 differences found +dataset: </grp1/grp2/dset1> and </grp1/grp2/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </grp1/grp2/dset2> +0 differences found +group : </grp1/grp2/grp3> and </grp1/grp2/grp3> +0 differences found +dataset: </grp1/grp2/grp3/dset1> and </grp1/grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/grp3/dset2> and </grp1/grp2/grp3/dset2> +0 differences found +dataset: </grp1/grp2/grp3/dset3> and </grp1/grp2/grp3/dset3> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_504.txt b/tools/h5diff/testfiles/h5diff_504.txt new file mode 100644 index 0000000..6cf43b3 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_504.txt @@ -0,0 +1,19 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset1 + x x /dset2 + x /dset3 + x /grp3 + x /grp3/dset1 + x /grp3/dset2 + x /grp3/dset3 + +group : </grp1/grp2> and </grp1/grp2/grp3> +0 differences found +dataset: </grp1/grp2/dset1> and </grp1/grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </grp1/grp2/grp3/dset2> +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_505.txt b/tools/h5diff/testfiles/h5diff_505.txt new file mode 100644 index 0000000..28640b7 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_505.txt @@ -0,0 +1,6 @@ +</grp1> is of type H5G_GROUP and </slink_grp1> is of type H5G_LINK +-------------------------------- +Some objects are not comparable +-------------------------------- +Use -c for a list of objects. +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_506.txt b/tools/h5diff/testfiles/h5diff_506.txt new file mode 100644 index 0000000..efef9a7 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_506.txt @@ -0,0 +1,26 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset1 + x x /dset2 + x x /grp3 + x x /grp3/dset1 + x x /grp3/dset2 + x x /grp3/dset3 + +group : </grp1/grp2> and </slink_grp2> +0 differences found +dataset: </grp1/grp2/dset1> and </slink_grp2/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </slink_grp2/dset2> +0 differences found +group : </grp1/grp2/grp3> and </slink_grp2/grp3> +0 differences found +dataset: </grp1/grp2/grp3/dset1> and </slink_grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/grp3/dset2> and </slink_grp2/grp3/dset2> +0 differences found +dataset: </grp1/grp2/grp3/dset3> and </slink_grp2/grp3/dset3> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_507.txt b/tools/h5diff/testfiles/h5diff_507.txt new file mode 100644 index 0000000..ed2b799 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_507.txt @@ -0,0 +1,6 @@ +</grp1> is of type H5G_GROUP and </elink_grp1> is of type H5G_UDLINK +-------------------------------- +Some objects are not comparable +-------------------------------- +Use -c for a list of objects. +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_508.txt b/tools/h5diff/testfiles/h5diff_508.txt new file mode 100644 index 0000000..9796345 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_508.txt @@ -0,0 +1,32 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset1 + x x /grp2 + x x /grp2/dset1 + x x /grp2/dset2 + x x /grp2/grp3 + x x /grp2/grp3/dset1 + x x /grp2/grp3/dset2 + x x /grp2/grp3/dset3 + +group : </grp1> and </elink_grp1> +0 differences found +dataset: </grp1/dset1> and </elink_grp1/dset1> +0 differences found +group : </grp1/grp2> and </elink_grp1/grp2> +0 differences found +dataset: </grp1/grp2/dset1> and </elink_grp1/grp2/dset1> +0 differences found +dataset: </grp1/grp2/dset2> and </elink_grp1/grp2/dset2> +0 differences found +group : </grp1/grp2/grp3> and </elink_grp1/grp2/grp3> +0 differences found +dataset: </grp1/grp2/grp3/dset1> and </elink_grp1/grp2/grp3/dset1> +0 differences found +dataset: </grp1/grp2/grp3/dset2> and </elink_grp1/grp2/grp3/dset2> +0 differences found +dataset: </grp1/grp2/grp3/dset3> and </elink_grp1/grp2/grp3/dset3> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_509.txt b/tools/h5diff/testfiles/h5diff_509.txt new file mode 100644 index 0000000..145cd9d --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_509.txt @@ -0,0 +1,6 @@ +</slink_grp1> is of type H5G_LINK and </elink_grp1> is of type H5G_UDLINK +-------------------------------- +Some objects are not comparable +-------------------------------- +Use -c for a list of objects. +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_510.txt b/tools/h5diff/testfiles/h5diff_510.txt new file mode 100644 index 0000000..9d92768 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_510.txt @@ -0,0 +1,32 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset1 + x x /grp2 + x x /grp2/dset1 + x x /grp2/dset2 + x x /grp2/grp3 + x x /grp2/grp3/dset1 + x x /grp2/grp3/dset2 + x x /grp2/grp3/dset3 + +group : </slink_grp1> and </elink_grp1> +0 differences found +dataset: </slink_grp1/dset1> and </elink_grp1/dset1> +0 differences found +group : </slink_grp1/grp2> and </elink_grp1/grp2> +0 differences found +dataset: </slink_grp1/grp2/dset1> and </elink_grp1/grp2/dset1> +0 differences found +dataset: </slink_grp1/grp2/dset2> and </elink_grp1/grp2/dset2> +0 differences found +group : </slink_grp1/grp2/grp3> and </elink_grp1/grp2/grp3> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset1> and </elink_grp1/grp2/grp3/dset1> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset2> and </elink_grp1/grp2/grp3/dset2> +0 differences found +dataset: </slink_grp1/grp2/grp3/dset3> and </elink_grp1/grp2/grp3/dset3> +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_511.txt b/tools/h5diff/testfiles/h5diff_511.txt new file mode 100644 index 0000000..4bac100 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_511.txt @@ -0,0 +1,24 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset4 + x x /dset5 + x x /elink_grp_circle + +group : </grp10> and </grp11> +0 differences found +dataset: </grp10/dset4> and </grp11/dset4> +0 differences found +dataset: </grp10/dset5> and </grp11/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 3 2 1 +[ 0 3 ] 3 2 1 +[ 1 0 ] 3 2 1 +[ 1 2 ] 3 2 1 +4 differences found +external link: </grp10/elink_grp_circle> and </grp11/elink_grp_circle> +1 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_512.txt b/tools/h5diff/testfiles/h5diff_512.txt new file mode 100644 index 0000000..23fbc12 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_512.txt @@ -0,0 +1,53 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset4 + x x /dset5 + x x /elink_grp_circle + x x /elink_grp_circle/dset4 + x x /elink_grp_circle/dset5 + x x /elink_grp_circle/elink_grp_circle + x x /elink_grp_circle/elink_grp_circle/dset4 + x x /elink_grp_circle/elink_grp_circle/dset5 + +group : </grp10> and </grp11> +0 differences found +dataset: </grp10/dset4> and </grp11/dset4> +0 differences found +dataset: </grp10/dset5> and </grp11/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 3 2 1 +[ 0 3 ] 3 2 1 +[ 1 0 ] 3 2 1 +[ 1 2 ] 3 2 1 +4 differences found +group : </grp10/elink_grp_circle> and </grp11/elink_grp_circle> +0 differences found +dataset: </grp10/elink_grp_circle/dset4> and </grp11/elink_grp_circle/dset4> +0 differences found +dataset: </grp10/elink_grp_circle/dset5> and </grp11/elink_grp_circle/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 2 3 1 +[ 0 3 ] 2 3 1 +[ 1 0 ] 2 3 1 +[ 1 2 ] 2 3 1 +4 differences found +group : </grp10/elink_grp_circle/elink_grp_circle> and </grp11/elink_grp_circle/elink_grp_circle> +0 differences found +dataset: </grp10/elink_grp_circle/elink_grp_circle/dset4> and </grp11/elink_grp_circle/elink_grp_circle/dset4> +0 differences found +dataset: </grp10/elink_grp_circle/elink_grp_circle/dset5> and </grp11/elink_grp_circle/elink_grp_circle/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 3 2 1 +[ 0 3 ] 3 2 1 +[ 1 0 ] 3 2 1 +[ 1 2 ] 3 2 1 +4 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_513.txt b/tools/h5diff/testfiles/h5diff_513.txt new file mode 100644 index 0000000..b0af15d --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_513.txt @@ -0,0 +1,3 @@ +link : </slink_grp10> and </slink_grp11> +1 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_514.txt b/tools/h5diff/testfiles/h5diff_514.txt new file mode 100644 index 0000000..f8e16e9 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_514.txt @@ -0,0 +1,53 @@ + +group1 group2 +--------------------------------------- + x x + x x /dset4 + x x /dset5 + x x /elink_grp_circle + x x /elink_grp_circle/dset4 + x x /elink_grp_circle/dset5 + x x /elink_grp_circle/elink_grp_circle + x x /elink_grp_circle/elink_grp_circle/dset4 + x x /elink_grp_circle/elink_grp_circle/dset5 + +group : </slink_grp10> and </slink_grp11> +0 differences found +dataset: </slink_grp10/dset4> and </slink_grp11/dset4> +0 differences found +dataset: </slink_grp10/dset5> and </slink_grp11/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 3 2 1 +[ 0 3 ] 3 2 1 +[ 1 0 ] 3 2 1 +[ 1 2 ] 3 2 1 +4 differences found +group : </slink_grp10/elink_grp_circle> and </slink_grp11/elink_grp_circle> +0 differences found +dataset: </slink_grp10/elink_grp_circle/dset4> and </slink_grp11/elink_grp_circle/dset4> +0 differences found +dataset: </slink_grp10/elink_grp_circle/dset5> and </slink_grp11/elink_grp_circle/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 2 3 1 +[ 0 3 ] 2 3 1 +[ 1 0 ] 2 3 1 +[ 1 2 ] 2 3 1 +4 differences found +group : </slink_grp10/elink_grp_circle/elink_grp_circle> and </slink_grp11/elink_grp_circle/elink_grp_circle> +0 differences found +dataset: </slink_grp10/elink_grp_circle/elink_grp_circle/dset4> and </slink_grp11/elink_grp_circle/elink_grp_circle/dset4> +0 differences found +dataset: </slink_grp10/elink_grp_circle/elink_grp_circle/dset5> and </slink_grp11/elink_grp_circle/elink_grp_circle/dset5> +size: [2x4] [2x4] +position dset5 dset5 difference +------------------------------------------------------------ +[ 0 1 ] 3 2 1 +[ 0 3 ] 3 2 1 +[ 1 0 ] 3 2 1 +[ 1 2 ] 3 2 1 +4 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_600.txt b/tools/h5diff/testfiles/h5diff_600.txt index cf540ab..b096ab5 100644 --- a/tools/h5diff/testfiles/h5diff_600.txt +++ b/tools/h5diff/testfiles/h5diff_600.txt @@ -1,4 +1,4 @@ -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -69,16 +69,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_601.txt b/tools/h5diff/testfiles/h5diff_601.txt new file mode 100644 index 0000000..eb12f38 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_601.txt @@ -0,0 +1,2 @@ +Object </nono_obj> could not be found in <h5diff_basic1.h5> +EXIT CODE: 2 diff --git a/tools/h5diff/testfiles/h5diff_603.txt b/tools/h5diff/testfiles/h5diff_603.txt index 2f2e93f..2b37530 100644 --- a/tools/h5diff/testfiles/h5diff_603.txt +++ b/tools/h5diff/testfiles/h5diff_603.txt @@ -1,5 +1,5 @@ <-d -4> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_606.txt b/tools/h5diff/testfiles/h5diff_606.txt index 3381406..63a1d53 100644 --- a/tools/h5diff/testfiles/h5diff_606.txt +++ b/tools/h5diff/testfiles/h5diff_606.txt @@ -1,5 +1,5 @@ <-d 0x1> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_612.txt b/tools/h5diff/testfiles/h5diff_612.txt index 8c6051e..6141495 100644 --- a/tools/h5diff/testfiles/h5diff_612.txt +++ b/tools/h5diff/testfiles/h5diff_612.txt @@ -1,5 +1,5 @@ <-p -4> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_615.txt b/tools/h5diff/testfiles/h5diff_615.txt index b713c7b..eaa2078 100644 --- a/tools/h5diff/testfiles/h5diff_615.txt +++ b/tools/h5diff/testfiles/h5diff_615.txt @@ -1,5 +1,5 @@ <-p 0x1> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_621.txt b/tools/h5diff/testfiles/h5diff_621.txt index ee23b90..8319db9 100644 --- a/tools/h5diff/testfiles/h5diff_621.txt +++ b/tools/h5diff/testfiles/h5diff_621.txt @@ -1,5 +1,5 @@ <-n -4> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_622.txt b/tools/h5diff/testfiles/h5diff_622.txt index 11e2ce1..1ccff92 100644 --- a/tools/h5diff/testfiles/h5diff_622.txt +++ b/tools/h5diff/testfiles/h5diff_622.txt @@ -1,5 +1,5 @@ <-n 0> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_623.txt b/tools/h5diff/testfiles/h5diff_623.txt index f87d6db..2c15d98 100644 --- a/tools/h5diff/testfiles/h5diff_623.txt +++ b/tools/h5diff/testfiles/h5diff_623.txt @@ -1,5 +1,5 @@ <-n u> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_624.txt b/tools/h5diff/testfiles/h5diff_624.txt index 4c9da26..272b9fc 100644 --- a/tools/h5diff/testfiles/h5diff_624.txt +++ b/tools/h5diff/testfiles/h5diff_624.txt @@ -1,5 +1,5 @@ <-n 0x1> is not a valid option -usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] +usage: h5diff [OPTIONS] file1 file2 [obj1[ obj2]] file1 File name of the first HDF5 file file2 File name of the second HDF5 file [obj1] Name of an HDF5 object, in absolute path @@ -70,16 +70,26 @@ usage: h5diff [OPTIONS] file1 file2 [obj1[obj2]] -v Verbose mode: print the above plus a list of objects and warnings -q Quiet mode: do not print output - Compare criteria - If no objects [obj1[obj2]] are specified, h5diff only compares objects - with the same absolute path in both files + File comparison: + If no objects [obj1[ obj2]] are specified, the h5diff comparison proceeds as + a comparison of the two files' root groups. That is, h5diff first compares + the names of root group members, generates a report of root group objects + that appear in only one file or in both files, and recursively compares + common objects. - The compare criteria is: - 1) datasets: numerical array differences - 2) groups: name string difference - 3) datatypes: the return value of H5Tequal - 4) links: name string difference of the linked value as default - (refer to --follow-symlinks option). + Object comparison: + 1) Groups + First compares the names of member objects (relative path, from the + specified group) and generates a report of objects that appear in only + one group or in both groups. Common objects are then compared recursively. + 2) Datasets + Array rank and dimensions, datatypes, and data values are compared. + 3) Datatypes + The comparison is based on the return value of H5Tequal. + 4) Symbolic links + The paths to the target objects are compared. + (The option --follow-symlinks overrides the default behavior when + symbolic links are compared.). Exit code: 0 if no differences, 1 if differences found, 2 if error diff --git a/tools/h5diff/testfiles/h5diff_grp_recurse1.h5 b/tools/h5diff/testfiles/h5diff_grp_recurse1.h5 Binary files differnew file mode 100644 index 0000000..cfd4e62 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_grp_recurse1.h5 diff --git a/tools/h5diff/testfiles/h5diff_grp_recurse2.h5 b/tools/h5diff/testfiles/h5diff_grp_recurse2.h5 Binary files differnew file mode 100644 index 0000000..54bcdec --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_grp_recurse2.h5 diff --git a/tools/h5diff/testh5diff.sh b/tools/h5diff/testh5diff.sh index 421bf73..f9d58c2 100755 --- a/tools/h5diff/testh5diff.sh +++ b/tools/h5diff/testh5diff.sh @@ -54,6 +54,8 @@ FILE17=h5diff_ext2softlink_src.h5 FILE18=h5diff_ext2softlink_trg.h5 DANGLE_LINK_FILE1=h5diff_danglelinks1.h5 DANGLE_LINK_FILE2=h5diff_danglelinks2.h5 +GRP_RECURSE_FILE1=h5diff_grp_recurse1.h5 +GRP_RECURSE_FILE2=h5diff_grp_recurse2.h5 TESTNAME=h5diff EXIT_SUCCESS=0 @@ -305,7 +307,6 @@ SKIP() { # # Common usage # ############################################################################ - # 1.0 TOOLTEST h5diff_10.txt -h @@ -425,6 +426,9 @@ TOOLTEST h5diff_58.txt -v $FILE7 $FILE8 refreg # 6.0: Check if the command line number of arguments is less than 3 TOOLTEST h5diff_600.txt $FILE1 +# 6.1: Check if non-exist object name is specified +TOOLTEST h5diff_601.txt $FILE1 $FILE1 nono_obj + # ############################################################################## # # -d @@ -688,6 +692,44 @@ TOOLTEST h5diff_459.txt --follow-symlinks -v --no-dangling-links $FILE15 $FILE # ############################################################################## +# # test for group diff recursivly +# ############################################################################## +# root +TOOLTEST h5diff_500.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 / / +TOOLTEST h5diff_501.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 / / + +# root vs group +TOOLTEST h5diff_502.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 / /grp1/grp2/grp3 + +# group vs group (same name and structure) +TOOLTEST h5diff_503.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1 /grp1 + +# group vs group (different name and structure) +TOOLTEST h5diff_504.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1/grp2 /grp1/grp2/grp3 + +# groups vs soft-link +TOOLTEST h5diff_505.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1 /slink_grp1 +TOOLTEST h5diff_506.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1/grp2 /slink_grp2 + +# groups vs ext-link +TOOLTEST h5diff_507.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1 /elink_grp1 +TOOLTEST h5diff_508.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp1 /elink_grp1 + +# soft-link vs ext-link +TOOLTEST h5diff_509.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /slink_grp1 /elink_grp1 +TOOLTEST h5diff_510.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /slink_grp1 /elink_grp1 + +# circled ext links +TOOLTEST h5diff_511.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp10 /grp11 +TOOLTEST h5diff_512.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /grp10 /grp11 + +# circled soft2ext-link vs soft2ext-link +TOOLTEST h5diff_513.txt -v $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /slink_grp10 /slink_grp11 +TOOLTEST h5diff_514.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FILE2 /slink_grp10 /slink_grp11 + + + +# ############################################################################## # # END # ############################################################################## diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index 5bda0b4..b1d9ee9 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -34,18 +34,6 @@ #define NAME_BUF_SIZE 2048 -/* Struct to keep track of symbolic link targets visited */ -typedef struct symlink_trav_t { - size_t nalloc; - size_t nused; - struct { - H5L_type_t type; - char *file; - char *path; - } *objs; - hbool_t dangle_link; -} symlink_trav_t; - /* Struct to pass through to visitors */ typedef struct { const char *fname; /* Filename */ @@ -1842,120 +1830,6 @@ done: return 0; } /* end list_obj() */ - -/*------------------------------------------------------------------------- - * Function: symlink_visit_add - * - * Purpose: Add an symbolic link to visited data structure - * - * Return: 0 on success, -1 on failure - * - * Programmer: Neil Fortner, nfortne2@hdfgroup.org - * Adapted from trav_addr_add in h5trav.c by Quincey Koziol - * - * Date: September 5, 2008 - * - * Modified: - * Jonathan Kim - * - Renamed from elink_trav_add to symlink_visit_add for both soft and - * external links. (May 25, 2010) - * - Add type parameter to distingush between soft and external link for - * sure, which prevent from mixing up visited link when the target names - * are same between the soft and external link, as code marks with the - * target name. (May 25,2010) - * - *------------------------------------------------------------------------- - */ -static herr_t -symlink_visit_add(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path) -{ - size_t idx; /* Index of address to use */ - void *tmp_ptr; - - /* Allocate space if necessary */ - if(visited->nused == visited->nalloc) - { - visited->nalloc = MAX(1, visited->nalloc * 2); - if(NULL == (tmp_ptr = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0])))) - return -1; - visited->objs = tmp_ptr; - } /* end if */ - - /* Append it */ - idx = visited->nused++; - - visited->objs[idx].type = type; - visited->objs[idx].file = NULL; - visited->objs[idx].path = NULL; - - if (type == H5L_TYPE_EXTERNAL) - { - if(NULL == (visited->objs[idx].file = HDstrdup(file))) - { - visited->nused--; - return -1; - } - } - - if(NULL == (visited->objs[idx].path = HDstrdup(path))) - { - visited->nused--; - if (visited->objs[idx].file) - HDfree (visited->objs[idx].file); - return -1; - } - - return 0; -} /* end symlink_visit_add() */ - - -/*------------------------------------------------------------------------- - * Function: symlink_is_visited - * - * Purpose: Check if an symbolic link has already been visited - * - * Return: TRUE/FALSE - * - * Programmer: Neil Fortner, nfortne2@hdfgroup.org - * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol - * - * Date: September 5, 2008 - * - * Modified: - * Jonathan Kim - * - Renamed from elink_trav_visited to symlink_is_visited for both soft and - * external links. (May 25, 2010) - * - Add type parameter to distingush between soft and external link for - * sure, which prevent from mixing up visited link when the target names - * are same between the soft and external link, as code marks with the - * target name. (May 25,2010) - * - *------------------------------------------------------------------------- - */ -static hbool_t -symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path) -{ - size_t u; /* Local index variable */ - - /* Look for symlink */ - for(u = 0; u < visited->nused; u++) - { - /* Check for symlink values already in array */ - /* check type and path pair to distingush between symbolic links */ - if ((visited->objs[u].type == type) && !HDstrcmp(visited->objs[u].path, path)) - { - /* if external link, file need to be matched as well */ - if (visited->objs[u].type == H5L_TYPE_EXTERNAL) - { - if (!HDstrcmp(visited->objs[u].file, file)) - return (TRUE); - } - return (TRUE); - } - } - /* Didn't find symlink */ - return(FALSE); -} /* end symlink_is_visited() */ /*------------------------------------------------------------------------- @@ -1983,7 +1857,7 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) /* init linkinfo struct */ memset(&lnk_info, 0, sizeof(h5tool_link_info_t)); - /* if verbose, make H5tools_get_link_info() display more */ + /* if verbose, make H5tools_get_symlink_info() display more */ if (verbose_g) lnk_info.opt.msg_mode=1; @@ -1992,8 +1866,8 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) switch(linfo->type) { case H5L_TYPE_SOFT: - ret = H5tools_get_link_info(iter->fid, name, &lnk_info, follow_symlink_g); - /* lnk_info.trg_path is malloced in H5tools_get_link_info() + ret = H5tools_get_symlink_info(iter->fid, name, &lnk_info, follow_symlink_g); + /* lnk_info.trg_path is malloced in H5tools_get_symlink_info() * so it will be freed via buf later */ buf = lnk_info.trg_path; /* error */ @@ -2050,8 +1924,8 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) const char *path; hbool_t follow_link = follow_symlink_g || follow_elink_g; - ret = H5tools_get_link_info(iter->fid, name, &lnk_info, follow_link); - /* lnk_info.trg_path is malloced in H5tools_get_link_info() + ret = H5tools_get_symlink_info(iter->fid, name, &lnk_info, follow_link); + /* lnk_info.trg_path is malloced in H5tools_get_symlink_info() * so it will be freed via buf later */ buf = lnk_info.trg_path; /* error */ diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 5d2343a..2734bef 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -219,18 +219,265 @@ static int is_valid_options(diff_opt_t *options) } out: - if (!ret) - { -#ifdef H5_HAVE_PARALLEL - if(g_Parallel) - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); -#endif - } return ret; } +/*------------------------------------------------------------------------- + * Function: build_match_list + * + * Purpose: get list of matching path_name from info1 and info2 + * + * Note: + * Find common objects; the algorithm used for this search is the + * cosequential match algorithm and is described in + * Folk, Michael; Zoellick, Bill. (1992). File Structures. Addison-Wesley. + * Moved out from diff_match() to make code more flexible. + * + * Parameter: + * table_out [OUT] : return the list + * + * Programmer: Jonathan Kim + * + * Date: Aug 18, 2010 + *------------------------------------------------------------------------*/ +static void build_match_list (const char *objname1, trav_info_t *info1, const char *objname2, trav_info_t *info2, trav_table_t ** table_out, diff_opt_t *options) +{ + unsigned i; + size_t curr1 = 0; + size_t curr2 = 0; + unsigned infile[2]; + char * path1_lp; + char * path2_lp; + int path1_offset = 0; + int path2_offset = 0; + int cmp; + trav_table_t *table; + + /* init */ + trav_table_init( &table ); + + /* + * This is necessary for the case that given objects are group and + * have different names (ex: obj1 is /grp1 and obj2 is /grp5). + * All the objects belong to given groups are the cadidates. + * So prepare to compare paths without the group names. + */ + /* if obj1 is not root */ + if (HDstrcmp (objname1,"/") != 0) + path1_offset = HDstrlen(objname1); + /* if obj2 is not root */ + if (HDstrcmp (objname2,"/") != 0) + path2_offset = HDstrlen(objname2); + + /*-------------------------------------------------- + * build the list + */ + while(curr1 < info1->nused && curr2 < info2->nused) + { + + path1_lp = (info1->paths[curr1].path) + path1_offset; + path2_lp = (info2->paths[curr2].path) + path2_offset; + + /* criteria is string compare */ + cmp = HDstrcmp(path1_lp, path2_lp); + + if(cmp == 0) { + infile[0] = 1; + infile[1] = 1; + trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); + + curr1++; + curr2++; + } /* end if */ + else if(cmp < 0) + { + infile[0] = 1; + infile[1] = 0; + trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); + curr1++; + } /* end else-if */ + else + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); + curr2++; + } /* end else */ + } /* end while */ + + /* list1 did not end */ + infile[0] = 1; + infile[1] = 0; + while(curr1 < info1->nused) + { + path1_lp = (info1->paths[curr1].path) + path1_offset; + trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); + curr1++; + } /* end while */ + + /* list2 did not end */ + infile[0] = 0; + infile[1] = 1; + while(curr2 < info2->nused) + { + path2_lp = (info2->paths[curr2].path) + path2_offset; + trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); + curr2++; + } /* end while */ + + /*------------------------------------------------------ + * print the list + */ + if(options->m_verbose) + { + parallel_print("\n"); + /* if given objects is group under root */ + if (HDstrcmp (objname1,"/") || HDstrcmp (objname2,"/")) + parallel_print("group1 group2\n"); + else + parallel_print("file1 file2\n"); + parallel_print("---------------------------------------\n"); + for(i = 0; i < table->nobjs; i++) + { + char c1, c2; + c1 = (table->objs[i].flags[0]) ? 'x' : ' '; + c2 = (table->objs[i].flags[1]) ? 'x' : ' '; + parallel_print("%5c %6c %-15s\n", c1, c2, table->objs[i].name); + } /* end for */ + parallel_print ("\n"); + } /* end if */ + + *table_out = table; +} + + +/*------------------------------------------------------------------------- + * Function: trav_grp_objs + * + * Purpose: + * Call back function from h5trav_visit(). + * + * Programmer: Jonathan Kim + * + * Date: Aug 16, 2010 + *------------------------------------------------------------------------*/ +static herr_t trav_grp_objs(const char *path, const H5O_info_t *oinfo, + const char *already_visited, void *udata) +{ + trav_info_visit_obj(path, oinfo, already_visited, udata); + + return 0; +} + +/*------------------------------------------------------------------------- + * Function: trav_grp_symlinks + * + * Purpose: + * Call back function from h5trav_visit(). + * Track and extra checkings while visiting all symbolic-links. + * + * Programmer: Jonathan Kim + * + * Date: Aug 16, 2010 + *------------------------------------------------------------------------*/ +static herr_t trav_grp_symlinks(const char *path, const H5L_info_t *linfo, + void *udata) +{ + trav_info_t *tinfo = (trav_info_t *)udata; + diff_opt_t *opts = (diff_opt_t *)tinfo->opts; + int ret; + h5tool_link_info_t lnk_info; + const char *ext_fname; + const char *ext_path; + + /* init linkinfo struct */ + memset(&lnk_info, 0, sizeof(h5tool_link_info_t)); + + if (!opts->follow_links) + { + trav_info_visit_lnk(path, linfo, tinfo); + goto done; + } + + switch(linfo->type) + { + case H5L_TYPE_SOFT: + ret = H5tools_get_symlink_info(tinfo->fid, path, &lnk_info, opts->follow_links); + /* error */ + if (ret < 0) + goto done; + /* no dangling link option given and detect dangling link */ + else if (ret == 0) + { + tinfo->symlink_visited.dangle_link = TRUE; + trav_info_visit_lnk(path, linfo, tinfo); + if (opts->no_dangle_links) + opts->err_stat = 1; /* make dgangling link is error */ + goto done; + } + + /* check if already visit the target object */ + if(symlink_is_visited( &(tinfo->symlink_visited), linfo->type, NULL, lnk_info.trg_path)) + goto done; + + /* add this link as visited link */ + if(symlink_visit_add( &(tinfo->symlink_visited), linfo->type, NULL, lnk_info.trg_path) < 0) + goto done; + + if(h5trav_visit(tinfo->fid, path, TRUE, TRUE, + trav_grp_objs,trav_grp_symlinks, tinfo) < 0) + { + parallel_print("Error: Could not get file contents\n"); + opts->err_stat = 1; + goto done; + } + break; + + case H5L_TYPE_EXTERNAL: + ret = H5tools_get_symlink_info(tinfo->fid, path, &lnk_info, opts->follow_links); + /* error */ + if (ret < 0) + goto done; + /* no dangling link option given and detect dangling link */ + else if (ret == 0) + { + tinfo->symlink_visited.dangle_link = TRUE; + trav_info_visit_lnk(path, linfo, tinfo); + if (opts->no_dangle_links) + opts->err_stat = 1; /* make dgangling link is error */ + goto done; + } + + if(H5Lunpack_elink_val(lnk_info.trg_path, linfo->u.val_size, NULL, &ext_fname, &ext_path) < 0) + goto done; + + /* check if already visit the target object */ + if(symlink_is_visited( &(tinfo->symlink_visited), linfo->type, ext_fname, ext_path)) + goto done; + + /* add this link as visited link */ + if(symlink_visit_add( &(tinfo->symlink_visited), linfo->type, ext_fname, ext_path) < 0) + goto done; + + if(h5trav_visit(tinfo->fid, path, TRUE, TRUE, + trav_grp_objs,trav_grp_symlinks, tinfo) < 0) + { + parallel_print("Error: Could not get file contents\n"); + opts->err_stat = 1; + goto done; + } + break; + default: + ; + break; + } /* end of switch */ + +done: + if (lnk_info.trg_path) + HDfree(lnk_info.trg_path); + return 0; +} /*------------------------------------------------------------------------- @@ -253,14 +500,42 @@ hsize_t h5diff(const char *fname1, const char *objname2, diff_opt_t *options) { - trav_info_t *info1=NULL; - trav_info_t *info2=NULL; hid_t file1_id = (-1); hid_t file2_id = (-1); - char filenames[2][1024]; + char filenames[2][MAX_FILENAME]; hsize_t nfound = 0; - - HDmemset(filenames, 0, 1024 * 2); + int i; + //int i1, i2; + int l_ret; + const char * obj1fullname = NULL; + const char * obj2fullname = NULL; + /* init to group type */ + h5trav_type_t obj1type = H5TRAV_TYPE_GROUP; + h5trav_type_t obj2type = H5TRAV_TYPE_GROUP; + /* for single object */ + H5O_info_t oinfo1, oinfo2; /* object info */ + trav_info_t *info1_obj = NULL; + trav_info_t *info2_obj = NULL; + /* for group object */ + trav_info_t *info1_grp = NULL; + trav_info_t *info2_grp = NULL; + /* local pointer */ + trav_info_t *info1_lp; + trav_info_t *info2_lp; + /* link info from specified object */ + H5L_info_t src_linfo1; + H5L_info_t src_linfo2; + /* link info from member object */ + h5tool_link_info_t trg_linfo1; + h5tool_link_info_t trg_linfo2; + /* list for common objects */ + trav_table_t *match_list = NULL; + + /* init filenames */ + HDmemset(filenames, 0, MAX_FILENAME * 2); + /* init link info struct */ + HDmemset(&trg_linfo1, 0, sizeof(h5tool_link_info_t)); + HDmemset(&trg_linfo2, 0, sizeof(h5tool_link_info_t)); /*------------------------------------------------------------------------- * check invalid combination of options @@ -277,35 +552,19 @@ hsize_t h5diff(const char *fname1, H5E_BEGIN_TRY { /* open file 1 */ - if((file1_id = h5tools_fopen(fname1, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { - parallel_print("h5diff: <%s>: unable to open file\n", fname1); options->err_stat = 1; - -#ifdef H5_HAVE_PARALLEL - if(g_Parallel) - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); -#endif goto out; } /* end if */ /* open file 2 */ - if((file2_id = h5tools_fopen(fname2, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, (size_t)0)) < 0) { - parallel_print("h5diff: <%s>: unable to open file\n", fname2); options->err_stat = 1; - -#ifdef H5_HAVE_PARALLEL - if(g_Parallel) - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); -#endif goto out; } /* end if */ /* enable error reporting */ @@ -315,61 +574,274 @@ hsize_t h5diff(const char *fname1, * Initialize the info structs *------------------------------------------------------------------------- */ - trav_info_init(&info1); - trav_info_init(&info2); + trav_info_init(fname1, file1_id, &info1_obj); + trav_info_init(fname2, file2_id, &info2_obj); - /*------------------------------------------------------------------------- - * get the list of objects in the files - *------------------------------------------------------------------------- - */ - if(h5trav_getinfo(file1_id, info1) < 0 || h5trav_getinfo(file2_id, info2) < 0) { - parallel_print("Error: Could not get file contents\n"); - options->err_stat = 1; -#ifdef H5_HAVE_PARALLEL - if(g_Parallel) - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); -#endif - goto out; - } /* end if */ - - /*------------------------------------------------------------------------- - * object name was supplied - *------------------------------------------------------------------------- - */ - if( objname1 ) + /* if any object is specified */ + if (objname1) { -#ifdef H5_HAVE_PARALLEL - if(g_Parallel) - /* Let tasks know that they won't be needed */ - phdiff_dismiss_workers(); -#endif - assert(objname2); - options->cmn_objs = 1; /* eliminate warning */ - nfound = diff_compare(file1_id, - fname1, - objname1, - info1, - file2_id, - fname2, - objname2, - info2, - options); - } /* end if */ - /*------------------------------------------------------------------------- - * compare all - *------------------------------------------------------------------------- - */ + /* malloc 2 more for "/" and end-of-line */ + obj1fullname = (char*)HDcalloc(HDstrlen(objname1) + 2, sizeof(char)); + obj2fullname = (char*)HDcalloc(HDstrlen(objname2) + 2, sizeof(char)); + + /* make the given object1 fullpath, start with "/" */ + if (HDstrncmp(objname1, "/", 1)) + { + HDstrcpy(obj1fullname, "/"); + HDstrcat(obj1fullname, objname1); + } + else + HDstrcpy(obj1fullname, objname1); + + /* make the given object2 fullpath, start with "/" */ + if (HDstrncmp(objname2, "/", 1)) + { + HDstrcpy(obj2fullname, "/"); + HDstrcat(obj2fullname, objname2); + } + else + HDstrcpy(obj2fullname, objname2); + + /*---------------------------------------------------------- + * check if obj1 is root, group, single object or symlink + */ + if(!HDstrcmp(obj1fullname, "/")) + { + obj1type = H5TRAV_TYPE_GROUP; + } + else + { + /* check if link itself exist */ + if(H5Lexists(file1_id, obj1fullname, H5P_DEFAULT) <= 0) + { + parallel_print ("Object <%s> could not be found in <%s>\n", obj1fullname, fname1); + options->err_stat = 1; + goto out; + } + /* get info from link */ + if(H5Lget_info(file1_id, obj1fullname, &src_linfo1, H5P_DEFAULT) < 0) + { + parallel_print("Unable to get link info from <%s>\n", obj1fullname); + goto out; + } + + info1_lp = info1_obj; + + /* + * check the type of specified path for hard and symbolic links + */ + if(src_linfo1.type == H5L_TYPE_HARD) + { + /* optional data pass */ + info1_obj->opts = (diff_opt_t*)options; + + if(H5Oget_info_by_name(file1_id, obj1fullname, &oinfo1, H5P_DEFAULT) < 0) + { + parallel_print("Error: Could not get file contents\n"); + options->err_stat = 1; + goto out; + } + obj1type = oinfo1.type; + trav_info_add(info1_obj, obj1fullname, obj1type); + } + else if (src_linfo1.type == H5L_TYPE_SOFT) + { + obj1type = H5TRAV_TYPE_LINK; + trav_info_add(info1_obj, obj1fullname, obj1type); + } + else if (src_linfo1.type == H5L_TYPE_EXTERNAL) + { + obj1type = H5TRAV_TYPE_UDLINK; + trav_info_add(info1_obj, obj1fullname, obj1type); + } + } + + /*---------------------------------------------------------- + * check if obj2 is root, group, single object or symlink + */ + if(!HDstrcmp(obj2fullname, "/")) + { + obj2type = H5TRAV_TYPE_GROUP; + } + else + { + /* check if link itself exist */ + if(H5Lexists(file2_id, obj2fullname, H5P_DEFAULT) <= 0) + { + parallel_print ("Object <%s> could not be found in <%s>\n", obj2fullname, fname2); + options->err_stat = 1; + goto out; + } + /* get info from link */ + if(H5Lget_info(file2_id, obj2fullname, &src_linfo2, H5P_DEFAULT) < 0) + { + parallel_print("Unable to get link info from <%s>\n", obj2fullname); + goto out; + } + + info2_lp = info2_obj; + + /* + * check the type of specified path for hard and symbolic links + */ + if(src_linfo2.type == H5L_TYPE_HARD) + { + /* optional data pass */ + info2_obj->opts = (diff_opt_t*)options; + + if(H5Oget_info_by_name(file2_id, obj2fullname, &oinfo2, H5P_DEFAULT) < 0) + { + parallel_print("Error: Could not get file contents\n"); + options->err_stat = 1; + goto out; + } + obj2type = oinfo2.type; + trav_info_add(info2_obj, obj2fullname, obj2type); + } + else if (src_linfo2.type == H5L_TYPE_SOFT) + { + obj2type = H5TRAV_TYPE_LINK; + trav_info_add(info2_obj, obj2fullname, obj2type); + } + else if (src_linfo2.type == H5L_TYPE_EXTERNAL) + { + obj2type = H5TRAV_TYPE_UDLINK; + trav_info_add(info2_obj, obj2fullname, obj2type); + } + } + } + /* if no object specified */ else { + /* set root group */ + obj1fullname = (char*)HDcalloc(2, sizeof(char)); + HDstrcat(obj1fullname, "/"); + obj2fullname = (char*)HDcalloc(2, sizeof(char)); + HDstrcat(obj2fullname, "/"); + } + + options->cmn_objs = 1; /* eliminate warning */ + + /*--------------------------------------------- + * check for following symlinks + */ + if (options->follow_links) + { + /* pass how to handle printing warning to linkinfo option */ + if(print_warn(options)) + trg_linfo1.opt.msg_mode = trg_linfo2.opt.msg_mode = 1; + + /*------------------------------- + * check symbolic link (object1) + */ + l_ret = H5tools_get_symlink_info(file1_id, obj1fullname, &trg_linfo1, TRUE); + /* dangling link */ + if (l_ret == 0) + { + if (options->no_dangle_links) + { + /* gangling link is error */ + if(options->m_verbose) + parallel_print("Warning: <%s> is a dangling link.\n", obj1fullname); + options->err_stat = 1; + goto out; + } + else + { + if(options->m_verbose) + parallel_print("obj1 <%s> is a dangling link.\n", obj1fullname); + nfound++; + print_found(nfound); + goto out; + } + } + else if(l_ret < 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 */ + 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 (options->no_dangle_links) + { + /* gangling link is error */ + if(options->m_verbose) + parallel_print("Warning: <%s> is a dangling link.\n", obj2fullname); + options->err_stat = 1; + goto out; + } + else + { + if(options->m_verbose) + parallel_print("obj2 <%s> is a dangling link.\n", obj2fullname); + nfound++; + print_found(nfound); + goto out; + } + } + else if(l_ret < 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 */ + obj2type = trg_linfo2.trg_type; + } /* end of if follow symlinks */ + + + /* if both obj1 and obj2 are group */ + if (obj1type == H5TRAV_TYPE_GROUP && obj2type == H5TRAV_TYPE_GROUP) + { + /* + * traverse group1 + */ + trav_info_init(fname1, file1_id, &info1_grp); + /* optional data pass */ + info1_grp->opts = (diff_opt_t*)options; + + if(h5trav_visit(file1_id,obj1fullname,TRUE,TRUE, + trav_grp_objs,trav_grp_symlinks, info1_grp) < 0) + { + parallel_print("Error: Could not get file contents\n"); + options->err_stat = 1; + goto out; + } + info1_lp = info1_grp; + + /* + * traverse group2 + */ + trav_info_init(fname2, file2_id, &info2_grp); + /* optional data pass */ + info2_grp->opts = (diff_opt_t*)options; + + if(h5trav_visit(file2_id,obj2fullname,TRUE,TRUE, + trav_grp_objs,trav_grp_symlinks, info2_grp) < 0) + { + parallel_print("Error: Could not get file contents\n"); + options->err_stat = 1; + goto out; + } /* end if */ + info2_lp = info2_grp; + + #ifdef H5_HAVE_PARALLEL if(g_Parallel) { - int i; - - if((HDstrlen(fname1) > 1024) || (HDstrlen(fname2) > 1024)) + if((HDstrlen(fname1) > MAX_FILENAME) || + (HDstrlen(fname2) > MAX_FILENAME)) { - fprintf(stderr, "The parallel diff only supports path names up to 1024 characters\n"); + fprintf(stderr, "The parallel diff only supports path names up to %d characters\n", MAX_FILENAME); MPI_Abort(MPI_COMM_WORLD, 0); } /* end if */ @@ -378,21 +850,57 @@ hsize_t h5diff(const char *fname1, /* Alert the worker tasks that there's going to be work. */ for(i = 1; i < g_nTasks; i++) - MPI_Send(filenames, (1024 * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); + MPI_Send(filenames, (MAX_FILENAME * 2), MPI_CHAR, i, MPI_TAG_PARALLEL, MPI_COMM_WORLD); } /* end if */ #endif + build_match_list (obj1fullname, info1_lp, obj2fullname, info2_lp, + &match_list, options); + nfound = diff_match(file1_id, obj1fullname, info1_lp, + file2_id, obj2fullname, info2_lp, + match_list, options); + } + else + { +#ifdef H5_HAVE_PARALLEL + if(g_Parallel) + /* Only single object diff, parallel workers won't be needed */ + phdiff_dismiss_workers(); +#endif - nfound = diff_match(file1_id, - info1, - file2_id, - info2, - options); - } /* end else */ - - trav_info_free(info1); - trav_info_free(info2); + nfound = diff_compare(file1_id, fname1, obj1fullname, info1_lp, + file2_id, fname2, obj2fullname, info2_lp, + options); + } out: +#ifdef H5_HAVE_PARALLEL + if(g_Parallel) + /* All done at this point, let tasks know that they won't be needed */ + phdiff_dismiss_workers(); +#endif + /* free buffers in trav_info structures */ + if (info1_obj) + trav_info_free(info1_obj); + if (info2_obj) + trav_info_free(info2_obj); + + if (info1_grp) + trav_info_free(info1_grp); + if (info2_grp) + trav_info_free(info2_grp); + + /* free buffers */ + if (obj1fullname) + HDfree(obj1fullname); + if (obj2fullname) + HDfree(obj2fullname); + + /* free link info buffer */ + if (trg_linfo1.trg_path) + HDfree(trg_linfo1.trg_path); + if (trg_linfo2.trg_path) + HDfree(trg_linfo2.trg_path); + /* close */ H5E_BEGIN_TRY { @@ -408,9 +916,11 @@ out: /*------------------------------------------------------------------------- * Function: diff_match * - * Purpose: Find common objects; the algorithm used for this search is the - * cosequential match algorithm and is described in - * Folk, Michael; Zoellick, Bill. (1992). File Structures. Addison-Wesley. + * Purpose: + * Compare common objects in given groups according to table structure. + * The table structure has flags which can be used to find common objects + * and will be compared. + * Common object means same name (absolute path) objects in both location. * * Return: Number of differences found * @@ -428,94 +938,27 @@ out: * 3) objects with the same name are not of the same type *------------------------------------------------------------------------- */ -hsize_t diff_match(hid_t file1_id, - trav_info_t *info1, - hid_t file2_id, - trav_info_t *info2, - diff_opt_t *options) +hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, + hid_t file2_id, const char *grp2, trav_info_t *info2, + trav_table_t *table, diff_opt_t *options) { - trav_table_t *table = NULL; - size_t curr1; - size_t curr2; - unsigned infile[2]; hsize_t nfound = 0; unsigned i; - /*------------------------------------------------------------------------- - * build the list - *------------------------------------------------------------------------- - */ - trav_table_init( &table ); - - curr1 = 0; - curr2 = 0; - while(curr1 < info1->nused && curr2 < info2->nused) - { - /* criteria is string compare */ - int cmp = HDstrcmp(info1->paths[curr1].path, info2->paths[curr2].path); - - if(cmp == 0) { - infile[0] = 1; - infile[1] = 1; - trav_table_addflags(infile, info1->paths[curr1].path, info1->paths[curr1].type, table); - - curr1++; - curr2++; - } /* end if */ - else if(cmp < 0) - { - infile[0] = 1; - infile[1] = 0; - trav_table_addflags(infile, info1->paths[curr1].path, info1->paths[curr1].type, table); - curr1++; - } /* end else-if */ - else - { - infile[0] = 0; - infile[1] = 1; - trav_table_addflags(infile, info2->paths[curr2].path, info2->paths[curr2].type, table); - curr2++; - } /* end else */ - } /* end while */ - - /* list1 did not end */ - infile[0] = 1; - infile[1] = 0; - while(curr1 < info1->nused) - { - trav_table_addflags(infile, info1->paths[curr1].path, info1->paths[curr1].type, table); - curr1++; - } /* end while */ - - /* list2 did not end */ - infile[0] = 0; - infile[1] = 1; - while(curr2 < info2->nused) - { - trav_table_addflags(infile, info2->paths[curr2].path, info2->paths[curr2].type, table); - curr2++; - } /* end while */ - - /*------------------------------------------------------------------------- - * print the list - *------------------------------------------------------------------------- - */ - if(options->m_verbose) - { - parallel_print("\n"); - parallel_print("file1 file2\n"); - parallel_print("---------------------------------------\n"); - for(i = 0; i < table->nobjs; i++) { - char c1, c2; - - c1 = (table->objs[i].flags[0]) ? 'x' : ' '; - c2 = (table->objs[i].flags[1]) ? 'x' : ' '; - parallel_print("%5c %6c %-15s\n", c1, c2, table->objs[i].name); - } /* end for */ - parallel_print ("\n"); - } /* end if */ + char * grp1_path = ""; + char * grp2_path = ""; + char * obj1_fullpath = NULL; + char * obj2_fullpath = NULL; + /* + * if not root, prepare object name to be pre-appended to group path to + * make full path + */ + if (HDstrcmp (grp1, "/")) + grp1_path = grp1; + if (HDstrcmp (grp2, "/")) + grp2_path = grp2; /*------------------------------------------------------------------------- * regarding the return value of h5diff (0, no difference in files, 1 difference ) @@ -552,8 +995,6 @@ hsize_t diff_match(hid_t file1_id, } } - - /*------------------------------------------------------------------------- * do the diff for common objects *------------------------------------------------------------------------- @@ -576,13 +1017,22 @@ hsize_t diff_match(hid_t file1_id, { if( table->objs[i].flags[0] && table->objs[i].flags[1]) { + /* make full path for obj1 */ + obj1_fullpath = (char*)HDcalloc (strlen(grp1_path) + strlen (table->objs[i].name) + 1, sizeof (char)); + HDstrcpy(obj1_fullpath, grp1_path); + HDstrcat(obj1_fullpath, table->objs[i].name); + + /* make full path for obj2 */ + obj2_fullpath = (char*)HDcalloc (strlen(grp2_path) + strlen (table->objs[i].name) + 1, sizeof (char)); + HDstrcpy(obj2_fullpath, grp2_path); + HDstrcat(obj2_fullpath, table->objs[i].name); + options->cmn_objs = 1; if(!g_Parallel) { - nfound += diff(file1_id, - table->objs[i].name, - file2_id, - table->objs[i].name, options, table->objs[i].type); + nfound += diff(file1_id, obj1_fullpath, + file2_id, obj2_fullpath, + options, table->objs[i].type); } /* end if */ #ifdef H5_HAVE_PARALLEL else @@ -599,13 +1049,15 @@ hsize_t diff_match(hid_t file1_id, */ /*Set up args to pass to worker task. */ - if(HDstrlen(table->objs[i].name) > 255) + if(HDstrlen(obj1_fullpath) > 255 || + HDstrlen(obj2_fullpath) > 255) { printf("The parallel diff only supports object names up to 255 characters\n"); MPI_Abort(MPI_COMM_WORLD, 0); } /* end if */ - HDstrcpy(args.name, table->objs[i].name); + HDstrcpy(args.name1, obj1_fullpath); + HDstrcpy(args.name2, obj2_fullpath); args.options = *options; args.type = table->objs[i].type; @@ -751,6 +1203,10 @@ hsize_t diff_match(hid_t file1_id, } /* end if */ } /* end else */ #endif /* H5_HAVE_PARALLEL */ + if (obj1_fullpath) + HDfree (obj1_fullpath); + if (obj2_fullpath) + HDfree (obj2_fullpath); } /* end if */ } /* end for */ h5diffdebug("done with for loop\n"); @@ -855,7 +1311,8 @@ hsize_t diff_match(hid_t file1_id, #endif /* H5_HAVE_PARALLEL */ /* free table */ - trav_table_free(table); + if (table) + trav_table_free(table); return nfound; } @@ -893,6 +1350,8 @@ hsize_t diff_compare(hid_t file1_id, int l_ret; int is_dangle_link1 = 0; int is_dangle_link2 = 0; + const char *obj1name = obj1_name; + const char *obj2name = obj2_name; /* local variables for diff() */ h5trav_type_t obj1type, obj2type; @@ -905,18 +1364,18 @@ hsize_t diff_compare(hid_t file1_id, HDmemset(&linkinfo1, 0, sizeof(h5tool_link_info_t)); HDmemset(&linkinfo2, 0, sizeof(h5tool_link_info_t)); - i = h5trav_getindex (info1, obj1_name); - j = h5trav_getindex (info2, obj2_name); + i = h5trav_getindex (info1, obj1name); + j = h5trav_getindex (info2, obj2name); if (i == -1) { - parallel_print ("Object <%s> could not be found in <%s>\n", obj1_name, + parallel_print ("Object <%s> could not be found in <%s>\n", obj1name, file1_name); f1 = 1; } if (j == -1) { - parallel_print ("Object <%s> could not be found in <%s>\n", obj2_name, + parallel_print ("Object <%s> could not be found in <%s>\n", obj2name, file2_name); f2 = 1; } @@ -925,10 +1384,9 @@ hsize_t diff_compare(hid_t file1_id, options->err_stat = 1; return 0; } - /* use the name with "/" first, as obtained by iterator function */ - obj1_name = info1->paths[i].path; - obj2_name = info2->paths[j].path; + obj1name = info1->paths[i].path; + obj2name = info2->paths[j].path; obj1type = info1->paths[i].type; obj2type = info2->paths[j].type; @@ -951,7 +1409,7 @@ hsize_t diff_compare(hid_t file1_id, if (obj1type == H5TRAV_TYPE_LINK) { /* get type of target object */ - l_ret = H5tools_get_link_info(file1_id, obj1_name, &linkinfo1, TRUE); + l_ret = H5tools_get_symlink_info(file1_id, obj1name, &linkinfo1, TRUE); /* dangling link */ if (l_ret == 0) { @@ -959,7 +1417,7 @@ hsize_t diff_compare(hid_t file1_id, { /* gangling link is error */ if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", obj1_name); + parallel_print("Warning: <%s> is a dangling link.\n", obj1name); options->err_stat = 1; goto out; } @@ -984,7 +1442,7 @@ hsize_t diff_compare(hid_t file1_id, if (obj2type == H5TRAV_TYPE_LINK) { /* get type target object */ - l_ret = H5tools_get_link_info(file2_id, obj2_name, &linkinfo2, TRUE); + l_ret = H5tools_get_symlink_info(file2_id, obj2name, &linkinfo2, TRUE); /* dangling link */ if (l_ret == 0) { @@ -992,7 +1450,7 @@ hsize_t diff_compare(hid_t file1_id, { /* gangling link is error */ if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", obj2_name); + parallel_print("Warning: <%s> is a dangling link.\n", obj2name); options->err_stat = 1; goto out; } @@ -1021,7 +1479,7 @@ hsize_t diff_compare(hid_t file1_id, if (obj1type == H5TRAV_TYPE_UDLINK) { /* get type and name of target object */ - l_ret = H5tools_get_link_info(file1_id, obj1_name, &linkinfo1, TRUE); + l_ret = H5tools_get_symlink_info(file1_id, obj1name, &linkinfo1, TRUE); /* dangling link */ if (l_ret == 0) { @@ -1029,7 +1487,7 @@ hsize_t diff_compare(hid_t file1_id, { /* gangling link is error */ if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", obj1_name); + parallel_print("Warning: <%s> is a dangling link.\n", obj1name); options->err_stat = 1; goto out; } @@ -1055,7 +1513,7 @@ hsize_t diff_compare(hid_t file1_id, if (obj2type == H5TRAV_TYPE_UDLINK) { /* get type and name of target object */ - l_ret = H5tools_get_link_info(file2_id, obj2_name, &linkinfo2, TRUE); + l_ret = H5tools_get_symlink_info(file2_id, obj2name, &linkinfo2, TRUE); /* dangling link */ if (l_ret == 0) { @@ -1063,7 +1521,7 @@ hsize_t diff_compare(hid_t file1_id, { /* gangling link is error */ if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", obj2_name); + parallel_print("Warning: <%s> is a dangling link.\n", obj2name); options->err_stat = 1; goto out; } @@ -1094,15 +1552,15 @@ hsize_t diff_compare(hid_t file1_id, if (options->m_verbose||options->m_list_not_cmp) { parallel_print("<%s> is of type %s and <%s> is of type %s\n", - obj1_name, get_type(obj1type), - obj2_name, get_type(obj2type)); + obj1name, get_type(obj1type), + obj2name, get_type(obj2type)); } options->not_cmp=1; goto out; } - nfound = diff(file1_id, obj1_name, - file2_id, obj2_name, + nfound = diff(file1_id, obj1name, + file2_id, obj2name, options, obj1type); out: @@ -1113,7 +1571,7 @@ out: { if(print_objname(options, nfound)) { - do_print_objname("dangling link", obj1_name, obj2_name); + do_print_objname("dangling link", obj1name, obj2name); print_found(nfound); } } @@ -1121,7 +1579,7 @@ out: else if (is_dangle_link1) { if(options->m_verbose) - parallel_print("obj1 <%s> is a dangling link.\n", obj1_name); + parallel_print("obj1 <%s> is a dangling link.\n", obj1name); nfound++; if(print_objname(options, nfound)) print_found(nfound); @@ -1130,7 +1588,7 @@ out: else if (is_dangle_link2) { if(options->m_verbose) - parallel_print("obj2 <%s> is a dangling link.\n", obj2_name); + parallel_print("obj2 <%s> is a dangling link.\n", obj2name); nfound++; if(print_objname(options, nfound)) print_found(nfound); @@ -1195,6 +1653,53 @@ hsize_t diff(hid_t file1_id, if(print_warn(options)) linkinfo1.opt.msg_mode = linkinfo2.opt.msg_mode = 1; + /* + * Get target object info for obj1 and obj2 and check dangling links. + * (for hard-linked-objects, because diff() only get the obj1's type, + * so obj2's type should be check here when diff() is called from + * diff_match() for same-named objects with dangling link only one side.) + */ + + /* target object1 - get type and name */ + ret = H5tools_get_symlink_info(file1_id, path1, &linkinfo1, TRUE); + /* dangling link */ + if (ret == 0) + { + if (options->no_dangle_links) + { + /* gangling link is error */ + if(options->m_verbose) + parallel_print("Warning: <%s> is a dangling link.\n", path1); + goto out; + } + else + is_dangle_link1 = 1; + } + else if (ret < 0) + goto out; + + /* target object2 - get type and name */ + ret = H5tools_get_symlink_info(file2_id, path2, &linkinfo2, TRUE); + /* dangling link */ + if (ret == 0) + { + if (options->no_dangle_links) + { + /* gangling link is error */ + if(options->m_verbose) + parallel_print("Warning: <%s> is a dangling link.\n", path2); + goto out; + } + else + is_dangle_link2 = 1; + } + else if (ret < 0) + goto out; + + /* found dangling link */ + if (is_dangle_link1 || is_dangle_link2) + goto out2; + switch(type) { /*---------------------------------------------------------------------- @@ -1270,11 +1775,6 @@ hsize_t diff(hid_t file1_id, *---------------------------------------------------------------------- */ case H5TRAV_TYPE_GROUP: - ret = HDstrcmp(path1, path2); - - /* if "path1" != "path2" then the groups are "different" */ - nfound = (ret != 0) ? 1 : 0; - if(print_objname(options, nfound)) do_print_objname("group", path1, path2); @@ -1309,47 +1809,6 @@ hsize_t diff(hid_t file1_id, */ case H5TRAV_TYPE_LINK: { - /* get type and name of target object */ - ret = H5tools_get_link_info(file1_id, path1, &linkinfo1, TRUE); - /* dangling link */ - if (ret == 0) - { - if (options->no_dangle_links) - { - /* gangling link is error */ - if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", path1); - goto out; - } - else - is_dangle_link1 = 1; - } - else if (ret < 0) - goto out; - - /* get type and name of target object */ - ret = H5tools_get_link_info(file2_id, path2, &linkinfo2, TRUE); - /* dangling link */ - if (ret == 0) - { - if (options->no_dangle_links) - { - /* gangling link is error */ - if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", path2); - goto out; - } - else - is_dangle_link2 = 1; - } - else if (ret < 0) - goto out; - - - /* found dangling link */ - if (is_dangle_link1 || is_dangle_link2) - goto out2; - ret = HDstrcmp(linkinfo1.trg_path, linkinfo2.trg_path); /* if the target link name is not same then the links are "different" */ @@ -1393,46 +1852,6 @@ hsize_t diff(hid_t file1_id, */ case H5TRAV_TYPE_UDLINK: { - /* get type and name of target object */ - ret = H5tools_get_link_info(file1_id, path1, &linkinfo1, TRUE); - /* dangling link */ - if (ret == 0) - { - if (options->no_dangle_links) - { - /* gangling link is error */ - if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", path1); - goto out; - } - else - is_dangle_link1=1; - } - else if (ret < 0) - goto out; - - /* get type and name of target object */ - ret = H5tools_get_link_info(file2_id, path2, &linkinfo2, TRUE); - /* dangling link */ - if (ret == 0) - { - if (options->no_dangle_links) - { - /* gangling link is error */ - if(options->m_verbose) - parallel_print("Warning: <%s> is a dangling link.\n", path2); - goto out; - } - else - is_dangle_link2=1; - } - else if (ret < 0) - goto out; - - /* found dangling link */ - if (is_dangle_link1 || is_dangle_link2) - goto out2; - /* Only external links will have a query function registered */ if(linkinfo1.linfo.type == H5L_TYPE_EXTERNAL && linkinfo2.linfo.type == H5L_TYPE_EXTERNAL) { diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h index 71993b8..916197d 100644 --- a/tools/lib/h5diff.h +++ b/tools/lib/h5diff.h @@ -19,6 +19,8 @@ #include "hdf5.h" #include "h5trav.h" +#define MAX_FILENAME 1024 + /*------------------------------------------------------------------------- * command line options *------------------------------------------------------------------------- @@ -107,11 +109,9 @@ hsize_t diff_compare( hid_t file1_id, trav_info_t *info2, diff_opt_t *options ); -hsize_t diff_match( hid_t file1_id, - trav_info_t *info1, - hid_t file2_id, - trav_info_t *info2, - diff_opt_t *options ); +hsize_t diff_match( hid_t file1_id, const char *grp1, trav_info_t *info1, + hid_t file2_id, const char *grp2, trav_info_t *info2, + trav_table_t *table, diff_opt_t *options ); hsize_t diff_array( void *_mem1, void *_mem2, diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c index a0fca8b..7586fd0 100644 --- a/tools/lib/h5tools_utils.c +++ b/tools/lib/h5tools_utils.c @@ -702,9 +702,9 @@ tmpfile(void) #endif /*------------------------------------------------------------------------- - * Function: H5tools_get_link_info + * Function: H5tools_get_symlink_info * - * Purpose: Get link (soft, external) info and its target object type + * Purpose: Get symbolic link (soft, external) info and its target object type (dataset, group, named datatype) and path, if exist * * Patameters: @@ -726,7 +726,7 @@ tmpfile(void) * Date: Feb 8, 2010 *-------------------------------------------------------------------------*/ int -H5tools_get_link_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info, +H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info, hbool_t get_obj_type) { htri_t l_ret; @@ -738,6 +738,14 @@ H5tools_get_link_info(hid_t file_id, const char * linkpath, h5tool_link_info_t * /* init */ link_info->trg_type = H5O_TYPE_UNKNOWN; + /* if path is root, return group type */ + if(!HDstrcmp(linkpath,"/")) + { + link_info->trg_type = H5O_TYPE_GROUP; + ret = 2; + goto out; + } + /* check if link itself exist */ if(H5Lexists(file_id, linkpath, H5P_DEFAULT) <= 0) { if(link_info->opt.msg_mode == 1) @@ -827,7 +835,7 @@ out: H5Pclose(lapl); return ret; -} /* end H5tools_get_link_info() */ +} /* end H5tools_get_symlink_info() */ /*------------------------------------------------------------------------- * Audience: Public diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h index 08451e1..88ab7ea 100644 --- a/tools/lib/h5tools_utils.h +++ b/tools/lib/h5tools_utils.h @@ -145,18 +145,18 @@ typedef struct { int msg_mode; } h5tool_opt_t; -/* obtain link info from H5tools_get_link_info() */ +/* obtain link info from H5tools_get_symlink_info() */ typedef struct { H5O_type_t trg_type; /* OUT: target type */ const char *trg_path; /* OUT: target obj path. This must be freed - * when used with H5tools_get_link_info() */ + * when used with H5tools_get_symlink_info() */ H5L_info_t linfo; /* OUT: link info */ h5tool_opt_t opt; /* IN: options */ } h5tool_link_info_t; /* Definitions of routines */ -H5TOOLS_DLL int H5tools_get_link_info(hid_t file_id, const char * linkpath, +H5TOOLS_DLL int H5tools_get_symlink_info(hid_t file_id, const char * linkpath, h5tool_link_info_t *link_info, hbool_t get_obj_type); H5TOOLS_DLL const char *h5tools_getprogname(void); H5TOOLS_DLL void h5tools_setprogname(const char*progname); diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c index 287af29..5195261 100644 --- a/tools/lib/h5trav.c +++ b/tools/lib/h5trav.c @@ -292,7 +292,7 @@ traverse(hid_t file_id, const char *grp_name, hbool_t visit_start, * *------------------------------------------------------------------------- */ -static void +void trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type) { size_t idx; /* Index of address to use */ @@ -323,7 +323,7 @@ trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type) * *------------------------------------------------------------------------- */ -static int +int trav_info_visit_obj(const char *path, const H5O_info_t *oinfo, const char UNUSED *already_visited, void *udata) { @@ -348,7 +348,7 @@ trav_info_visit_obj(const char *path, const H5O_info_t *oinfo, * *------------------------------------------------------------------------- */ -static int +int trav_info_visit_lnk(const char *path, const H5L_info_t *linfo, void *udata) { /* Add the link to the 'info' struct */ @@ -438,14 +438,21 @@ h5trav_getindex(const trav_info_t *info, const char *obj) */ void -trav_info_init(trav_info_t **_info) +trav_info_init(const char *filename, hid_t fileid, trav_info_t **_info) { trav_info_t *info = (trav_info_t *)HDmalloc(sizeof(trav_info_t)); /* Init info structure */ info->nused = info->nalloc = 0; info->paths = NULL; - + info->fname = filename; + info->fid = fileid; + + /* Initialize list of visited symbolic links */ + info->symlink_visited.nused = 0; + info->symlink_visited.nalloc = 0; + info->symlink_visited.objs = NULL; + info->symlink_visited.dangle_link = FALSE; *_info = info; } /* end trav_info_init() */ @@ -464,6 +471,16 @@ trav_info_free(trav_info_t *info) size_t u; /* Local index variable */ if(info) { + /* Free visited symbolic links path and file (if alloc) */ + for(u=0; u < info->symlink_visited.nused; u++) + { + if (info->symlink_visited.objs[u].file) + HDfree(info->symlink_visited.objs[u].file); + + HDfree(info->symlink_visited.objs[u].path); + } + HDfree(info->symlink_visited.objs); + /* Free path names */ for(u = 0; u < info->nused; u++) HDfree(info->paths[u].path); @@ -973,3 +990,119 @@ h5trav_visit(hid_t fid, const char *grp_name, hbool_t visit_start, return 0; } +/*------------------------------------------------------------------------- + * Function: symlink_visit_add + * + * Purpose: Add an symbolic link to visited data structure + * + * Return: 0 on success, -1 on failure + * + * Programmer: Neil Fortner, nfortne2@hdfgroup.org + * Adapted from trav_addr_add in h5trav.c by Quincey Koziol + * + * Date: September 5, 2008 + * + * Modified: + * Jonathan Kim + * - Moved from h5ls.c to share among tools. (Sep 16, 2010) + * - Renamed from elink_trav_add to symlink_visit_add for both soft and + * external links. (May 25, 2010) + * - Add type parameter to distingush between soft and external link for + * sure, which prevent from mixing up visited link when the target names + * are same between the soft and external link, as code marks with the + * target name. (May 25,2010) + * + *------------------------------------------------------------------------- + */ +herr_t +symlink_visit_add(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path) +{ + size_t idx; /* Index of address to use */ + void *tmp_ptr; + + /* Allocate space if necessary */ + if(visited->nused == visited->nalloc) + { + visited->nalloc = MAX(1, visited->nalloc * 2); + if(NULL == (tmp_ptr = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0])))) + return -1; + visited->objs = tmp_ptr; + } /* end if */ + + /* Append it */ + idx = visited->nused++; + + visited->objs[idx].type = type; + visited->objs[idx].file = NULL; + visited->objs[idx].path = NULL; + + if (type == H5L_TYPE_EXTERNAL) + { + if(NULL == (visited->objs[idx].file = HDstrdup(file))) + { + visited->nused--; + return -1; + } + } + + if(NULL == (visited->objs[idx].path = HDstrdup(path))) + { + visited->nused--; + if (visited->objs[idx].file) + HDfree (visited->objs[idx].file); + return -1; + } + + return 0; +} /* end symlink_visit_add() */ + + +/*------------------------------------------------------------------------- + * Function: symlink_is_visited + * + * Purpose: Check if an symbolic link has already been visited + * + * Return: TRUE/FALSE + * + * Programmer: Neil Fortner, nfortne2@hdfgroup.org + * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol + * + * Date: September 5, 2008 + * + * Modified: + * Jonathan Kim + * - Moved from h5ls.c to share among tools. (Sep 16, 2010) + * - Renamed from elink_trav_visited to symlink_is_visited for both soft and + * external links. (May 25, 2010) + * - Add type parameter to distingush between soft and external link for + * sure, which prevent from mixing up visited link when the target names + * are same between the soft and external link, as code marks with the + * target name. (May 25,2010) + * + *------------------------------------------------------------------------- + */ +hbool_t +symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path) +{ + size_t u; /* Local index variable */ + + /* Look for symlink */ + for(u = 0; u < visited->nused; u++) + { + /* Check for symlink values already in array */ + /* check type and path pair to distingush between symbolic links */ + if ((visited->objs[u].type == type) && !HDstrcmp(visited->objs[u].path, path)) + { + /* if external link, file need to be matched as well */ + if (visited->objs[u].type == H5L_TYPE_EXTERNAL) + { + if (!HDstrcmp(visited->objs[u].file, file)) + return (TRUE); + } + return (TRUE); + } + } + /* Didn't find symlink */ + return(FALSE); +} /* end symlink_is_visited() */ + diff --git a/tools/lib/h5trav.h b/tools/lib/h5trav.h index bb31461..8eb93fa 100644 --- a/tools/lib/h5trav.h +++ b/tools/lib/h5trav.h @@ -36,7 +36,7 @@ typedef herr_t (*h5trav_lnk_func_t)(const char *path_name, const H5L_info_t *lin *------------------------------------------------------------------------- */ typedef enum { - H5TRAV_TYPE_UNKNOWN = -1, /* Unknown object type */ + H5TRAV_TYPE_UNKNOWN = -1, /* Unknown object type */ H5TRAV_TYPE_GROUP, /* Object is a group */ H5TRAV_TYPE_DATASET, /* Object is a dataset */ H5TRAV_TYPE_NAMED_DATATYPE, /* Object is a named datatype */ @@ -48,6 +48,20 @@ typedef enum { * public struct to store name and type of an object *------------------------------------------------------------------------- */ +/* Struct to keep track of symbolic link targets visited. + * Functions: symlink_visit_add() and symlink_is_visited() + */ +typedef struct symlink_trav_t { + size_t nalloc; + size_t nused; + struct { + H5L_type_t type; + char *file; + char *path; + } *objs; + hbool_t dangle_link; +} symlink_trav_t; + typedef struct trav_path_t { char *path; h5trav_type_t type; @@ -56,7 +70,11 @@ typedef struct trav_path_t { typedef struct trav_info_t { size_t nalloc; size_t nused; + const char *fname; + hid_t fid; /* File ID */ trav_path_t *paths; + symlink_trav_t symlink_visited; /* already visited symbolic links */ + void * opts; /* optional data passing */ } trav_info_t; @@ -110,9 +128,11 @@ extern "C" { * "h5trav general" public functions *------------------------------------------------------------------------- */ -H5TOOLS_DLL int h5trav_visit(hid_t file_id, const char *grp_name, hbool_t visit_start, - hbool_t recurse, h5trav_obj_func_t visit_obj, h5trav_lnk_func_t visit_lnk, - void *udata); +H5TOOLS_DLL int h5trav_visit(hid_t file_id, const char *grp_name, + hbool_t visit_start, hbool_t recurse, h5trav_obj_func_t visit_obj, + h5trav_lnk_func_t visit_lnk, void *udata); +H5TOOLS_DLL herr_t symlink_visit_add(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path); +H5TOOLS_DLL hbool_t symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path); /*------------------------------------------------------------------------- * "h5trav info" public functions @@ -120,6 +140,8 @@ H5TOOLS_DLL int h5trav_visit(hid_t file_id, const char *grp_name, hbool_t visit_ */ H5TOOLS_DLL int h5trav_getinfo(hid_t file_id, trav_info_t *info); H5TOOLS_DLL ssize_t h5trav_getindex(const trav_info_t *info, const char *obj); +H5TOOLS_DLL int trav_info_visit_obj (const char *path, const H5O_info_t *oinfo, const char *already_visited, void *udata); +H5TOOLS_DLL int trav_info_visit_lnk (const char *path, const H5L_info_t *linfo, void *udata); /*------------------------------------------------------------------------- * "h5trav table" public functions @@ -144,10 +166,12 @@ H5TOOLS_DLL int h5trav_print(hid_t fid); *------------------------------------------------------------------------- */ -H5TOOLS_DLL void trav_info_init(trav_info_t **info); +H5TOOLS_DLL void trav_info_init(const char *filename, hid_t fileid, trav_info_t **info); H5TOOLS_DLL void trav_info_free(trav_info_t *info); +H5TOOLS_DLL void trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type); + /*------------------------------------------------------------------------- * table private functions *------------------------------------------------------------------------- diff --git a/tools/lib/ph5diff.h b/tools/lib/ph5diff.h index e48a643..0e454c8 100644 --- a/tools/lib/ph5diff.h +++ b/tools/lib/ph5diff.h @@ -38,7 +38,8 @@ extern FILE * overflow_file; struct diff_args { - char name[256]; + char name1[256]; + char name2[256]; h5trav_type_t type; diff_opt_t options; }; diff --git a/windows/tools/h5diff/testh5diff.bat b/windows/tools/h5diff/testh5diff.bat index 0023ec3..17babe4 100644 --- a/windows/tools/h5diff/testh5diff.bat +++ b/windows/tools/h5diff/testh5diff.bat @@ -48,6 +48,8 @@ set srcfile17=h5diff_ext2softlink_src.h5 set srcfile18=h5diff_ext2softlink_trg.h5
set srclnkfile1=h5diff_danglelinks1.h5
set srclnkfile2=h5diff_danglelinks2.h5
+set src_grp_recurse1=h5diff_grp_recurse1.h5
+set src_grp_recurse2=h5diff_grp_recurse2.h5
set file1=%indir%\h5diff_basic1.h5
set file2=%indir%\h5diff_basic2.h5
@@ -69,6 +71,8 @@ set file17=%indir%\h5diff_ext2softlink_src.h5 set file18=%indir%\h5diff_ext2softlink_trg.h5
set lnkfile1=%indir%\h5diff_danglelinks1.h5
set lnkfile2=%indir%\h5diff_danglelinks2.h5
+set grp_recurse1=%indir%\h5diff_grp_recurse1.h5
+set grp_recurse2=%indir%\h5diff_grp_recurse2.h5
rem The tool name
@@ -222,7 +226,7 @@ rem The tests rem To avoid the printing of the complete full path of the test file, that hides
rem all the other parameters for long paths, the printing of the command line
rem is done first in
-rem TESTING with the name only of the test file $TOOL, not its full path $TESTFILErem ############################################################################
+rem TESTING with the name only of the test file $TOOL, not its full path $TESTFILE
rem ############################################################################
rem ############################################################################
@@ -282,9 +286,9 @@ rem ############################################################################ call :testing %h5diff% -q %srcfile1% %srcfile2%
call :tooltest h5diff_18.txt -q %file1% %file2%
- rem ##############################################################################
+ rem ########################################################################
rem # not comparable types
- rem ##############################################################################
+ rem ########################################################################
rem 2.0
call :testing %h5diff% -v %srcfile3% %srcfile3% dset g1
@@ -298,9 +302,9 @@ rem ############################################################################ call :testing %h5diff% -v %srcfile3% %srcfile3% dset t1
call :tooltest h5diff_22.txt -v %file3% %file3% dset t1
- rem ##############################################################################
+ rem #######################################################################
rem # compare groups, types, links (no differences and differences)
- rem ##############################################################################
+ rem #######################################################################
rem 2.3
call :testing %h5diff% -v %srcfile3% %srcfile3% g1 g1
@@ -328,9 +332,9 @@ rem ############################################################################ - rem ##############################################################################
+ rem ########################################################################
rem # Dataset datatypes
- rem ##############################################################################
+ rem ########################################################################
rem 5.0
call :testing %h5diff% -v %srcfile4% %srcfile4% dset0a dset0b
@@ -368,19 +372,23 @@ rem ############################################################################ call :testing %h5diff% -v %srcfile7% %srcfile8% refreg
call :tooltest h5diff_58.txt -v %file7% %file8% refreg
- rem ##############################################################################
+ rem ########################################################################
rem # Error messages
- rem ##############################################################################
+ rem ########################################################################
rem 6.0: Check if the command line number of arguments is less than 3
call :testing %h5diff% %srcfile1%
call :tooltest h5diff_600.txt %file1%
+ rem 6.1: Check if non-exist object name is specified
+ call :testing %h5diff% %srcfile1% %srcfile1% nono_obj
+ call :tooltest h5diff_601.txt %file1% %file1% nono_obj
- rem ##############################################################################
+
+ rem ########################################################################
rem # -d
- rem ##############################################################################
+ rem ########################################################################
rem 6.3: negative value
@@ -416,9 +424,9 @@ rem ############################################################################ call :tooltest h5diff_610.txt -d 1 %file1% %file2% g1/dset3 g1/dset4
- rem ##############################################################################
+ rem ########################################################################
rem # -p
- rem ##############################################################################
+ rem ########################################################################
@@ -455,9 +463,9 @@ rem ############################################################################ call :tooltest h5diff_619.txt -p 0.005 %file1% %file2% g1/dset3 g1/dset4
- rem ##############################################################################
+ rem ########################################################################
rem # -n
- rem ##############################################################################
+ rem ########################################################################
rem 6.21: negative value
call :testing %h5diff% -n -4 %srcfile1% %srcfile2% g1/dset3 g1/dset4
@@ -496,15 +504,15 @@ rem ############################################################################ call :testing %h5diff% file1.h6 file2.h6
call :tooltest h5diff_629.txt file1.h6 file2.h6
- rem ##############################################################################
+ rem ########################################################################
rem 7. attributes
- rem ##############################################################################
+ rem ########################################################################
call :testing %h5diff% -v %srcfile5% %srcfile6%
call :tooltest h5diff_70.txt -v %file5% %file6%
- rem ##############################################################################
+ rem #######################################################################
rem 8. all dataset datatypes
- rem ##############################################################################
+ rem #######################################################################
call :testing %h5diff% -v %srcfile7% %srcfile8%
call :tooltest h5diff_80.txt -v %file7% %file8%
@@ -513,13 +521,13 @@ rem ############################################################################ call :tooltest h5diff_90.txt -v %file2% %file2%
rem 10. read by hyperslab, print indexes
- rem ##############################################################################
+ rem #######################################################################
rem Not skipped on windows as this has not been a problem - ADB 1/22/2009
rem if test -n "$pmode" -a "$mydomainname" = hdfgroup.uiuc.edu; then
rem # skip this test which sometimes hangs in some THG machines
rem SKIP -v $SRCFILE9 $SRCFILE10
rem else
- rem ##############################################################################
+ rem #######################################################################
call :testing %h5diff% -v %srcfile9% %srcfile10%
call :tooltest h5diff_100.txt -v %file9% %file10%
rem fi
@@ -563,16 +571,16 @@ rem ############################################################################ call :testing %h5diff% -c %srcfile2% %srcfile2% g2/dset8 g2/dset9
call :tooltest h5diff_207.txt -c %file2% %file2% g2/dset8 g2/dset9
- rem ##############################################################################
+ rem #######################################################################
rem # Links compare without --follow-symlinks nor --no-dangling-links
- rem ##############################################################################
+ rem #######################################################################
rem test for bug1749
call :testing %h5diff% -v %srcfile12% %srcfile12% /link_g1 /link_g2
call :tooltest h5diff_300.txt -v %file12% %file12% /link_g1 /link_g2
- rem ##############################################################################
+ rem #######################################################################
rem # Links compare with --follow-symlinks Only
- rem ##############################################################################
+ rem #######################################################################
rem soft links file to file
call :testing %h5diff% --follow-symlinks -v %srcfile13% %srcfile13%
call :tooltest h5diff_400.txt --follow-symlinks -v %file13% %file13%
@@ -678,9 +686,9 @@ rem ############################################################################ call :tooltest h5diff_425.txt --follow-symlinks -v %file17% %file17% /ext_link_to_slink1 /ext_link_to_slink2
- rem ##############################################################################
+ rem #######################################################################
rem # Dangling links compare (--follow-symlinks and --no-dangling-links)
- rem ##############################################################################
+ rem #######################################################################
rem dangling links --follow-symlinks (FILE to FILE)
call :testing %h5diff% --follow-symlinks -v %srclnkfile1% %srclnkfile2%
call :tooltest h5diff_450.txt --follow-symlinks -v %lnkfile1% %lnkfile2%
@@ -721,10 +729,66 @@ rem ############################################################################ call :testing %h5diff% --follow-symlinks -v --no-dangling-links %srcfile15% %srcfile15% /ext_link_noexist1 /ext_link_noexist2
call :tooltest h5diff_459.txt --follow-symlinks -v --no-dangling-links %file15% %file15% /ext_link_noexist1 /ext_link_noexist2
+ rem ########################################################################
+ rem # test for group diff recursivly
+ rem ########################################################################
+ rem root
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% / /
+ call :tooltest h5diff_500.txt -v %grp_recurse1% %grp_recurse2% / /
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% / /
+ call :tooltest h5diff_501.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% / /
+
+ rem root vs group
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% / /grp1/grp2/grp3
+ call :tooltest h5diff_502.txt -v %grp_recurse1% %grp_recurse2% / /grp1/grp2/grp3
+
+ rem group vs group (same name and structure)
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /grp1 /grp1
+ call :tooltest h5diff_503.txt -v %grp_recurse1% %grp_recurse2% /grp1 /grp1
+
+ rem group vs group (different name and structure)
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /grp1/grp2 /grp1/grp2/grp3
+ call :tooltest h5diff_504.txt -v %grp_recurse1% %grp_recurse2% /grp1/grp2 /grp1/grp2/grp3
+
+ rem groups vs soft-link
+ call :testing %h5diff%
+ call :tooltest h5diff_505.txt -v %grp_recurse1% %grp_recurse2% /grp1 /slink_grp1
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% /grp1/grp2 /slink_grp2
+ call :tooltest h5diff_506.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% /grp1/grp2 /slink_grp2
+
+ rem groups vs ext-link
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /grp1 /elink_grp1
+ call :tooltest h5diff_507.txt -v %grp_recurse1% %grp_recurse2% /grp1 /elink_grp1
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% /grp1 /elink_grp1
+ call :tooltest h5diff_508.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% /grp1 /elink_grp1
+
+ rem soft-link vs ext-link
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /slink_grp1 /elink_grp1
+ call :tooltest h5diff_509.txt -v %grp_recurse1% %grp_recurse2% /slink_grp1 /elink_grp1
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% /slink_grp1 /elink_grp1
+ call :tooltest h5diff_510.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% /slink_grp1 /elink_grp1
+
+ rem circled ext links
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /grp10 /grp11
+ call :tooltest h5diff_511.txt -v %grp_recurse1% %grp_recurse2% /grp10 /grp11
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% /grp10 /grp11
+ call :tooltest h5diff_512.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% /grp10 /grp11
+
+ rem circled soft2ext-link vs soft2ext-link
+ call :testing %h5diff% -v %src_grp_recurse1% %src_grp_recurse2% /slink_grp10 /slink_grp11
+ call :tooltest h5diff_513.txt -v %grp_recurse1% %grp_recurse2% /slink_grp10 /slink_grp11
+
+ call :testing %h5diff% -v --follow-symlinks %src_grp_recurse1% %src_grp_recurse2% /slink_grp10 /slink_grp11
+ call :tooltest h5diff_514.txt -v --follow-symlinks %grp_recurse1% %grp_recurse2% /slink_grp10 /slink_grp11
- rem ##############################################################################
+ rem #######################################################################
rem # END
- rem ##############################################################################
+ rem #######################################################################
if %nerrors% equ 0 (
echo.All %h5diff% tests passed.
|