summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Kim <jkm@hdfgroup.org>2010-09-16 21:46:16 (GMT)
committerJonathan Kim <jkm@hdfgroup.org>2010-09-16 21:46:16 (GMT)
commiteb7b5b2ceffb9bed00959c4131ce9cfed09628c4 (patch)
treedb0f10ded30b447a2f2900628e3457455f06976f
parent4bae291b1f0f4d6a51f24d18bc68e4c4475498b5 (diff)
downloadhdf5-eb7b5b2ceffb9bed00959c4131ce9cfed09628c4.zip
hdf5-eb7b5b2ceffb9bed00959c4131ce9cfed09628c4.tar.gz
hdf5-eb7b5b2ceffb9bed00959c4131ce9cfed09628c4.tar.bz2
[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
-rw-r--r--MANIFEST9
-rw-r--r--release_docs/RELEASE.txt4
-rw-r--r--tools/h5diff/CMakeLists.txt36
-rw-r--r--tools/h5diff/h5diff_common.c38
-rw-r--r--tools/h5diff/h5diffgentest.c293
-rw-r--r--tools/h5diff/testfiles/h5diff_480.txt17
-rw-r--r--tools/h5diff/testfiles/h5diff_481.txt30
-rw-r--r--tools/h5diff/testfiles/h5diff_482.txt17
-rw-r--r--tools/h5diff/testfiles/h5diff_483.txt18
-rw-r--r--tools/h5diff/testfiles/h5diff_exclude1-1.h5bin0 -> 5064 bytes
-rw-r--r--tools/h5diff/testfiles/h5diff_exclude1-2.h5bin0 -> 5064 bytes
-rw-r--r--tools/h5diff/testfiles/h5diff_exclude2-1.h5bin0 -> 5064 bytes
-rw-r--r--tools/h5diff/testfiles/h5diff_exclude2-2.h5bin0 -> 6056 bytes
-rwxr-xr-xtools/h5diff/testh5diff.sh25
-rw-r--r--tools/lib/h5diff.c147
-rw-r--r--tools/lib/h5diff.h8
-rw-r--r--windows/tools/h5diff/testh5diff.bat35
17 files changed, 659 insertions, 18 deletions
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: </dset1> and </dset1>
+0 differences found
+group : </group1> and </group1>
+0 differences found
+dataset: </group1/dset2> and </group1/dset2>
+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: </dset1> and </dset1>
+0 differences found
+group : </group1> and </group1>
+0 differences found
+dataset: </group1/dset2> and </group1/dset2>
+0 differences found
+dataset: </group1/dset3> and </group1/dset3>
+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: </dset10> and </dset10>
+0 differences found
+group : </group10> and </group10>
+0 differences found
+dataset: </group10/dset2> and </group10/dset2>
+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: </dset10> and </dset10>
+0 differences found
+group : </group10> and </group10>
+0 differences found
+dataset: </group10/dset2> and </group10/dset2>
+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
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_exclude1-1.h5
Binary files 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
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_exclude1-2.h5
Binary files 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
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_exclude2-1.h5
Binary files 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
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_exclude2-2.h5
Binary files 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