From d476ce138bbb78d3f7bf22a21172724f6519a1cf Mon Sep 17 00:00:00 2001
From: Jonathan Kim <jkm@hdfgroup.org>
Date: Wed, 21 Mar 2012 16:00:15 -0500
Subject: [svn-r22114] Purpose:   Fix for HDFFV-7837 - h5diff: incorrect
 behavior with exclude-path option when unique object exist only in one file

Description:
  If unique objects exists only in one file and try to exclude
  the unique objects with --exclude-path option, h5diff missed
  excluding some objects.
  Fixed to exclude objects correctly in such case.
  Test cases were added and tagged with jira#.


Tested:
  jam (linux32-LE), koala (linux64-LE), ostrich (linuxppc64-BE), tejeda (mac32-LE), linew (solaris-BE),  Windows (32-LE cmake), Cmake (jam)
---
 MANIFEST                                    |   5 ++
 release_docs/RELEASE.txt                    |   5 ++
 tools/h5diff/CMakeLists.txt                 |  18 +++++
 tools/h5diff/h5diffgentest.c                | 100 +++++++++++++++++++++++++++-
 tools/h5diff/testfiles/h5diff_485.txt       |  11 +++
 tools/h5diff/testfiles/h5diff_486.txt       |  11 +++
 tools/h5diff/testfiles/h5diff_487.txt       |  12 ++++
 tools/h5diff/testfiles/h5diff_exclude3-1.h5 | Bin 0 -> 4792 bytes
 tools/h5diff/testfiles/h5diff_exclude3-2.h5 | Bin 0 -> 2176 bytes
 tools/h5diff/testh5diff.sh                  |  11 +++
 tools/lib/h5diff.c                          |  19 ++++--
 11 files changed, 184 insertions(+), 8 deletions(-)
 create mode 100644 tools/h5diff/testfiles/h5diff_485.txt
 create mode 100644 tools/h5diff/testfiles/h5diff_486.txt
 create mode 100644 tools/h5diff/testfiles/h5diff_487.txt
 create mode 100644 tools/h5diff/testfiles/h5diff_exclude3-1.h5
 create mode 100644 tools/h5diff/testfiles/h5diff_exclude3-2.h5

diff --git a/MANIFEST b/MANIFEST
index ddf5423..fe3a612 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1862,6 +1862,9 @@
 ./tools/h5diff/testfiles/h5diff_482.txt
 ./tools/h5diff/testfiles/h5diff_483.txt
 ./tools/h5diff/testfiles/h5diff_484.txt
+./tools/h5diff/testfiles/h5diff_485.txt
+./tools/h5diff/testfiles/h5diff_486.txt
+./tools/h5diff/testfiles/h5diff_487.txt
 ./tools/h5diff/testfiles/h5diff_500.txt
 ./tools/h5diff/testfiles/h5diff_501.txt
 ./tools/h5diff/testfiles/h5diff_502.txt
@@ -1916,6 +1919,8 @@
 ./tools/h5diff/testfiles/h5diff_exclude1-2.h5
 ./tools/h5diff/testfiles/h5diff_exclude2-1.h5
 ./tools/h5diff/testfiles/h5diff_exclude2-2.h5
+./tools/h5diff/testfiles/h5diff_exclude3-1.h5
+./tools/h5diff/testfiles/h5diff_exclude3-2.h5
 ./tools/h5diff/testfiles/h5diff_comp_vl_strs.h5
 ./tools/h5diff/testfiles/h5diff_dset_zero_dim_size1.h5
 ./tools/h5diff/testfiles/h5diff_dset_zero_dim_size2.h5
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 2726ff1..f0f296c 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -666,6 +666,11 @@ Bug Fixes since HDF5-1.8.0 release
 
     Tools
     -----
+        - h5diff: If unique objects exists only in one file and try to exclude
+          the unique objects with --exclude-path option, h5diff missed 
+          excluding some objects. 
+          Fixed to exclude objects correctly in such case.
+          HDFFV-7837 (JKM 2012/03/20)
         - h5dump: Added tools library error stack to properly catch error
           information generated within the library.
           HDFFV-7958 (ADB 2012/03/12)
diff --git a/tools/h5diff/CMakeLists.txt b/tools/h5diff/CMakeLists.txt
index f178f19..dfd1800 100644
--- a/tools/h5diff/CMakeLists.txt
+++ b/tools/h5diff/CMakeLists.txt
@@ -139,6 +139,9 @@ IF (BUILD_TESTING)
       h5diff_482.txt
       h5diff_483.txt
       h5diff_484.txt
+      h5diff_485.txt
+      h5diff_486.txt
+      h5diff_487.txt
       h5diff_50.txt
       h5diff_51.txt
       h5diff_52.txt
@@ -253,6 +256,8 @@ IF (BUILD_TESTING)
       h5diff_exclude1-2.h5
       h5diff_exclude2-1.h5
       h5diff_exclude2-2.h5
+      h5diff_exclude3-1.h5
+      h5diff_exclude3-2.h5
       h5diff_comp_vl_strs.h5
       h5diff_attr_v_level1.h5
       h5diff_attr_v_level2.h5
@@ -490,6 +495,9 @@ IF (BUILD_TESTING)
   # different structure and obj names
   SET (EXCLUDE_FILE2_1 h5diff_exclude2-1.h5)
   SET (EXCLUDE_FILE2_2 h5diff_exclude2-2.h5)
+  # Only one file contains unique objs. Common objs are same.
+  SET (EXCLUDE_FILE3_1 h5diff_exclude3-1.h5)
+  SET (EXCLUDE_FILE3_2 h5diff_exclude3-2.h5)
   # compound type with multiple vlen string types
   SET (COMP_VL_STRS_FILE h5diff_comp_vl_strs.h5)
   # container types (array,vlen) with multiple nested compound types
@@ -1359,6 +1367,16 @@ ADD_H5_TEST (h5diff_483 1 -v --exclude-path "/group1" ${EXCLUDE_FILE2_1} ${EXCLU
 # Exclude from group compare
 ADD_H5_TEST (h5diff_484 0 -v --exclude-path "/dset3" ${EXCLUDE_FILE1_1} ${EXCLUDE_FILE1_2} /group1)
 
+#
+# Only one file contains unique objs. Common objs are same.
+# (HDFFV-7837)
+#
+ADD_H5_TEST (h5diff_485 0 -v --exclude-path "/group1" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5)
+ADD_H5_TEST (h5diff_486 0 -v --exclude-path "/group1" h5diff_exclude3-2.h5 h5diff_exclude3-1.h5)
+ADD_H5_TEST (h5diff_487 1 -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5)
+
+
+
 # ##############################################################################
 # # diff various multiple vlen and fixed strings in a compound type dataset
 # ##############################################################################
diff --git a/tools/h5diff/h5diffgentest.c b/tools/h5diff/h5diffgentest.c
index d58e1b4..b57c98a 100644
--- a/tools/h5diff/h5diffgentest.c
+++ b/tools/h5diff/h5diffgentest.c
@@ -77,6 +77,9 @@ hsize_t H5TOOLS_MALLOCSIZE = (128 * 1024 * 1024);
 /* different structure and obj names */
 #define EXCLUDE_FILE2_1     "h5diff_exclude2-1.h5"
 #define EXCLUDE_FILE2_2     "h5diff_exclude2-2.h5"
+/* only one file has unique objs  */
+#define EXCLUDE_FILE3_1     "h5diff_exclude3-1.h5"
+#define EXCLUDE_FILE3_2     "h5diff_exclude3-2.h5"
 /* compound type with multiple vlen string types */
 #define COMP_VL_STRS_FILE   "h5diff_comp_vl_strs.h5"
 /* attribute compre with verbose level */
@@ -144,6 +147,7 @@ static int test_group_recurse(const char *fname1, const char *fname2);
 static int test_group_recurse2(void);
 static int test_exclude_obj1(const char *fname1, const char *fname2);
 static int test_exclude_obj2(const char *fname1, const char *fname2);
+static int test_exclude_obj3(const char *fname1, const char *fname2);
 static int test_comp_vlen_strings(const char *fname1, const char *grp_name, int is_file_new);
 static int test_attributes_verbose_level(const char *fname1, const char *fname2);
 static int test_enums(const char *fname);
@@ -213,6 +217,7 @@ int main(void)
 
     test_exclude_obj1(EXCLUDE_FILE1_1, EXCLUDE_FILE1_2);
     test_exclude_obj2(EXCLUDE_FILE2_1, EXCLUDE_FILE2_2);
+    test_exclude_obj3(EXCLUDE_FILE3_1, EXCLUDE_FILE3_2);
 
     /* diff various multiple vlen and fixlen string types in a compound dataset */
     test_comp_vlen_strings(COMP_VL_STRS_FILE, "group", 1);
@@ -3344,6 +3349,100 @@ out:
 
 /*-------------------------------------------------------------------------
 *
+* Purpose: Create test files for excluding obj.
+*          Only one file contains unique objs. Common objs are same.
+* Test : exclude unique objs to verify the rest are same
+*  - HDFFV-7837
+*
+* Programmer: Jonathan Kim (Mar, 19, 2012)
+*
+*-------------------------------------------------------------------------*/
+static int test_exclude_obj3(const char *fname1, const char *fname2)
+{
+    hid_t   fid1=0;
+    hid_t   fid2=0;
+    hid_t   gid1=0;
+    hsize_t dims2[2] = {2,4};
+    int data1[4][2] = {{0,0},{0,0},{0,0},{0,0}};
+    herr_t  status = SUCCEED;
+
+    /*-----------------------------------------------------------------------
+    * Create file(s)
+    *------------------------------------------------------------------------*/
+    fid1 = H5Fcreate (fname1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    if (fid1 < 0)
+    {
+        fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname1);
+        status = FAIL;
+        goto out;
+    }
+
+    fid2 = H5Fcreate (fname2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    if (fid2 < 0)
+    {
+        fprintf(stderr, "Error: %s> H5Fcreate failed.\n", fname2);
+        status = FAIL;
+        goto out;
+    }
+
+
+   /*-----------------------------------------------------------------------
+    * Group
+    *------------------------------------------------------------------------*/
+    /* file1 */
+    gid1 = H5Gcreate2(fid1, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+    if (gid1 < 0)
+    {
+        fprintf(stderr, "Error: %s> H5Gcreate2 failed.\n", fname1);
+        status = FAIL;
+        goto out;
+    }
+
+    /*-----------------------------------------------------------------------
+    * Datasets
+    *------------------------------------------------------------------------*/
+    /* file1 */
+    status = write_dset(fid1,2,dims2,"dset1",H5T_NATIVE_INT,data1);
+    if (status == FAIL)
+    {
+        fprintf(stderr, "Error: %s> write_dset failed\n", fname1);
+        status = FAIL;
+        goto out;
+    }
+
+    status = write_dset(gid1,2,dims2,"dset",H5T_NATIVE_INT,data1);
+    if (status == FAIL)
+    {
+        fprintf(stderr, "Error: %s> write_dset failed\n", fname1);
+        status = FAIL;
+        goto out;
+    }
+
+    /* file2 */
+    status = write_dset(fid2,2,dims2,"dset1",H5T_NATIVE_INT,data1);
+    if (status == FAIL)
+    {
+        fprintf(stderr, "Error: %s> write_dset failed\n", fname2);
+        status = FAIL;
+        goto out;
+    }
+
+out:
+    /*-----------------------------------------------------------------------
+    * Close
+    *-----------------------------------------------------------------------*/
+    if(fid1)
+        H5Fclose(fid1);
+    if(fid2)
+        H5Fclose(fid2);
+    if(gid1)
+        H5Gclose(gid1);
+
+    return status;
+}
+
+/*-------------------------------------------------------------------------
+*
 * Purpose: Create test files for multiple variable length string/string array
 *          along with fixed length string/string array types in
 *          a compound type dataset.
@@ -4717,7 +4816,6 @@ static void test_non_comparables (const char * fname, int make_diffs)
     int rank_attr;
     char data1_str[DIM_ARRY][STR_SIZE]= {"ab","cd","ef"};
     herr_t  status = SUCCEED;
-    int i;
     void *dset_data_ptr1=NULL;
     void *dset_data_ptr2=NULL;
     void *dset_data_ptr3=NULL;
diff --git a/tools/h5diff/testfiles/h5diff_485.txt b/tools/h5diff/testfiles/h5diff_485.txt
new file mode 100644
index 0000000..4175809
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_485.txt
@@ -0,0 +1,11 @@
+
+file1     file2
+---------------------------------------
+    x      x    /              
+    x      x    /dset1         
+
+group  : </> and </>
+0 differences found
+dataset: </dset1> and </dset1>
+0 differences found
+EXIT CODE: 0
diff --git a/tools/h5diff/testfiles/h5diff_486.txt b/tools/h5diff/testfiles/h5diff_486.txt
new file mode 100644
index 0000000..4175809
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_486.txt
@@ -0,0 +1,11 @@
+
+file1     file2
+---------------------------------------
+    x      x    /              
+    x      x    /dset1         
+
+group  : </> and </>
+0 differences found
+dataset: </dset1> and </dset1>
+0 differences found
+EXIT CODE: 0
diff --git a/tools/h5diff/testfiles/h5diff_487.txt b/tools/h5diff/testfiles/h5diff_487.txt
new file mode 100644
index 0000000..8555a71
--- /dev/null
+++ b/tools/h5diff/testfiles/h5diff_487.txt
@@ -0,0 +1,12 @@
+
+file1     file2
+---------------------------------------
+    x      x    /              
+    x      x    /dset1         
+    x           /group1        
+
+group  : </> and </>
+0 differences found
+dataset: </dset1> and </dset1>
+0 differences found
+EXIT CODE: 1
diff --git a/tools/h5diff/testfiles/h5diff_exclude3-1.h5 b/tools/h5diff/testfiles/h5diff_exclude3-1.h5
new file mode 100644
index 0000000..f9cc83d
Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude3-1.h5 differ
diff --git a/tools/h5diff/testfiles/h5diff_exclude3-2.h5 b/tools/h5diff/testfiles/h5diff_exclude3-2.h5
new file mode 100644
index 0000000..f811905
Binary files /dev/null and b/tools/h5diff/testfiles/h5diff_exclude3-2.h5 differ
diff --git a/tools/h5diff/testh5diff.sh b/tools/h5diff/testh5diff.sh
index 2e2feb9..27fb253 100755
--- a/tools/h5diff/testh5diff.sh
+++ b/tools/h5diff/testh5diff.sh
@@ -111,6 +111,8 @@ $SRC_H5DIFF_TESTFILES/h5diff_exclude1-1.h5
 $SRC_H5DIFF_TESTFILES/h5diff_exclude1-2.h5
 $SRC_H5DIFF_TESTFILES/h5diff_exclude2-1.h5
 $SRC_H5DIFF_TESTFILES/h5diff_exclude2-2.h5
+$SRC_H5DIFF_TESTFILES/h5diff_exclude3-1.h5
+$SRC_H5DIFF_TESTFILES/h5diff_exclude3-2.h5
 $SRC_H5DIFF_TESTFILES/h5diff_comp_vl_strs.h5
 $SRC_H5DIFF_TESTFILES/compounds_array_vlen1.h5
 $SRC_H5DIFF_TESTFILES/compounds_array_vlen2.h5
@@ -1027,6 +1029,15 @@ TOOLTEST h5diff_483.txt -v --exclude-path "/group1" h5diff_exclude2-1.h5 h5diff_
 # Exclude from group compare
 TOOLTEST h5diff_484.txt -v --exclude-path "/dset3" h5diff_exclude1-1.h5 h5diff_exclude1-2.h5 /group1
 
+#
+# Only one file contains unique objs. Common objs are same.
+# (HDFFV-7837)
+#
+TOOLTEST h5diff_485.txt -v --exclude-path "/group1" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5
+TOOLTEST h5diff_486.txt -v --exclude-path "/group1" h5diff_exclude3-2.h5 h5diff_exclude3-1.h5
+TOOLTEST h5diff_487.txt -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5 h5diff_exclude3-2.h5
+
+
 # ##############################################################################
 # # diff various multiple vlen and fixed strings in a compound type dataset
 # ##############################################################################
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c
index c6353eb..cef30dd 100644
--- a/tools/lib/h5diff.c
+++ b/tools/lib/h5diff.c
@@ -270,12 +270,12 @@ static int is_exclude_path (char * path, h5trav_type_t type, diff_opt_t *options
     /* search objects in exclude list */
     while (NULL != exclude_path_ptr)
     {
-        /* if given object is group, exclude its members as well */
+        /* if exclude path is is group, exclude its members as well */
         if (exclude_path_ptr->obj_type == H5TRAV_TYPE_GROUP)
         {
             ret_cmp = HDstrncmp(exclude_path_ptr->obj_path, path,
                                 HDstrlen(exclude_path_ptr->obj_path));
-            if (ret_cmp == 0)
+            if (ret_cmp == 0)  /* found matching members */
             {
                 /* check if given path belong to an excluding group, if so 
                  * exclude it as well.
@@ -295,12 +295,13 @@ static int is_exclude_path (char * path, h5trav_type_t type, diff_opt_t *options
         else  
         {
             ret_cmp = HDstrcmp(exclude_path_ptr->obj_path, path);
-            if (ret_cmp == 0)
+            if (ret_cmp == 0)  /* found matching object */
             {
                 /* excluded non-group object */
                 ret = 1;
-                /* assign type as scan progress, which is sufficient to 
-                 * determine type for excluding groups from the above if. */
+                /* remember the type of this maching object. 
+                 * if it's group, it can be used for excluding its member 
+                 * objects in this while() loop */
                 exclude_path_ptr->obj_type = type;
                 break; /* while */
             }
@@ -443,9 +444,11 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch
     infile[1] = 0;
     while(curr1 < info1->nused)
     {
+        path1_lp = (info1->paths[curr1].path) + path1_offset;
+        type1_l = info1->paths[curr1].type;
+
         if(!is_exclude_path(path1_lp, type1_l, options))
         {
-            path1_lp = (info1->paths[curr1].path) + path1_offset;
             trav_table_addflags(infile, path1_lp, info1->paths[curr1].type, table);
         }
         curr1++;
@@ -456,9 +459,11 @@ static void build_match_list (const char *objname1, trav_info_t *info1, const ch
     infile[1] = 1;
     while(curr2 < info2->nused)
     {
+        path2_lp = (info2->paths[curr2].path) + path2_offset;
+        type2_l = info2->paths[curr2].type;
+
         if (!is_exclude_path(path2_lp, type2_l, options))
         {
-            path2_lp = (info2->paths[curr2].path) + path2_offset;
             trav_table_addflags(infile, path2_lp, info2->paths[curr2].type, table);
         } 
         curr2++;
-- 
cgit v0.12