From 6d97ffcc6cec0c23e718da16fcf0f2043df046c5 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Thu, 16 Sep 2010 16:57:27 -0500 Subject: [svn-r19407] Purpose: Add --exclude-path option Description: Merged from hdf5 trunk (r19406). 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 --- 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 7b8eaab..316861a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1581,6 +1581,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 @@ -1619,7 +1623,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 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 2e8a3ad..7680d46 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -84,6 +84,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 909d2e2..739cc18 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 ed2a68f..29823e4 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