From eb7b5b2ceffb9bed00959c4131ce9cfed09628c4 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Thu, 16 Sep 2010 16:46:16 -0500 Subject: [svn-r19406] Purpose: Add --exclude-path option Description: Specified path to an object will be excluded from comparing the two files or two groups. If group is specified all the member objects will be excluded. Related to "1890: h5diff excluding object for file comparison via command line" Tested: jam, amani and heiwa --- MANIFEST | 9 +- release_docs/RELEASE.txt | 4 + tools/h5diff/CMakeLists.txt | 36 ++++ tools/h5diff/h5diff_common.c | 38 ++++ tools/h5diff/h5diffgentest.c | 293 ++++++++++++++++++++++++++++ tools/h5diff/testfiles/h5diff_480.txt | 17 ++ tools/h5diff/testfiles/h5diff_481.txt | 30 +++ tools/h5diff/testfiles/h5diff_482.txt | 17 ++ tools/h5diff/testfiles/h5diff_483.txt | 18 ++ tools/h5diff/testfiles/h5diff_exclude1-1.h5 | Bin 0 -> 5064 bytes tools/h5diff/testfiles/h5diff_exclude1-2.h5 | Bin 0 -> 5064 bytes tools/h5diff/testfiles/h5diff_exclude2-1.h5 | Bin 0 -> 5064 bytes tools/h5diff/testfiles/h5diff_exclude2-2.h5 | Bin 0 -> 6056 bytes tools/h5diff/testh5diff.sh | 25 +++ tools/lib/h5diff.c | 147 ++++++++++++-- tools/lib/h5diff.h | 8 + windows/tools/h5diff/testh5diff.bat | 35 ++++ 17 files changed, 659 insertions(+), 18 deletions(-) create mode 100644 tools/h5diff/testfiles/h5diff_480.txt create mode 100644 tools/h5diff/testfiles/h5diff_481.txt create mode 100644 tools/h5diff/testfiles/h5diff_482.txt create mode 100644 tools/h5diff/testfiles/h5diff_483.txt create mode 100644 tools/h5diff/testfiles/h5diff_exclude1-1.h5 create mode 100644 tools/h5diff/testfiles/h5diff_exclude1-2.h5 create mode 100644 tools/h5diff/testfiles/h5diff_exclude2-1.h5 create mode 100644 tools/h5diff/testfiles/h5diff_exclude2-2.h5 diff --git a/MANIFEST b/MANIFEST index 63e9e10..df795fe 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1608,6 +1608,10 @@ ./tools/h5diff/testfiles/h5diff_457.txt ./tools/h5diff/testfiles/h5diff_458.txt ./tools/h5diff/testfiles/h5diff_459.txt +./tools/h5diff/testfiles/h5diff_480.txt +./tools/h5diff/testfiles/h5diff_481.txt +./tools/h5diff/testfiles/h5diff_482.txt +./tools/h5diff/testfiles/h5diff_483.txt ./tools/h5diff/testfiles/h5diff_500.txt ./tools/h5diff/testfiles/h5diff_501.txt ./tools/h5diff/testfiles/h5diff_502.txt @@ -1646,7 +1650,10 @@ ./tools/h5diff/testfiles/h5diff_danglelinks2.h5 ./tools/h5diff/testfiles/h5diff_grp_recurse1.h5 ./tools/h5diff/testfiles/h5diff_grp_recurse2.h5 - +./tools/h5diff/testfiles/h5diff_exclude1-1.h5 +./tools/h5diff/testfiles/h5diff_exclude1-2.h5 +./tools/h5diff/testfiles/h5diff_exclude2-1.h5 +./tools/h5diff/testfiles/h5diff_exclude2-2.h5 #test files for h5repack diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 85c4fe2..991ba77 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -174,6 +174,10 @@ New Features Tools: ------ + - h5diff: Add a new flag --exclude-path. Specified path to an object will + be excluded from comparing the two files or two groups. If group + is specified all the member objects will be excluded. + (JKM - 2010/09/16). - h5ls: Add new flag --no-dangling-links. (refer to --help for details) (JKM - 2010/06/15) - h5ls: Add new flag --follow-symlinks. (refer to --help for details) diff --git a/tools/h5diff/CMakeLists.txt b/tools/h5diff/CMakeLists.txt index c31f650..a22e0e3 100644 --- a/tools/h5diff/CMakeLists.txt +++ b/tools/h5diff/CMakeLists.txt @@ -114,6 +114,10 @@ IF (BUILD_TESTING) h5diff_457.txt h5diff_458.txt h5diff_459.txt + h5diff_480.txt + h5diff_481.txt + h5diff_482.txt + h5diff_483.txt h5diff_50.txt h5diff_51.txt h5diff_52.txt @@ -190,6 +194,10 @@ IF (BUILD_TESTING) h5diff_danglelinks2.h5 h5diff_grp_recurse1.h5 h5diff_grp_recurse2.h5 + h5diff_exclude1-1.h5 + h5diff_exclude1-2.h5 + h5diff_exclude2-1.h5 + h5diff_exclude2-2.h5 ) FOREACH (txt_file ${HDF5_REFERENCE_FILES}) @@ -296,6 +304,13 @@ 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) +# same structure, same obj name with different value +SET (EXCLUDE_FILE1_1 h5diff_exclude1-1.h5) +SET (EXCLUDE_FILE1_2 h5diff_exclude1-2.h5) +# different structure and obj names +SET (EXCLUDE_FILE2_1 h5diff_exclude2-1.h5) +SET (EXCLUDE_FILE2_2 h5diff_exclude2-2.h5) + # ############################################################################ # # Common usage @@ -716,6 +731,27 @@ ADD_H5_TEST (h5diff_512 -v --follow-symlinks ${GRP_RECURSE_FILE1} ${GRP_RECURSE_ # 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) + + +# ############################################################################## +# # Exclude path (--exclude-path) +# ############################################################################## +# +# Same structure, same names and different value. +# +# Exclude the object with different value. Expect return - same +ADD_H5_TEST (h5diff_480 0 -v --exclude-path /group1/dset3 ${EXCLUDE_FILE1_1} ${EXCLUDE_FILE1_2}) +# Verify different by not excluding. Expect return - diff +ADD_H5_TEST (h5diff_481 1 -v ${EXCLUDE_FILE1_1} ${EXCLUDE_FILE1_2}) + +# +# Different structure, different names. +# +# Exclude all the different objects. Expect return - same +ADD_H5_TEST (h5diff_482 0 -v --exclude-path "/group1" --exclude-path "/dset1" ${EXCLUDE_FILE2_1} ${EXCLUDE_FILE2_2}) +# Exclude only some different objects. Expect return - diff +ADD_H5_TEST (h5diff_483 1 -v --exclude-path "/group1" ${EXCLUDE_FILE2_1} ${EXCLUDE_FILE2_2}) + ENDIF (BUILD_TESTING) diff --git a/tools/h5diff/h5diff_common.c b/tools/h5diff/h5diff_common.c index b897a7f..a678b2f 100644 --- a/tools/h5diff/h5diff_common.c +++ b/tools/h5diff/h5diff_common.c @@ -42,6 +42,7 @@ static struct long_options l_opts[] = { { "use-system-epsilon", no_arg, 'e' }, { "follow-symlinks", no_arg, 'l' }, { "no-dangling-links", no_arg, 'x' }, + { "exclude-path", require_arg, 'E' }, { NULL, 0, '\0' } }; @@ -64,6 +65,7 @@ void parse_command_line(int argc, { int opt; + struct exclude_path_list *exclude_head, *exclude_prev, *exclude_node; /* process the command-line */ memset(options, 0, sizeof (diff_opt_t)); @@ -74,6 +76,9 @@ void parse_command_line(int argc, /* NaNs are handled by default */ options->do_nans = 1; + /* init for exclude-path option */ + exclude_head = NULL; + /* parse command line options */ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) { @@ -104,6 +109,35 @@ void parse_command_line(int argc, case 'x': options->no_dangle_links = 1; break; + case 'E': + options->exclude_path = 1; + + /* create linked list of excluding objects */ + if( (exclude_node = (struct exclude_path_list*) malloc(sizeof(struct exclude_path_list))) == NULL) + { + printf("Error: lack of memory!\n"); + h5diff_exit(EXIT_FAILURE); + } + + /* init */ + exclude_node->obj_path = opt_arg; + exclude_node->obj_type = H5TRAV_TYPE_UNKNOWN; + exclude_prev = exclude_head; + + if (NULL == exclude_head) + { + exclude_head = exclude_node; + exclude_head->next = NULL; + } + else + { + while(NULL != exclude_prev->next) + exclude_prev=exclude_prev->next; + + exclude_node->next = NULL; + exclude_prev->next = exclude_node; + } + break; case 'd': options->d=1; @@ -163,6 +197,10 @@ void parse_command_line(int argc, } } + /* if exclude-path option is used, keep the exclude path list */ + if (options->exclude_path) + options->exclude = exclude_head; + /* if use system epsilon, unset -p and -d option */ if (options->use_system_epsilon) options->d = options->p = 0; diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c index 1f6cb2a..20797f4 100644 --- a/tools/h5diff/h5diffgentest.c +++ b/tools/h5diff/h5diffgentest.c @@ -57,6 +57,12 @@ #define DANGLE_LINK_FILE2 "h5diff_danglelinks2.h5" #define GRP_RECURSE_FILE1 "h5diff_grp_recurse1.h5" #define GRP_RECURSE_FILE2 "h5diff_grp_recurse2.h5" +/* same structure, same obj name with different value */ +#define EXCLUDE_FILE1_1 "h5diff_exclude1-1.h5" +#define EXCLUDE_FILE1_2 "h5diff_exclude1-2.h5" +/* different structure and obj names */ +#define EXCLUDE_FILE2_1 "h5diff_exclude2-1.h5" +#define EXCLUDE_FILE2_2 "h5diff_exclude2-2.h5" #define UIMAX 4294967295u /*Maximum value for a variable of type unsigned int */ #define STR_SIZE 3 @@ -102,6 +108,8 @@ 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); +static int test_exclude_obj1(const char *fname1, const char *fname2); +static int test_exclude_obj2(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); @@ -153,6 +161,10 @@ int main(void) test_group_recurse(GRP_RECURSE_FILE1, GRP_RECURSE_FILE2); + test_exclude_obj1(EXCLUDE_FILE1_1, EXCLUDE_FILE1_2); + test_exclude_obj2(EXCLUDE_FILE2_1, EXCLUDE_FILE2_2); + + return 0; } @@ -2292,6 +2304,287 @@ out: } /*------------------------------------------------------------------------- +* +* Purpose: Create test files for excluding obj. +* Same structure, same obj names +* Test : exclude obj with different value to verify the rest are same +* +* Programmer: Jonathan Kim (July, 21, 2010) +* +*-------------------------------------------------------------------------*/ +static int test_exclude_obj1(const char *fname1, const char *fname2) +{ + hid_t fid1=0; + hid_t fid2=0; + hid_t gid1=0; + hid_t gid2=0; + hsize_t dims2[2] = {2,4}; + int data1[4][2] = {{0,0},{0,0},{0,0},{0,0}}; + int data2[4][2] = {{0,1},{2,3},{1,2},{3,4}}; + herr_t status = SUCCEED; + + /*----------------------------------------------------------------------- + * Create file(s) + *------------------------------------------------------------------------*/ + fid1 = H5Fcreate (fname1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid1 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname1); + status = FAIL; + goto out; + } + + fid2 = H5Fcreate (fname2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid2 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Group + *------------------------------------------------------------------------*/ + /* file1 */ + gid1 = H5Gcreate2(fid1, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + gid2 = H5Gcreate2(fid2, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (gid2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Datasets + *------------------------------------------------------------------------*/ + /* file1 */ + status = write_dset(fid1,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid1,2,dims2,"dset2",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid1,2,dims2,"dset3",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + + /* file2 */ + status = write_dset(fid2,2,dims2,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid2,2,dims2,"dset2",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid2,2,dims2,"dset3",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + +out: + /*----------------------------------------------------------------------- + * Close + *-----------------------------------------------------------------------*/ + if(fid1) + H5Fclose(fid1); + if(fid2) + H5Fclose(fid2); + if(gid1) + H5Gclose(gid1); + if(gid2) + H5Gclose(gid2); + + return status; +} + +/*------------------------------------------------------------------------- +* +* Purpose: Create test files for excluding obj. +* different structure and name +* Test : exclude different objs to verify the rest are same +* +* Programmer: Jonathan Kim (July, 21, 2010) +* +*-------------------------------------------------------------------------*/ +static int test_exclude_obj2(const char *fname1, const char *fname2) +{ + hid_t fid1=0; + hid_t fid2=0; + hid_t gid1=0; + hid_t gid2=0; + hid_t gid3=0; + hsize_t dims2[2] = {2,4}; + int data1[4][2] = {{0,0},{0,0},{0,0},{0,0}}; + int data2[4][2] = {{0,1},{2,3},{1,2},{3,4}}; + herr_t status = SUCCEED; + + /*----------------------------------------------------------------------- + * Create file(s) + *------------------------------------------------------------------------*/ + fid1 = H5Fcreate (fname1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid1 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname1); + status = FAIL; + goto out; + } + + fid2 = H5Fcreate (fname2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if (fid2 < 0) + { + fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Group + *------------------------------------------------------------------------*/ + /* file1 */ + gid1 = H5Gcreate2(fid1, "group10", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (gid1 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1); + status = FAIL; + goto out; + } + + /* file2 */ + gid2 = H5Gcreate2(fid2, "group10", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (gid2 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + /* subset name from group10 */ + gid3 = H5Gcreate2(fid2, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + if (gid3 < 0) + { + fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname2); + status = FAIL; + goto out; + } + + + /*----------------------------------------------------------------------- + * Datasets + *------------------------------------------------------------------------*/ + /* file1 */ + status = write_dset(fid1,2,dims2,"dset10",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,"dset1",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + status = write_dset(gid1,2,dims2,"dset2",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname1); + status = FAIL; + goto out; + } + + + /* file2 */ + status = write_dset(fid2,2,dims2,"dset10",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid2,2,dims2,"dset2",H5T_NATIVE_INT,data1); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + status = write_dset(gid3,2,dims2,"dset3",H5T_NATIVE_INT,data2); + if (status == FAIL) + { + fprintf(stderr, "Error: %s> write_dset failed\n", fname2); + status = FAIL; + goto out; + } + + +out: + /*----------------------------------------------------------------------- + * Close + *-----------------------------------------------------------------------*/ + if(fid1) + H5Fclose(fid1); + if(fid2) + H5Fclose(fid2); + if(gid1) + H5Gclose(gid1); + if(gid2) + H5Gclose(gid2); + if(gid3) + H5Gclose(gid3); + + return status; +} + +/*------------------------------------------------------------------------- * Function: write_attr_in * * Purpose: write attributes in LOC_ID (dataset, group, named datatype) diff --git a/tools/h5diff/testfiles/h5diff_480.txt b/tools/h5diff/testfiles/h5diff_480.txt new file mode 100644 index 0000000..3e1f900 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_480.txt @@ -0,0 +1,17 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + x x /group1 + x x /group1/dset2 + +group : and +0 differences found +dataset: and +0 differences found +group : and +0 differences found +dataset: and +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_481.txt b/tools/h5diff/testfiles/h5diff_481.txt new file mode 100644 index 0000000..c4f2448 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_481.txt @@ -0,0 +1,30 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset1 + x x /group1 + x x /group1/dset2 + x x /group1/dset3 + +group : and +0 differences found +dataset: and +0 differences found +group : and +0 differences found +dataset: and +0 differences found +dataset: and +size: [2x4] [2x4] +position dset3 dset3 difference +------------------------------------------------------------ +[ 0 1 ] 0 1 1 +[ 0 2 ] 0 2 2 +[ 0 3 ] 0 3 3 +[ 1 0 ] 0 1 1 +[ 1 1 ] 0 2 2 +[ 1 2 ] 0 3 3 +[ 1 3 ] 0 4 4 +7 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_482.txt b/tools/h5diff/testfiles/h5diff_482.txt new file mode 100644 index 0000000..5b3c8c1 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_482.txt @@ -0,0 +1,17 @@ + +file1 file2 +--------------------------------------- + x x / + x x /dset10 + x x /group10 + x x /group10/dset2 + +group : and +0 differences found +dataset: and +0 differences found +group : and +0 differences found +dataset: and +0 differences found +EXIT CODE: 0 diff --git a/tools/h5diff/testfiles/h5diff_483.txt b/tools/h5diff/testfiles/h5diff_483.txt new file mode 100644 index 0000000..a45e928 --- /dev/null +++ b/tools/h5diff/testfiles/h5diff_483.txt @@ -0,0 +1,18 @@ + +file1 file2 +--------------------------------------- + x x / + x /dset1 + x x /dset10 + x x /group10 + x x /group10/dset2 + +group : and +0 differences found +dataset: and +0 differences found +group : and +0 differences found +dataset: and +0 differences found +EXIT CODE: 1 diff --git a/tools/h5diff/testfiles/h5diff_exclude1-1.h5 b/tools/h5diff/testfiles/h5diff_exclude1-1.h5 new file mode 100644 index 0000000..8b675ea Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude1-1.h5 differ diff --git a/tools/h5diff/testfiles/h5diff_exclude1-2.h5 b/tools/h5diff/testfiles/h5diff_exclude1-2.h5 new file mode 100644 index 0000000..78854cd Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude1-2.h5 differ diff --git a/tools/h5diff/testfiles/h5diff_exclude2-1.h5 b/tools/h5diff/testfiles/h5diff_exclude2-1.h5 new file mode 100644 index 0000000..8923111 Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude2-1.h5 differ diff --git a/tools/h5diff/testfiles/h5diff_exclude2-2.h5 b/tools/h5diff/testfiles/h5diff_exclude2-2.h5 new file mode 100644 index 0000000..9e42007 Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude2-2.h5 differ diff --git a/tools/h5diff/testh5diff.sh b/tools/h5diff/testh5diff.sh index f9d58c2..71d78e7 100755 --- a/tools/h5diff/testh5diff.sh +++ b/tools/h5diff/testh5diff.sh @@ -56,6 +56,12 @@ 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 +# same structure, same obj name with different value +EXCLUDE_FILE1_1=h5diff_exclude1-1.h5 +EXCLUDE_FILE1_2=h5diff_exclude1-2.h5 +# different structure and obj names +EXCLUDE_FILE2_1=h5diff_exclude2-1.h5 +EXCLUDE_FILE2_2=h5diff_exclude2-2.h5 TESTNAME=h5diff EXIT_SUCCESS=0 @@ -727,6 +733,25 @@ TOOLTEST h5diff_512.txt -v --follow-symlinks $GRP_RECURSE_FILE1 $GRP_RECURSE_FIL 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 +# ############################################################################## +# # Exclude objects (--exclude-path) +# ############################################################################## +# +# Same structure, same names and different value. +# +# Exclude the object with different value. Expect return - same +TOOLTEST h5diff_480.txt -v --exclude-path /group1/dset3 $EXCLUDE_FILE1_1 $EXCLUDE_FILE1_2 +# Verify different by not excluding. Expect return - diff +TOOLTEST h5diff_481.txt -v $EXCLUDE_FILE1_1 $EXCLUDE_FILE1_2 + +# +# Different structure, different names. +# +# Exclude all the different objects. Expect return - same +TOOLTEST h5diff_482.txt -v --exclude-path "/group1" --exclude-path "/dset1" $EXCLUDE_FILE2_1 $EXCLUDE_FILE2_2 +# Exclude only some different objects. Expect return - diff +TOOLTEST h5diff_483.txt -v --exclude-path "/group1" $EXCLUDE_FILE2_1 $EXCLUDE_FILE2_2 + # ############################################################################## diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c index 2734bef..d462b45 100644 --- a/tools/lib/h5diff.c +++ b/tools/lib/h5diff.c @@ -224,6 +224,99 @@ out: } /*------------------------------------------------------------------------- + * Function: is_exclude_path + * + * Purpose: check if 'paths' are part of exclude path list + * + * Return: + * 1 - excluded path + * 0 - not excluded path + * + * Programmer: Jonathan Kim + * Date: Aug 23, 2010 + *------------------------------------------------------------------------*/ +static int is_exclude_path (trav_path_t * paths, diff_opt_t *options) +{ + struct exclude_path_list * exclude_path_ptr; + int ret_cmp; + int ret = 0; + int len_grp; + + /* check if exclude path option is given */ + if (!options->exclude_path) + goto out; + + /* assign to local exclude list pointer */ + exclude_path_ptr = options->exclude; + + /* search objects in exclude list */ + while (NULL != exclude_path_ptr) + { + /* if given object is group, exclude its members as well */ + if (exclude_path_ptr->obj_type == H5TRAV_TYPE_GROUP) + { + ret_cmp = HDstrncmp(exclude_path_ptr->obj_path, paths->path, + strlen(exclude_path_ptr->obj_path)); + if (ret_cmp == 0) + { + /* check if given path belong to an excluding group, if so + * exclude it as well. + * This verifies if “/grp1/dset1” is only under “/grp1”, but + * not under “/grp1xxx/” group. + */ + len_grp = HDstrlen(exclude_path_ptr->obj_path); + if (paths->path[len_grp] == '/') + { + /* belong to excluded group! */ + ret = 1; + break; /* while */ + } + } + } + /* exclude target is not group, just exclude the object */ + else + { + ret_cmp = HDstrcmp(exclude_path_ptr->obj_path, paths->path); + if (ret_cmp == 0) + { + /* excluded non-group object */ + ret = 1; + /* assign type as scan progress, which is sufficient to + * determine type for excluding groups from the above if. */ + exclude_path_ptr->obj_type = paths->type; + break; /* while */ + } + } + exclude_path_ptr = exclude_path_ptr->next; + } + +out: + return ret; +} + + +/*------------------------------------------------------------------------- + * Function: free_exclude_path_list + * + * Purpose: free exclud object list from diff options + * + * Programmer: Jonathan Kim + * Date: Aug 23, 2010 + *------------------------------------------------------------------------*/ +static void free_exclude_path_list(diff_opt_t *options) +{ + struct exclude_path_list * curr = options->exclude; + struct exclude_path_list * next; + + while (NULL != curr) + { + next = curr->next; + HDfree(curr); + curr = next; + } +} + +/*------------------------------------------------------------------------- * Function: build_match_list * * Purpose: get list of matching path_name from info1 and info2 @@ -283,25 +376,33 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch 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); - + if(!is_exclude_path(&(info1->paths[curr1]), options)) + { + 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); + if(!is_exclude_path(&(info1->paths[curr1]), options)) + { + 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); + if (!is_exclude_path(&(info2->paths[curr2]), options)) + { + infile[0] = 0; + infile[1] = 1; + trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); + } curr2++; } /* end else */ } /* end while */ @@ -311,8 +412,11 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch infile[1] = 0; while(curr1 < info1->nused) { - path1_lp = (info1->paths[curr1].path) + path1_offset; - trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); + if(!is_exclude_path(&(info1->paths[curr1]), options)) + { + path1_lp = (info1->paths[curr1].path) + path1_offset; + trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table); + } curr1++; } /* end while */ @@ -321,11 +425,15 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch infile[1] = 1; while(curr2 < info2->nused) { - path2_lp = (info2->paths[curr2].path) + path2_offset; - trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); + if (!is_exclude_path(&(info2->paths[curr2]), options)) + { + path2_lp = (info2->paths[curr2].path) + path2_offset; + trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table); + } curr2++; } /* end while */ + free_exclude_path_list (options); /*------------------------------------------------------ * print the list */ @@ -968,10 +1076,14 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, *------------------------------------------------------------------------- */ - /* number of different objects */ - if ( info1->nused != info2->nused ) + /* not valid compare nused when --exclude-path option is used */ + if (!options->exclude_path) { - options->contents = 0; + /* number of different objects */ + if ( info1->nused != info2->nused ) + { + options->contents = 0; + } } /* objects in one file and not the other */ @@ -980,6 +1092,7 @@ hsize_t diff_match(hid_t file1_id, const char *grp1, trav_info_t *info1, if( table->objs[i].flags[0] != table->objs[i].flags[1] ) { options->contents = 0; + break; } } diff --git a/tools/lib/h5diff.h b/tools/lib/h5diff.h index 916197d..c89b9d3 100644 --- a/tools/lib/h5diff.h +++ b/tools/lib/h5diff.h @@ -25,6 +25,12 @@ * command line options *------------------------------------------------------------------------- */ +/* linked list to keep exclude path list */ +struct exclude_path_list { + char *obj_path; + h5trav_type_t obj_type; + struct exclude_path_list * next; +}; typedef struct { int m_quiet; /* quiet mide: no output at all */ @@ -45,6 +51,8 @@ typedef struct { int contents; /* equal contents */ int do_nans; /* consider Nans while diffing floats */ int m_list_not_cmp; /* list not comparable messages */ + int exclude_path; /* exclude path to an object */ + struct exclude_path_list * exclude; /* keep exclude path list */ } diff_opt_t; diff --git a/windows/tools/h5diff/testh5diff.bat b/windows/tools/h5diff/testh5diff.bat index 17babe4..d8c3100 100644 --- a/windows/tools/h5diff/testh5diff.bat +++ b/windows/tools/h5diff/testh5diff.bat @@ -50,6 +50,10 @@ 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 srcexclude1_1=h5diff_exclude1-1.h5 +set srcexclude1_2=h5diff_exclude1-2.h5 +set srcexclude2_1=h5diff_exclude2-1.h5 +set srcexclude2_2=h5diff_exclude2-2.h5 set file1=%indir%\h5diff_basic1.h5 set file2=%indir%\h5diff_basic2.h5 @@ -73,6 +77,10 @@ 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 +set exclude1_1=%indir%\h5diff_exclude1-1.h5 +set exclude1_2=%indir%\h5diff_exclude1-2.h5 +set exclude2_1=%indir%\h5diff_exclude2-1.h5 +set exclude2_2=%indir%\h5diff_exclude2-2.h5 rem The tool name @@ -785,6 +793,33 @@ rem ############################################################################ 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 # Exclude objects (--exclude-object) + rem ############################################################################## + rem #------------------------------------------------- + rem # Same structure, same names and different value. + + rem Exclude the object with different value. Expect return - same + call :testing %h5diff% -v --exclude-object /group1/dset3 %srcexclude1_1% %srcexclude1_2% + call :tooltest h5diff_480.txt -v --exclude-object /group1/dset3 %exclude1_1% %exclude1_2% + + rem Verify different by not excluding. Expect return - diff + call :testing %h5diff% -v %srcexclude1_1% %srcexclude1_2% + call :tooltest h5diff_481.txt -v %exclude1_1% %exclude1_2% + + rem #---------------------------------------- + rem # Different structure, different names. + + rem Exclude all the different objects. Expect return - same + call :testing %h5diff% -v --exclude-object "/group1" --exclude-object "/dset1" %srcexclude2_1% %srcexclude2_2% + call :tooltest h5diff_482.txt -v --exclude-object "/group1" --exclude-object "/dset1" %exclude2_1% %exclude2_2% + + rem Exclude only some different objects. Expect return - diff + call :testing %h5diff% -v --exclude-object "/group1" %srcexclude2_1% %srcexclude2_2% + call :tooltest h5diff_483.txt -v --exclude-object "/group1" %exclude2_1% %exclude2_2% + rem ####################################################################### rem # END -- cgit v0.12