From 0c6929dfdefec1c5e6cdaae92b314b8a74492a47 Mon Sep 17 00:00:00 2001
From: Jonathan Kim <jkm@hdfgroup.org>
Date: Mon, 18 Oct 2010 18:17:33 -0500
Subject: [svn-r19634] Purpose:  Fix for bug# 2040 - h5copy should fail
 gracefully for expected failure copying to non-exist nested group without -p
 option.

Description:
 Fixed h5copy to fail gracefully when copying object to non-exist group without -p option. This is expected to be failed.
 Merged from hdf5 trunk r19633.


Tested:
 jam, amani
---
 MANIFEST                                |   1 +
 release_docs/RELEASE.txt                |   3 +-
 tools/h5copy/h5copy.c                   |  26 +++++++-
 tools/h5copy/testfiles/h5copy_misc1.out |   3 +
 tools/h5copy/testh5copy.sh              | 110 +++++++++++++++++++++++++-------
 5 files changed, 116 insertions(+), 27 deletions(-)
 create mode 100644 tools/h5copy/testfiles/h5copy_misc1.out

diff --git a/MANIFEST b/MANIFEST
index da8e50b..c6bf38e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1694,6 +1694,7 @@
 ./tools/h5copy/testfiles/h5copy_extlinks_src.h5
 ./tools/h5copy/testfiles/h5copy_extlinks_trg.h5
 ./tools/h5copy/testfiles/h5copy_extlinks_src.out.ls
+./tools/h5copy/testfiles/h5copy_misc1.out
 
 # test files for h5mkgrp
 ./tools/testfiles/h5mkgrp_help.ls
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 80b8146..625ea43 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -106,7 +106,8 @@ Bug Fixes since HDF5-1.8.6
 
     Tools
     -----
-    - None
+    - Fixed h5copy to fail gracefully when copying object to non-exist
+          group without -p option. Bug#2040 (JKM 2010/10/18)
 
     F90 API
     ------
diff --git a/tools/h5copy/h5copy.c b/tools/h5copy/h5copy.c
index eb16754..e974063 100644
--- a/tools/h5copy/h5copy.c
+++ b/tools/h5copy/h5copy.c
@@ -215,12 +215,17 @@ main (int argc, const char *argv[])
  int          opt;
  int          li_ret;
  h5tool_link_info_t linkinfo;
+ int          i, len;
+ char         *str_prt=NULL;
 
  h5tools_setprogname(PROGRAMNAME);
  h5tools_setstatus(EXIT_SUCCESS);
 /* initialize h5tools lib */
  h5tools_init();
 
+ /* init linkinfo struct */
+ memset(&linkinfo, 0, sizeof(h5tool_link_info_t));
+
  /* Check for no command line parameters */
  if(argc == 1) {
    usage();
@@ -406,12 +411,29 @@ main (int argc, const char *argv[])
         if(verbose)
             printf("%s: Creating parent groups\n", h5tools_getprogname());
     } /* end if */
+    else /* error, if parent groups doesn't already exist in destination file */
+    {
+        len = strlen(oname_dst);        
+        /* check if all the parents groups exist. skip root group */
+        for (i = 1; i < len-1; i++)
+        {
+            if ('/'==oname_dst[i])
+            {
+                str_prt = strndup(oname_dst, (size_t)i);
+                if (H5Lexists(fid_dst, str_prt, H5P_DEFAULT) <= 0)
+                {
+                    error_msg("group <%s> doesn't exist. Use -p to create parent groups.\n", str_prt);
+                    free(str_prt);
+                    goto error;
+                }
+                free(str_prt);
+            }
+        }
+    }
 
 /*-------------------------------------------------------------------------
  * do the copy
  *-------------------------------------------------------------------------*/
- /* init linkinfo struct */
- memset(&linkinfo, 0, sizeof(h5tool_link_info_t));
  
  if(verbose)
     linkinfo.opt.msg_mode = 1;
diff --git a/tools/h5copy/testfiles/h5copy_misc1.out b/tools/h5copy/testfiles/h5copy_misc1.out
new file mode 100644
index 0000000..370b1a5
--- /dev/null
+++ b/tools/h5copy/testfiles/h5copy_misc1.out
@@ -0,0 +1,3 @@
+Copying file <h5copytst.h5> and object </simple> to file <./testfiles/h5copytst.out.h5> and object </g1/g2/simple>
+Error in copy...Exiting
+h5copy error: group </g1> doesn't exist. Use -p to create parent groups.
diff --git a/tools/h5copy/testh5copy.sh b/tools/h5copy/testh5copy.sh
index a54816e..7d26b3b 100644
--- a/tools/h5copy/testh5copy.sh
+++ b/tools/h5copy/testh5copy.sh
@@ -91,6 +91,15 @@ VERIFY_H5LS()
     echo "Verifying h5ls file structure $* $SPACES" | cut -c1-70 | tr -d '\012'
 }
 
+# Print a line-line message left justified in a field of 70 characters
+# beginning with the word "Verifying".
+#
+VERIFY_OUTPUT() 
+{
+    SPACES="                                                               "
+    echo "Verifying output files $* $SPACES" | cut -c1-70 | tr -d '\012'
+}
+
 # Run a test and print PASS or *FAIL*. If h5copy can complete
 # with exit status 0, consider it pass. If a test fails then increment
 # the `nerrors' global variable.
@@ -143,44 +152,74 @@ TOOLTEST()
 }
 
 
+# Compare the two text files
+# PASS if same
+# FAIL if different, and show the diff
+#
+# Assumed arguments:
+# $1 is text file1 (expected output)
+# $2 is text file2 (actual output)
+CMP_OUTPUT()
+{
+    expect=$1
+    actual=$2
+
+    VERIFY_OUTPUT $@
+    if [ ! -f $expect ]; then
+        # Create the expect file if it doesn't yet exist.
+        echo " CREATED"
+        cp $actual $expect
+    elif $CMP $expect $actual; then
+        echo " PASSED"
+    else
+        echo "*FAILED*"
+        echo "    Expected output differs from actual output"
+        nerrors="`expr $nerrors + 1`"
+        test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/    /'
+    fi
+}
+
 TOOLTEST_FAIL() 
 {
-     runh5diff=yes
-     if [ "$1" = -i ]; then
+    expectout="$INDIR/$1"
+    actualout="$OUTDIR/$1.out"
+    actualerr="$OUTDIR/$1.err"
+    shift
+    if [ "$1" = -i ]; then
       inputfile=$2
-     else
-      runh5diff=no
-     fi
-     if [ "$3" = -o ]; then
+    fi
+    if [ "$3" = -o ]; then
       outputfile=$4
-     else 
-      runh5diff=no
-     fi
-  
+    fi
+
     TESTING $H5COPY $@
     (
-    echo "#############################"
-    echo " output for '$H5COPY $@'"
-    echo "#############################"
+    #echo "#############################"
+    #echo " output for '$H5COPY $@'"
+    #echo "#############################"
     $RUNSERIAL $H5COPY_BIN $@
-    ) > output.out
+    ) > $actualout 2> $actualerr
     RET=$?
     if [ $RET != 0 ]; then
+        echo " PASSED"
+        # Verifying output text from h5copy
+        if [ "$expectout" != "SKIP" ]; then
+            # combine stderr to stdout to compare the output at once.
+            # We may seperate stdout and stderr later.
+            cat $actualerr >> $actualout
+            CMP_OUTPUT $expectout $actualout
+        fi
+    else
         echo "*FAILED*"
         echo "failed result is:"
-        cat output.out
+        cat $actualout
         nerrors="`expr $nerrors + 1`"
-    else
-        echo " PASSED"
-
-        # Clean up output file
-        if test -z "$HDF5_NOCLEANUP"; then
-           rm -f output.out
-        fi
     fi
    
-    if [ $runh5diff != no ]; then
-     H5DIFFTEST_FAIL $inputfile $outputfile $7 $9
+
+    # Clean up output file
+    if test -z "$HDF5_NOCLEANUP"; then
+       rm -f $actualout $actualerr
     fi
 }
 
@@ -389,6 +428,28 @@ COPY_EXT_LINKS()
     fi
 }
 
+# Test misc.
+#
+# Assumed arguments:
+# <none>
+TEST_MISC() 
+{
+    TESTFILE="$HDF_FILE1"
+    FILEOUT="$OUTDIR/`basename $HDF_FILE1 .h5`.out.h5"
+
+    # Remove any output file left over from previous test run
+    rm -f $FILEOUT
+
+    echo "Test copying object into group which doesn't exist, without -p"
+    TOOLTEST_FAIL h5copy_misc1.out -v -i $TESTFILE -o $FILEOUT -s /simple  -d /g1/g2/simple
+
+    # Remove output file created, if the "no cleanup" environment variable is
+    #   not defined
+    if test -z "$HDF5_NOCLEANUP"; then
+        rm -f $FILEOUT
+    fi
+}
+
 ##############################################################################
 ###           T H E   T E S T S                                            ###
 ##############################################################################
@@ -396,6 +457,7 @@ COPY_EXT_LINKS()
 COPY_OBJECTS 
 COPY_REFERENCES
 COPY_EXT_LINKS
+TEST_MISC
 
 
 if test $nerrors -eq 0 ; then
-- 
cgit v0.12